linear-momentum
Download scriptThis tool is designed to help traders visualize the underlying strength and speed of price movements by calculating "Linear Momentum." Instead of simply looking at whether a price went up or down, this script analyzes how quickly that change occurred over a specific timeframe, helping to filter out market noise.
The logic follows a three-step process to arrive at the final visual result:
1. Measuring Velocity
The script begins by determining the "Velocity" of the market for every individual candle. It does this by looking at two factors:
- Distance: The difference between the opening price and the closing price of a candle (converted into points).
- Time: The actual amount of time that passed during that candle.
By dividing the distance by the time, the script identifies how fast the price moved. If a large price move happens in a very short amount of time, it registers a higher velocity; if a small move takes a long time, the velocity is lower.
2. Weighting by Activity
Once the velocity is established, the script accounts for market participation using "Tick Volume." It multiplies the velocity by the number of times the price updated (ticks) during that period. This ensures that price movements occurring during high-activity periods carry more weight than those occurring during low-volume, illiquid moments.
3. Smoothing the Data
Because raw market data can be jagged and erratic, the final step applies a smoothing filter. The script takes the weighted momentum data and runs it through a Moving Average (based on your chosen period and method). This transforms the raw calculations into a continuous, flowing line.
How to interpret the results: The resulting line provides a clearer picture of the trend's "momentum." By observing the direction and steepness of this line, you can better understand if the current market trend is accelerating, decelerating, or losing steam, providing a more nuanced view than price action alone.
//+------------------------------------------------------------------+
//| Linear Momentum.mq4 |
//| Copyright 2015, Totom Sukopratomo |
//| https://www.mqlmonster.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Totom Sukopratomo"
#property link "https://www.mqlmonster.com"
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_level1 0.0
//--- plot MoLin
#property indicator_label1 "Linear Momentum"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
input int SmoothingPeriod=14; // Smoothing Period
input ENUM_MA_METHOD SmoothingMethod=MODE_EMA; // Smoothing Method
//--- indicator buffers
double LinearMomentumBuffer[];
double Velocity[];
double Temporary[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
IndicatorBuffers(3);
SetIndexBuffer(0,LinearMomentumBuffer);
SetIndexBuffer(1,Velocity);
SetIndexBuffer(2,Temporary);
SetIndexDrawBegin(0,SmoothingPeriod);
IndicatorDigits(1);
IndicatorShortName("LM ("+IntegerToString(SmoothingPeriod)+")");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//--- Set arrays as series for easier calculation
ArraySetAsSeries(LinearMomentumBuffer,true);
ArraySetAsSeries(Velocity,true);
ArraySetAsSeries(Temporary,true);
ArraySetAsSeries(time,true);
ArraySetAsSeries(open,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(tick_volume,true);
//--- Not all candles will be recounted on every incoming tick
int limit;
limit=rates_total-prev_calculated;
if(prev_calculated>0)
{
limit++;
}
else
{
limit--;
}
//--- Calculate Velocity
for(int x=0; x<limit; x++)
{
int _Seconds;
if(x>0)
{
_Seconds=(int)(time[x]-time[x+1]);
}
else
{
_Seconds=(int)(TimeCurrent()-time[x]);
}
double Distance;
if(NormalizeDouble(close[x]-open[x],8)!=0.00000000)
{
Distance=(close[x]-open[x])/_Point;
}
else
{
Distance=0.0;
}
if(NormalizeDouble(Distance,8)!=0.00000000 && _Seconds!=0)
{
Velocity[x]=Distance/_Seconds;
}
else
{
Velocity[x]=0.0;
}
}
//--- Calculate Momentum Linear
for(int x=0; x<limit; x++)
{
Temporary[x]=tick_volume[x]*Velocity[x];
}
//--- Do smooth Momentum Linear
for(int x=0; x<limit; x++)
{
LinearMomentumBuffer[x]=iMAOnArray(Temporary,0,SmoothingPeriod,0,SmoothingMethod,x);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Comments