Files
Range-Bars-Charting/Include/RangeBarIndicator.mqh
T

310 lines
7.2 KiB
Plaintext

//+------------------------------------------------------------------+
//| RangeBarIndicator.mq5 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property library
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#property version "1.10"
#include <RangeBars.mqh>
class RangeBarIndicator
{
private:
RangeBars * rangeBars;
int rates_total;
int prev_calculated;
bool useAppliedPrice;
ENUM_APPLIED_PRICE applied_price;
public:
double Open[];
double Low[];
double High[];
double Close[];
double Price[];
RangeBarIndicator();
~RangeBarIndicator();
void SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) { this.useAppliedPrice = true; this.applied_price = _applied_price; };
bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &Time[]);
int GetPrevCalculated() { return prev_calculated; };
private:
bool CheckStatus();
bool NeedsReload();
int GetOLHC(int start, int count);
void OLHCShiftRight();
void OLHCResize();
bool Canvas_IsNewBar(const datetime &_Time[]);
bool Canvas_IsRatesTotalChanged(int ratesTotalNow);
ENUM_TIMEFRAMES TFMigrate(int tf);
datetime iTime(string symbol,int tf,int index);
};
RangeBarIndicator::RangeBarIndicator(void)
{
rangeBars = new RangeBars();
if(rangeBars != NULL)
rangeBars.Init();
useAppliedPrice = false;
}
RangeBarIndicator::~RangeBarIndicator(void)
{
if(rangeBars != NULL)
{
rangeBars.Deinit();
delete rangeBars;
}
}
bool RangeBarIndicator::CheckStatus(void)
{
int handle = rangeBars.GetHandle();
if(handle == INVALID_HANDLE)
return false;
return true;
}
bool RangeBarIndicator::NeedsReload(void)
{
if(rangeBars.Reload())
{
Print("Chart settings changed - reloading indicator with new settings");
return true;
}
return false;
}
bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &Time[])
{
static bool firstRun = true;
if(firstRun)
{
Canvas_IsRatesTotalChanged(_rates_total);
firstRun = false;
}
if(!CheckStatus())
return false;
ArraySetAsSeries(this.Open,false);
ArraySetAsSeries(this.High,false);
ArraySetAsSeries(this.Low,false);
ArraySetAsSeries(this.Close,false);
ArraySetAsSeries(this.Price,false);
if(Canvas_IsRatesTotalChanged(_rates_total))
{
OLHCResize();
this.prev_calculated = prev_calculated;
Canvas_IsNewBar(Time);
return true;
}
else if(Canvas_IsNewBar(Time))
{
//Print("Got Canvas_IsNewBar");
//GetOLHC(0,0);
if(ArraySize(this.Open) == 0)
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
//Print("canvas new bar ZERO elements -> getting new : ArraySize of Open = "+ArraySize(this.Open));
return false;
}
OLHCShiftRight();
this.prev_calculated = prev_calculated;
return true;
}
if(NeedsReload() || rangeBars.IsNewBar())
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return false;
}
//
// Recalculate lst bar
//
GetOLHC(0,0);
this.prev_calculated = prev_calculated;
return true;
}
int RangeBarIndicator::GetOLHC(int start, int count)
{
if((start == 0) && (count == 0))
{
MqlRates tempRates[1];
int last = ArraySize(Open)-1;
if(last < 0)
return 0;
rangeBars.GetMqlRates(tempRates,0,1);
this.Open[last] = tempRates[0].open;
this.Low[last] = tempRates[0].low;
this.High[last] = tempRates[0].high;
this.Close[last] = tempRates[0].close;
if(useAppliedPrice)
{
this.Price[last] = rangeBars.CalcAppliedPrice(tempRates[0],this.applied_price);
}
return 1;
}
else
{
if(useAppliedPrice)
return rangeBars.GetOLHCAndApplPriceForIndicatorCalc(this.Open,this.Low,this.High,this.Close,this.Price,this.applied_price,0,count);
else
return rangeBars.GetOLHCForIndicatorCalc(this.Open,this.Low,this.High,this.Close,0,count);
}
}
void RangeBarIndicator::OLHCShiftRight()
{
int count = ArraySize(this.Open);
if(count <= 0)
return;
count--;
for(int i=count; i>0; i--)
{
this.Open[i] = this.Open[i-1];
this.High[i] = this.High[i-1];
this.Low[i] = this.Low[i-1];
this.Close[i] = this.Close[i-1];
this.Price[i] = this.Price[i-1];
}
this.Open[0] = 0.0;
this.High[0] = 0.0;
this.Low[0] = 0.0;
this.Close[0] = 0.0;
this.Price[0] = 0.0;
}
void RangeBarIndicator::OLHCResize()
{
int count = ArraySize(this.Open);
if(count <= 0)
return;
ArrayResize(this.Open,count+1);
ArrayResize(this.Low,count+1);
ArrayResize(this.High,count+1);
ArrayResize(this.Close,count+1);
ArrayResize(this.Price,count+1);
OLHCShiftRight();
}
bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[])
{
ArraySetAsSeries(_Time,true);
datetime now = _Time[0];
ArraySetAsSeries(_Time,false);
static datetime prevTime = 0;
if(prevTime != now)
{
prevTime = now;
return true;
}
return false;
}
bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow)
{
static int prevRatesTotal = 0;
if(prevRatesTotal == 0)
prevRatesTotal = ratesTotalNow;
if(prevRatesTotal != ratesTotalNow)
{
prevRatesTotal = ratesTotalNow;
return true;
}
return false;
}
ENUM_TIMEFRAMES RangeBarIndicator::TFMigrate(int tf)
{
switch(tf)
{
case 0: return(PERIOD_CURRENT);
case 1: return(PERIOD_M1);
case 5: return(PERIOD_M5);
case 15: return(PERIOD_M15);
case 30: return(PERIOD_M30);
case 60: return(PERIOD_H1);
case 240: return(PERIOD_H4);
case 1440: return(PERIOD_D1);
case 10080: return(PERIOD_W1);
case 43200: return(PERIOD_MN1);
case 2: return(PERIOD_M2);
case 3: return(PERIOD_M3);
case 4: return(PERIOD_M4);
case 6: return(PERIOD_M6);
case 10: return(PERIOD_M10);
case 12: return(PERIOD_M12);
case 16385: return(PERIOD_H1);
case 16386: return(PERIOD_H2);
case 16387: return(PERIOD_H3);
case 16388: return(PERIOD_H4);
case 16390: return(PERIOD_H6);
case 16392: return(PERIOD_H8);
case 16396: return(PERIOD_H12);
case 16408: return(PERIOD_D1);
case 32769: return(PERIOD_W1);
case 49153: return(PERIOD_MN1);
default: return(PERIOD_CURRENT);
}
}
datetime RangeBarIndicator::iTime(string symbol,int tf,int index)
{
if(index < 0) return(-1);
ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
datetime Arr[];
if(CopyTime(symbol, timeframe, index, 1, Arr)>0)
return(Arr[0]);
else return(-1);
}