Login Page - Create Account

Support Board


Date/Time: Sun, 16 Mar 2025 17:04:10 +0000



Request for New flex MACD

View Count: 1784

[2014-04-23 04:23:10]
Willson - Posts: 176
MACD is very useful indicator. But many times custom selection of the move avg types is needed.
Please consider a MACD universal where user can select the type ( MA type, and which bar (close, open)) of mov avg to be used for each of the MA's in MACD. Maybe best to use MA's or indicators that are in the list of applied indicators for the chart or another chart)
At this time I need an EMA and an WMA. In fact any two indicators (with similar ranges) can be used in the MACD, even if it is originating from another chart. No other charting system can do this.
Regards

[2014-04-24 23:42:13]
vegasfoster - Posts: 444
The Subgraphs Difference Study is designed to accomplish this, among other things. https://www.sierrachart.com/index.php?l=doc/doc_TechnicalStudiesReference.html#s227 You can use it to create any type of MACD.
[2014-04-25 17:10:42]
Sierra Chart Engineering - Posts: 104368
For this, we recommend using the MACD code and customizing it. Refer to this page:
https://www.sierrachart.com/index.php?l=doc/doc_BuildCustomStudiesDLL.html

Here is the code:


SCSFExport scsf_MACD(SCStudyInterfaceRef sc)
{
  SCSubgraphRef MACD    = sc.Subgraph[0];
  SCSubgraphRef MovAvgOfMACD  = sc.Subgraph[1];
  SCSubgraphRef MACDDiff  = sc.Subgraph[2];
  SCSubgraphRef RefLine  = sc.Subgraph[3];

  SCInputRef InputData  = sc.Input[0];
  SCInputRef FastLength    = sc.Input[3];
  SCInputRef SlowLength    = sc.Input[4];
  SCInputRef MACDLength    = sc.Input[5];
  SCInputRef MovingAverageType    = sc.Input[6];


  if(sc.SetDefaults)
  {
    sc.GraphName = "MACD";
    sc.AutoLoop          = 1;

    sc.GraphRegion        = 1;
    sc.ValueFormat        = 3;
    
    MACD.Name = "MACD";
    MACD.DrawStyle = DRAWSTYLE_LINE;
    MACD.DrawZeros = true;
    MACD.PrimaryColor = RGB(0,255,0);

    MovAvgOfMACD.Name  = "MA of MACD";
    MovAvgOfMACD.DrawStyle = DRAWSTYLE_LINE;
    MovAvgOfMACD.DrawZeros = true;
    MovAvgOfMACD.PrimaryColor = RGB(255,0,255);

    MACDDiff.Name = "MACD Diff";
    MACDDiff.DrawStyle = DRAWSTYLE_BAR;
    MACDDiff.DrawZeros = true;
    MACDDiff.PrimaryColor = RGB(255,255,0);

    RefLine.Name = "Line";
    RefLine.DrawStyle = DRAWSTYLE_LINE;
    RefLine.DrawZeros = true;
    RefLine.PrimaryColor = RGB(255,127,0);

    InputData.Name = "Input Data";
    InputData.SetInputDataIndex(SC_LAST);

    FastLength.Name ="Fast Moving Average Length";
    FastLength.SetInt(12);
    FastLength.SetIntLimits(1,MAX_STUDY_LENGTH);

    SlowLength.Name = "Slow Moving Average Length";
    SlowLength.SetInt(26);
    SlowLength.SetIntLimits(1,MAX_STUDY_LENGTH);

    MACDLength.Name = "MACD Moving Average Length";
    MACDLength.SetInt(9);
    MACDLength.SetIntLimits(1,MAX_STUDY_LENGTH);

    MovingAverageType.Name = "Moving Average Type";
    MovingAverageType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);

    return;
  }

  if (MovingAverageType.GetMovAvgType()==MOVAVGTYPE_EXPONENTIAL)
      sc.DataStartIndex = 2;
  else
    sc.DataStartIndex = MACDLength.GetInt() + max(FastLength.GetInt(), SlowLength.GetInt());

  sc.MACD(sc.BaseDataIn[InputData.GetInputDataIndex()], MACD, sc.Index, FastLength.GetInt(), SlowLength.GetInt(), MACDLength.GetInt(), MovingAverageType.GetInt());

  MovAvgOfMACD[sc.Index]  = MACD.Arrays[2][sc.Index];
  MACDDiff[sc.Index]  = MACD.Arrays[3][sc.Index];
  RefLine[sc.Index]  = 0;  
}


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
[2014-04-26 03:14:31]
Willson - Posts: 176
Thankyou for this. Now I have incentive to get with the code learning.
This head start is critical for me. Hope I get help from members when I get stalled.
Regards
[2014-04-26 04:49:32]
Sierra Chart Engineering - Posts: 104368
We just realized that sc.MACD function takes a single Moving Average Type. So you cannot use that function. Instead you need to call the individual moving average functions there are available in ACSIL to build your own MACD.
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
[2022-08-27 02:32:19]
ertrader - Posts: 682
Is there an updated version? This gives a few errors when compiling.

FlexMACD.cpp: In function 'c_ArrayWrapper<float>& MovingAvg(SCStudyInterfaceRef, SCFloatArrayRef, SCFloatArrayRef, unsigned int, int, int)':
FlexMACD.cpp:80:59: error: no matching function for call to 's_sc::SmoothedMovingAverage(c_ArrayWrapper<float>&, c_ArrayWrapper<float>&, int&, int&, int)'
80 | return sc.SmoothedMovingAverage(In, Out, Index, Length,0);
| ^
In file included from FlexMACD.cpp:2:
sierrachart.h:544:18: note: candidate: 'c_ArrayWrapper<float>& s_sc::SmoothedMovingAverage(SCFloatArrayRef, SCFloatArrayRef, int, int)'
544 | SCFloatArrayRef SmoothedMovingAverage(SCFloatArrayRef In, SCFloatArrayRef Out, int Index, int Length)
| ^~~~~~~~~~~~~~~~~~~~~
sierrachart.h:544:18: note: candidate expects 4 arguments, 5 provided
sierrachart.h:548:18: note: candidate: 'c_ArrayWrapper<float>& s_sc::SmoothedMovingAverage(SCFloatArrayRef, SCFloatArrayRef, int)'
548 | SCFloatArrayRef SmoothedMovingAverage(SCFloatArrayRef In, SCFloatArrayRef Out, int Length)
| ^~~~~~~~~~~~~~~~~~~~~
sierrachart.h:548:18: note: candidate expects 3 arguments, 5 provided
Date Time Of Last Edit: 2022-08-27 02:33:06
[2022-08-27 02:57:55]
GravisHTG - Posts: 306
guess I was not the only one looking for it :)
[2022-08-27 03:43:41]
User90125 - Posts: 715
Here's an updated version:

// The top of every source code file must include this required line
#include "sierrachart.h"
// #include "scstudyfunctions.h"
// #include "scstudyfunctions.cpp"

//DLL Name also required for initialization; can be SCDLLInit instead of SCDLLName.
//format: SCDLLName("Your DLL Name Here")

SCDLLName("FlexMACD")

/*==========================================================================*/
SCFloatArrayRef SimpleMovAvgSkipZeros_S(SCFloatArrayRef In, SCFloatArrayRef Out, int Index, int Length)
{
  int count = 0;
  float Sum = 0.0f;

  if (Length > Index + 1)
    Length = Index + 1;

  for(int ArrayIndex= Index - Length + 1; ArrayIndex <= Index; ArrayIndex++)
  {
    float Value = In[ArrayIndex];

    if (Value != 0.0f)
    {
      Sum += Value;
      count++;
    }
  }

  if (count > 0)
  {
    Out[Index] = Sum / count;
  }
  else
  {
    Out[Index] = 0.0f;
  }

  return Out;
}


/*==========================================================================*/
SCFloatArrayRef MovingAvg(SCStudyGraphRef sc, SCFloatArrayRef In, SCFloatArrayRef Out, unsigned int MovingAverageType, int Index, int Length)
{
  
  if (Length < 1 || Index < 0)
return Out;
      
  if (Length == 1 || Index == 0)
  {
Out[Index] = In[Index];
    return Out;  
  }  
  
  
  switch (MovingAverageType)
  {
    case MOVAVGTYPE_EXPONENTIAL:
    return sc.ExponentialMovAvg(In, Out, Index, Length);
    
    case MOVAVGTYPE_LINEARREGRESSION:
    return sc.LinearRegressionIndicator(In, Out, Index, Length);
    
    default: // Unknown moving average type
    case MOVAVGTYPE_SIMPLE:
    return sc.SimpleMovAvg(In, Out, Index, Length);
    
    case MOVAVGTYPE_WEIGHTED:
    return sc.WeightedMovingAverage(In, Out, Index, Length);
    
    case MOVAVGTYPE_WILDERS:
    return sc.WildersMovingAverage(In, Out, Index, Length);

    case MOVAVGTYPE_SIMPLE_SKIP_ZEROS:
    return SimpleMovAvgSkipZeros_S(In, Out, Index, Length);

    case MOVAVGTYPE_SMOOTHED:
    return sc.SmoothedMovingAverage(In, Out, Index, Length);

  }
}

SCFloatArrayRef Flex_MACD(SCStudyGraphRef sc, SCFloatArrayRef In, SCFloatArrayRef FastMAOut, SCFloatArrayRef SlowMAOut,
        SCFloatArrayRef MACDOut, SCFloatArrayRef SigMAOut, SCFloatArrayRef MACDHistOut,
        int Index, int FastMALength, int SlowMALength, int SigMALength,
        int FastMovAvgType, int SlowMovAvgType, int SigMovAvgType )
{
  MovingAvg(sc,In,FastMAOut,FastMovAvgType,Index,FastMALength);
  MovingAvg(sc,In,SlowMAOut,SlowMovAvgType,Index,SlowMALength);
  MACDOut[Index] = FastMAOut[Index] - SlowMAOut[Index];

  MovingAvg(sc,MACDOut,SigMAOut, SigMovAvgType,Index,SigMALength);
  MACDHistOut[Index] = MACDOut[Index] - SigMAOut[Index];
  

  return MACDOut;
}



SCSFExport scsf_FlexMACD(SCStudyInterfaceRef sc)
{

  SCSubgraphRef MACD    = sc.Subgraph[0];
  SCSubgraphRef Signal  = sc.Subgraph[1];  
  SCSubgraphRef Histogram  = sc.Subgraph[2];
  SCSubgraphRef ZeroLine  = sc.Subgraph[3];  

  SCSubgraphRef MACDTemp  = sc.Subgraph[4];  



  
  SCInputRef InputData    = sc.Input[0];
  SCInputRef FastLength    = sc.Input[1];
  SCInputRef SlowLength    = sc.Input[2];
  SCInputRef SignalLength    = sc.Input[3];
  SCInputRef FastMAType     = sc.Input[4];
  SCInputRef SlowMAType     = sc.Input[5];
  SCInputRef SignalMAType   = sc.Input[6];
  SCInputRef InvertMACD     = sc.Input[7];
  SCInputRef InvertSig     = sc.Input[8];
  SCInputRef InvertHist     = sc.Input[9];  
  SCInputRef InvertStudy    = sc.Input[10];  

  
  if(sc.SetDefaults)
  {
    sc.GraphName = "Flex MACD";
    sc.AutoLoop          = 1;

    sc.GraphRegion        = 1;
    sc.ValueFormat        = 3;
    
    
    
    MACD.Name = "Main";
    MACD.DrawStyle = DRAWSTYLE_LINE;
    MACD.DrawZeros = true;
    MACD.PrimaryColor = RGB(0,128,255);
    MACD.LineWidth = 2;
    
    Signal.Name  = "Sig";
    Signal.DrawStyle = DRAWSTYLE_LINE;
    Signal.DrawZeros = true;
    Signal.PrimaryColor = RGB(255,0,0);
    Signal.LineWidth = 2;    

    Histogram.Name = "Hist";
    Histogram.DrawStyle = DRAWSTYLE_FILLTOZERO_TRANSPARENT;
//    Histogram.DrawStyle = DRAWSTYLE_FILLTOZERO;    
    Histogram.DrawZeros = true;  
    Histogram.LineStyle = LINESTYLE_SOLID;  
    Histogram.PrimaryColor = RGB(0,128,0);
    Histogram.SecondaryColor = RGB(220,0,0);  
    Histogram.SecondaryColorUsed = 1;
    Histogram.AutoColoring = AUTOCOLOR_POSNEG;
    Histogram.LineWidth = 2;  
    
    ZeroLine.Name = "ZeroLine";
    ZeroLine.DrawStyle = DRAWSTYLE_LINE;
    ZeroLine.LineStyle = LINESTYLE_DASH;      
    ZeroLine.DrawZeros = true;
    ZeroLine.PrimaryColor = RGB(128,128,0);
    ZeroLine.LineWidth = 0;
    ZeroLine.DisplayNameValueInWindowsFlags = 0;  
    ZeroLine.DisplayNameValueInDataLine = 0;
    
  
    unsigned short DisplayOrder = 1;
  
    InputData.Name = "Input Data";
    InputData.SetInputDataIndex(SC_LAST);
    InputData.DisplayOrder = DisplayOrder++;

    FastLength.Name = "Fast Moving Average Length";
    FastLength.SetInt(12);
    FastLength.SetIntLimits(1,MAX_STUDY_LENGTH);
    FastLength.DisplayOrder = DisplayOrder++;

    SlowLength.Name = "Slow Moving Average Length";
    SlowLength.SetInt(26);
    SlowLength.SetIntLimits(1,MAX_STUDY_LENGTH);
    SlowLength.DisplayOrder = DisplayOrder++;

    SignalLength.Name = "Signal Moving Average Length";
    SignalLength.SetInt(9);
    SignalLength.SetIntLimits(1,MAX_STUDY_LENGTH);
    SignalLength.DisplayOrder = DisplayOrder++;
    
  
    FastMAType.Name = "Fast Moving Average Type";
    FastMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);
    FastMAType.DisplayOrder = DisplayOrder++;
    
    SlowMAType.Name = "Slow Moving Average Type";
    SlowMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);    
    SlowMAType.DisplayOrder = DisplayOrder++;
    
    SignalMAType.Name = "Signal Moving Average Type";
    SignalMAType.SetMovAvgType(MOVAVGTYPE_EXPONENTIAL);    
    SignalMAType.DisplayOrder = DisplayOrder++;    
      
      
    InvertMACD.Name ="Invert MACD";
    InvertMACD.SetCustomInputStrings("No;Yes");
    InvertMACD.SetCustomInputIndex(0);  
    InvertMACD.DisplayOrder = DisplayOrder++;
    
    InvertSig.Name ="Invert Signal";
    InvertSig.SetCustomInputStrings("No;Yes");
    InvertSig.SetCustomInputIndex(0);  
    InvertSig.DisplayOrder = DisplayOrder++;
    
    InvertHist.Name ="Invert Histogram";
    InvertHist.SetCustomInputStrings("No;Yes");
    InvertHist.SetCustomInputIndex(0);  
    InvertHist.DisplayOrder = DisplayOrder++;

    InvertStudy.Name ="Invert Study";
    InvertStudy.SetYesNo(0);
    InvertStudy.DisplayOrder = DisplayOrder++;

    
    sc.FreeDLL = 0;
  
    return;
  }

  if (sc.HideStudy)
    return;

  
  int FastL = FastLength.GetInt();
  int SlowL = SlowLength.GetInt();
  int SigL = SignalLength.GetInt();  

  int FastTypeMA = FastMAType.GetInt();
  int SlowTypeMA = SlowMAType.GetInt();
  int SigTypeMA = SignalMAType.GetInt();  
  

  Flex_MACD(sc, sc.BaseDataIn[InputData.GetInputDataIndex()], MACDTemp.Arrays[0], MACDTemp.Arrays[1],
      MACDTemp, MACDTemp.Arrays[2], MACDTemp.Arrays[3],
      sc.Index, FastL, SlowL, SigL,   
      FastTypeMA, SlowTypeMA, SigTypeMA
    );
  
  
  sc.DataStartIndex = min(FastLength.GetInt(), SlowLength.GetInt()) + 1;
  
  
  if(sc.Index < sc.DataStartIndex)
  {  
    MACD[sc.Index]    = 0;
    Signal[sc.Index]  = 0;
    Histogram[sc.Index]  = 0;  
    
    return;
  }
  
  
  
  MACD[sc.Index]    = MACDTemp[sc.Index];
  Signal[sc.Index]  = MACDTemp.Arrays[2][sc.Index];
  Histogram[sc.Index]  = MACDTemp.Arrays[3][sc.Index];


  
  if(InvertMACD.GetIndex() == 1)
    MACD[sc.Index]    = -MACDTemp[sc.Index];

  
  if(InvertSig.GetIndex() == 1)
    Signal[sc.Index]  = -MACDTemp.Arrays[2][sc.Index];

  
  if(InvertHist.GetIndex() == 1)
    Histogram[sc.Index]  = -MACDTemp.Arrays[3][sc.Index];

  
    
  if(InvertStudy.GetYesNo())
  {
  MACD[sc.Index]    = -MACD[sc.Index];
  Signal[sc.Index]  = -Signal[sc.Index];
  Histogram[sc.Index]  = -Histogram[sc.Index];
  }
  
  ZeroLine[sc.Index]  = 0;  
  
}
/************************************************************/

Compiles in v2428. As always, YMMV :)
attachmentFlexMACD.cpp - Attached On 2022-08-27 03:42:58 UTC - Size: 7.71 KB - 115 views
[2022-08-27 14:52:16]
ertrader - Posts: 682
Great.. thank you!

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

Login

Login Page - Create Account