VininI ConstTicksSMA
Download scriptThis script is designed to generate a specialized Simple Moving Average (SMA) on your trading charts. Unlike a standard moving average that simply looks at the most recent price points, this tool uses a sophisticated multi-layered logic to determine its values.
Core Logic Overview
1. Dynamic Data Fetching Instead of relying solely on the basic "Close" or "Open" prices of a candle, the script communicates with an external data source (a secondary custom indicator). It pulls specific price information based on three customizable factors:
- Price Mode: Determines the specific type of pricing behavior to follow.
- Tick Count: Controls the volume of data points considered within the calculation.
- Draw All Toggle: A setting that determines whether to visualize the entire historical data set or focus only on recent updates.
2. Variable Spacing Awareness One of the most unique features of this script is its ability to handle "shifts" in data. The logic doesn't assume that every data point is perfectly adjacent. It calculates the distance between different price points dynamically. If there are gaps or shifts in the underlying data, the script identifies these positions and ensures the moving average remains accurately aligned with the timeline, rather than being distorted by missing information.
3. The Moving Average Calculation Once the correct prices are gathered into a temporary internal list:
- The script sums up the values across the user-defined MA Period (the number of data points to include).
- It divides that sum by the period to find the average.
- It then plots this value on your chart as a continuous line.
4. Visual Cleanup To ensure the chart remains clean and professional, the script includes a "cleaning" phase. If the user chooses not to draw the entire history, the logic will automatically identify segments of the chart where data isn't applicable and clear them out (setting them to an empty value). This prevents the moving average line from "bleeding" into areas where it shouldn't exist, providing a much sharper and more readable visual experience.
Summary for the User
In short, this is a high-precision Moving Average. It is built for traders who need a trend line that accounts for specific tick behaviors and complex data spacing rather than just a basic average of the current candle prices. It ensures that the "Average" you see on your screen is mathematically anchored to the correct price points provided by your secondary data source.
//+------------------------------------------------------------------+
//| Custom Moving Average.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int Price_Mode=0;
extern int MA_Period=13;
extern int CountTick=100;
extern bool DrawAll=false;
//---- indicator buffers
double ExtMapBuffer[];
int ExtCountedBars=0;
double Price[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() {
string short_name;
SetIndexStyle(0,DRAW_SECTION);
short_name="SMA(";
IndicatorShortName(short_name+MA_Period+")");
SetIndexBuffer(0,ExtMapBuffer);
ArrayResize(Price,MA_Period);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start() {
int limit;
int counted_bars=IndicatorCounted();
int i, pos;
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for (i = limit;i>=0;i--){
PriceArray(Price,i);
sma(i);
}
return(0);
}
bool PriceArray(double &Price[], int pos){
int i,shift;
shift=0;
for (i=0;i<MA_Period;i++){
Price[i]=iCustom(NULL,0,"VininI ConstTickPrice",Price_Mode,CountTick,DrawAll,0,pos+shift);
shift+=(iCustom(NULL,0,"VininI ConstTickPrice",Price_Mode,CountTick,DrawAll,1,pos+shift)+1);
}
}
//+------------------------------------------------------------------+
//| Simple Moving Average |
//+------------------------------------------------------------------+
void sma(int pos) {
int i,shift;
double sum=0;
if (!DrawAll) {
shift=iCustom(NULL,0,"VininI ConstTickPrice",Price_Mode,CountTick,DrawAll,1,pos);
for (i=1;i<=shift;i++) ExtMapBuffer[pos+i]=EMPTY_VALUE;
}
for(i=0;i<MA_Period;i++) sum+=Price[i];
ExtMapBuffer[pos]=sum/MA_Period;
}
/*
//+------------------------------------------------------------------+
//| Exponential Moving Average |
//+------------------------------------------------------------------+
void ema(int pos) {
int i,shift;
double pr=2.0/(MA_Period+1);
if (!DrawAll) {
shift=iCustom(NULL,0,"VininI ConstTickPrice",Price_Mode,CountTick,DrawAll,1,pos);
for (i=1;i<=shift;i++) ExtMapBuffer[pos+i]=EMPTY_VALUE;
}
if(pos==Bars-2) ExtMapBuffer[pos+1]=Close[pos+1];
ExtMapBuffer[pos]=Close[pos]*pr+ExtMapBuffer[pos+1]*(1-pr);
pos--;
}
}
//+------------------------------------------------------------------+
//| Smoothed Moving Average |
//+------------------------------------------------------------------+
void smma()
{
double sum=0;
int i,k,pos=Bars-ExtCountedBars+1;
//---- main calculation loop
pos=Bars-MA_Period;
if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars;
while(pos>=0)
{
if(pos==Bars-MA_Period)
{
//---- initial accumulation
for(i=0,k=pos;i<MA_Period;i++,k++)
{
sum+=Close[k];
//---- zero initial bars
ExtMapBuffer[k]=0;
}
}
else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+Close[pos];
ExtMapBuffer[pos]=sum/MA_Period;
pos--;
}
}
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average |
//+------------------------------------------------------------------+
void lwma()
{
double sum=0.0,lsum=0.0;
double price;
int i,weight=0,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<=MA_Period;i++,pos--)
{
price=Close[pos];
sum+=price*i;
lsum+=price;
weight+=i;
}
//---- main calculation loop
pos++;
i=pos+MA_Period;
while(pos>=0)
{
ExtMapBuffer[pos]=sum/weight;
if(pos==0) break;
pos--;
i--;
price=Close[pos];
sum=sum-lsum+price*MA_Period;
lsum-=Close[i];
lsum+=price;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
//+------------------------------------------------------------------+
*/
Comments