Login Page - Create Account

Support Board


Date/Time: Thu, 25 Apr 2024 20:30:51 +0000



Simple ACSIL example to scale in to a trade

View Count: 3514

[2016-04-28 15:17:58]
cclarke - Posts: 5
Support,
I am having trouble getting scaling in to work using ACSIL and I was unable to find a relevant code example. Do you have an example using ACSIL that demonstrates adding to a position once the price moves in your favor? For instance, start the position with 1 contract with attached profit target and stop loss defined in code and add an additional 2 contracts if the price moves in your favor by 10 ticks.
Thanks!
[2016-04-28 17:25:00]
Sierra Chart Engineering - Posts: 104368
We will see if we can put together an example in the next couple of days.
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
[2016-05-02 01:06:51]
Sierra Chart Engineering - Posts: 104368
We should have the example ready before the end of the 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
[2016-05-02 22:03:54]
Sierra Chart Engineering - Posts: 104368
Here is an updated example:


SCSFExport scsf_TradingScaleInExample(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];

  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: Scale In";

    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;

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

    TargetValue.Name = "Target Offset in Ticks";
    TargetValue.SetFloat(10.0f);

    StopValue.Name = "Stop Offset in Ticks";
    StopValue.SetFloat(10.0f);

    sc.StudyDescription = "This study function is an example of how to use the ACSIL Trading Functions and increase the Trade Position quantity by scaling in.";

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

    sc.FreeDLL = 0;

    //Any of the following variables can also be set outside and below the sc.SetDefaults code block

    sc.AllowMultipleEntriesInSameDirection = true;
    sc.MaximumPositionAllowed = 2;
    sc.SupportReversals = false;

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

    sc.AllowOppositeEntryWithOpposingPositionOrOrders = false;

    //This must be true for Scale In to work
    sc.SupportAttachedOrdersForTrading = true;

    sc.CancelAllOrdersOnEntriesAndReversals= false;
    sc.AllowEntryWithWorkingOrders = true;
    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;

    return;
  }

  sc.SupportTradingScaleIn = true;
  sc.SupportTradingScaleOut = false;

  if (!Enabled.GetYesNo())
    return;


  // Get the Trade Position data
  s_SCPositionData PositionData;
  sc.GetTradePosition(PositionData) ;


  int& r_BuyEntryInternalOrderID = sc.GetPersistentInt(1);

  // This Boolean needs to be set to true when the condition for your initial entry has been met. This trading example does not actually define any entry condition but has code to enter a buy order when an entry condition has occurred.
  bool ConditionForInitialBuyEntry = true;
  bool ConditionForSecondBuyEntry = true;

  // Buy when the last price crosses the moving average from below.
  if (ConditionForInitialBuyEntry && PositionData.PositionQuantity == 0
    && !PositionData.WorkingOrdersExist)
  {

    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
    NewOrder.Target1Offset = TargetValue.GetFloat() * sc.TickSize;
    NewOrder.Stop1Offset = StopValue.GetFloat() * sc.TickSize;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
  else if (ConditionForSecondBuyEntry
    && PositionData.PositionQuantity == 1
    && !PositionData.NonAttachedWorkingOrdersExist
  )
  {

    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
}

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: 2016-05-04 02:42:54
[2016-05-03 14:49:30]
cclarke - Posts: 5
Thanks for the help with this. It seems like the code is still not working correctly but I may have done something wrong. I took the code provided and modified to enter the first position on a moving average cross over and scale in immediately on the bar after the initial entry. When I backtest, instead of scaling in a single time, it scales in twice and then never fully exits the position. It should not do this since a condition of the scale in is PositionData.PositionQuantity == 1 but I have backtested on 2 symbols with the same results. This is similar to the issue I was having in my original code that prompted the support request. I have included the modified code. Can you provide a suggestion?



SCSFExport scsf_TradingScaleInExample(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 Scale In 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;

    Enabled.Name = "Enabled";
    Enabled.SetYesNo(0);
    
    TargetValue.Name = "Target Offset Value";
    TargetValue.SetFloat(10.0f);

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

    sc.StudyDescription = "This study function is an example of how to use the ACSIL Trading Functions and increase the Trade Position quantity by scaling in.";

    sc.AutoLoop = 1;
    sc.GraphRegion = 0;
    sc.FreeDLL = 1;
    
    //Any of the following variables can also be set outside and below the sc.SetDefaults code block
    sc.AllowMultipleEntriesInSameDirection = true;
    sc.MaximumPositionAllowed = 2;
    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 = false;
    sc.AllowEntryWithWorkingOrders = true;
    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;

    return;
  }
  
  sc.SupportTradingScaleIn = true;
  sc.SupportTradingScaleOut = false;

  if (!Enabled.GetYesNo())
    return;

  SCFloatArrayRef Last = sc.Close;
  // Calculate the moving average
  sc.SimpleMovAvg(Last, SimpMovAvgSubgraph, sc.Index, 10);

  // Get the Trade Position data
  s_SCPositionData PositionData;
  sc.GetTradePosition(PositionData);

  int& r_BuyEntryInternalOrderID = sc.GetPersistentInt(1);

  bool ConditionForInitialBuyEntry = sc.CrossOver(Last, SimpMovAvgSubgraph) == CROSS_FROM_BOTTOM && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED;
  bool ConditionForSecondBuyEntry = true;

  // Buy when the last price crosses the moving average from below.
  if (ConditionForInitialBuyEntry && PositionData.PositionQuantity == 0)
  {
    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
    NewOrder.Target1Offset = TargetValue.FloatValue * sc.TickSize;
    NewOrder.Stop1Offset = StopValue.FloatValue * sc.TickSize;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
  else if (ConditionForSecondBuyEntry && PositionData.PositionQuantity == 1 && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED)
  {
    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
}


Thanks again for the help.
[2016-05-04 02:42:04]
Sierra Chart Engineering - Posts: 104368
You will need to use the following code.

This code requires version 1406 which will be out today or tomorrow.

Our other code example we gave above has been updated to this one.

SCSFExport scsf_TradingScaleInExample(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];

  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: Scale In";

    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;

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

    TargetValue.Name = "Target Offset in Ticks";
    TargetValue.SetFloat(10.0f);

    StopValue.Name = "Stop Offset in Ticks";
    StopValue.SetFloat(10.0f);

    sc.StudyDescription = "This study function is an example of how to use the ACSIL Trading Functions and increase the Trade Position quantity by scaling in.";

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

    sc.FreeDLL = 0;

    //Any of the following variables can also be set outside and below the sc.SetDefaults code block

    sc.AllowMultipleEntriesInSameDirection = true;
    sc.MaximumPositionAllowed = 2;
    sc.SupportReversals = false;

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

    sc.AllowOppositeEntryWithOpposingPositionOrOrders = false;

    //This must be true for Scale In to work
    sc.SupportAttachedOrdersForTrading = true;

    sc.CancelAllOrdersOnEntriesAndReversals= false;
    sc.AllowEntryWithWorkingOrders = true;
    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;

    return;
  }

  sc.SupportTradingScaleIn = true;
  sc.SupportTradingScaleOut = false;

  if (!Enabled.GetYesNo())
    return;


  // Get the Trade Position data
  s_SCPositionData PositionData;
  sc.GetTradePosition(PositionData) ;


  int& r_BuyEntryInternalOrderID = sc.GetPersistentInt(1);

  // This Boolean needs to be set to true when the condition for your initial entry has been met. This trading example does not actually define any entry condition but has code to enter a buy order when an entry condition has occurred.
  bool ConditionForInitialBuyEntry = true;
  bool ConditionForSecondBuyEntry = true;

  // Buy when the last price crosses the moving average from below.
  if (ConditionForInitialBuyEntry && PositionData.PositionQuantity == 0
    && !PositionData.WorkingOrdersExist)
  {

    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
    NewOrder.Target1Offset = TargetValue.GetFloat() * sc.TickSize;
    NewOrder.Stop1Offset = StopValue.GetFloat() * sc.TickSize;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
  else if (ConditionForSecondBuyEntry
    && PositionData.PositionQuantity == 1
    && !PositionData.NonAttachedWorkingOrdersExist
  )
  {

    // Create an s_SCNewOrder object.
    s_SCNewOrder NewOrder;
    NewOrder.OrderQuantity = 1;
    NewOrder.OrderType = SCT_ORDERTYPE_MARKET;

    int Result = sc.BuyEntry(NewOrder);
    //If there has been a successful order entry, then draw an arrow at the low of the bar.
    if (Result > 0)
    {
      r_BuyEntryInternalOrderID = NewOrder.InternalOrderID;
      BuyEntrySubgraph[sc.Index] = sc.Low[sc.Index];
    }
  }
}

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
[2016-05-05 23:33:47]
cclarke - Posts: 5
The updated code worked great. Thanks for the great support!

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

Login

Login Page - Create Account