Login Page - Create Account

Support Board


Date/Time: Thu, 28 Mar 2024 18:55:32 +0000



[User Discussion] - Can I put in a new Pivot Point formula request?

View Count: 2647

[2013-04-15 14:57:45]
Trint - Posts: 112
Hello Support,

Can I put in a new PP formula request for Variable Pivots for a future release (it's for Daily/Weekly/Monthly timeframes if possible). This has a few more levels to the 'Daily OHLC' and I was hoping to use it across a few more timeframes. I tried adding it as Formula 22 in my local copy of code but it fails to work.

==============================
PivotPoint = (High + Low) / 2;
R2 = (PivotPoint + High) / 2;
R1 = (PivotPoint + R2) / 2;
S2 = (PivotPoint + Low) / 2;
S1 = (PivotPoint + S2) / 2;
R3 = High;
S3 = Low;
===============================

On another note, I can submit some code I've created to label Swing Highs/Lows in terms of some importance (Larry Williams Market Structure, a general enquiry I lodged on the forum which I've managed to get working)

Regards,
Tim

Date Time Of Last Edit: 2013-04-15 14:59:50
[2013-04-16 11:18:32]
Trint - Posts: 112
Just realised the Internal Date-Time parameter fix in v964 has now sorted out the custom formula in my code after a rebuild with the latest, excellent. Thanks. :)

Please ignore the stuff above (if you haven't already done so).


Date Time Of Last Edit: 2013-04-16 11:21:22
[2013-04-16 17:55:10]
Sierra Chart Engineering - Posts: 104368
We can add the pivot points formula. Should we do that?
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
[2013-04-16 20:01:49]
Trint - Posts: 112
To be honest I'm not sure it's all that popular as I haven't seen many use it (not referenced on many sites) but I find it useful to have although I have a custom workaround now with the new fix and wouldn't need an update. Saying that, I use a combination of Pivot forumlas to get the lines I need, the High and Low pivot is useful but a new formula might just add extra baggage to the SC code. Thanks for still considering it.

Date Time Of Last Edit: 2013-04-16 20:02:01
[2013-04-16 20:26:07]
Sierra Chart Engineering - Posts: 104368
If you want to provide the code to label Swing Highs and Swing Lows, we can add that as a User Contributed study. No problem. Please post it here.
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
[2013-04-17 08:01:00]
Trint - Posts: 112
Would that mean I get the keys to the forum...

It needs a bit of tidying up (which I'll do today, adding comments) I'm not sure the code is the most efficient and it's not perfect but it works for what I need.

I've attached a picture of the the Study using the Hourly chart GBPUSD pair from the London Open this morning. The most recent 'I' would eventually update to a 'L' if a a lower 'I' is formed subsequently but basically a Short Term High is using the code for a Swing High. An Intermediate High having lower Short Term Highs either side of it and a Long Term High having lower Intermediate Highs either side of it. Obviously opposite for Lows.

edit: The 'Offset' study setting is needed for the chart so the MS characters are not too far away or to close to the candles.


Date Time Of Last Edit: 2013-04-17 08:03:23
imageMarketStructurePointExample.png / V - Attached On 2013-04-17 07:48:51 UTC - Size: 37.46 KB - 715 views
[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
[2013-04-23 02:25:04]
Sierra Chart Engineering - Posts: 104368
The code has been added to the User Contributed studies.
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
[2013-04-23 09:06:06]
Trint - Posts: 112
Feels good to add to the community, I have some Sierra Chart legacy. :)
[2018-11-19 22:49:28]
EdCarp - Posts: 25
Trint, I can't figure out how this works - How would you trade with this study? The structure points show up in the study out far behind price action, and they will change as time goes on. Scratching my head over this one. Any help appreciated, thanks!

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

Login

Login Page - Create Account