Login Page - Create Account

Support Board


Date/Time: Sun, 28 Apr 2024 19:13:50 +0000



Post From: Ninja Trader 7 code block converted over to Sierra code

[2018-09-12 01:38:17]
JoseyWales - Posts: 67
You may never end up finding a perfect 1 to 1 match between SierraChart and NinjaTrader chart bars. A few reasons I can think of is different platforms may not use the same tick sizes. For example NT uses .00001 for non JPY Forex data, whereas SC uses .00005. Another reason is both SC and NT have their own interpretations of how to calculate Renko bars. If either NT or SC Renko bar logic differs from one another, then one may create a bar where the other does not. The last reason I can think of is NT uses "Break at end of day" and SC "New Bar on Season Start" settings and session times could be different. And the data providers may be different, therefore different raw tick data.

The biggest thing to learn/remember when programming SC ACSIL studies is variables and arrays that aren't a reference are destroyed at the end of the scope. And when AutoLoop = 1 this means it occurs at every update. Data assigned in a SCFloatArray will not be retained, whereas data in a SCFloatArrayRef will be. So the variables carryForward, result, and swing were being reset to 0 every iteration when they should have retained their value from the previous update. SC ACSIL is function like programming compared to NinjaScript's class based programming where a simple field stays in the scope of the class until the class is deleted, not on every update.

SierraChart has Persistent variables that solve this dilemma. If you don't need an entire SCFloatArrayRef and just need a variable to be carried over to the next update, use Persistent variables. It takes an int parameter as a key, so be sure to use different key values for persistent variables of the same type. And don't forget to make the type as a reference (double& name = sc.GetPersistentDouble(0), int& name = sc.GetPersistentInt(0)) so it is assignable. If you forget the reference operator, the code will compile fine but it will be confusing trying to debug until you realize you forgot to make it a reference type.

sc.GetPersistentInt()

This is the code as seen in my attached pictures. Changing the input named Factor changes the output much more than Trend Length. It has another input named "Color Background or Color Bars?" if the user wants to paint the background or bars. If you want to have the stop level as a single subgraph, you can create a new subgraph and assign to it the variable "result" in the bottom if/else blocks like Bullish/Bearish Lines do. The subgraph named Trend assigns -1 for bearish and 1 for bullish conditions. Because it is a subgraph, it can be referenced in an alert condition (ID1.SG3[0] > 0).

Study/Chart Alerts And Scanning

Apparently you can't have a subgraph painting the background and another subgraph painting the bar colors within the same indicator. That's why the user has to choose either or neither, but not both. It might be a SierraChart bug.

Let me know what you think and if there's any improvements I can make for you.


#include "sierrachart.h"

SCSFExport scsf_BG_ColorAndTrailingStop(SCStudyInterfaceRef sc)
{
  SCSubgraphRef BullishLine = sc.Subgraph[0];
  SCSubgraphRef BearishLine = sc.Subgraph[1];
  SCSubgraphRef Trend = sc.Subgraph[2];
  SCSubgraphRef BackgroundColor = sc.Subgraph[3];
  SCSubgraphRef BarColor = sc.Subgraph[4];
  SCSubgraphRef ATR = sc.Subgraph[5];

  SCInputRef TrendLength = sc.Input[0];
  SCInputRef Factor = sc.Input[1];
  SCInputRef ColorType = sc.Input[2];

  if (sc.SetDefaults)
  {
    sc.AutoLoop = 1;
    sc.FreeDLL = 0;
    sc.GraphName = "Color Background";
    sc.GraphRegion = 0;

    // Graphs

    BullishLine.Name = "Bullish Line";
    BullishLine.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS;
    BullishLine.PrimaryColor = COLOR_DODGERBLUE;
    BullishLine.LineWidth = 3;

    BearishLine.Name = "Bearish Line";
    BearishLine.DrawStyle = DRAWSTYLE_LINE_SKIP_ZEROS;
    BearishLine.PrimaryColor = COLOR_MAGENTA;
    BearishLine.LineWidth = 3;

    Trend.Name = "Trend";
    Trend.DrawStyle = DRAWSTYLE_IGNORE;
    Trend.SecondaryColorUsed = true;
    Trend.PrimaryColor = COLOR_GREEN;
    Trend.SecondaryColor = COLOR_RED;
    Trend.DrawZeros = false;

    BackgroundColor.Name = "Background Color";
    BackgroundColor.SecondaryColorUsed = true;
    BackgroundColor.PrimaryColor = COLOR_GREEN;
    BackgroundColor.SecondaryColor = COLOR_RED;
    BackgroundColor.DrawZeros = false;

    BarColor.Name = "Bar Color";
    BarColor.DrawStyle = DRAWSTYLE_COLOR_BAR;
    BarColor.PrimaryColor = COLOR_DODGERBLUE;
    BarColor.SecondaryColor = COLOR_RED;
    BarColor.SecondaryColorUsed = true;

    // Inputs

    TrendLength.Name = "Trend Length";
    TrendLength.SetInt(20);

    Factor.Name = "Factor";
    Factor.SetDouble(1.5);

    ColorType.Name = "Color Background or Color Bars?";
    ColorType.SetCustomInputStrings("No;Color Background;Color Bars");
    ColorType.SetCustomInputIndex(0);

    return;
  }

  double& carryForward = sc.GetPersistentDouble(0);
  double& result = sc.GetPersistentDouble(1);
  int& swing = sc.GetPersistentInt(0);

  if (sc.Index < TrendLength.GetInt())
  {
    swing = 1;

    if (ColorType.GetIndex() == 1)
      BackgroundColor.DrawStyle = DRAWSTYLE_BACKGROUND_TRANSPARENT;
    else if (ColorType.GetIndex() == 2)
      BackgroundColor.DrawStyle = DRAWSTYLE_IGNORE;

    return;
  }

  sc.ATR(sc.BaseDataIn, ATR, TrendLength.GetInt(), MOVAVGTYPE_SIMPLE);

  double num = Factor.GetDouble() * ATR[sc.Index];

  if (swing == 1 && sc.Close[sc.Index] <= result)
  {
    swing = -1;
    result = DBL_MAX;
  }
  else if (swing == -1 && sc.Close[sc.Index] >= result)
  {
    swing = 1;
    result = DBL_MIN;
  }
  if (swing == 1)
  {
    if (sc.Low[sc.Index] - carryForward > result)
      result = sc.Low[sc.Index] - carryForward;

    BullishLine[sc.Index] = result;
    Trend[sc.Index] = swing;

    // Color Bullish
    Trend.DataColor[sc.Index] = Trend.PrimaryColor;

    if (ColorType.GetIndex() == 1)
    {
      BackgroundColor[sc.Index] = swing;
      BackgroundColor.DataColor[sc.Index] = BackgroundColor.PrimaryColor;
    }

    else if (ColorType.GetIndex() == 2)
    {
      BarColor[sc.Index] = swing;
      BarColor.DataColor[sc.Index] = BarColor.PrimaryColor;
    }
  }
  else if (swing == -1)
  {
    if (sc.High[sc.Index] + carryForward < result)
      result = sc.High[sc.Index] + carryForward;

    BearishLine[sc.Index] = result;
    Trend[sc.Index] = swing;

    // Color Bearish
    Trend.DataColor[sc.Index] = Trend.SecondaryColor;

    if (ColorType.GetIndex() == 1)
    {
      BackgroundColor[sc.Index] = swing;
      BackgroundColor.DataColor[sc.Index] = BackgroundColor.SecondaryColor;
    }
    else if (ColorType.GetIndex() == 2)
    {
      BarColor[sc.Index] = swing;
      BarColor.DataColor[sc.Index] = BarColor.SecondaryColor;
    }
  }

  carryForward = num;
}

imageSierraChart Color Background - Color Bar.png / V - Attached On 2018-09-12 01:22:06 UTC - Size: 404.92 KB - 459 views
imageSierraChart vs NinjaTrader 8 - Renko Comparison.png / V - Attached On 2018-09-12 01:23:21 UTC - Size: 550.33 KB - 494 views
Attachment Deleted.