Login Page - Create Account

Support Board


Date/Time: Thu, 28 Mar 2024 23:34:45 +0000



[User Discussion] - Auto Trade ACSIL: how to enter at bar close

View Count: 5400

[2013-12-08 16:03:45]
User11748 - Posts: 14
Hi,

In ACSIL "Trading example" provided by SC, the strategy enters "at the market" at the open of the next day.

For testing purpose, I would need the backtest to run with entry at today's bar close (the same day as the signal is observed).

Is it technically possible using ACSIL?

I have searched into the documentation, but found no answer. Sorry if I missed it.

Thanks in advance,

Nicolas
[2013-12-08 20:27:37]
Sierra Chart Engineering - Posts: 104368
Yes. This is the default. Nothing special to do, just make sure that you do not prevent processing on the last bar in the chart.

Specifically what is the code you are referring to that does this:

the strategy enters "at the market" at the open of the next day.

Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing
Date Time Of Last Edit: 2013-12-08 20:28:06
[2013-12-08 20:44:55]
User11748 - Posts: 14
I am using "scsf_TradingExample" proposed as an example by SC in tradingsystem.cpp

I have made no modification, except adding
SCDLLName("Test Strategy");
at the beginning.

Full code below.

As shown on the screenshot, the strategy enters at the open of the bar after.

For the purpose of backtesting, is it possible to have it enter at the close of the current bar (the one on which the signal is activated)?

Thanks in advance,

Nicolas


#include "sierrachart.h"


SCDLLName("Test Strategy");

SCSFExport scsf_TradingExample(SCStudyInterfaceRef sc)
{
  //Define references to the Subgraphs and Inputs for easy reference
  SCSubgraphRef BuyEntrySubgraph = sc.Subgraph[0];
  SCSubgraphRef BuyExitSubgraph = sc.Subgraph[1];
  SCSubgraphRef SellEntrySubgraph = sc.Subgraph[2];
  SCSubgraphRef SellExitSubgraph = sc.Subgraph[3];

  SCSubgraphRef SimpMovAvgSubgraph = sc.Subgraph[4];

  SCInputRef Enabled = sc.Input[0];
  SCInputRef TargetValue = sc.Input[1];
  SCInputRef StopValue = sc.Input[2];


  if (sc.SetDefaults)
  {
    // Set the study configuration and defaults.

    sc.GraphName = "Trading Example";

    BuyEntrySubgraph.Name = "Buy Entry";
    BuyEntrySubgraph.DrawStyle = DRAWSTYLE_ARROWUP;
    BuyEntrySubgraph.PrimaryColor = RGB(0, 255, 0);
    BuyEntrySubgraph.LineWidth = 2;
    BuyEntrySubgraph.DrawZeros = false;

    BuyExitSubgraph.Name = "Buy Exit";
    BuyExitSubgraph.DrawStyle = DRAWSTYLE_ARROWDOWN;
    BuyExitSubgraph.PrimaryColor = RGB(255, 128, 128);
    BuyExitSubgraph.LineWidth = 2;
    BuyExitSubgraph.DrawZeros = false;

    SellEntrySubgraph.Name = "Sell Entry";
    SellEntrySubgraph.DrawStyle = DRAWSTYLE_ARROWDOWN;
    SellEntrySubgraph.PrimaryColor = RGB(255, 0, 0);
    SellEntrySubgraph.LineWidth = 2;
    SellEntrySubgraph.DrawZeros = false;

    SellExitSubgraph.Name = "Sell Exit";
    SellExitSubgraph.DrawStyle = DRAWSTYLE_ARROWUP;
    SellExitSubgraph.PrimaryColor = RGB(128, 255, 128);
    SellExitSubgraph.LineWidth = 2;
    SellExitSubgraph.DrawZeros = false;

    SimpMovAvgSubgraph.Name = "Simple Moving Average";
    SimpMovAvgSubgraph.DrawStyle = DRAWSTYLE_LINE;
    SimpMovAvgSubgraph.DrawZeros = false;

    Enabled.Name = "Enabled";
    Enabled.SetYesNo(0);

    TargetValue.Name = "Target Value";
    TargetValue.SetFloat(2.0f);

    StopValue.Name = "Stop Value";
    StopValue.SetFloat(1.0f);

    sc.StudyDescription = "This study function is an example of how to use the ACSIL Trading Functions. This function will display a simple moving average and perform a Buy Entry when the Last price crosses the moving average from below and a Sell Entry when the Last price crosses the moving average from above. A new entry cannot occur until the Target or Stop has been hit. When an order is sent, a corresponding arrow will appear on the chart to show that an order was sent. This study will do nothing until the Enabled Input is set to Yes.";

    sc.AllowMultipleEntriesInSameDirection = false;
    sc.MaximumPositionAllowed = 10;
    sc.SupportReversals = false;

    // This is false by default. Orders will go to the simulation system always.
    sc.SendOrdersToTradeService = false;

    sc.AllowOppositeEntryWithOpposingPositionOrOrders = false;
    sc.SupportAttachedOrdersForTrading = false;
    sc.CancelAllOrdersOnEntriesAndReversals= true;
    sc.AllowEntryWithWorkingOrders = false;
    sc.CancelAllWorkingOrdersOnExit = false;

    // Only 1 trade for each Order Action type is allowed per bar.
    sc.AllowOnlyOneTradePerBar = true;

    //This needs to be set to true when a trading study uses trading functions.
    sc.MaintainTradeStatisticsAndTradesData = true;

    sc.AutoLoop = 1;
    sc.GraphRegion = 0;

    // During development set this flag to 1, so the DLL can be modified. When development is completed, set it to 0 to improve performance.
    sc.FreeDLL = 0;

    return;
  }




  if (!Enabled.GetYesNo())
    return;
  
  SCFloatArrayRef Last = sc.Close;
  
  // Simple moving average in the 5th subgraph.
  sc.SimpleMovAvg(Last, SimpMovAvgSubgraph, sc.Index, 10);
  

  // Get the Internal Position data to be used for position exit processing.
  s_SCPositionData PositionData;
  sc.GetTradePosition(PositionData) ;


  float LastTradePrice = sc.Close[sc.Index];

  // Create an s_SCNewOrder object.
  s_SCNewOrder NewOrder;
  NewOrder.OrderQuantity = 1;
  NewOrder.OrderType = SCT_MARKET;
  int Result;

  // Buy when the last price crosses the moving average from below.
  if (sc.CrossOver(Last, SimpMovAvgSubgraph) == CROSS_FROM_BOTTOM && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED)
  {
      Result = sc.BuyEntry(NewOrder);
      if (Result > 0) //If there has been a successful order entry, then draw an arrow at the low of the bar.
        BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
  }
  
  
  // When there is a long position AND the Last price is less than the price the Buy Entry was filled at minus Stop Value, OR there is a long position AND the Last price is greater than the price the Buy Entry was filled at plus the Target Value.
  else if (PositionData.PositionQuantity > 0
    && (LastTradePrice <= PositionData.AveragePrice - StopValue.GetFloat() ||
    LastTradePrice >= PositionData.AveragePrice + TargetValue.GetFloat()))
  {
    Result = sc.BuyExit(NewOrder);
    if(Result>0) //If there has been a successful order entry, then draw an arrow at the high of the bar.
      BuyExitSubgraph[sc.Index] = sc.High[sc.Index];
  }
  
  
  // Sell when the last price crosses the moving average from above.
  else if (sc.CrossOver(Last, SimpMovAvgSubgraph) == CROSS_FROM_TOP && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED)
  {
    Result = sc.SellEntry(NewOrder);
    if(Result>0) //If there has been a successful order entry, then draw an arrow at the high of the bar.
      SellEntrySubgraph[sc.Index] = sc.High[sc.Index];
  }
  
  // When there is a short position AND the Last price is greater than the price the Sell Entry was filled at plus the Stop Value, OR there is a short position AND the Last price is less than the price the Sell Entry was filled at minus the Target Value.
  else if (PositionData.PositionQuantity < 0
    && (LastTradePrice >= PositionData.AveragePrice + StopValue.GetFloat() ||
    LastTradePrice <= PositionData.AveragePrice - TargetValue.GetFloat()))
  {
    Result = sc.SellExit(NewOrder);
    if(Result>0) //If there has been a successful order entry, then draw an arrow at the low of the bar.
      SellExitSubgraph[sc.Index] = sc.Low[sc.Index];
  }

}

[2013-12-08 20:46:53]
User11748 - Posts: 14
I am not sure that the screenshot was attached.
Please find it enclosed.
[2013-12-08 21:03:41]
Sierra Chart Engineering - Posts: 104368
We do not see the screenshot attached.

You need to remove this from the if statements:
&& sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED
Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing
[2013-12-08 21:20:36]
User11748 - Posts: 14
Thanks for your answer.
New attempt to attach screenshot.
[2013-12-08 21:22:22]
User11748 - Posts: 14
Strange. When I preview the message, the picture is attached. But it seems to disappear when "Submit New Reply".
Link to the picture: http://content.screencast.com/users/Nicolas98/folders/Jing/media/51cfcc5a-c655-49a8-be24-15158f1e68dc/SC.png
[2013-12-08 21:28:41]
User11748 - Posts: 14
I have removed
&& sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED

And also kept only the code for the "long" trades.

Now, the trade is triggered on the same bar as the one on which the crossover happens. :)
But not at the close of the bar. :(
Apparently at the open +/- 1 tick.

Screenshot: http://content.screencast.com/users/Nicolas98/folders/Jing/media/fb09c213-f96a-49fb-8c3d-b82a635ae5b7/2013-12-08_2226.png

Nicolas
Date Time Of Last Edit: 2013-12-08 21:54:54
[2013-12-09 17:53:44]
Sierra Chart Engineering - Posts: 104368
When you submit an order, it will be filled at whatever the current price is. If you submit the order when a bar closes, then effectively that is trading at the close of the bar. In the case of an Intraday chart, the close of a bar and the open of the next bar should be very close to each other.

So it is up to you to time the submission of the order to occur at the time that you want.


Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing
[2013-12-09 20:28:10]
User11748 - Posts: 14
Thanks for your answer.

I try to rephrase my question:
Is there the equivalent of market-on-close order ("market order that is submitted to execute as close to the closing price as possible") in SC ACSIL, or a way to emulate them for backtesting purpose?
Reference: https://www.interactivebrokers.com/en/?f=%2Fen%2Ftrading%2Forders%2Fmoc.php

Thanks,

Nicolas
[2013-12-09 20:40:26]
Sierra Chart Engineering - Posts: 104368
There are no order types within Sierra Chart which execute at a particular point in time.
Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service:
Sierra Chart Teton Futures Order Routing
[2020-04-21 00:20:54]
JDMontero - Posts: 34
So it is up to you to time the submission of the order to occur at the time that you want.

So, is it possible to time the submission of the order at the end of the day, on the same day that the conditions are met?

User 11748 and I are clearly trying to backtest a strategy with historical data, and wish to enter at bar close the day that the conditions are met, we go to SC after going through other charting platforms where this can be simply done, and we find it astonishing how hard it is in SC, -the best charting platform- to execute a strategy on bar close on the same day conditions are me.

PLEASE SIERRA CHART, please make a tiny additional subgraph in Trading system based on alert conditions that allows to trade at the bar close on the day that conditions are met, please, please.

In the meantime, please guide us in the steps that need to be taken in ACSIL to achieve the same thing. Can we time the order to be at bar close, without the an order type that executes at a particular point in time, which SC does not have?

Thanks!
[2020-04-21 05:05:54]
Flipper - Posts: 65
If you are using intraday data you can have an order trigger after a time if other conditions are meet. Then make it 30 seconds before the close of day.

for example,

int TradeTime = HMS_TIME(15, 59, 30); // this is 30 seconds before 4:00pm as an example
int BarTime = sc.BaseDateTimeIn[sc.Index].GetTime();


// then in the trading code condition from above example .

if (sc.CrossOver(Last, SimpMovAvgSubgraph) == CROSS_FROM_BOTTOM && BarTime > TradeTime )

{

Result = sc.BuyEntry(NewOrder);

if (Result > 0) //If there has been a successful order entry, then draw an arrow at the low of the bar.

BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];

}

[2020-04-21 14:11:42]
JDMontero - Posts: 34
Thanks Flipper!

Would there be a difference if I am using Historical data? (Daily bars)

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account