Login Page - Create Account

Support Board


Date/Time: Sun, 28 Apr 2024 07:53:12 +0000



Post From: Can I put in a new Pivot Point formula request?

[2013-04-17 18:57:40]
Trint - Posts: 112
Here's that code, it'll need a review and I perhaps should've added a function to repeat the main 'logic' part for allowing both equal/non-equal highs but it works (it works off the Swing High/Low functionality that already exists). Not sure the code is the most efficient.

There is a slight discrepancy with the SwingHighAllowEqual part when identifying two equal highs or lows in succession but it's minor and I think it has something to do with the rounding in the sc.BaseGraphValueFormat?. For the EURUSD pair I like 4 decimal places and setting it to 5 sorts it out perfectly but the high or low gets labelled in any case…… Anyway have a look and see what you think.

Anyone who chooses to implement/use or run any of the following code does so at their own risk and they are responsible for any problems that may arise from using it.



#include "sierrachart.h"

SCDLLName("Swing Market Structure v0.1")

//Taken from the SCSTUDYFUNCTIONS.CPP
/*********************************************************************/
int IsSwingHighAllowEqual(SCStudyInterfaceRef sc, int AllowEqual, int Index, int Length)
{
  for(int i = 1; i <= Length; i++)
  {

    if (AllowEqual)
    {
      if (sc.FormattedEvaluate(sc.BaseData [SC_HIGH][Index] , sc.BaseGraphValueFormat, LESS_OPERATOR, sc.BaseData [SC_HIGH][Index-i], sc.BaseGraphValueFormat)
        ||
        sc.FormattedEvaluate(sc.BaseData [SC_HIGH][Index] , sc.BaseGraphValueFormat, LESS_OPERATOR, sc.BaseData [SC_HIGH][Index+i], sc.BaseGraphValueFormat)
        )
        return 0;


    }
    else
    {
      if (sc.FormattedEvaluate(sc.BaseData [SC_HIGH][Index] , sc.BaseGraphValueFormat, LESS_EQUAL_OPERATOR, sc.BaseData [SC_HIGH][Index-i], sc.BaseGraphValueFormat)
        ||
        sc.FormattedEvaluate(sc.BaseData [SC_HIGH][Index] , sc.BaseGraphValueFormat, LESS_EQUAL_OPERATOR, sc.BaseData [SC_HIGH][Index+i], sc.BaseGraphValueFormat)
        )
        return 0;


    }
  }

  return 1;
}

//Taken from the SCSTUDYFUNCTIONS.CPP
/*==========================================================================*/
int IsSwingLowAllowEqual(SCStudyInterfaceRef sc, int AllowEqual, int Index, int Length)
{
  for(int i = 1; i <= Length; i++)
  {

    if (AllowEqual)
    {
      if (sc.FormattedEvaluate(sc.BaseData [SC_LOW][Index] , sc.BaseGraphValueFormat, GREATER_OPERATOR, sc.BaseData [SC_LOW][Index-i], sc.BaseGraphValueFormat)
        ||
        sc.FormattedEvaluate(sc.BaseData [SC_LOW][Index] , sc.BaseGraphValueFormat, GREATER_OPERATOR, sc.BaseData [SC_LOW][Index+i], sc.BaseGraphValueFormat)
        )
        return 0;


    }
    else
    {
      if (sc.FormattedEvaluate(sc.BaseData [SC_LOW][Index] , sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, sc.BaseData [SC_LOW][Index-i], sc.BaseGraphValueFormat)
        ||
        sc.FormattedEvaluate(sc.BaseData [SC_LOW][Index] , sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, sc.BaseData [SC_LOW][Index+i], sc.BaseGraphValueFormat)
        )
        return 0;


    }
  }

  return 1;
}

/************************************************************************/
SCSFExport scsf_SwingMarketStructure(SCStudyInterfaceRef sc)
{
  SCSubgraphRef SwingShortHigh = sc.Subgraph[0];
  SCSubgraphRef SwingShortLow = sc.Subgraph[1];
  SCSubgraphRef SwingIntermediateHigh = sc.Subgraph[2];
  SCSubgraphRef SwingIntermediateLow = sc.Subgraph[3];
  SCSubgraphRef SwingLongHigh = sc.Subgraph[4];
  SCSubgraphRef SwingLongLow = sc.Subgraph[5];
  
  SCInputRef ArrowOffsetValue= sc.Input[0];
  SCInputRef Length = sc.Input[1];
  SCInputRef AllowEqualBars = sc.Input[2];
  
  if ( sc.SetDefaults )
  {
    sc.GraphName = "Swing Market Structure Points";
    sc.StudyDescription = "Market Structure Short/Intermediate/Long Points";

    sc.FreeDLL = 0;
    sc.GraphRegion = 0;
    sc.ValueFormat= VALUEFORMAT_INHERITED;

    SwingShortHigh.Name = "Swing Short High";
    SwingShortHigh.DrawStyle = DRAWSTYLE_TEXT;
    SwingShortHigh.TextDrawStyleText = "s";
    SwingShortHigh.LineWidth = 9;
    SwingShortHigh.PrimaryColor = RGB(0,255,255);
    SwingShortHigh.DrawZeros = false;
    
    SwingShortLow.Name = "Swing Short Low";
    SwingShortLow.DrawStyle = DRAWSTYLE_TEXT;
    SwingShortLow.TextDrawStyleText = "s";
    SwingShortLow.LineWidth = 9;
    SwingShortLow.PrimaryColor = RGB(255,128,128);
    SwingShortLow.DrawZeros = false;
    
    SwingIntermediateHigh.Name = "Swing Intermediate High";
    SwingIntermediateHigh.DrawStyle = DRAWSTYLE_TEXT;
    SwingIntermediateHigh.TextDrawStyleText = "I";
    SwingIntermediateHigh.LineWidth = 13;
    SwingIntermediateHigh.PrimaryColor = RGB(0,255,255);
    SwingIntermediateHigh.DrawZeros = false;
    
    SwingIntermediateLow.Name = "Swing Intermediate Low";
    SwingIntermediateLow.DrawStyle = DRAWSTYLE_TEXT;
    SwingIntermediateLow.TextDrawStyleText = "I";
    SwingIntermediateLow.LineWidth = 13;
    SwingIntermediateLow.PrimaryColor = RGB(255,128,128);
    SwingIntermediateLow.DrawZeros = false;
    
    SwingLongHigh.Name = "Swing Long High";
    SwingLongHigh.DrawStyle = DRAWSTYLE_TEXT;
    SwingLongHigh.TextDrawStyleText = "L";
    SwingLongHigh.LineWidth = 15;
    SwingLongHigh.PrimaryColor = RGB(0,255,255);
    SwingLongHigh.DrawZeros = false;
    
    SwingLongLow.Name = "Swing Long Low";
    SwingLongLow.DrawStyle = DRAWSTYLE_TEXT;
    SwingLongLow.TextDrawStyleText = "L";
    SwingLongLow.LineWidth = 15;
    SwingLongLow.PrimaryColor = RGB(255,128,128);
    SwingLongLow.DrawZeros = false;

    ArrowOffsetValue.Name = "Arrow Offset as Percentage";
    ArrowOffsetValue.SetFloat(1.5f);
    
    Length.Name = "Length";
    Length.SetInt(2);
    Length.SetIntLimits(1,MAX_STUDY_LENGTH);
    
    // Need to add/repeat code for false - comments in BOLD below
    AllowEqualBars.Name = "Allow Equal High/Low Bars";
    AllowEqualBars.SetYesNo(true);

    sc.AutoLoop = true;
    return;
  }
  
  //Persistant Variables to retain the previous Swing High/Low info when going through the Index
  int& tempITHIndex     = sc.PersistVars->i1;
  int& tempLTHIndex     = sc.PersistVars->i2;
  int& tempITLIndex     = sc.PersistVars->i3;
  int& tempLTLIndex     = sc.PersistVars->i4;
  
  int& ITHFlag       = sc.PersistVars->i5;
  int& LTHFlag       = sc.PersistVars->i6;
  int& ITLFlag       = sc.PersistVars->i7;
  int& LTLFlag       = sc.PersistVars->i8;
  
  float& tempSTHigh    = sc.PersistVars->f1;
  float& tempITHigh   = sc.PersistVars->f2;
  float& tempSTLow      = sc.PersistVars->f3;
  float& tempITLow   = sc.PersistVars->f4;
  
  int IndexToEvaluate = sc.Index - Length.GetInt();

  if(IndexToEvaluate -Length.GetInt() < 0)
  {
    return;
  }

  float ArrowOffsetHighs=(sc.High[IndexToEvaluate])*(ArrowOffsetValue.GetFloat() * 0.01f);
  float ArrowOffsetLows=(sc.Low[IndexToEvaluate])*(ArrowOffsetValue.GetFloat() * 0.01f);
  
  SwingShortHigh[IndexToEvaluate] = 0;
  SwingShortLow[IndexToEvaluate] = 0;
  SwingIntermediateHigh[IndexToEvaluate] = 0;
  SwingIntermediateLow[IndexToEvaluate] = 0;
  SwingLongHigh[IndexToEvaluate] = 0;
  SwingLongLow[IndexToEvaluate] = 0;

  if(sc.Index == 0)
  {
    // Swing Highs
    tempSTHigh   = 0;
    tempITHigh     = 0;
    tempITHIndex   = 0;
    tempLTHIndex   = 0;
    ITHFlag     = 0;
    LTHFlag     = 0;
    
    //  Swing Lows
    tempSTLow   = 0;
    tempITLow     = 0;
    tempITLIndex   = 0;
    tempLTLIndex   = 0;
    ITLFlag     = 0;
    LTLFlag     = 0;
    
  }
  
  // check for Swing High
  if ( !AllowEqualBars.GetYesNo() )
  {
    if (sc.IsSwingHigh(sc.High, IndexToEvaluate, Length.GetInt() ) )
    {
      //BASICALLY THE SAME CODE FOR THE SWING HIGH AllowEqualBars 'ELSE IF' CONDITION (JUST BELOW) WOULD GO HERE
      //PROBABLY BEST TO WRITE A SEPERATE FUNCTION()... MOST EFFICIENT WAY?
    }
  }
  else if ( IsSwingHighAllowEqual( sc, true , IndexToEvaluate, Length.GetInt()))
  {
    //As we have a swing high, label it as a Short Term High
    SwingShortHigh[IndexToEvaluate] = sc.High[IndexToEvaluate] + ArrowOffsetHighs;
              
    //Potentially the first Short Term High could be part of a more important Intermediate high
    if(tempSTHigh == 0)
      tempSTHigh = sc.High[IndexToEvaluate];
    
    //A higher swing high than the last so potentially it could be an Intermediate Term High if the next swing high is lower, Flag it as potential.    
    if(sc.High[IndexToEvaluate] > tempSTHigh)
    {
      tempSTHigh = sc.High[IndexToEvaluate];
      ITHFlag = 1;
      tempITHIndex = IndexToEvaluate;
    }
      
    //We have a lower Short Term high and have now confirmed that potential Intermediate High, label Intermediate High and reset flags
    if((sc.High[IndexToEvaluate] < tempSTHigh) && (ITHFlag == 1))
    {
      SwingIntermediateHigh[tempITHIndex] = sc.High[tempITHIndex] + ArrowOffsetHighs;
      SwingShortHigh[tempITHIndex] = 0;
      ITHFlag = 0;
      tempSTHigh = sc.High[IndexToEvaluate]; // log the Short Term High for further checks
      
      //Potentially the first Intermediate Term High could be part of a more important Long Term High
      if(tempITHigh == 0)
        tempITHigh=sc.High[tempITHIndex];
      
      //A higher Intermediate swing high than the last so potentially could be a Long Term High, flag it as potential
      if(sc.High[tempITHIndex] > tempITHigh)
      {
        tempITHigh = sc.High[tempITHIndex];
        LTHFlag = 1;
        tempLTHIndex = tempITHIndex;
      }
      
      // We have a lower Intermediate High, so that potential Long Term high is confirmed, label Long Term High and reset flags
      if((sc.High[tempITHIndex] < tempITHigh) && (LTHFlag == 1))
      {
        SwingLongHigh[tempLTHIndex] = sc.High[tempLTHIndex] + ArrowOffsetHighs;
        SwingIntermediateHigh[tempLTHIndex] = 0;
        LTHFlag = 0;
        tempITHigh=sc.High[tempITHIndex];
      }
      else  //otherwise just another successive higher Intermediate high so log it
        tempITHigh=sc.High[tempITHIndex];          
    }
    else //otherwise just another successive higher Short Term high so log it
    {
      tempSTHigh = sc.High[IndexToEvaluate];
    }
  }
  
  // check for Swing Low
  if ( !AllowEqualBars.GetYesNo() )
  {
    if (sc.IsSwingLow(sc.Low, IndexToEvaluate, Length.GetInt() ) )
    {
      //BASICALLY THE SAME CODE FOR THE SWING LOW 'ELSE IF' CONDITION JUST BELOW WOULD GO HERE
      //PROBABLY BEST TO WRITE A SEPERATE FUNCTION()
    }
  }
  else if (IsSwingLowAllowEqual( sc, true , IndexToEvaluate, Length.GetInt()) )
  {
    // Similar to the logic for the Swing High (see above), only for lows obviously
    SwingShortLow[IndexToEvaluate] = sc.Low[IndexToEvaluate] - ArrowOffsetLows;
                
    if(tempSTLow == 0)
      tempSTLow = sc.Low[IndexToEvaluate];
      
    if(sc.Low[IndexToEvaluate] < tempSTLow)
    {
      tempSTLow = sc.Low[IndexToEvaluate];
      ITLFlag = 1;
      tempITLIndex = IndexToEvaluate;
    }
      
    if((sc.Low[IndexToEvaluate] > tempSTLow) && (ITLFlag == 1))
    {
      SwingIntermediateLow[tempITLIndex] = sc.Low[tempITLIndex] - ArrowOffsetLows;
      SwingShortLow[tempITLIndex] = 0;
      ITLFlag = 0;
      tempSTLow = sc.Low[IndexToEvaluate];
      if(tempITLow == 0)
        tempITLow=sc.Low[tempITLIndex];

      if(sc.Low[tempITLIndex] < tempITLow)
      {
        tempITLow = sc.Low[tempITLIndex];
        LTLFlag = 1;
        tempLTLIndex = tempITLIndex;
      }
      
      if((sc.Low[tempITLIndex] > tempITLow) && (LTLFlag == 1))
      {
        SwingLongLow[tempLTLIndex] = sc.Low[tempLTLIndex] - ArrowOffsetLows;
        SwingIntermediateLow[tempLTLIndex] = 0;
        LTLFlag = 0;
        tempITLow=sc.Low[tempITLIndex];
      }
      else
        tempITLow=sc.Low[tempITLIndex];          
    }
    else
    {
      tempSTLow = sc.Low[IndexToEvaluate];
    }
  }
}


Date Time Of Last Edit: 2013-04-17 19:24:40