FiboPivot Points
Download scriptThis tool is designed to automatically calculate and display "Pivot Points" on a trading chart. Pivot Points are technical analysis levels used by traders to identify potential support and resistance zones, helping them gauge where the market might experience a price reversal or consolidation.
Core Functionality
The script organizes market data into three distinct timeframes, allowing you to choose which scope of analysis you want to view:
- Daily: Calculates levels based on the previous day's trading activity.
- Weekly: Calculates levels based on the previous week's trading activity.
- Monthly: Calculates levels based on the previous month's trading activity.
How the Logic Works
To ensure the data is accurate, the script follows a structured sequence of operations:
1. Timeframe Detection and Filtering The script first checks which timeframe you are currently viewing on your chart. To prevent visual clutter and maintain logical consistency, it includes safety checks: for example, it will hide Daily Pivot levels if you are looking at a weekly chart, or Monthly levels if you are viewing a daily chart.
2. Historical Data Retrieval Once the desired timeframe (Daily, Weekly, or Monthly) is selected, the script "looks back" into the historical price data. It specifically identifies the period of the previous session to extract four critical pieces of information:
- The highest price reached (High)
- The lowest price reached (Low)
- The price at which the session opened (Open)
- The price at which the session closed (Close)
3. Pivot Calculation After gathering the previous period's high, low, and close prices, the script applies a mathematical formula to generate seven specific levels:
- The Pivot Point (PP): The central equilibrium point, calculated as the average of the previous period's High, Low, and Close.
- Resistance Levels (R1, R2, R3): These are calculated above the Pivot Point. They represent areas where sellers might step in to push prices down.
- Support Levels (S1, S2, S3): These are calculated below the Pivot Point. They represent areas where buyers might step in to push prices up.
The script uses specific multipliers (based on Fibonacci-style proportions) to determine the distance of these levels from the center Pivot Point.
4. Dynamic Visualization Finally, the script draws these levels on your chart. It is programmed to update automatically as new trading sessions begin. When a new day, week, or month starts, the script detects the transition, pulls the updated historical data from the session that just ended, and refreshes the lines on your screen accordingly.
//+------------------------------------------------------------------+
//| Pivot Points v8.mq4 |
//| Copyright © 2007, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Jason Normandin"
//FiboPivot calculations inserted by Jack Hewings
#property link ""
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 MediumVioletRed
#property indicator_color2 MediumVioletRed
#property indicator_color3 MediumVioletRed
#property indicator_color4 Tomato
#property indicator_color5 Teal
#property indicator_color6 Teal
#property indicator_color7 Teal
#property indicator_width1 3
#property indicator_width2 2
#property indicator_width3 1
#property indicator_width4 3
#property indicator_width5 1
#property indicator_width6 2
#property indicator_width7 3
/*
#property indicator_style1 STYLE_DOT
#property indicator_style2 STYLE_DOT
#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_SOLID
#property indicator_style5 STYLE_DOT
#property indicator_style6 STYLE_DOT
#property indicator_style7 STYLE_DOT
*/
#define SECONDS_IN_MINUTE 60
#define SECONDS_IN_HOUR 3600
#define SECONDS_IN_DAY 86400
#define PIVOTSET_DAILY 1
#define PIVOTSET_WEEKLY 2
#define PIVOTSET_MONTHLY 3
#define PIVOT_R3 0
#define PIVOT_R2 1
#define PIVOT_R1 2
#define PIVOT_PP 3
#define PIVOT_S1 4
#define PIVOT_S2 5
#define PIVOT_S3 6
// input parameters
extern int PivotSet = PIVOTSET_DAILY;
extern int DayStartHour = 0; // Metaquotes is +2 GMT
// buffers
double dR3Buffer[];
double dR2Buffer[];
double dR1Buffer[];
double dPPBuffer[];
double dS1Buffer[];
double dS2Buffer[];
double dS3Buffer[];
int init() {
SetIndexBuffer(0,dR3Buffer);
SetIndexBuffer(1,dR2Buffer);
SetIndexBuffer(2,dR1Buffer);
SetIndexBuffer(3,dPPBuffer);
SetIndexBuffer(4,dS1Buffer);
SetIndexBuffer(5,dS2Buffer);
SetIndexBuffer(6,dS3Buffer);
switch (PivotSet) {
case PIVOTSET_DAILY:
IndicatorShortName("Daily Pivot Points");
SetIndexLabel(0,"Daily Pivot R3");
SetIndexLabel(1,"Daily Pivot R2");
SetIndexLabel(2,"Daily Pivot R1");
SetIndexLabel(3,"Daily Pivot Point");
SetIndexLabel(4,"Daily Pivot S1");
SetIndexLabel(5,"Daily Pivot S2");
SetIndexLabel(6,"Daily Pivot S3");
break;
case PIVOTSET_WEEKLY:
IndicatorShortName("Weekly Pivot Points");
SetIndexLabel(0,"Weekly Pivot R3");
SetIndexLabel(1,"Weekly Pivot R2");
SetIndexLabel(2,"Weekly Pivot R1");
SetIndexLabel(3,"Weekly Pivot Point");
SetIndexLabel(4,"Weekly Pivot S1");
SetIndexLabel(5,"Weekly Pivot S2");
SetIndexLabel(6,"Weekly Pivot S3");
break;
case PIVOTSET_MONTHLY:
IndicatorShortName("Monthly Pivot Points");
SetIndexLabel(0,"Monthly Pivot R3");
SetIndexLabel(1,"Monthly Pivot R2");
SetIndexLabel(2,"Monthly Pivot R1");
SetIndexLabel(3,"Monthly Pivot Point");
SetIndexLabel(4,"Monthly Pivot S1");
SetIndexLabel(5,"Monthly Pivot S2");
SetIndexLabel(6,"Monthly Pivot S3");
break;
}
return(0);
}
int start() {
double dPrices[4];
double dPivots[7];
// Don't show lines on inappropriate timeframes
switch (PivotSet) {
case PIVOTSET_DAILY:
if (Period() > PERIOD_H1) return(0);
break;
case PIVOTSET_WEEKLY:
if (Period() > PERIOD_D1) return(0);
break;
case PIVOTSET_MONTHLY:
if (Period() > PERIOD_W1) return(0);
break;
}
// Determine how far back to iterate
int iBarsToCalc = Bars - IndicatorCounted();
if (iBarsToCalc < Bars) iBarsToCalc++;
// Iterate over bars and perform calcs
for (int i=iBarsToCalc-1;i>=0;i--) {
// DAILY PIVOTS
// If PivotSet = PIVOTSET_DAILY and it's a new day then calc pivots
if (PivotSet == PIVOTSET_DAILY) {
datetime dtDayStart0 = getDayStart(Time[i]);
datetime dtDayStart1 = getDayStart(Time[i+1]);
if (dtDayStart0 != dtDayStart1) {
getPrevDayPrices(dPrices,dtDayStart0);
getPivots(dPivots,dPrices);
}
} // end daily pivot block
// WEEKLY PIVOTS
// If PivotSet = PIVOTSET_WEEKLY and it's a new week then calc pivots
if (PivotSet == PIVOTSET_WEEKLY) {
datetime dtWeekStart0 = getWeekStart(Time[i]);
datetime dtWeekStart1 = getWeekStart(Time[i+1]);
if (dtWeekStart0 != dtWeekStart1) {
getPrevWeekPrices(dPrices,dtWeekStart0);
getPivots(dPivots,dPrices);
}
} // end weekly pivot block
// MONTHLY PIVOTS
// If PivotSet = PIVOTSET_MONTHLY and it's a new month then calc pivots
if (PivotSet == PIVOTSET_MONTHLY) {
datetime dtMonthStart0 = getMonthStart(Time[i]);
datetime dtMonthStart1 = getMonthStart(Time[i+1]);
if (dtMonthStart0 != dtMonthStart1) {
getPrevMonthPrices(dPrices,dtMonthStart0);
getPivots(dPivots,dPrices);
}
} // end weekly pivot block
// If the pivots have been updated, this will push out the changes
// if the pivots haven't been updated, the previous values will carry forward
dR3Buffer[i] = dPivots[PIVOT_R3];
dR2Buffer[i] = dPivots[PIVOT_R2];
dR1Buffer[i] = dPivots[PIVOT_R1];
dPPBuffer[i] = dPivots[PIVOT_PP];
dS1Buffer[i] = dPivots[PIVOT_S1];
dS2Buffer[i] = dPivots[PIVOT_S2];
dS3Buffer[i] = dPivots[PIVOT_S3];
}
return(0);
}
void getPivots(double& pivots[], double prices[]) {
// Calculate the pivots
pivots[PIVOT_PP] = NormalizeDouble((prices[PRICE_HIGH] + prices[PRICE_LOW] + prices[PRICE_CLOSE]) / 3,Digits);
pivots[PIVOT_R1] = NormalizeDouble(pivots[PIVOT_PP] + ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 0.382),Digits);
pivots[PIVOT_S1] = NormalizeDouble(pivots[PIVOT_PP] - ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 0.382),Digits);
pivots[PIVOT_R2] = NormalizeDouble(pivots[PIVOT_PP] + ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 0.618),Digits);
pivots[PIVOT_S2] = NormalizeDouble(pivots[PIVOT_PP] - ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 0.618),Digits);
pivots[PIVOT_R3] = NormalizeDouble(pivots[PIVOT_PP] + ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 1.000),Digits);
pivots[PIVOT_S3] = NormalizeDouble(pivots[PIVOT_PP] - ((prices[PRICE_HIGH] - prices[PRICE_LOW]) * 1.000),Digits);
}
void getPrevDayPrices(double& prices[], datetime timestamp) {
// Get the last bar of the previous trading day
// since iBarShift exact param = false, the previous existing bar will be returned
int iBarIndex = iBarShift(NULL,PERIOD_H1,timestamp-SECONDS_IN_HOUR,false);
datetime dtPrevDayStart = getDayStart(iTime(NULL,PERIOD_H1,iBarIndex));
// Get close price for the day and set initial values for high and low
prices[PRICE_HIGH] = iHigh (NULL,PERIOD_H1,iBarIndex);
prices[PRICE_LOW] = iLow (NULL,PERIOD_H1,iBarIndex);
prices[PRICE_OPEN] = iOpen (NULL,PERIOD_H1,iBarIndex);
prices[PRICE_CLOSE] = iClose(NULL,PERIOD_H1,iBarIndex);
iBarIndex++;
// Iterate back and check for high/low prices until all of previous trading day covered
while (getDayStart(iTime(NULL,PERIOD_H1,iBarIndex)) == dtPrevDayStart) {
prices[PRICE_HIGH] = MathMax(prices[PRICE_HIGH], iHigh (NULL,PERIOD_H1,iBarIndex));
prices[PRICE_LOW] = MathMin(prices[PRICE_LOW], iLow (NULL,PERIOD_H1,iBarIndex));
prices[PRICE_OPEN] = iOpen(NULL,PERIOD_H1,iBarIndex);
iBarIndex++;
}
return;
}
void getPrevWeekPrices(double& prices[], datetime timestamp) {
// Get start of previous week
datetime dtPrevWeekStart = timestamp - 7 * SECONDS_IN_DAY;
// Get offset for previous week bar
int iBarIndex = iBarShift(NULL,PERIOD_W1,dtPrevWeekStart,true);
// Get pricing for previous week and fill array
prices[PRICE_HIGH] = iHigh (NULL,PERIOD_W1,iBarIndex);
prices[PRICE_LOW] = iLow (NULL,PERIOD_W1,iBarIndex);
prices[PRICE_OPEN] = iOpen (NULL,PERIOD_W1,iBarIndex);
prices[PRICE_CLOSE] = iClose(NULL,PERIOD_W1,iBarIndex);
return;
}
void getPrevMonthPrices(double& prices[], datetime timestamp) {
// Get start of previous month
datetime dtPrevMonthStart = getMonthStart(timestamp - SECONDS_IN_DAY);
// Get offset for previous month bar
int iBarIndex = iBarShift(NULL,PERIOD_MN1,dtPrevMonthStart,true);
// Get pricing for previous week and fill array
prices[PRICE_HIGH] = iHigh (NULL,PERIOD_MN1,iBarIndex);
prices[PRICE_LOW] = iLow (NULL,PERIOD_MN1,iBarIndex);
prices[PRICE_OPEN] = iOpen (NULL,PERIOD_MN1,iBarIndex);
prices[PRICE_CLOSE] = iClose(NULL,PERIOD_MN1,iBarIndex);
return;
}
datetime getDayStart(datetime timestamp) {
// Strip seconds from timestamp
// (probably not required)
timestamp -= TimeSeconds(timestamp);
// Strip minutes from timestamp
timestamp -= TimeMinute(timestamp) * SECONDS_IN_MINUTE;
// Subtract enough hours to reach previous day start
if (TimeHour(timestamp) >= DayStartHour)
timestamp -= (TimeHour(timestamp) - DayStartHour) * SECONDS_IN_HOUR;
else
timestamp -= (TimeHour(timestamp) + (24 - DayStartHour)) * SECONDS_IN_HOUR;
return(timestamp);
}
datetime getWeekStart(datetime timestamp) {
// Strip seconds from timestamp
// (probably not required)
timestamp -= TimeSeconds(timestamp);
// Strip minutes from timestamp
timestamp -= TimeMinute(timestamp) * SECONDS_IN_MINUTE;
// Strip hours from timestamp
timestamp -= TimeHour(timestamp) * SECONDS_IN_HOUR;
// Strip days past Sunday from timestamp
timestamp -= TimeDayOfWeek(timestamp) * SECONDS_IN_DAY;
return(timestamp);
}
datetime getMonthStart(datetime timestamp) {
// Strip seconds from timestamp
// (probably not required)
timestamp -= TimeSeconds(timestamp);
// Strip minutes from timestamp
timestamp -= TimeMinute(timestamp) * SECONDS_IN_MINUTE;
// Strip hours from timestamp
timestamp -= TimeHour(timestamp) * SECONDS_IN_HOUR;
// Strip days past 1 from timestamp
timestamp -= (TimeDay(timestamp) - 1) * SECONDS_IN_DAY;
return(timestamp);
}
Comments