Login Page - Create Account

Support Board


Date/Time: Sun, 05 May 2024 15:13:47 +0000



Post From: Simple ACSIL example to scale in to a trade

[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.