Re: Convert MT4 indicators to MT5
Posted: Fri Dec 27, 2024 1:32 am
THIS IS THE CODE I'M TRYING TO Convert.
Regards
Regards
Code: Select all
//+------------------------------------------------------------------+
//| XU_v004_RSIOMA |
//| A direct MQL4->MQL5 conversion (with further fixes) to compile |
//+------------------------------------------------------------------+
#property copyright "None"
#property link ""
#property version "1.003"
#property strict
#property description "THIS IS A FREE INDICATOR WITH NO TIME RESTRICTIONS"
#property description "Welcome to the XARD UNIVERSE"
#property description "Let the light shine and illuminate your trading world"
#property description "and with it secure your financial prosperity"
//--- Separate window
#property indicator_separate_window
//--- We will have 13 visible plots:
#property indicator_plots 13
//--- Plot 0 => levelu
#property indicator_label0 "LevelUp"
#property indicator_type0 DRAW_LINE
#property indicator_color0 C'0,144,0'
#property indicator_style0 STYLE_DOT
#property indicator_width0 1
//--- Plot 1 => leveld
#property indicator_label1 "LevelDown"
#property indicator_type1 DRAW_LINE
#property indicator_color1 C'144,0,0'
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//--- Plot 2 => middle
#property indicator_label2 "Middle"
#property indicator_type2 DRAW_LINE
#property indicator_color2 C'78,78,78'
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//--- Plot 3 => val (main RSI line)
#property indicator_label3 "RsiValue"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrSilver
#property indicator_width3 2
//--- Plot 4 => valua
#property indicator_label4 "ValUA"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrSpringGreen
#property indicator_width4 3
//--- Plot 5 => valub
#property indicator_label5 "ValUB"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrSpringGreen
#property indicator_width5 3
//--- Plot 6 => valda
#property indicator_label6 "ValDA"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrCrimson
#property indicator_width6 3
//--- Plot 7 => valdb
#property indicator_label7 "ValDB"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrCrimson
#property indicator_width7 3
//--- Plot 8 => avgs
#property indicator_label8 "Average"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrGray
#property indicator_width8 1
//--- Plot 9 => histoNeu
#property indicator_label9 "HistoNeu"
#property indicator_type9 DRAW_HISTOGRAM
#property indicator_color9 clrGray
#property indicator_style9 STYLE_SOLID
#property indicator_width9 2
//--- Plot 10 => histoNed
#property indicator_label10 "HistoNed"
#property indicator_type10 DRAW_HISTOGRAM
#property indicator_color10 clrGray
#property indicator_style10 STYLE_SOLID
#property indicator_width10 2
//--- Plot 11 => histou
#property indicator_label11 "HistoUp"
#property indicator_type11 DRAW_HISTOGRAM
#property indicator_color11 clrGreen
#property indicator_style11 STYLE_SOLID
#property indicator_width11 2
//--- Plot 12 => histod
#property indicator_label12 "HistoDown"
#property indicator_type12 DRAW_HISTOGRAM
#property indicator_color12 C'145,79,50'
#property indicator_style12 STYLE_SOLID
#property indicator_width12 2
//--- We also store more buffers for calculations:
#property indicator_buffers 26
//+------------------------------------------------------------------+
// ENUMS & INPUTS
//+------------------------------------------------------------------+
enum enTimeFrames
{
tf_cu = PERIOD_CURRENT,
tf_m1 = PERIOD_M1,
tf_m5 = PERIOD_M5,
tf_m15 = PERIOD_M15,
tf_m30 = PERIOD_M30,
tf_h1 = PERIOD_H1,
tf_h4 = PERIOD_H4,
tf_d1 = PERIOD_D1,
tf_w1 = PERIOD_W1,
tf_mn1 = PERIOD_MN1,
tf_n1 = -1,
tf_n2 = -2,
tf_n3 = -3
};
enum enPrices
{
pr_close,
pr_open,
pr_high,
pr_low,
pr_median,
pr_typical,
pr_weighted,
pr_average,
pr_medianb,
pr_tbiased,
pr_tbiased2,
pr_haclose,
pr_haopen,
pr_hahigh,
pr_halow,
pr_hamedian,
pr_hatypical,
pr_haweighted,
pr_haaverage,
pr_hamedianb,
pr_hatbiased,
pr_hatbiased2,
pr_habclose,
pr_habopen,
pr_habhigh,
pr_hablow,
pr_habmedian,
pr_habtypical,
pr_habweighted,
pr_habaverage,
pr_habmedianb,
pr_habtbiased,
pr_habtbiased2
};
enum enArrowsUp
{
arr_00=108,
arr_01=159,
arr_02=217,
arr_03=241,
arr_04=246,
arr_05=225,
arr_06=228,
arr_07=233,
arr_08=236,
arr_09=200,
arr_10=221
};
enum enArrowsDn
{
ard_00=108,
ard_01=159,
ard_02=218,
ard_03=242,
ard_04=248,
ard_05=226,
ard_06=230,
ard_07=234,
ard_08=238,
ard_09=202,
ard_10=222
};
enum enRsiTypes
{
rsi_rsi,
rsi_wil,
rsi_rap,
rsi_har,
rsi_rsx,
rsi_cut,
rsi_ehl
};
enum enColorOn
{
cc_onSlope,
cc_onMiddle,
cc_onLevels,
cc_onMa
};
enum enColorOnh
{
cc_onMiddleh,
cc_onLevels4h,
cc_onALLFh,
cc_onFIRSTFh
};
enum enMaTypes
{
ma_sma,
ma_ema,
ma_smma,
ma_lwma,
ma_linr
};
enum enArrowsOn
{
cc_onLine,
cc_onHisto,
cc_onAll,
cc_onFIRST
};
//+------------------------------------------------------------------+
// Inputs
//+------------------------------------------------------------------+
input enTimeFrames TimeFrame = tf_cu;
input enArrowsOn colorOna = cc_onAll;
input enColorOn colorOn = cc_onMiddle;
input enColorOnh colorOnh = cc_onMiddleh;
input int upw = 104;
//--- RSI
input enRsiTypes RsiType = rsi_rsi;
input int RsiPeriod = 10;
input int JmaLength = 10;
input enMaTypes smoothType = ma_ema;
input enPrices RsiPrice = pr_close;
input bool ShowLevels = false;
input bool ShowMiddle = true;
input double OverSold = 60.0;
input double OverBought = 40.0;
input int AveragePeriod = 7;
input enMaTypes AverageType = ma_ema;
//--- Trend MAs
input int S1MAper = 13;
input enMaTypes S1MAmode = ma_ema;
input enPrices MAPrice2 = pr_median;
input int T1MAper = 50;
input enMaTypes T1MAmode = ma_ema;
input enPrices MAPrice1 = pr_median;
//--- Filter
input int Filterperiod = 200;
input enMaTypes Filtermode = ma_ema;
input enPrices FilterPrice = pr_median;
//--- High/Low price settings
input enPrices priceH = pr_high;
input enPrices priceL = pr_low;
//--- Header
input bool showSymbolHeader = true;
input int header_Subwindow = 1;
input string ID = " xu1";
input int LR = -408;
input int UD = 30;
input int HDRsize = 16;
input ENUM_BASE_CORNER Header_corner = CORNER_RIGHT_LOWER;
input color Sbg = clrBlack;
color SymClr;
//--- Histo
input double upl = 11;
input double dnl = -11;
input double nel = 11;
input double ne2 = -11;
input int Width = 2;
input bool UseAutoWidth = true;
input color ColorUp = clrGreen;
input color ColorDn = C'145,79,50';
input color ColorNe = clrGray;
//--- Alerts
input bool alertsOn = false;
input bool alertsOnCurrent = false;
input bool alertsMessage = true;
input bool alertsSound = true;
input bool alertsNotify = false;
input bool alertsEmail = false;
//--- Arrows
input bool arrowsVisible = false;
input string arrowsIdentifier = " rsi Arrows1";
input bool arrowsOnNewest = false;
input color arrowsUpColor = clrMediumSeaGreen;
input color arrowsDnColor = clrCrimson;
input enArrowsUp arrowsUpCode = arr_08;
input enArrowsDn arrowsDnCode = ard_08;
input int arrowsUpSize = 1;
//--- Lines
input bool verticalLinesVisible = false;
input bool linesOnNewest = false;
input string verticalLinesID = "rsi Lines";
input color verticalLinesUpColor = clrDeepSkyBlue;
input color verticalLinesDnColor = clrPaleVioletRed;
input ENUM_LINE_STYLE verticalLinesStyle = STYLE_DOT;
//--- MTF interpolation
input bool Interpolate = true; // (not fully used here)
//+------------------------------------------------------------------+
// Buffers
//+------------------------------------------------------------------+
double levelu[],leveld[],middle[];
double val[],valua[],valub[],valda[],valdb[],avgs[],state[],countBuf[];
double histou[],histod[],histoNeu[],histoNed[],alltrend[],trend[];
double S1hi[],S1lo[],T1hi[],T1lo[],valcS1[],valcT1[];
double T1MA[],S1MA[],filterr[];
// For name checks
string Name = MQLInfoString(MQL_PROGRAM_NAME);
string MyName="XU v004-RSIOMA+XUHISTO";
string indicatorFileName="";
// Chart scaling
int getChartScale=WRONG_VALUE;
//+------------------------------------------------------------------+
// OnInit
//+------------------------------------------------------------------+
int OnInit()
{
// Assign buffers to plots 0..12:
SetIndexBuffer(0, levelu, INDICATOR_DATA);
SetIndexBuffer(1, leveld, INDICATOR_DATA);
SetIndexBuffer(2, middle, INDICATOR_DATA);
SetIndexBuffer(3, val, INDICATOR_DATA);
SetIndexBuffer(4, valua, INDICATOR_DATA);
SetIndexBuffer(5, valub, INDICATOR_DATA);
SetIndexBuffer(6, valda, INDICATOR_DATA);
SetIndexBuffer(7, valdb, INDICATOR_DATA);
SetIndexBuffer(8, avgs, INDICATOR_DATA);
SetIndexBuffer(9, histoNeu, INDICATOR_DATA);
SetIndexBuffer(10,histoNed, INDICATOR_DATA);
SetIndexBuffer(11,histou, INDICATOR_DATA);
SetIndexBuffer(12,histod, INDICATOR_DATA);
// Additional calc buffers (13..25)
SetIndexBuffer(13, T1MA, INDICATOR_CALCULATIONS);
SetIndexBuffer(14, S1MA, INDICATOR_CALCULATIONS);
SetIndexBuffer(15, filterr, INDICATOR_CALCULATIONS);
SetIndexBuffer(16, S1hi, INDICATOR_CALCULATIONS);
SetIndexBuffer(17, S1lo, INDICATOR_CALCULATIONS);
SetIndexBuffer(18, T1hi, INDICATOR_CALCULATIONS);
SetIndexBuffer(19, T1lo, INDICATOR_CALCULATIONS);
SetIndexBuffer(20, valcT1, INDICATOR_CALCULATIONS);
SetIndexBuffer(21, valcS1, INDICATOR_CALCULATIONS);
SetIndexBuffer(22, trend, INDICATOR_CALCULATIONS);
SetIndexBuffer(23, state, INDICATOR_CALCULATIONS);
SetIndexBuffer(24, alltrend, INDICATOR_CALCULATIONS);
SetIndexBuffer(25, countBuf, INDICATOR_CALCULATIONS);
// Let system know total buffers
IndicatorBuffers(26);
// Empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,(double)EMPTY_VALUE);
// Adjust min/max
IndicatorSetDouble(INDICATOR_MINIMUM, -16.0);
IndicatorSetDouble(INDICATOR_MAXIMUM, (double)upw);
// Hide or show lines
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,(ShowLevels ? DRAW_LINE : DRAW_NONE)); // levelu
PlotIndexSetInteger(1,PLOT_DRAW_TYPE,(ShowLevels ? DRAW_LINE : DRAW_NONE)); // leveld
PlotIndexSetInteger(2,PLOT_DRAW_TYPE,(ShowMiddle ? DRAW_LINE : DRAW_NONE)); // middle
// Short name
indicatorFileName = Name;
string short_name = TimeFrameToString((ENUM_TIMEFRAMES)TimeFrame)+
" rsioma("+(string)RsiPeriod+","+(string)JmaLength+
", xu ma "+(string)S1MAper+","+(string)T1MAper+")";
IndicatorSetString(INDICATOR_SHORTNAME, short_name);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
// OnDeinit
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
deleteArrows();
CleanUpOnAisle16();
// remove vertical lines
string tlookFor = verticalLinesID+":";
int tlookForLength = (int)StringLen(tlookFor);
for(int i=ObjectsTotal()-1; i>=0; i--)
{
string tobjectName=ObjectName(i);
if(StringSubstr(tobjectName,0,tlookForLength)==tlookFor)
ObjectDelete(0, tobjectName);
}
}
//+------------------------------------------------------------------+
// OnCalculate
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
// minimal check
if(rates_total<2) return(0);
// read chart data using MqlRates
MqlRates price_info[];
ArraySetAsSeries(price_info,true);
int copied = CopyRates(_Symbol, _Period, 0, rates_total, price_info);
if(copied<=0) return(0);
// Build local arrays for time, open, high, low, close
static datetime time_array[];
ArrayResize(time_array,rates_total);
static double open_array[], high_array[], low_array[], close_array[];
ArrayResize(open_array, rates_total);
ArrayResize(high_array, rates_total);
ArrayResize(low_array, rates_total);
ArrayResize(close_array, rates_total);
for(int i=0; i<rates_total; i++)
{
time_array[i] = price_info[i].time;
open_array[i] = price_info[i].open;
high_array[i] = price_info[i].high;
low_array[i] = price_info[i].low;
close_array[i] = price_info[i].close;
}
// Basic name-check guard
if(Name!=MyName)
{
Print("Invalid File Name / indicator name mismatch");
return(rates_total);
}
// If user set a different TimeFrame than current, skip or do MTF logic
if((int)TimeFrame!=(int)_Period && TimeFrame!=tf_cu)
{
// MTF not implemented
return(rates_total);
}
// figure out how many bars we need to recalc
int start = MathMax(prev_calculated-1,0);
if(start>rates_total-1) start=rates_total-1;
// main loop
for(int iBar=rates_total-1; iBar>=start; iBar--)
{
// 1) RSI
double priceForRsi = iCustomMa(smoothType,
getPrice(RsiPrice, open_array, close_array, high_array, low_array, iBar, rates_total),
(double)JmaLength,
iBar, rates_total);
val[iBar] = iRsi(RsiType, priceForRsi, (double)RsiPeriod, iBar, rates_total);
avgs[iBar] = iCustomMa(AverageType, val[iBar], (double)AveragePeriod, iBar, rates_total);
levelu[iBar] = OverSold;
leveld[iBar] = OverBought;
middle[iBar] = 50.0;
// color states:
switch(colorOn)
{
case cc_onLevels:
state[iBar] = (val[iBar]>levelu[iBar])? 1 : (val[iBar]<leveld[iBar])? -1 : 0;
break;
case cc_onMiddle:
state[iBar] = (val[iBar]>50.0)? 1 : ((val[iBar]<50.0)? -1 : 0);
break;
case cc_onMa:
state[iBar] = (val[iBar]>avgs[iBar])? 1 : ((val[iBar]<avgs[iBar])? -1 : 0);
break;
default: // cc_onSlope
if(iBar<rates_total-1)
state[iBar] = (val[iBar]>val[iBar+1])? 1 : ((val[iBar]<val[iBar+1])? -1 : state[iBar+1]);
else
state[iBar] = 0;
break;
}
// up/down lines
valda[iBar] = EMPTY_VALUE;
valdb[iBar] = EMPTY_VALUE;
valua[iBar] = EMPTY_VALUE;
valub[iBar] = EMPTY_VALUE;
if(state[iBar]==1)
PlotPoint(iBar, valua, valub, val, rates_total);
else if(state[iBar]==-1)
PlotPoint(iBar, valda, valdb, val, rates_total);
// 2) T1 Trend
double t1HighPrice = getPrice(priceH, open_array, close_array, high_array, low_array, iBar, rates_total);
double t1LowPrice = getPrice(priceL, open_array, close_array, high_array, low_array, iBar, rates_total);
double t1MidPrice = getPrice(MAPrice1, open_array, close_array, high_array, low_array, iBar, rates_total);
T1hi[iBar] = iCustomMa(T1MAmode, t1HighPrice, (double)T1MAper, iBar, rates_total, 2);
T1lo[iBar] = iCustomMa(T1MAmode, t1LowPrice, (double)T1MAper, iBar, rates_total, 3);
T1MA[iBar] = iCustomMa(T1MAmode, t1MidPrice, (double)T1MAper, iBar, rates_total, 4);
if(iBar<rates_total-1)
valcT1[iBar] = (close_array[iBar]>T1hi[iBar+1])? 1 : ((close_array[iBar]<T1lo[iBar+1])? -1 : valcT1[iBar+1]);
else
valcT1[iBar] = 0;
// 3) S1 signal
double s1HighPrice = getPrice(priceH, open_array, close_array, high_array, low_array, iBar, rates_total);
double s1LowPrice = getPrice(priceL, open_array, close_array, high_array, low_array, iBar, rates_total);
double s1MidPrice = getPrice(MAPrice2, open_array, close_array, high_array, low_array, iBar, rates_total);
S1hi[iBar] = iCustomMa(S1MAmode, s1HighPrice, (double)S1MAper, iBar, rates_total, 5);
S1lo[iBar] = iCustomMa(S1MAmode, s1LowPrice, (double)S1MAper, iBar, rates_total, 6);
S1MA[iBar] = iCustomMa(S1MAmode, s1MidPrice, (double)S1MAper, iBar, rates_total, 7);
if(iBar<rates_total-1)
valcS1[iBar] = (close_array[iBar]>S1hi[iBar+1])? 1 : ((close_array[iBar]<S1lo[iBar+1])? -1 : valcS1[iBar+1]);
else
valcS1[iBar] = 0;
// 4) Filter
double fPrice = getPrice(FilterPrice, open_array, close_array, high_array, low_array, iBar, rates_total);
filterr[iBar] = iCustomMa(Filtermode, fPrice, (double)Filterperiod, iBar, rates_total, 8);
// 5) Trend color (histogram)
switch(colorOnh)
{
case cc_onMiddleh:
if(iBar<rates_total-1)
trend[iBar] = (valcS1[iBar]==1 && valcT1[iBar]==1)? 1 :
((valcS1[iBar]==-1 && valcT1[iBar]==-1)? -1 :
((valcS1[iBar]==1 && valcT1[iBar]==-1)? -2 :
((valcS1[iBar]==-1 && valcT1[iBar]==1)? 2 : trend[iBar+1])));
else
trend[iBar]=0;
break;
case cc_onLevels4h:
if(iBar<rates_total-1)
trend[iBar] = (valcS1[iBar]==1 && valcT1[iBar]==1)? 1 :
((valcS1[iBar]==-1 && valcT1[iBar]==-1)? -1 : trend[iBar+1]);
else
trend[iBar]=0;
break;
case cc_onALLFh:
if(iBar<rates_total-1)
trend[iBar] = (valcS1[iBar]==1 && valcT1[iBar]==1 && filterr[iBar]<close_array[iBar])? 1 :
((valcS1[iBar]==-1 && valcT1[iBar]==-1 && filterr[iBar]>close_array[iBar])? -1 :
((valcS1[iBar]==1 && valcT1[iBar]==-1)? -2 :
((valcS1[iBar]==-1 && valcT1[iBar]==1)? 2 : trend[iBar+1])));
else
trend[iBar]=0;
break;
case cc_onFIRSTFh:
if(iBar<rates_total-1)
trend[iBar] = (valcS1[iBar]==1 && valcT1[iBar]==1 && filterr[iBar]<close_array[iBar])? 1 :
((valcS1[iBar]==-1 && valcT1[iBar]==-1 && filterr[iBar]>close_array[iBar])? -1 :
trend[iBar+1]);
else
trend[iBar]=0;
break;
}
// Assign histogram
histou[iBar] = EMPTY_VALUE;
histod[iBar] = EMPTY_VALUE;
histoNeu[iBar] = EMPTY_VALUE;
histoNed[iBar] = EMPTY_VALUE;
if(trend[iBar]==1)
histou[iBar]=upl;
else if(trend[iBar]==-1)
histod[iBar]=dnl;
else if(trend[iBar]==2)
histoNeu[iBar]=nel;
else if(trend[iBar]==-2)
histoNed[iBar]=ne2;
// 6) Combine RSI & trend => alltrend
switch(colorOna)
{
case cc_onLine:
if(iBar<rates_total-1)
alltrend[iBar] = (state[iBar]==1)? 1 : ((state[iBar]==-1)? -1 : 0);
else
alltrend[iBar] = 0;
break;
case cc_onHisto:
if(iBar<rates_total-1)
alltrend[iBar] = (trend[iBar]==1)? 1 :
((trend[iBar]==-1)? -1 :
((trend[iBar]==2 || trend[iBar]==-2)? 0 : alltrend[iBar+1]));
else
alltrend[iBar]=0;
break;
case cc_onAll:
if(iBar<rates_total-1)
{
if(state[iBar]==1 && trend[iBar]==1) alltrend[iBar]= 1;
else if(state[iBar]==-1 && trend[iBar]==-1) alltrend[iBar]=-1;
else alltrend[iBar]=0;
}
else
alltrend[iBar]=0;
break;
case cc_onFIRST:
if(iBar<rates_total-1)
alltrend[iBar] = (state[iBar]==1 && trend[iBar]==1)? 1 :
((state[iBar]==-1 && trend[iBar]==-1)? -1 : alltrend[iBar+1]);
else
alltrend[iBar]=0;
break;
}
// 7) Arrows
if(arrowsVisible && iBar<rates_total-1)
{
if(alltrend[iBar]!=alltrend[iBar+1])
{
if(alltrend[iBar]==1)
drawArrow(iBar,arrowsUpColor,(int)arrowsUpCode,arrowsUpSize,false,time_array,high_array,low_array);
else if(alltrend[iBar]==-1)
drawArrow(iBar,arrowsDnColor,(int)arrowsDnCode,arrowsUpSize,true,time_array,high_array,low_array);
}
}
// 8) Lines
if(verticalLinesVisible && iBar<rates_total-1)
{
if(alltrend[iBar]!=alltrend[iBar+1])
{
if(alltrend[iBar]==1)
drawLine(iBar,verticalLinesUpColor,time_array);
else if(alltrend[iBar]==-1)
drawLine(iBar,verticalLinesDnColor,time_array);
}
}
// 9) Symbol header
if(alltrend[iBar]==-1) SymClr=ColorDn;
else if(alltrend[iBar]==1) SymClr=ColorUp;
else SymClr=ColorNe;
if(showSymbolHeader && iBar==0) // do once on last iteration
{
string tag=_Symbol+" "+TimeFrameToString((ENUM_TIMEFRAMES)_Period);
SetTextRight(ID+"X001",tag, LR+280+134,UD+1, Sbg, HDRsize);
SetTextRight(ID+"X002",tag, LR+279+134,UD+0, SymClr,HDRsize);
SetTextRight(ID+"X003",DoubleToString(val[iBar],1),
LR+230+182, UD+50, SymClr, HDRsize+16);
}
}
// 10) Alerts
if(alertsOn && rates_total>2)
{
int whichBar=(alertsOnCurrent ? 0 : 1);
if(whichBar+1<rates_total)
{
if(alltrend[whichBar]!=alltrend[whichBar+1])
{
if(alltrend[whichBar]==1) doAlert("UP");
if(alltrend[whichBar]==-1) doAlert("DOWN");
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
// PlotPoint
//+------------------------------------------------------------------+
void PlotPoint(int i,double &first[],double &second[],double &from[],int barsCount)
{
// Only do this if i+2 is valid
if(i>=barsCount-2) return;
if(first[i+1]==EMPTY_VALUE)
{
if((i+2)<barsCount && first[i+2]==EMPTY_VALUE)
{
first[i] = from[i];
first[i+1] = from[i+1];
second[i] = EMPTY_VALUE;
}
else
{
second[i] = from[i];
second[i+1] = from[i+1];
first[i] = EMPTY_VALUE;
}
}
else
{
first[i] = from[i];
second[i] = EMPTY_VALUE;
}
}
//+------------------------------------------------------------------+
// iCustomMa
//+------------------------------------------------------------------+
double iCustomMa(int mode,double price,double length,int r,int bars,int instanceNo=0)
{
int idx = bars - 1 - r;
if(idx<0) idx=0;
switch(mode)
{
case ma_sma: return(iSma(price,(int)MathCeil(length), idx,bars,instanceNo));
case ma_ema: return(iEma(price,length, idx,bars,instanceNo));
case ma_smma: return(iSmma(price,(int)MathCeil(length),idx,bars,instanceNo));
case ma_lwma: return(iLwma(price,(int)MathCeil(length),idx,bars,instanceNo));
case ma_linr: return(iLinr(price,(int)MathCeil(length),idx,bars,instanceNo));
default: return(price);
}
}
//+------------------------------------------------------------------+
// iSma
//+------------------------------------------------------------------+
#define _maInstances 9
double workSma[][_maInstances];
double iSma(double price,int period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workSma,0)!=_bars)
ArrayResize(workSma,_bars);
workSma[r][instanceNo]=price;
double sum=price; int k=1;
for(; k<period && (r-k)>=0; k++)
sum+=workSma[r-k][instanceNo];
return(sum/(double)k);
}
//+------------------------------------------------------------------+
// iEma
//+------------------------------------------------------------------+
double workEma[][_maInstances];
double iEma(double price,double period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workEma,0)!=_bars)
ArrayResize(workEma,_bars);
if(r==0)
{
workEma[r][instanceNo]=price;
return(price);
}
double prev=workEma[r-1][instanceNo];
double alpha=(2.0/(1.0+period));
workEma[r][instanceNo]=prev+alpha*(price-prev);
return(workEma[r][instanceNo]);
}
//+------------------------------------------------------------------+
// iSmma
//+------------------------------------------------------------------+
double workSmma[][_maInstances];
double iSmma(double price,double period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workSmma,0)!=_bars)
ArrayResize(workSmma,_bars);
if(r<1)
{
workSmma[r][instanceNo]=price;
return(price);
}
double prev=workSmma[r-1][instanceNo];
workSmma[r][instanceNo] = prev + (price - prev)/period;
return(workSmma[r][instanceNo]);
}
//+------------------------------------------------------------------+
// iLwma
//+------------------------------------------------------------------+
double workLwma[][_maInstances];
double iLwma(double price,int period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workLwma,0)!=_bars)
ArrayResize(workLwma,_bars);
workLwma[r][instanceNo]=price;
if(period<=1) return(price);
double sumw=period;
double sum =(double)period*price;
for(int k=1;k<period && (r-k)>=0; k++)
{
double weight=(double)(period-k);
sumw+=weight;
sum +=weight*workLwma[r-k][instanceNo];
}
return(sum/sumw);
}
//+------------------------------------------------------------------+
// iLinr
//+------------------------------------------------------------------+
double workLinr[][_maInstances];
double iLinr(double price,int period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workLinr,0)!=_bars)
ArrayResize(workLinr,_bars);
workLinr[r][instanceNo]=price;
if(r<period) return(price);
double lwmw=period;
double lwma=(double)period*price;
double sma=price;
for(int k=1; k<period && (r-k)>=0; k++)
{
double weight=(double)(period-k);
lwmw+=weight;
lwma+=weight*workLinr[r-k][instanceNo];
sma +=workLinr[r-k][instanceNo];
}
return(3.0*lwma/lwmw - 2.0*sma/period);
}
//+------------------------------------------------------------------+
// getPrice
//+------------------------------------------------------------------+
#define _prHABF(_prtype) (_prtype>=pr_habclose && _prtype<=pr_habtbiased2)
#define _priceInstances 9
#define _priceInstancesSize 4
double _priceWorkHa[][_priceInstances*_priceInstancesSize];
double getPrice(int tprice,
const double &openA[],
const double &closeA[],
const double &highA[],
const double &lowA[],
int i,int bars,int instanceNo=0)
{
// For normal price types
if(tprice<pr_haclose)
{
switch(tprice)
{
case pr_close: return(closeA[i]);
case pr_open: return(openA[i]);
case pr_high: return(highA[i]);
case pr_low: return(lowA[i]);
case pr_median: return((highA[i]+lowA[i])*0.5);
case pr_medianb: return((openA[i]+closeA[i])*0.5);
case pr_typical: return((highA[i]+lowA[i]+closeA[i])/3.0);
case pr_weighted: return((highA[i]+lowA[i]+closeA[i]+closeA[i])/4.0);
case pr_average: return((highA[i]+lowA[i]+closeA[i]+openA[i])/4.0);
case pr_tbiased:
if(closeA[i]>openA[i]) return((highA[i]+closeA[i])*0.5);
else return((lowA[i]+closeA[i])*0.5);
case pr_tbiased2:
if(closeA[i]>openA[i]) return(highA[i]);
if(closeA[i]<openA[i]) return(lowA[i]);
return(closeA[i]);
}
return(0.0);
}
// For Heiken Ashi (and “better formula”)
if(ArrayRange(_priceWorkHa,0)!=bars)
ArrayResize(_priceWorkHa,bars);
instanceNo*=_priceInstancesSize;
int r=bars -1 - i;
if(r<0) r=0;
double haOpen =(r>0)
? ( _priceWorkHa[r-1][instanceNo+2] + _priceWorkHa[r-1][instanceNo+3] )*0.5
: (openA[i] + closeA[i])*0.5;
double haClose=(openA[i] + highA[i] + lowA[i] + closeA[i])*0.25;
if(_prHABF(tprice))
{
double range=(highA[i]-lowA[i]);
if(range>1e-12)
haClose=( (openA[i]+closeA[i])*0.5 ) + ((closeA[i]-openA[i]) / range)*MathAbs((closeA[i]-openA[i])*0.5);
else
haClose=(openA[i]+closeA[i])*0.5;
}
double haHigh = MathMax(highA[i], MathMax(haOpen,haClose));
double haLow = MathMin(lowA[i], MathMin(haOpen,haClose));
// store
if(haOpen<haClose)
{
_priceWorkHa[r][instanceNo+0]=haLow;
_priceWorkHa[r][instanceNo+1]=haHigh;
}
else
{
_priceWorkHa[r][instanceNo+0]=haHigh;
_priceWorkHa[r][instanceNo+1]=haLow;
}
_priceWorkHa[r][instanceNo+2]=haOpen;
_priceWorkHa[r][instanceNo+3]=haClose;
// Return chosen
switch(tprice)
{
case pr_haclose:
case pr_habclose: return(haClose);
case pr_haopen:
case pr_habopen: return(haOpen);
case pr_hahigh:
case pr_habhigh: return(haHigh);
case pr_halow:
case pr_hablow: return(haLow);
case pr_hamedian:
case pr_habmedian: return((haHigh+haLow)*0.5);
case pr_hamedianb:
case pr_habmedianb: return((haOpen+haClose)*0.5);
case pr_hatypical:
case pr_habtypical: return((haHigh+haLow+haClose)/3.0);
case pr_haweighted:
case pr_habweighted: return((haHigh+haLow+(haClose*2.0))/4.0);
case pr_haaverage:
case pr_habaverage: return((haHigh+haLow+haClose+haOpen)*0.25);
case pr_hatbiased:
case pr_habtbiased:
if(haClose>haOpen) return((haHigh+haClose)*0.5);
else return((haLow+haClose)*0.5);
case pr_hatbiased2:
case pr_habtbiased2:
if(haClose>haOpen) return(haHigh);
if(haClose<haOpen) return(haLow);
return(haClose);
}
return(0.0);
}
//+------------------------------------------------------------------+
// iRsi
//+------------------------------------------------------------------+
#define rsiInstances 1
double workRsi[][13*rsiInstances];
double iRsi(int rsiMode,double price,double period,int iBar,int barsCount,int instanceNo=0)
{
// Make sure our work array matches barsCount:
if(ArrayRange(workRsi,0)!=barsCount)
ArrayResize(workRsi,barsCount);
int r = barsCount -1 - iBar;
if(r<0) r=0; // safety check
// store price
workRsi[r][0] = price;
switch(rsiMode)
{
case rsi_rsi:
{
double alpha=1.0/MathMax(period,1.0);
if(r<(int)period)
{
double sum=0.0;
int k=0;
for(k=0; k<(int)period && (r-k-1)>=0; k++)
sum+=MathAbs(workRsi[r-k][0] - workRsi[r-k-1][0]);
double chg = (workRsi[r][0] - workRsi[0][0]) / MathMax(k,1);
double chga= sum / (double)MathMax(k,1);
workRsi[r][1]=chg;
workRsi[r][2]=chga;
if(chga!=0.0) return(50.0*(chg/chga+1.0));
return(50.0);
}
else
{
double change = workRsi[r][0] - workRsi[r-1][0];
double prevCh = workRsi[r-1][1];
double prevCa = workRsi[r-1][2];
double currCh = prevCh + alpha*(change - prevCh);
double currCa = prevCa + alpha*(MathAbs(change) - prevCa);
workRsi[r][1]=currCh;
workRsi[r][2]=currCa;
if(currCa!=0.0) return(50.0*(currCh/currCa+1.0));
return(50.0);
}
}
case rsi_ehl:
{
double up=0.0,dn=0.0;
double prc=(r>2)? (workRsi[r][0] +2.0*workRsi[r-1][0] + workRsi[r-2][0])/4.0 : workRsi[r][0];
for(int k=0; k<(int)period && (r-k-1)>=0; k++)
{
double diff= prc - workRsi[r-k-1][0];
if(diff>0) up+=diff; else dn-=diff;
}
return(50.0*(up-dn)/MathMax(up+dn,1e-12)+50.0);
}
case rsi_wil:
{
double up=0.0,dn=0.0;
for(int k=0; k<(int)period && (r-k-1)>=0; k++)
{
double diff=workRsi[r-k][0]-workRsi[r-k-1][0];
if(diff>0) up+=diff; else dn-=diff;
}
if(r<1)
{
workRsi[r][3]=50.0;
return(50.0);
}
double prev = workRsi[r-1][3];
double tot = up+dn;
double v = (MathAbs(tot)<1e-12)? 50.0 : (100.0*up/(tot));
workRsi[r][3] = prev + (1.0/MathMax(period,1.0))*(v - prev);
return(workRsi[r][3]);
}
case rsi_rap:
{
double up=0.0,dn=0.0;
for(int k=0; k<(int)period && (r-k-1)>=0; k++)
{
double diff=workRsi[r-k][0]-workRsi[r-k-1][0];
if(diff>0) up+=diff; else dn-=diff;
}
if(MathAbs(up+dn)<1e-12) return(50.0);
return(100.0*up/(up+dn));
}
case rsi_har:
{
double avgUp=0.0,avgDn=0.0;
double up=0.0,dn=0.0;
for(int k=0; k<(int)period && (r-k-1)>=0; k++)
{
double diff=workRsi[r-k][0]-workRsi[r-k-1][0];
if(diff>0) {avgUp+=diff; up++;}
else {avgDn-=diff; dn++;}
}
if(up>0) avgUp/=up;
if(dn>0) avgDn/=dn;
double rs=1.0;
if(MathAbs(avgDn)>1e-12) rs=avgUp/avgDn;
return(100.0 - 100.0/(1.0+rs));
}
case rsi_rsx:
{
double Kg=3.0/(2.0+period), Hg=1.0-Kg;
if(r<(int)period)
{
for(int kk=1; kk<13; kk++)
workRsi[r][kk]=0.0;
return(50.0);
}
double mom= workRsi[r][0] - workRsi[r-1][0];
double moa= MathAbs(mom);
for(int k=0; k<3; k++)
{
int idx = k*2;
workRsi[r][idx+1] = Kg*mom + Hg*workRsi[r-1][idx+1];
workRsi[r][idx+2] = Kg*workRsi[r][idx+1] + Hg*workRsi[r-1][idx+2];
mom =1.5*workRsi[r][idx+1] - 0.5*workRsi[r][idx+2];
workRsi[r][idx+7] = Kg*moa + Hg*workRsi[r-1][idx+7];
workRsi[r][idx+8] = Kg*workRsi[r][idx+7] + Hg*workRsi[r-1][idx+8];
moa =1.5*workRsi[r][idx+7] - 0.5*workRsi[r][idx+8];
}
if(MathAbs(moa)>1e-12)
return(MathMax(MathMin((mom/moa+1.0)*50.0,100.0),0.0));
return(50.0);
}
case rsi_cut:
{
double sump=0.0,sumn=0.0;
for(int k=0; k<(int)period && (r-k-1)>=0; k++)
{
double diff=workRsi[r-k][0]-workRsi[r-k-1][0];
if(diff>0) sump+=diff; else sumn-=diff;
}
if(MathAbs(sumn)<1e-12) return(50.0);
return(100.0 - 100.0/(1.0 + sump/sumn));
}
}
return(0.0);
}
//+------------------------------------------------------------------+
// TimeFrameToString
//+------------------------------------------------------------------+
string TimeFrameToString(ENUM_TIMEFRAMES tf)
{
switch(tf)
{
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN");
default: return("Current");
}
}
//+------------------------------------------------------------------+
// doAlert
//+------------------------------------------------------------------+
void doAlert(string doWhat)
{
static string prevAlert="";
static datetime prevTime=0;
if(prevAlert!=doWhat || prevTime!=TimeCurrent())
{
prevAlert=doWhat;
prevTime=TimeCurrent();
string message=_Symbol+" ("+TimeFrameToString((ENUM_TIMEFRAMES)_Period)+") >> RSI/Histo "+doWhat;
if(alertsMessage) Alert(message);
if(alertsNotify) SendNotification(message);
if(alertsEmail) SendMail(_Symbol+" RSI/Histo",message);
if(alertsSound) PlaySound("alert2.wav");
}
}
//+------------------------------------------------------------------+
// drawArrow
//+------------------------------------------------------------------+
void drawArrow(int i,color theColor,int theCode,int theSize,bool up,
const datetime &time_array[],const double &highA[],const double &lowA[])
{
string name = arrowsIdentifier+":"+TimeToString(time_array[i],TIME_DATE|TIME_MINUTES|TIME_SECONDS);
ObjectDelete(0,name);
double gap = localAtr(20, i, highA, lowA);
datetime t = time_array[i];
if(arrowsOnNewest)
t+=(datetime)(_Period*60 -1);
if(!ObjectCreate(0,name,OBJ_ARROW,0,t,0))
return;
ObjectSetInteger(0,name,OBJPROP_ARROWCODE, theCode);
ObjectSetInteger(0,name,OBJPROP_WIDTH, theSize);
ObjectSetInteger(0,name,OBJPROP_COLOR, theColor);
double yPrice = (up ? highA[i]+(2.0*gap) : lowA[i]-(2.0*gap));
ObjectSetDouble(0,name,OBJPROP_PRICE1,yPrice);
}
//+------------------------------------------------------------------+
// deleteArrows
//+------------------------------------------------------------------+
void deleteArrows()
{
string lookFor=arrowsIdentifier+":";
int len=(int)StringLen(lookFor);
for(int i=ObjectsTotal()-1;i>=0;i--)
{
string onm=ObjectName(i);
if(StringSubstr(onm,0,len)==lookFor)
ObjectDelete(0,onm);
}
}
//+------------------------------------------------------------------+
// drawLine
//+------------------------------------------------------------------+
void drawLine(int i,color theColor,const datetime &time_array[])
{
string name=verticalLinesID+":"+TimeToString(time_array[i],TIME_DATE|TIME_MINUTES|TIME_SECONDS);
ObjectDelete(0,name);
datetime t=time_array[i];
if(linesOnNewest)
t+=(datetime)(_Period*60 -1);
if(!ObjectCreate(0,name,OBJ_VLINE,0,t,0))
return;
ObjectSetInteger(0,name,OBJPROP_COLOR,theColor);
ObjectSetInteger(0,name,OBJPROP_STYLE,verticalLinesStyle);
ObjectSetInteger(0,name,OBJPROP_WIDTH,0);
ObjectSetInteger(0,name,OBJPROP_BACK,true);
}
//+------------------------------------------------------------------+
// localAtr (rough local calculation for arrow offset)
//+------------------------------------------------------------------+
double localAtr(int atrPeriod,int iBar,const double &highA[],const double &lowA[])
{
if(iBar<1) return(0.0);
double sum=0.0; int count=0;
for(int k=0; k<atrPeriod && (iBar-k)>0; k++)
{
double tr=MathAbs(highA[iBar-k]-lowA[iBar-k]);
sum+=tr; count++;
}
return((count>0) ? sum/(double)count : 0.0);
}
//+------------------------------------------------------------------+
// OnChartEvent
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
fSetBuffers();
}
//+------------------------------------------------------------------+
// fSetBuffers
//+------------------------------------------------------------------+
void fSetBuffers()
{
// Auto adjust histogram widths based on chart scale
int iChartScale=(int)ChartGetInteger(0,CHART_SCALE);
if(getChartScale==iChartScale) return;
if(UseAutoWidth)
{
getChartScale=iChartScale;
int iW=1;
switch(iChartScale)
{
case 0: iW=1; break;
case 1: iW=1; break;
case 2: iW=2; break;
case 3: iW=4; break;
case 4: iW=8; break;
case 5: iW=16; break;
}
// set histogram widths for plots 9..12
PlotIndexSetInteger(9, PLOT_LINE_WIDTH, iW);
PlotIndexSetInteger(10, PLOT_LINE_WIDTH, iW);
PlotIndexSetInteger(11, PLOT_LINE_WIDTH, iW);
PlotIndexSetInteger(12, PLOT_LINE_WIDTH, iW);
}
else
getChartScale=Width;
ChartRedraw(0);
}
//+------------------------------------------------------------------+
// SetTextRight
//+------------------------------------------------------------------+
void SetTextRight(string name,string text,int x,int y,color colour,int fontsize=10,string font="Arial Black")
{
ObjectDelete(0,name);
if(ObjectCreate(0,name,OBJ_LABEL,header_Subwindow,0,0))
{
ObjectSetInteger(0,name,OBJPROP_CORNER,Header_corner);
ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER);
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
ObjectSetString(0,name,OBJPROP_TEXT,text);
ObjectSetString(0,name,OBJPROP_FONT,font);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
ObjectSetInteger(0,name,OBJPROP_COLOR,colour);
}
}
//+------------------------------------------------------------------+
// CleanUpOnAisle16
//+------------------------------------------------------------------+
void CleanUpOnAisle16()
{
for(int m=ObjectsTotal()-1; m>=0; m--)
{
string namem=ObjectName(m);
if(StringSubstr(namem,0,StringLen(ID))==ID)
ObjectDelete(0,namem);
}
}
//+------------------------------------------------------------------+
Is there an MTF version of this - either on the chart or histo? Thanks!!
Hello, have this histo version.JAECKER wrote: Sun Dec 29, 2024 11:21 am Is there an MTF version of this - either on the chart or histo? Thanks!!
Thanks, this is the histo version.budhi1976 wrote: Fri Jan 03, 2025 11:51 pm Respected mrtools, I am wondering where's supertrend new format histo indicator file? I see it in your screenshot.
Check here.GraniteChief wrote: Thu Jan 09, 2025 6:25 pm Hi, please can someone convert this indicator to MT5? It is very useful as a confirmation when identifying reversals.
It is very much appreciated.
GC