Center of Gravity_v3
Download scriptThis script is designed to provide a sophisticated visual analysis of price trends by identifying the "Center of Gravity" within market data. Unlike standard moving averages that simply smooth out price fluctuations, this tool uses advanced mathematical modeling to determine the underlying momentum and structural equilibrium of the market.
Core Logic and Methodology
The logic follows a structured three-step process to interpret price action:
1. Data Aggregation and Matrix Construction The indicator looks back at a specific history of price bars (defined by the user). It systematically collects closing prices and calculates their relationship to time. It then builds a mathematical matrix—a grid of numbers that represents how price movements correlate with the passage of time over that specific period.
2. Polynomial Regression (The "Gauss" Method) To find the true "center" of the price movement, the script employs a method known as Gaussian Elimination. This is a rigorous algebraic process used to solve complex systems of equations.
- It treats the price history not just as a series of dots, but as a curve.
- By solving this matrix, the script calculates a mathematical polynomial—a smooth curve that best fits the historical data points.
- Essentially, it filters out "noise" (random fluctuations) to reveal the primary direction and curvature of the trend.
3. Dynamic Deviation and Boundary Mapping Once the central trend line (the Center of Gravity) is established, the script calculates the volatility around that line. It generates four distinct visual components:
- The Core Trend: The primary line representing the calculated Center of Gravity.
- Standard Deviations: The script calculates two sets of boundaries based on statistical variance. These act as "envelopes" or "channels."
- Upper and Lower Limits: By applying a multiplier to the standard deviation, the script creates clear visual boundaries. These represent the zones where prices are considered statistically "overextended" relative to the current center of gravity.
Summary for the User
In practical terms, this script doesn't just tell you where the price was; it attempts to calculate where the "balance point" of the current trend is located. By identifying this center and projecting the surrounding statistical boundaries, it allows traders to visualize the equilibrium of the market, helping to distinguish between a significant trend shift and temporary price noise.
//+------------------------------------------------------------------+
//| Center of Gravity.mq4 |
//| Original Code from NG3110@latchess.com |
//| Linuxser 2007 for TSD http://www.forex-tsd.com/ |
//+------------------------------------------------------------------+
#property copyright "ANG3110@latchess.com"
//---------ang_PR (Din)--------------------
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 RoyalBlue
#property indicator_color2 LimeGreen
#property indicator_color3 LimeGreen
#property indicator_color4 Goldenrod
#property indicator_color5 Goldenrod
#property indicator_width1 1 //òîëùèíà ëèíèè
#property indicator_width2 2 //òîëùèíà ëèíèè
#property indicator_width3 2 //òîëùèíà ëèíèè
#property indicator_width4 3 //òîëùèíà ëèíèè
#property indicator_width5 3 //òîëùèíà ëèíèè
//-----------------------------------
extern int bars_back = 125;
extern int m = 2;
extern int i = 0;
extern double kstd = 2.0;
extern int sName = 1102;
//-----------------------
double fx[], sqh[], sql[], stdh[], stdl[];
double ai[10,10], b[10], x[10], sx[20];
double sum;
int ip, p, n, f;
double qq, mm, tt;
int ii, jj, kk, ll, nn;
double sq, std;
//*******************************************
int init()
{
IndicatorShortName("Center of Gravity");
SetIndexStyle(0, DRAW_LINE);
SetIndexBuffer(0, fx);
SetIndexBuffer(1, sqh);
SetIndexBuffer(2, sql);
SetIndexBuffer(3, stdh);
SetIndexBuffer(4, stdl);
p = MathRound(bars_back);
nn = m + 1;
ObjectCreate("pr" + sName, 22, 0, Time[p], fx[p]);
ObjectSet("pr" + sName, 14, 159);
return(0);
}
//----------------------------------------------------------
int deinit()
{
ObjectDelete("pr" + sName);
}
//**********************************************************************************************
int start()
{
int mi;
//-------------------------------------------------------------------------------------------
ip = iBarShift(Symbol(), Period(), ObjectGet("pr" + sName, OBJPROP_TIME1));
p = bars_back;
sx[1] = p + 1;
SetIndexDrawBegin(0, Bars - p - 1);
SetIndexDrawBegin(1, Bars - p - 1);
SetIndexDrawBegin(2, Bars - p - 1);
SetIndexDrawBegin(3, Bars - p - 1);
SetIndexDrawBegin(4, Bars - p - 1);
//----------------------sx-------------------------------------------------------------------
for(mi = 1; mi <= nn * 2 - 2; mi++)
{
sum = 0;
for(n = i; n <= i + p; n++)
{
sum += MathPow(n, mi);
}
sx[mi + 1] = sum;
}
//----------------------syx-----------
for(mi = 1; mi <= nn; mi++)
{
sum = 0.00000;
for(n = i; n <= i + p; n++)
{
if(mi == 1)
sum += Close[n];
else
sum += Close[n] * MathPow(n, mi - 1);
}
b[mi] = sum;
}
//===============Matrix=======================================================================================================
for(jj = 1; jj <= nn; jj++)
{
for(ii = 1; ii <= nn; ii++)
{
kk = ii + jj - 1;
ai[ii, jj] = sx[kk];
}
}
//===============Gauss========================================================================================================
for(kk = 1; kk <= nn - 1; kk++)
{
ll = 0; mm = 0;
for(ii = kk; ii <= nn; ii++)
{
if(MathAbs(ai[ii, kk]) > mm)
{
mm = MathAbs(ai[ii, kk]);
ll = ii;
}
}
if(ll == 0)
return(0);
if(ll != kk)
{
for(jj = 1; jj <= nn; jj++)
{
tt = ai[kk, jj];
ai[kk, jj] = ai[ll, jj];
ai[ll, jj] = tt;
}
tt = b[kk]; b[kk] = b[ll]; b[ll] = tt;
}
for(ii = kk + 1; ii <= nn; ii++)
{
qq = ai[ii, kk] / ai[kk, kk];
for(jj = 1; jj <= nn; jj++)
{
if(jj == kk)
ai[ii, jj] = 0;
else
ai[ii, jj] = ai[ii, jj] - qq * ai[kk, jj];
}
b[ii] = b[ii] - qq * b[kk];
}
}
x[nn] = b[nn] / ai[nn, nn];
for(ii = nn - 1; ii >= 1; ii--)
{
tt = 0;
for(jj = 1; jj <= nn - ii; jj++)
{
tt = tt + ai[ii, ii + jj] * x[ii + jj];
x[ii] = (1 / ai[ii, ii]) * (b[ii] - tt);
}
}
//===========================================================================================================================
for(n = i; n <= i + p; n++)
{
sum = 0;
for(kk = 1; kk <= m; kk++)
{
sum += x[kk + 1] * MathPow(n, kk);
}
fx[n] = x[1] + sum;
}
//-----------------------------------Std-----------------------------------------------------------------------------------
sq = 0.0;
for(n = i; n <= i + p; n++)
{
sq += MathPow(Close[n] - fx[n], 2);
}
sq = MathSqrt(sq / (p + 1)) * kstd;
std = iStdDev(NULL, 0, p, MODE_SMA, 0, PRICE_CLOSE, i) * kstd;
for(n = i; n <= i + p; n++)
{
sqh[n] = fx[n] + sq;
sql[n] = fx[n] - sq;
stdh[n] = fx[n] + std;
stdl[n] = fx[n] - std;
}
//-------------------------------------------------------------------------------
ObjectMove("pr" + sName, 0, Time[p], fx[p]);
//----------------------------------------------------------------------------------------------------------------------------
return(0);
}
//==========================================================================================================================
Comments