derivative
Download scriptThis script is designed as a custom technical indicator for the MetaTrader platform. Its primary purpose is to track and visualize price momentum by calculating the percentage change of a specific price point over a defined period.
Core Logic Overview
The tool operates by analyzing historical price data to determine how much the price has moved relative to its position a certain number of bars ago. It essentially "smooths" out market noise to show the velocity of price movement.
Key Components and Functionality
1. Customizable Price Basis Instead of relying solely on the standard closing price, the script allows users to choose which specific price data point should be used for the calculation. You can select from various types, including:
- Standard Points: Open, High, Low, or Close prices.
- Averages: Median (Average of High/Low), Typical (Average of High, Low, and Close), Weighted Close, or Full Median (Average of all four price points).
This flexibility ensures the indicator can be tailored to different trading styles—for example, using "High" and "Low" data might provide a broader view of volatility compared to just using the "Close."
2. Slowing Mechanism (The Time Window) The script features a "Slowing" parameter. This determines the "look-back" period. It compares the current price against the price from a specific number of bars in the past. By adjusting this value, traders can choose to see short-term fluctuations or broader, long-term trends.
3. Percentage Change Calculation The heart of the script's logic is its mathematical formula. It takes the difference between the current selected price and the selected price from the "Slowing" period ago, divides that difference by the period length, and multiplies it by 100.
- Result: This produces a percentage value. A positive value indicates an upward trend relative to the past, while a negative value indicates a downward trend.
4. Display and Performance Optimization
- Visual Output: The result is displayed as a line graph in a separate window below the main price chart, making it easier to see trends without cluttering the primary price action.
- Data Management: To ensure the platform remains fast and responsive, the script includes a "Bars Count" limit. This prevents the tool from trying to calculate data for an infinite amount of history, focusing only on the most relevant recent data (up to 10,000 bars by default).
- Error Handling: The script includes built-in checks to ensure that the inputs provided are valid (e.g., ensuring the slowing period is greater than zero) and will alert the user if the settings are incorrect before the indicator begins to run.
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2012, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Scriptong"
#property link "http://advancetools.net"
#property strict
#property indicator_separate_window
#property indicator_level1 0.0
#property indicator_buffers 1
#property indicator_color1 clrDodgerBlue
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
enum ENUM_PRICE_TYPE
{
PRICE_TYPE_CLOSE, // Close / Çàêðûòèå
PRICE_TYPE_OPEN, // Open / Îòêðûòèå
PRICE_TYPE_HIGH, // High / Ìàêñèìóì
PRICE_TYPE_LOW, // Low / Ìèíèìóì
PRICE_TYPE_MEDIAN, // Median / Ñðåäíÿÿ
PRICE_TYPE_TYPICAL, // Typical / Òèïè÷íàÿ
PRICE_TYPE_WEIGHTED, // Weighted close / Âçâåøåííîå çàêðûòèå
PRICE_TYPE_FULL_MEDIAN // Full median / Ïîëíàÿ ñðåäíÿÿ
};
//+------------------------------------------------------------------+
input int i_slowing = 34; // Slowing / Çàïàçäûâàíèå
input ENUM_PRICE_TYPE i_price = PRICE_WEIGHTED; // Applied price / Èñïîëüçóåìàÿ öåíà
input int i_indBarsCount = 10000; // The number of bars to display / Êîëè÷åñòâî áàðîâ îòîáðàæåíèÿ
//--- The indicator's buffers
double g_indValues[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(!IsTuningParametersCorrect())
return INIT_FAILED;
//---
if(!BuffersBind())
return (INIT_FAILED);
//---
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Checking the correctness of input parameters |
//+------------------------------------------------------------------+
bool IsTuningParametersCorrect()
{
string name=WindowExpertName();
//---
bool isRussianLang=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian");
//---
if(i_slowing<1)
{
Alert(name,(isRussianLang)? ": ïåðèîä çàìåäëåíèÿ äîëæåí áûòü áîëåå 0. Èíäèêàòîð îòêëþ÷åí." :
": period of slowing must be more than zero. The indicator is turned off.");
return false;
}
//---
return (true);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Binding of array and the indicator buffers |
//+------------------------------------------------------------------+
bool BuffersBind()
{
string name=WindowExpertName();
//---
bool isRussianLang=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian");
//--- Binding the array and indicator buffer
if(!SetIndexBuffer(0,g_indValues))
{
Alert(name,(isRussianLang)? ": îøèáêà ñâÿçûâàíèÿ ìàññèâîâ ñ áóôåðàìè èíäèêàòîðà. Îøèáêà ¹"+IntegerToString(GetLastError()) :
": error of binding of the arrays and the indicator buffers. Error N"+IntegerToString(GetLastError()));
return false;
}
//--- Set the type of indicator's buffer
SetIndexStyle(0,DRAW_LINE);
//---
return true;
}
//+------------------------------------------------------------------+
//| Initialize of all indicator buffers |
//+------------------------------------------------------------------+
void BuffersInitializeAll()
{
ArrayInitialize(g_indValues,EMPTY_VALUE);
}
//+------------------------------------------------------------------+
//| Determination of bar index which needed to recalculate |
//+------------------------------------------------------------------+
int GetRecalcIndex(int &total,const int ratesTotal,const int prevCalculated)
{
total=ratesTotal-i_slowing-2;
//---
if(i_indBarsCount>0 && i_indBarsCount<total)
total=MathMin(i_indBarsCount,total);
//---
if(prevCalculated<ratesTotal-1)
{
BuffersInitializeAll();
return total;
}
//---
return (MathMin(ratesTotal - prevCalculated, total));
}
//+------------------------------------------------------------------+
//| Calculation the applied price |
//+------------------------------------------------------------------+
double GetPrice(int barIndex)
{
double open=iOpen(NULL,0,barIndex);
double close= iClose(NULL,0,barIndex);
double high = iHigh(NULL,0,barIndex);
double low=iLow(NULL,0,barIndex);
//---
switch(i_price)
{
case PRICE_TYPE_CLOSE: return close;
case PRICE_TYPE_OPEN: return open;
case PRICE_TYPE_HIGH: return high;
case PRICE_TYPE_LOW: return low;
case PRICE_TYPE_MEDIAN: return (high + low) / 2;
case PRICE_TYPE_TYPICAL: return (high + low + close) / 3;
case PRICE_TYPE_WEIGHTED: return (high + low + 2 * close) / 4;
case PRICE_TYPE_FULL_MEDIAN: return (high + low + open + close) / 4;
}
//---
return 0.0;
}
//+------------------------------------------------------------------+
//| Calculation of indicators values |
//+------------------------------------------------------------------+
void CalcIndicatorData(int limit,int total)
{
for(int i=limit; i>=0; i--)
g_indValues[i]=100.0 *(GetPrice(i)-GetPrice(i+i_slowing))/i_slowing;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int total;
int limit=GetRecalcIndex(total,rates_total,prev_calculated);
//---
CalcIndicatorData(limit,total);
//---
return rates_total;
}
//+------------------------------------------------------------------+
Comments