Update to version 2.02

This commit is contained in:
9nix6
2017-12-05 13:16:14 +01:00
parent ec6cab350b
commit 32af8d84a2
32 changed files with 5341 additions and 874 deletions
Binary file not shown.
+766
View File
@@ -0,0 +1,766 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#property version "2.02"
#include <AZ-INVEST/SDK/RangeBars.mqh>
class RangeBarIndicator
{
private:
RangeBars * rangeBars;
int rates_total;
int prev_calculated;
bool getVolumes;
bool getVolumeBreakdown;
bool getTime;
bool useAppliedPrice;
ENUM_APPLIED_PRICE applied_price;
bool dataReady;
public:
datetime Time[];
double Open[];
double Low[];
double High[];
double Close[];
double Price[];
long Tick_volume[];
long Real_volume[];
double Buy_volume[];
double Sell_volume[];
double BuySell_volume[];
bool IsNewBar;
RangeBarIndicator();
~RangeBarIndicator();
void SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) { this.useAppliedPrice = true; this.applied_price = _applied_price; };
void SetGetVolumesFlag() { this.getVolumes = true; };
void SetGetVolumeBreakdownFlag() { this.getVolumeBreakdown = true; };
void SetGetTimeFlag() { this.getTime = true; };
bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &_Time[]);
int GetPrevCalculated() { return prev_calculated; };
void BufferShiftLeft(double &buffer[]);
private:
bool CheckStatus();
bool NeedsReload();
int GetOLHC(int start, int count);
int GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], int start, int count);
int GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count);
void OLHCShiftRight();
void OLHCResize();
bool Canvas_IsNewBar(const datetime &_Time[]);
bool Canvas_IsRatesTotalChanged(int ratesTotalNow);
int Canvas_RatesTotalChangedBy(int ratesTotalNow);
double CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE applied_price);
double CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c,ENUM_APPLIED_PRICE applied_price);
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;
getVolumes = false;
getTime = false;
dataReady = 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_IsNewBar(_Time);
Canvas_RatesTotalChangedBy(_rates_total);
IsNewBar = rangeBars.IsNewBar();
firstRun = false;
}
if(!CheckStatus())
{
if(rangeBars != NULL)
delete rangeBars;
rangeBars = new RangeBars();
if(rangeBars != NULL)
rangeBars.Init();
return false;
}
ArraySetAsSeries(this.Time,false);
ArraySetAsSeries(this.Open,false);
ArraySetAsSeries(this.High,false);
ArraySetAsSeries(this.Low,false);
ArraySetAsSeries(this.Close,false);
ArraySetAsSeries(this.Price,false);
ArraySetAsSeries(this.Tick_volume,false);
ArraySetAsSeries(this.Real_volume,false);
ArraySetAsSeries(this.Buy_volume,false);
ArraySetAsSeries(this.Sell_volume,false);
ArraySetAsSeries(this.BuySell_volume,false);
bool needsReload = (NeedsReload() || (!this.dataReady));
if(needsReload)
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return false;
}
/*
if(needsReload || IsNewBar || canvasIsNewTime || (change != 0))
{
Print("reload="+needsReload+", renkoisnewbar="+IsNewBar+", canvasIsNewTime="+canvasIsNewTime+", change="+change);
GetOLHC(0,_rates_total);
this.prev_calculated = ArraySize(this.Open);
return true;
}
*/
bool change = Canvas_RatesTotalChangedBy(_rates_total);
if(change != 0)
{
#ifdef DISPLAY_DEBUG_MSG
Print("rates total changed to:"+_rates_total);
#endif
if(change == 1)
{
#ifdef DISPLAY_DEBUG_MSG
Print("changed by 1 => Resize called");
#endif
OLHCResize();
}
else
{
#ifdef DISPLAY_DEBUG_MSG
Print("changed by "+change+" => getting ALL");
#endif
GetOLHC(0,_rates_total);
}
this.prev_calculated = 0;//_prev_calculated;
Canvas_IsNewBar(_Time);
return true;
}
else if(Canvas_IsNewBar(_Time))
{
#ifdef DISPLAY_DEBUG_MSG
Print("Got Canvas_IsNewBar");
#endif
if(ArraySize(this.Open) == 0)
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return true; ///////// false
}
OLHCShiftRight();
this.prev_calculated = _prev_calculated;
return true;
}
IsNewBar = rangeBars.IsNewBar();
if(IsNewBar)
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return true;
}
//
// Only recalculate last bar
//
GetOLHC(0,0);
this.prev_calculated = _prev_calculated;
return true;
}
int RangeBarIndicator::GetOLHC(int start, int count)
{
if((start == 0) && (count == 0) && dataReady)
{
MqlRates tempRates[1];
double b[1],s[1],bs[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(getTime)
{
this.Time[last] = tempRates[0].time;
}
if(getVolumes)
{
this.Tick_volume[last] = tempRates[0].tick_volume;
this.Real_volume[last] = tempRates[0].real_volume;
}
if(useAppliedPrice)
{
this.Price[last] = CalcAppliedPrice(tempRates[0],this.applied_price);
}
if(getVolumeBreakdown)
{
rangeBars.GetBuySellVolumeBreakdown(b,s,bs,0,1);
this.Buy_volume[last] = b[0];
this.Sell_volume[last] = s[0];
this.BuySell_volume[last] = bs[0];
}
return 1;
}
else
{
return GetOLHCAndApplPriceForIndicatorCalc(this.Open,this.Low,this.High,this.Close,this.Time,this.Tick_volume,this.Real_volume, this.Buy_volume, this.Sell_volume, this.BuySell_volume, this.Price,this.applied_price,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];
if(getTime)
this.Time[i] = this.Time[i-1];
if(useAppliedPrice)
this.Price[i] = this.Price[i-1];
if(getVolumes)
{
this.Tick_volume[i] = this.Tick_volume[i-1];
this.Real_volume[i] = this.Real_volume[i-1];
}
if(getVolumeBreakdown)
{
this.Buy_volume[i] = this.Buy_volume[i-1];
this.Sell_volume[i] = this.Sell_volume[i-1];
this.BuySell_volume[i] = this.BuySell_volume[i-1];
}
}
this.Open[0] = 0.0;
this.High[0] = 0.0;
this.Low[0] = 0.0;
this.Close[0] = 0.0;
if(getTime)
this.Time[0] = 0;
if(useAppliedPrice)
this.Price[0] = 0.0;
if(getVolumes)
{
this.Tick_volume[0] = 0.0;
this.Real_volume[0] = 0.0;
}
if(getVolumeBreakdown)
{
this.Buy_volume[0] = 0;
this.Sell_volume[0] = 0;
this.BuySell_volume[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);
if(getTime)
ArrayResize(this.Time,count+1);
if(useAppliedPrice)
ArrayResize(this.Price,count+1);
if(getVolumes)
{
ArrayResize(this.Tick_volume,count+1);
ArrayResize(this.Real_volume,count+1);
}
if(getVolumeBreakdown)
{
ArrayResize(this.Buy_volume,count+1);
ArrayResize(this.Sell_volume,count+1);
ArrayResize(this.BuySell_volume,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;
}
int RangeBarIndicator::Canvas_RatesTotalChangedBy(int ratesTotalNow)
{
int changedBy = 0;
static int prevRatesTotal = 0;
if(prevRatesTotal == 0)
prevRatesTotal = ratesTotalNow;
if(prevRatesTotal != ratesTotalNow)
{
changedBy = (ratesTotalNow - prevRatesTotal);
prevRatesTotal = ratesTotalNow;
return changedBy;
}
return 0;
}
int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[], long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], int start, int count)
{
int handle;
double temp[];
if(ArrayResize(temp,count) == -1)
return -1;
if(ArrayResize(o,count) == -1)
return -1;
if(ArrayResize(l,count) == -1)
return -1;
if(ArrayResize(h,count) == -1)
return -1;
if(ArrayResize(c,count) == -1)
return -1;
if(getVolumes)
{
if(ArrayResize(tickVolume,count) == -1)
return -1;
if(ArrayResize(realVolume,count) == -1)
return -1;
}
if(getTime)
{
if(ArrayResize(t,count) == -1)
return -1;
}
if(getVolumeBreakdown)
{
if(ArrayResize(buyVolume,count) == -1)
return -1;
if(ArrayResize(sellVolume,count) == -1)
return -1;
if(ArrayResize(buySellVolume,count) == -1)
return -1;
}
handle = rangeBars.GetHandle();
if(handle == INVALID_HANDLE)
return -1;
int _count = CopyBuffer(handle,RANGEBAR_OPEN,start,count,temp);
if(_count == -1)
{
int errorCode = GetLastError();
if(errorCode == ERR_INDICATOR_DATA_NOT_FOUND)
{
Print("Waiting for buffers ready flag");
return -2;
}
else
return -1;
}
if(_count < count)
{
#ifdef DISPLAY_DEBUG_MSG
Print("Fixing offset (req:"+count+" res:"+_count+")");
#endif
ArrayInitialize(o,0x0);
ArrayInitialize(l,0x0);
ArrayInitialize(h,0x0);
ArrayInitialize(c,0x0);
if(getTime)
ArrayInitialize(t,0x0);
if(getVolumes)
{
ArrayInitialize(tickVolume,0x0);
ArrayInitialize(realVolume,0x0);
}
if(getVolumeBreakdown)
{
ArrayInitialize(buyVolume,0x0);
ArrayInitialize(sellVolume,0x0);
ArrayInitialize(buySellVolume,0x0);
}
// less data - indicator requres more
ArrayCopy(o,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_LOW,start,_count,temp) == -1)
return -1;
ArrayCopy(l,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_HIGH,start,_count,temp) == -1)
return -1;
ArrayCopy(h,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_CLOSE,start,_count,temp) == -1)
return -1;
ArrayCopy(c,temp,(count-_count),0);
if(getTime)
{
if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,_count,temp) == -1)
return -1;
ArrayCopy(t,temp,(count-_count),0);
}
if(getVolumes)
{
if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(tickVolume,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(realVolume,temp,(count-_count),0);
}
#ifdef P_RANGEBAR_BR
#ifdef P_RANGEBAR_BR_PRO
if(getVolumeBreakdown)
{
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp,(count-_count),0);
}
#else
#endif
#else
if(getVolumeBreakdown)
{
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp,(count-_count),0);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp,(count-_count),0);
}
#endif
}
else
{
if(CopyBuffer(handle,RANGEBAR_OPEN,start,count,o) == -1)
return -1;
if(CopyBuffer(handle,RANGEBAR_LOW,start,count,l) == -1)
return -1;
if(CopyBuffer(handle,RANGEBAR_HIGH,start,count,h) == -1)
return -1;
if(CopyBuffer(handle,RANGEBAR_CLOSE,start,count,c) == -1)
return -1;
if(getTime)
{
if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,count,temp) == -1)
return -1;
ArrayCopy(t,temp);
}
if(getVolumes)
{
if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(tickVolume,temp);
if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(realVolume,temp);
}
#ifdef P_RANGEBAR_BR
#ifdef P_RANGEBAR_BR_PRO
if(getVolumeBreakdown)
{
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp);
}
#else
#endif
#else
if(getVolumeBreakdown)
{
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp);
}
#endif
}
return count;
}
//
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
//
int RangeBarIndicator::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[],double &buyVolume[], double &sellVolume[], double &buySellVolume[],double &price[],ENUM_APPLIED_PRICE _applied_price, int start, int count)
{
dataReady = true;
int _count = GetOLHCForIndicatorCalc(o,l,h,c,t,tickVolume,realVolume,buyVolume,sellVolume,buySellVolume,start,count);
if(_count < 0)
{
dataReady = false;
return _count;
}
if(applied_price == PRICE_CLOSE)
{
return ArrayCopy(price,c);
}
else if(applied_price == PRICE_OPEN)
{
return ArrayCopy(price,o);
}
else if(applied_price == PRICE_HIGH)
{
return ArrayCopy(price,h);
}
else if(applied_price == PRICE_LOW)
{
return ArrayCopy(price,l);
}
else
{
if(ArrayResize(price,_count) == -1)
return -1;
for(int i=0; i<_count; i++)
{
price[i] = CalcAppliedPrice(o[i],l[i],h[i],c[i],_applied_price);
}
}
return _count;
}
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);
}
//
// Function used for calculating the Apllied Price based on Renko OLHC values
//
double RangeBarIndicator::CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE _applied_price)
{
if(_applied_price == PRICE_CLOSE)
return _rates.close;
else if (_applied_price == PRICE_OPEN)
return _rates.open;
else if (_applied_price == PRICE_HIGH)
return _rates.high;
else if (_applied_price == PRICE_LOW)
return _rates.low;
else if (_applied_price == PRICE_MEDIAN)
return (_rates.high + _rates.low) / 2;
else if (_applied_price == PRICE_TYPICAL)
return (_rates.high + _rates.low + _rates.close) / 3;
else if (_applied_price == PRICE_WEIGHTED)
return (_rates.high + _rates.low + _rates.close + _rates.close) / 4;
return 0.0;
}
double RangeBarIndicator::CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c, ENUM_APPLIED_PRICE _applied_price)
{
if(_applied_price == PRICE_CLOSE)
return c;
else if (_applied_price == PRICE_OPEN)
return o;
else if (_applied_price == PRICE_HIGH)
return h;
else if (_applied_price == PRICE_LOW)
return l;
else if (_applied_price == PRICE_MEDIAN)
return (h + l) / 2;
else if (_applied_price == PRICE_TYPICAL)
return (h + l + c) / 3;
else if (_applied_price == PRICE_WEIGHTED)
return (h + l + c +c) / 4;
return 0.0;
}
void RangeBarIndicator::BufferShiftLeft(double &buffer[])
{
int size = ArraySize(buffer);
for(int i=1; i<size; i++)
buffer[i-1] = buffer[i];
}
+345
View File
@@ -0,0 +1,345 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#include <AZ-INVEST/SDK/CommonSettings.mqh>
#define CUSTOM_CHART_NAME "Range Bars"
#ifdef SHOW_INDICATOR_INPUTS
input int barSizeInTicks = 100; // Range bar size (in points)
input ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
input int atrPeriod = 14; // ATR period
input int atrPercentage = 10; // Use percentage of ATR
ENUM_BOOL useRealVolume = false; // Use real volume ( false for FX )
ENUM_TICK_PRICE_TYPE plotPrice = tickBid; // Build chart using
input int showNumberOfDays = 14; // Show history for number of days
input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
input double TopBottomPaddingPercentage = 0.30; // Use padding top/bottom (0.0 - 1.0)
input ENUM_PIVOT_POINTS showPivots = ppNone; // Show pivot levels
input ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3; // Pivot point calculation method
input color RColor = clrDodgerBlue; // Resistance line color
input color PColor = clrGold; // Pivot line color
input color SColor = clrFireBrick; // Support line color
input color PDHColor = clrHotPink; // Previous day's high
input color PDLColor = clrLightSkyBlue; // Previous day's low
input color PDCColor = clrGainsboro; // Previous day's close
input ENUM_BOOL showNextBarLevels = true; // Show current bar's close projections
input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color
input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color
input ENUM_BOOL showCurrentBarOpenTime = true; // Display chart info and current bar's open time
input color InfoTextColor = clrWhite; // Current bar's open time info color
input ENUM_BOOL UseSoundSignalOnNewBar = false; // Play sound on new bar
input ENUM_BOOL OnlySignalReversalBars = false; // Only signal reversals
input ENUM_BOOL UseAlertWindow = false; // Display Alert window with new bar info
input ENUM_BOOL SendPushNotifications = false; // Send new bar info push notification to smartphone
input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close
input string SoundFileBear = "timeout.wav"; // Use sound file for bearish bar close
input ENUM_BOOL MA1on = false; // Show first MA
input int MA1period = 20; // 1st MA period
input ENUM_MA_METHOD_EXT MA1method = _MODE_SMA; // 1st MA method
input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; // 1st MA apply to
input int MA1shift = 0; // 1st MA shift
input ENUM_BOOL MA2on = false; // Show second MA
input int MA2period = 50; // 2nd MA period
input ENUM_MA_METHOD_EXT MA2method = _MODE_EMA; // 2nd MA method
input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to
input int MA2shift = 0; // 2nd MA shift
input ENUM_BOOL MA3on = false; // Show third MA
input int MA3period = 20; // 3rd MA period
input ENUM_MA_METHOD_EXT MA3method = _VWAP_TICKVOL; // 3rd MA method
input ENUM_APPLIED_PRICE MA3applyTo = PRICE_CLOSE; // 3rd MA apply to
input int MA3shift = 0; // 3rd MA shift
input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel
input string Channel_Settings = "-------------------"; // Channel settings
input int DonchianPeriod = 20; // Donchian Channel period
input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; // Bollinger Bands apply to
input int BollingerBandsPeriod = 20; // Bollinger Bands period
input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations
input int SuperTrendPeriod = 10; // Super Trend period
input double SuperTrendMultiplier=1.7; // Super Trend multiplier
input string Misc_Settings = "-------------------"; // Misc settings
input ENUM_BOOL DisplayAsBarChart = false; // Display as bar chart
input ENUM_BOOL UsedInEA = false; // Indicator used in EA via iCustom()
#else
//
// This block should always be set to the following values
//
double TopBottomPaddingPercentage = 0;
ENUM_PIVOT_POINTS showPivots = ppNone;
ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3;
color RColor = clrNONE;
color PColor = clrNONE;
color SColor = clrNONE;
color PDHColor = clrNONE;
color PDLColor = clrNONE;
color PDCColor = clrNONE;
ENUM_BOOL showNextBarLevels = false;
color HighThresholdIndicatorColor = clrNONE;
color LowThresholdIndicatorColor = clrNONE;
ENUM_BOOL showCurrentBarOpenTime = false;
color InfoTextColor = clrNONE;
ENUM_BOOL UseSoundSignalOnNewBar = false;
ENUM_BOOL OnlySignalReversalBars = false;
ENUM_BOOL UseAlertWindow = false;
ENUM_BOOL SendPushNotifications = false;
string SoundFileBull = "";
string SoundFileBear = "";
ENUM_BOOL DisplayAsBarChart = true;
ENUM_BOOL UsedInEA = true; // This should always be set to TRUE for EAs & Indicators
//
//
//
#endif
struct RANGEBAR_SETTINGS
{
int barSizeInTicks;
ENUM_BOOL atrEnabled;
ENUM_TIMEFRAMES atrTimeFrame;
int atrPeriod;
int atrPercentage;
ENUM_BOOL useRealVolume;
ENUM_TICK_PRICE_TYPE plotPrice;
int showNumberOfDays;
ENUM_BOOL resetOpenOnNewTradingDay;
};
class RangeBarSettings
{
protected:
string settingsFileName;
string chartTypeFileName;
RANGEBAR_SETTINGS settings;
CHART_INDICATOR_SETTINGS chartIndicatorSettings;
ALERT_INFO_SETTINGS alertInfoSettings;
public:
RangeBarSettings(void);
~RangeBarSettings(void);
RANGEBAR_SETTINGS GetRangeBarSettings(void);
ALERT_INFO_SETTINGS GetAlertInfoSettings(void);
CHART_INDICATOR_SETTINGS GetChartIndicatorSettings(void);
void Set(void);
void Save(void);
bool Load(void);
void Delete(void);
bool Changed(void);
};
void RangeBarSettings::RangeBarSettings(void)
{
this.settingsFileName = CUSTOM_CHART_NAME+(string)ChartID()+".set";
this.chartTypeFileName = (string)ChartID()+".id";
}
void RangeBarSettings::~RangeBarSettings(void)
{
}
void RangeBarSettings::Save(void)
{
if(IS_TESTING || this.chartIndicatorSettings.UsedInEA)
return;
this.Delete();
//
// Store indicator settings
//
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN);
uint result = 0;
result += FileWriteStruct(handle,this.settings);
result += FileWriteStruct(handle,this.chartIndicatorSettings);
//FileWriteStruct(handle,this.alertInfoSettings);
FileClose(handle);
//
// Store chart type identifier
//
handle = FileOpen(this.chartTypeFileName,FILE_SHARE_READ|FILE_WRITE|FILE_ANSI);
FileWriteString(handle,CUSTOM_CHART_NAME);
FileClose(handle);
}
void RangeBarSettings::Delete(void)
{
if(IS_TESTING || this.chartIndicatorSettings.UsedInEA)
return;
if(FileIsExist(this.settingsFileName))
FileDelete(this.settingsFileName);
}
bool RangeBarSettings::Load(void)
{
#ifdef SHOW_INDICATOR_INPUTS
Set();
return true;
#else
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
if(handle == INVALID_HANDLE)
return false;
if(FileReadStruct(handle,this.settings) <= 0)
{
Print("Failed loading settings(1)!");
FileClose(handle);
return false;
}
if(FileReadStruct(handle,this.chartIndicatorSettings) <= 0)
{
Print("Failed loading settings(2)!");
FileClose(handle);
return false;
}
/*
if(FileReadStruct(handle,this.alertInfoSettings) <= 0)
{
Print("Failed loading settings(3)!");
FileClose(handle);
return false;
}
*/
FileClose(handle);
return true;
#endif
}
ALERT_INFO_SETTINGS RangeBarSettings::GetAlertInfoSettings(void)
{
return this.alertInfoSettings;
}
CHART_INDICATOR_SETTINGS RangeBarSettings::GetChartIndicatorSettings(void)
{
return this.chartIndicatorSettings;
}
RANGEBAR_SETTINGS RangeBarSettings::GetRangeBarSettings(void)
{
return this.settings;
}
void RangeBarSettings::Set(void)
{
#ifdef SHOW_INDICATOR_INPUTS
settings.barSizeInTicks = barSizeInTicks;
settings.atrEnabled = atrEnabled;
settings.atrTimeFrame = atrTimeFrame;
settings.atrPeriod = atrPeriod;
settings.atrPercentage = atrPercentage;
settings.useRealVolume = useRealVolume;
settings.plotPrice = plotPrice;
settings.showNumberOfDays = showNumberOfDays;
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
//
//
//
chartIndicatorSettings.MA1on = MA1on;
chartIndicatorSettings.MA1period = MA1period;
chartIndicatorSettings.MA1method = MA1method;
chartIndicatorSettings.MA1applyTo = MA1applyTo;
chartIndicatorSettings.MA1shift = MA1shift;
chartIndicatorSettings.MA2on = MA2on;
chartIndicatorSettings.MA2period = MA2period;
chartIndicatorSettings.MA2method = MA2method;
chartIndicatorSettings.MA2applyTo = MA2applyTo;
chartIndicatorSettings.MA2shift = MA2shift;
/*
chartIndicatorSettings.ShowVWAP = ShowVWAP;
chartIndicatorSettings.VWAP_Period = VWAP_Period;
chartIndicatorSettings.VWAPapplyTo = VWAPapplyTo;
chartIndicatorSettings.VWAPvolume = VWAPvolume;
*/
chartIndicatorSettings.MA3on = MA3on;
chartIndicatorSettings.MA3period = MA3period;
chartIndicatorSettings.MA3method = MA3method;
chartIndicatorSettings.MA3applyTo = MA3applyTo;
chartIndicatorSettings.MA3shift = MA3shift;
chartIndicatorSettings.ShowChannel = ShowChannel;
chartIndicatorSettings.DonchianPeriod = DonchianPeriod;
chartIndicatorSettings.BBapplyTo = BBapplyTo;
chartIndicatorSettings.BollingerBandsPeriod = BollingerBandsPeriod;
chartIndicatorSettings.BollingerBandsDeviations = BollingerBandsDeviations;
chartIndicatorSettings.SuperTrendPeriod = SuperTrendPeriod;
chartIndicatorSettings.SuperTrendMultiplier = SuperTrendMultiplier;
chartIndicatorSettings.UsedInEA = UsedInEA;
//
//
//
alertInfoSettings.TopBottomPaddingPercentage = TopBottomPaddingPercentage;
alertInfoSettings.showPiovots = showPivots;
alertInfoSettings.pivotPointCalculationType = pivotPointCalculationType;
alertInfoSettings.Rcolor = RColor;
alertInfoSettings.Pcolor = PColor;
alertInfoSettings.Scolor = SColor;
alertInfoSettings.PDHColor = PDHColor;
alertInfoSettings.PDLColor = PDLColor;
alertInfoSettings.PDCColor = PDCColor;
alertInfoSettings.showNextBarLevels = showNextBarLevels;
alertInfoSettings.HighThresholdIndicatorColor = HighThresholdIndicatorColor;
alertInfoSettings.LowThresholdIndicatorColor = LowThresholdIndicatorColor;
alertInfoSettings.showCurrentBarOpenTime = showCurrentBarOpenTime;
alertInfoSettings.InfoTextColor = InfoTextColor;
alertInfoSettings.UseSoundSignalOnNewBar = UseSoundSignalOnNewBar;
alertInfoSettings.OnlySignalReversalBars = OnlySignalReversalBars;
alertInfoSettings.UseAlertWindow = UseAlertWindow;
alertInfoSettings.SendPushNotifications = SendPushNotifications;
alertInfoSettings.SoundFileBull = SoundFileBull;
alertInfoSettings.SoundFileBear = SoundFileBear;
alertInfoSettings.DisplayAsBarChart = DisplayAsBarChart;
#endif
}
bool RangeBarSettings::Changed(void)
{
if(MQLInfoInteger((int)MQL5_TESTING))
return false;
static datetime prevFileTime = 0;
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE);
FileClose(handle);
if(prevFileTime != currFileTime)
{
prevFileTime = currFileTime;
return true;
}
return false;
}
@@ -1,5 +1,5 @@
//+------------------------------------------------------------------+
//| RangeBars.mqh ver:1.47.0 |
//| RangeBars.mqh ver:2.03.0 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
@@ -7,21 +7,27 @@
#property link "http://www.az-invest.eu"
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay203"
#define RANGEBAR_MA1 0
#define RANGEBAR_MA2 1
#define RANGEBAR_CHANNEL_HIGH 2
#define RANGEBAR_CHANNEL_MID 3
#define RANGEBAR_CHANNEL_LOW 4
#define RANGEBAR_OPEN 5
#define RANGEBAR_HIGH 6
#define RANGEBAR_LOW 7
#define RANGEBAR_CLOSE 8
#define RANGEBAR_COLOR_CODE 9
#define RANGEBAR_BAR_OPEN_TIME 10
#define RANGEBAR_TICK_VOLUME 11
#define RANGEBAR_OPEN 00
#define RANGEBAR_HIGH 01
#define RANGEBAR_LOW 02
#define RANGEBAR_CLOSE 03
#define RANGEBAR_BAR_COLOR 04
#define RANGEBAR_MA1 05
#define RANGEBAR_MA2 06
#define RANGEBAR_MA3 07
#define RANGEBAR_CHANNEL_HIGH 08
#define RANGEBAR_CHANNEL_MID 09
#define RANGEBAR_CHANNEL_LOW 10
#define RANGEBAR_BAR_OPEN_TIME 11
#define RANGEBAR_TICK_VOLUME 12
#define RANGEBAR_REAL_VOLUME 13
#define RANGEBAR_BUY_VOLUME 14
#define RANGEBAR_SELL_VOLUME 15
#define RANGEBAR_BUYSELL_VOLUME 16
#include <RangeBarSettings.mqh>
#include <AZ-INVEST/SDK/RangeBarSettings.mqh>
class RangeBars
{
@@ -48,15 +54,14 @@ class RangeBars
int GetHandle(void) { return rangeBarsHandle; };
bool GetMqlRates(MqlRates &ratesInfoArray[], int start, int count);
int GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[], int start, int count);
int GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count);
double CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE applied_price);
double CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c,ENUM_APPLIED_PRICE applied_price);
bool GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count);
bool GetMA1(double &MA[], int start, int count);
bool GetMA2(double &MA[], int start, int count);
bool GetMA3(double &MA[], int start, int count);
bool GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
bool GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
bool GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count);
bool IsNewBar();
private:
@@ -67,6 +72,7 @@ class RangeBars
RangeBars::RangeBars(void)
{
#define CONSTRUCTOR1
rangeBarSettings = new RangeBarSettings();
rangeBarsHandle = INVALID_HANDLE;
rangeBarsSymbol = _Symbol;
@@ -74,6 +80,7 @@ RangeBars::RangeBars(void)
RangeBars::RangeBars(string symbol)
{
#define CONSTRUCTOR2
rangeBarSettings = new RangeBarSettings();
rangeBarsHandle = INVALID_HANDLE;
rangeBarsSymbol = symbol;
@@ -103,8 +110,7 @@ int RangeBars::Init()
}
else
{
Print("Failed to load indicator settings.");
Alert("You need to put the Median Renko indicator on your chart first!");
Print("Failed to load indicator settings - RangeBar indicator not on chart");
return INVALID_HANDLE;
}
}
@@ -128,14 +134,28 @@ int RangeBars::Init()
#endif
}
RANGEBAR_SETTINGS s = rangeBarSettings.Get();
RANGEBAR_SETTINGS s = rangeBarSettings.GetRangeBarSettings();
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
//RangeBarSettings.Debug();
rangeBarsHandle = iCustom(this.rangeBarsSymbol,PERIOD_M1,RANGEBAR_INDICATOR_NAME,
rangeBarsHandle = iCustom(this.rangeBarsSymbol,_Period,RANGEBAR_INDICATOR_NAME,
s.barSizeInTicks,
s._startFromDateTime,
s.atrEnabled,
//s.atrTimeFrame,
s.atrPeriod,
s.atrPercentage,
s.showNumberOfDays,
s.resetOpenOnNewTradingDay,
TopBottomPaddingPercentage,
showPivots,
pivotPointCalculationType,
RColor,
PColor,
SColor,
PDHColor,
PDLColor,
PDCColor,
showNextBarLevels,
HighThresholdIndicatorColor,
LowThresholdIndicatorColor,
@@ -147,34 +167,41 @@ int RangeBars::Init()
SendPushNotifications,
SoundFileBull,
SoundFileBear,
s.MA1on,
s.MA1period,
s.MA1method,
s.MA1applyTo,
s.MA1shift,
s.MA2on,
s.MA2period,
s.MA2method,
s.MA2applyTo,
s.MA2shift,
s.ShowChannel,
cis.MA1on,
cis.MA1period,
cis.MA1method,
cis.MA1applyTo,
cis.MA1shift,
cis.MA2on,
cis.MA2period,
cis.MA2method,
cis.MA2applyTo,
cis.MA2shift,
cis.MA3on,
cis.MA3period,
cis.MA3method,
cis.MA3applyTo,
cis.MA3shift,
cis.ShowChannel,
"",
s.DonchianPeriod,
s.BBapplyTo,
s.BollingerBandsPeriod,
s.BollingerBandsDeviations,
s.SuperTrendPeriod,
s.SuperTrendMultiplier,
cis.DonchianPeriod,
cis.BBapplyTo,
cis.BollingerBandsPeriod,
cis.BollingerBandsDeviations,
cis.SuperTrendPeriod,
cis.SuperTrendMultiplier,
"",
DisplayAsBarChart,
UsedInEA);
if(rangeBarsHandle == INVALID_HANDLE)
{
Print("RangeBars indicator init failed on error ",GetLastError());
Print("RangeBar indicator init failed on error ",GetLastError());
}
else
{
Print("RangeBars indicator init OK");
Print("RangeBar indicator init OK");
}
return rangeBarsHandle;
@@ -207,9 +234,9 @@ void RangeBars::Deinit()
return;
if(IndicatorRelease(rangeBarsHandle))
Print("RangeBars indicator handle released");
Print("RangeBar indicator handle released");
else
Print("Failed to release RangeBars indicator handle");
Print("Failed to release RangeBar indicator handle");
}
//
@@ -218,25 +245,21 @@ void RangeBars::Deinit()
bool RangeBars::IsNewBar()
{
MqlRates currentRenko[1];
static MqlRates prevRenko;
MqlRates currentBar[1];
static datetime prevBarTime;
GetMqlRates(currentRenko,1,1);
GetMqlRates(currentBar,0,1);
if((prevRenko.open != currentRenko[0].open) ||
(prevRenko.high != currentRenko[0].high) ||
(prevRenko.low != currentRenko[0].low) ||
(prevRenko.close != currentRenko[0].close))
if(currentBar[0].time == 0)
return false;
if(prevBarTime < currentBar[0].time)
{
prevRenko.open = currentRenko[0].open;
prevRenko.high = currentRenko[0].high;
prevRenko.low = currentRenko[0].low;
prevRenko.close = currentRenko[0].close;
prevBarTime = currentBar[0].time;
return true;
}
return false;
}
return false;}
//
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
@@ -244,7 +267,7 @@ bool RangeBars::IsNewBar()
bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
{
double o[],l[],h[],c[],time[],tick_volume[];
double o[],l[],h[],c[],barColor[],time[],tick_volume[],real_volume[];
if(ArrayResize(o,count) == -1)
return false;
@@ -254,10 +277,14 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
return false;
if(ArrayResize(c,count) == -1)
return false;
if(ArrayResize(barColor,count) == -1)
return false;
if(ArrayResize(time,count) == -1)
return false;
if(ArrayResize(tick_volume,count) == -1)
return false;
if(ArrayResize(real_volume,count) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o) == -1)
@@ -270,8 +297,12 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BAR_OPEN_TIME,start,count,time) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BAR_COLOR,start,count,barColor) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_TICK_VOLUME,start,count,tick_volume) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_REAL_VOLUME,start,count,real_volume) == -1)
return false;
if(ArrayResize(ratesInfoArray,count) == -1)
return false;
@@ -285,117 +316,72 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
ratesInfoArray[tempOffset-i].close = c[i];
ratesInfoArray[tempOffset-i].time = (datetime)time[i];
ratesInfoArray[tempOffset-i].tick_volume = (long)tick_volume[i];
ratesInfoArray[tempOffset-i].real_volume = (long)real_volume[i];
ratesInfoArray[tempOffset-i].spread = (int)barColor[i];
}
ArrayFree(o);
ArrayFree(l);
ArrayFree(h);
ArrayFree(c);
ArrayFree(barColor);
ArrayFree(time);
ArrayFree(tick_volume);
ArrayFree(real_volume);
return true;
}
//
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
//
int RangeBars::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[], int start, int count)
bool RangeBars::GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count)
{
if(ArrayResize(o,count) == -1)
double b[],s[],bs[];
if(ArrayResize(b,count) == -1)
return false;
if(ArrayResize(s,count) == -1)
return false;
if(ArrayResize(bs,count) == -1)
return false;
int _count = CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o);
if(_count == -1)
return _count;
if(ArrayResize(o,_count) == -1)
return -1;
if(ArrayResize(l,_count) == -1)
return -1;
if(ArrayResize(h,_count) == -1)
return -1;
if(ArrayResize(c,_count) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,_count,o) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,_count,l) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,_count,h) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,_count,c) == -1)
return -1;
return _count;
}
//
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
//
int RangeBars::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count)
{
if(ArrayResize(o,count) == -1)
#ifdef P_RANGEBAR_BR
#ifdef P_RANGEBAR_BR_PRO
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1)
return false;
#endif
#else
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1)
return false;
#endif
int _count = CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o);
if(_count == -1)
return _count;
if(ArrayResize(buy,count) == -1)
return false;
if(ArrayResize(sell,count) == -1)
return false;
if(ArrayResize(buySell,count) == -1)
return false;
if(ArrayResize(o,_count) == -1)
return -1;
if(ArrayResize(l,_count) == -1)
return -1;
if(ArrayResize(h,_count) == -1)
return -1;
if(ArrayResize(c,_count) == -1)
return -1;
if(ArrayResize(price,_count) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,_count,o) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,_count,l) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,_count,h) == -1)
return -1;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,_count,c) == -1)
return -1;
if(applied_price == PRICE_CLOSE)
int tempOffset = count-1;
for(int i=0; i<count; i++)
{
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,_count,price) == -1)
return -1;
}
else if(applied_price == PRICE_OPEN)
{
if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,_count,price) == -1)
return -1;
}
else if(applied_price == PRICE_HIGH)
{
if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,_count,price) == -1)
return -1;
}
else if(applied_price == PRICE_LOW)
{
if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,_count,price) == -1)
return -1;
}
else
{
for(int i=0; i<_count; i++)
{
price[i] = CalcAppliedPrice(o[i],l[i],h[i],c[i],applied_price);
}
buy[tempOffset-i] = b[i];
sell[tempOffset-i] = s[i];
buySell[tempOffset-i] = bs[i];
}
ArrayFree(b);
ArrayFree(s);
ArrayFree(bs);
return _count;
return true;
}
//
@@ -448,6 +434,31 @@ bool RangeBars::GetMA2(double &MA[], int start, int count)
return true;
}
//
// Get "count" MovingAverage3 values into "MA[]" starting from "start" bar
//
bool RangeBars::GetMA3(double &MA[], int start, int count)
{
double tempMA[];
if(ArrayResize(tempMA,count) == -1)
return false;
if(ArrayResize(MA,count) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_MA3,start,count,tempMA) == -1)
return false;
for(int i=0; i<count; i++)
{
MA[count-1-i] = tempMA[i];
}
ArrayFree(tempMA);
return true;
}
//
// Get "count" Renko Donchian channel values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
//
@@ -484,6 +495,9 @@ bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowA
{
double tempH[], tempM[], tempL[];
#ifdef P_RANGEBAR_BR
return false;
#else
if(ArrayResize(tempH,count) == -1)
return false;
if(ArrayResize(tempM,count) == -1)
@@ -518,48 +532,6 @@ bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowA
ArrayFree(tempL);
return true;
#endif
}
//
// Function used for calculating the Apllied Price based on Renko OLHC values
//
double RangeBars::CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE applied_price)
{
if(applied_price == PRICE_CLOSE)
return _rates.close;
else if (applied_price == PRICE_OPEN)
return _rates.open;
else if (applied_price == PRICE_HIGH)
return _rates.high;
else if (applied_price == PRICE_LOW)
return _rates.low;
else if (applied_price == PRICE_MEDIAN)
return (_rates.high + _rates.low) / 2;
else if (applied_price == PRICE_TYPICAL)
return (_rates.high + _rates.low + _rates.close) / 3;
else if (applied_price == PRICE_WEIGHTED)
return (_rates.high + _rates.low + _rates.close + _rates.close) / 4;
return 0.0;
}
double RangeBars::CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c, ENUM_APPLIED_PRICE applied_price)
{
if(applied_price == PRICE_CLOSE)
return c;
else if (applied_price == PRICE_OPEN)
return o;
else if (applied_price == PRICE_HIGH)
return h;
else if (applied_price == PRICE_LOW)
return l;
else if (applied_price == PRICE_MEDIAN)
return (h + l) / 2;
else if (applied_price == PRICE_TYPICAL)
return (h + l + c) / 3;
else if (applied_price == PRICE_WEIGHTED)
return (h + l + c +c) / 4;
return 0.0;
}
+611
View File
@@ -0,0 +1,611 @@
//+------------------------------------------------------------------+
//| TradeFunctions.mqh |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#include <Trade\Trade.mqh>
#define POSITION_TYPE_NONE -1
//
// Positions (market orders)
//
struct CMarketOrderParameters
{
bool m_async_mode; // trade mode
ulong m_magic; // expert magic number
ulong m_deviation; // deviation default
ENUM_ORDER_TYPE_FILLING m_type_filling;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
};
class CMarketOrder
{
protected:
CTrade * ctrade;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
public:
CMarketOrder(CMarketOrderParameters &params);
~CMarketOrder(void);
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0);
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0);
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0);
bool Modify(ulong ticket, double priceSL=0,double priceTP=0);
bool Close(ulong ticket);
bool ClosePartial(ulong ticket, double lots);
bool Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0);
bool Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0);
bool IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0);
bool IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0);
bool IsOpen(string symbol, long magicNumber = 0);
bool IsOpen(ulong &ticket, string symbol, long magicNumber = 0);
bool IsOpen(ulong &ticket, ENUM_POSITION_TYPE &type, string symbol, long magicNumber = 0);
string PositionTypeToString(ENUM_POSITION_TYPE t);
bool RetryOrderRequest(int retryNumber);
private:
bool _IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber);
bool _IsOpen(ulong &ticket, string symbol, long magicNumber);
bool _IsNettingAccount() { return ((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) ? true : false; };
};
CMarketOrder::CMarketOrder(CMarketOrderParameters &params)
{
ctrade = new CTrade();
ctrade.SetExpertMagicNumber(params.m_magic);
ctrade.SetDeviationInPoints(params.m_deviation);
ctrade.SetTypeFilling(params.m_type_filling);
ctrade.SetAsyncMode(params.m_async_mode);
this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries;
this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms;
this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms;
}
CMarketOrder::~CMarketOrder(void)
{
if(ctrade != NULL)
delete ctrade;
}
bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
{
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : 0.0);
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0)
{
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
{
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : 0.0);
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0)
{
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double priceSL;
double priceTP;
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP));
}
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP));
}
else
return false;
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Modify(ulong ticket, double priceSL=0,double priceTP=0)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Close(ulong ticket)
{
if(!PositionSelectByTicket(ticket))
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
result = ctrade.PositionClose(ticket);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::ClosePartial(ulong ticket, double lots)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
result = ctrade.PositionClosePartial(ticket, NormalizeLots(symbol,lots));
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double positionLots = PositionGetDouble(POSITION_VOLUME);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(!this.Close(ticket))
return false;
if(type == POSITION_TYPE_BUY)
{
return this.Short(symbol,(lots ? lots : positionLots),stoploss,takeprofit);
}
else if(type == POSITION_TYPE_SELL)
{
return this.Long(symbol,(lots ? lots : positionLots),stoploss,takeprofit);
}
return false;
}
bool CMarketOrder::Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double positionLots = PositionGetDouble(POSITION_VOLUME);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(!this.Close(ticket))
return false;
if(type == POSITION_TYPE_BUY)
{
return this.Short(symbol,(lots ? lots : positionLots),priceSL,priceTP);
}
else if(type == POSITION_TYPE_SELL)
{
return this.Long(symbol,(lots ? lots : positionLots),priceSL,priceTP);
}
return false;
}
bool CMarketOrder::IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0)
{
ulong ticket;
return this._IsOpen(ticket,symbol,type,magicNumber);
}
bool CMarketOrder::IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0)
{
return this._IsOpen(ticket, symbol,type,magicNumber);
}
bool CMarketOrder::IsOpen(string symbol, long magicNumber = 0)
{
ulong ticket;
return this._IsOpen(ticket,symbol,magicNumber);
}
bool CMarketOrder::IsOpen(ulong &ticket, string symbol, long magicNumber = 0)
{
return this._IsOpen(ticket,symbol,magicNumber);
}
bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,long magicNumber=0)
{
int positions=PositionsTotal();
for(int i=0;i<positions;i++)
{
ResetLastError();
ulong _ticket=PositionGetTicket(i);
if(_ticket!=0)
{
if(PositionSelectByTicket(_ticket))
{
if(magicNumber > 0)
{
if(PositionGetInteger(POSITION_MAGIC) != magicNumber)
continue;
}
if(PositionGetString(POSITION_SYMBOL) == symbol)
{
ticket = _ticket;
type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
return true;
}
}
}
else
{
PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError());
}
}
return false;
}
bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber)
{
int positions=PositionsTotal();
long _type;
for(int i=0;i<positions;i++)
{
ResetLastError();
ulong _ticket=PositionGetTicket(i);
if(_ticket!=0)
{
if(PositionSelectByTicket(_ticket))
{
if(magicNumber > 0)
{
if(PositionGetInteger(POSITION_MAGIC) != magicNumber)
continue;
}
if(!PositionGetInteger(POSITION_TYPE,_type))
continue;
if((_type == type) && (PositionGetString(POSITION_SYMBOL) == symbol))
{
ticket = _ticket;
return true;
}
}
}
else
{
PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError());
}
}
return false;
}
bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, long magicNumber = 0)
{
int positions=PositionsTotal();
for(int i=0;i<positions;i++)
{
ResetLastError();
ulong _ticket=PositionGetTicket(i);
if(_ticket!=0)
{
if(PositionSelectByTicket(_ticket))
{
if(magicNumber > 0)
{
if(PositionGetInteger(POSITION_MAGIC) != magicNumber)
continue;
}
if((PositionGetString(POSITION_SYMBOL) == symbol))
{
ticket = _ticket;
return true;
}
}
}
else
{
PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError());
}
}
return false;
}
string CMarketOrder::PositionTypeToString(ENUM_POSITION_TYPE t)
{
if(t == POSITION_TYPE_BUY)
return "Buy";
else if(t == POSITION_TYPE_SELL)
return "Sell";
else
return "-";
}
bool CMarketOrder::RetryOrderRequest(int retryNumber)
{
if(retryNumber >= this.numberOfRetries)
{
PrintFormat("Giving up on maximum number of retries (%d)",this.numberOfRetries);
return false;
}
switch(ctrade.ResultRetcode())
{
case TRADE_RETCODE_REQUOTE :
Sleep(this.requoteTimeout_ms);
return true;
break;
case TRADE_RETCODE_REJECT :
case TRADE_RETCODE_ERROR :
case TRADE_RETCODE_TIMEOUT :
case TRADE_RETCODE_PRICE_OFF :
case TRADE_RETCODE_TOO_MANY_REQUESTS :
Sleep(this.busyTimeout_ms);
return true;
break;
default:
return false;
}
}
//+------------------------------------------------------------------+
//| Normalizing |
//+------------------------------------------------------------------+
double NormalizeLots(string symbol, double InputLots)
{
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
if(InputLots < lotsMin)
InputLots = lotsMin;
if(InputLots > lotsMax)
InputLots = lotsMax;
return NormalizeDouble(InputLots, lotsDigits);
}
double NormalizePrice(string symbol, double price, double tick = 0)
{
double _tick = tick ? tick : SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
int _digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
if (tick)
return NormalizeDouble(MathRound(price/_tick)*_tick,_digits);
else
return NormalizeDouble(price,_digits);
}
-309
View File
@@ -1,309 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
-318
View File
@@ -1,318 +0,0 @@
//+------------------------------------------------------------------+
//| RangeBarSettings.mqh ver 1.04 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
enum ENUM_CHANNEL_TYPE
{
None = 0, // None
Donchian_Channel, // Donchian Channel
Bollinger_Bands, // Bollinger Bands
SuperTrend, // Super Trend
// VWAP,
};
#ifdef SHOW_INDICATOR_INPUTS
input int barSizeInTicks = 100; // Range bar size (in points)
double customBarSize = barSizeInTicks * Point();
bool useTickVolume = true; // Use tick volume (for FX)
input datetime _startFromDateTime = 0; // Start building chart from date/time
datetime startFromDateTime = 0;
input bool resetOpenOnNewTradingDay = false; // Synchronize first bar's open on new day
input bool showNextBarLevels = true; // Show current bar's close projections
input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color
input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color
input bool showCurrentBarOpenTime = true; // Display chart info and current bar's open time
input color InfoTextColor = clrWhite; // Current bar's open time info color
input bool UseSoundSignalOnNewBar = false; // Play sound on new bar
input bool OnlySignalReversalBars = false; // Only signal reversals
input bool UseAlertWindow = false; // Display Alert window with new bar info
input bool SendPushNotifications = false; // Send new bar info push notification to smartphone
input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close
input string SoundFileBear = "news.wav"; // Use sound file for bearish bar close
input bool MA1on = false; // Show first MA
input int MA1period = 20; // 1st MA period
input ENUM_MA_METHOD MA1method = MODE_EMA; // 1st MA metod
input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; //1st MA apply to
input int MA1shift = 0; //1st MA shift
input bool MA2on = false; // Show second MA
input int MA2period = 50; // 2nd MA period
input ENUM_MA_METHOD MA2method = MODE_EMA; // 2nd MA method
input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to
input int MA2shift = 0; //2nd MA shift
input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel
input string Channel_Settings = "--------------------------"; // Channel settings
input int DonchianPeriod = 20; // Donchian Channel period
input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; //Bollinger Bands apply to
input int BollingerBandsPeriod = 20; // Bollinger Bands period
input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations
input int SuperTrendPeriod = 10; // Super Trend period
input double SuperTrendMultiplier=1.7; // Super Trend multiplier
input string Misc_Settings = "--------------------------"; // Misc settings
input bool UsedInEA = false; // Indicator used in EA via iCustom()
#else
int barSizeInTicks;
bool useTickVolume = true;
datetime startFromDateTime;
datetime _startFromDateTime = 0;
bool resetOpenOnNewTradingDay;
//
// This block should always be set to the follwong values
//
bool showNextBarLevels = false;
color HighThresholdIndicatorColor = clrNONE;
color LowThresholdIndicatorColor = clrNONE;
bool showCurrentBarOpenTime = false;
color InfoTextColor = clrNONE;
bool UseSoundSignalOnNewBar = false;
bool OnlySignalReversalBars = false;
bool UseAlertWindow = false;
bool SendPushNotifications = false;
string SoundFileBull = "";
string SoundFileBear = "";
bool UsedInEA = true; // This should always be set to TRUE for EAs & Indicators
//
//
//
bool MA1on;
int MA1period;
ENUM_MA_METHOD MA1method;
ENUM_APPLIED_PRICE MA1applyTo;
int MA1shift;
bool MA2on;
int MA2period;
ENUM_MA_METHOD MA2method;
ENUM_APPLIED_PRICE MA2applyTo;
int MA2shift;
ENUM_CHANNEL_TYPE ShowChannel;
int DonchianPeriod;
ENUM_APPLIED_PRICE BBapplyTo;
int BollingerBandsPeriod;
double BollingerBandsDeviations;
int SuperTrendPeriod = 10;
double SuperTrendMultiplier=1.7;
#endif
struct RANGEBAR_SETTINGS
{
int barSizeInTicks;
bool useTickVolume;
datetime _startFromDateTime;
bool resetOpenOnNewTradingDay;
bool MA1on;
int MA1period;
ENUM_MA_METHOD MA1method;
ENUM_APPLIED_PRICE MA1applyTo;
int MA1shift;
bool MA2on;
int MA2period;
ENUM_MA_METHOD MA2method;
ENUM_APPLIED_PRICE MA2applyTo;
int MA2shift;
ENUM_CHANNEL_TYPE ShowChannel;
int DonchianPeriod;
ENUM_APPLIED_PRICE BBapplyTo;
int BollingerBandsPeriod;
double BollingerBandsDeviations;
int SuperTrendPeriod;
double SuperTrendMultiplier;
};
class RangeBarSettings
{
protected:
string settingsFileName;
RANGEBAR_SETTINGS settings;
public:
RangeBarSettings(void);
~RangeBarSettings(void);
void Save(void);
bool Load(void);
void Delete(void);
bool Changed(void);
RANGEBAR_SETTINGS Get(void);
void Debug(void);
};
void RangeBarSettings::RangeBarSettings(void)
{
this.settingsFileName = "RangeBars"+(string)ChartID()+".set";
}
void RangeBarSettings::~RangeBarSettings(void)
{
}
void RangeBarSettings::Save(void)
{
settings.barSizeInTicks = barSizeInTicks;
settings.useTickVolume = useTickVolume;
settings._startFromDateTime = startFromDateTime;
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
settings.MA1on = MA1on;
settings.MA1period = MA1period;
settings.MA1method = MA1method;
settings.MA1applyTo = MA1applyTo;
settings.MA1shift = MA1shift;
settings.MA2on = MA2on;
settings.MA2period = MA2period;
settings.MA2method = MA2method;
settings.MA2applyTo = MA2applyTo;
settings.MA2shift = MA2shift;
settings.ShowChannel = ShowChannel;
settings.DonchianPeriod = DonchianPeriod;
settings.BBapplyTo = BBapplyTo;
settings.BollingerBandsPeriod = BollingerBandsPeriod;
settings.BollingerBandsDeviations = BollingerBandsDeviations;
settings.SuperTrendPeriod = SuperTrendPeriod;
settings.SuperTrendMultiplier = SuperTrendMultiplier;
if(MQLInfoInteger((int)MQL5_TESTING))
return;
this.Delete();
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN);
FileWriteStruct(handle,this.settings);
FileClose(handle);
}
void RangeBarSettings::Delete(void)
{
if(FileIsExist(this.settingsFileName))
FileDelete(this.settingsFileName);
}
bool RangeBarSettings::Load(void)
{
#ifdef SHOW_INDICATOR_INPUTS
this.settings.barSizeInTicks = barSizeInTicks;
this.settings.useTickVolume = useTickVolume;
this.settings._startFromDateTime = _startFromDateTime;
this.settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
this.settings.MA1on = MA1on;
this.settings.MA1period = MA1period;
this.settings.MA1method = MA1method;
this.settings.MA1applyTo = MA1applyTo;
this.settings.MA1shift = MA1shift;
this.settings.MA2on = MA2on;
this.settings.MA2period = MA2period;
this.settings.MA2method = MA2method;
this.settings.MA2applyTo = MA2applyTo;
this.settings.MA2shift = MA2shift;
this.settings.ShowChannel = ShowChannel;
this.settings.DonchianPeriod = DonchianPeriod;
this.settings.BBapplyTo = BBapplyTo;
this.settings.BollingerBandsPeriod = BollingerBandsPeriod;
this.settings.BollingerBandsDeviations = BollingerBandsDeviations;
this.settings.SuperTrendPeriod = SuperTrendPeriod;
this.settings.SuperTrendMultiplier = SuperTrendMultiplier;
return true;
#else
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
if(handle == INVALID_HANDLE)
return false;
if(FileReadStruct(handle,this.settings) <= 0)
{
Print("Failed loading settigns!");
FileClose(handle);
return false;
}
// this.Debug();
FileClose(handle);
return true;
#endif
}
RANGEBAR_SETTINGS RangeBarSettings::Get(void)
{
this.Debug();
return this.settings;
}
bool RangeBarSettings::Changed(void)
{
if(MQLInfoInteger((int)MQL5_TESTING))
return false;
static datetime prevFileTime = 0;
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE);
FileClose(handle);
if(prevFileTime != currFileTime)
{
prevFileTime = currFileTime;
return true;
}
return false;
}
void RangeBarSettings::Debug(void)
{
Print("RangeBars settings:");
Print("barSizeInTicks = "+(string)settings.barSizeInTicks);
Print("useTickVolume = "+(string)settings.useTickVolume);
Print("startFromDateTime = "+(string)settings._startFromDateTime);
Print("resetOpenOnNewTradingDay = "+(string)settings.resetOpenOnNewTradingDay);
Print("MA1on = "+(string)settings.MA1on);
Print("MA1period = "+(string)settings.MA1period);
Print("MA1method = "+(string)settings.MA1method);
Print("MA1applyTo = "+(string)settings.MA1applyTo);
Print("MA1shift = "+(string)settings.MA1shift);
Print("MA2on = "+(string)settings.MA2on);
Print("MA2period = "+(string)settings.MA2period);
Print("MA2method = "+(string)settings.MA2method);
Print("MA2applyTo = "+(string)settings.MA2applyTo);
Print("MA2shift = "+(string)settings.MA1shift);
Print("ShowChannel = "+(string)settings.ShowChannel);
Print("DonchianPeriod = "+(string)settings.DonchianPeriod);
Print("BBapplyTo = "+(string)settings.BBapplyTo);
Print("BBperiod = "+(string)settings.BollingerBandsPeriod);
Print("BBdeviations = "+(string)settings.BollingerBandsDeviations);
Print("SuperTrendPeriod = "+(string)settings.SuperTrendPeriod);
Print("SuperTrendMultiplier = "+(string)settings.SuperTrendMultiplier);
Print("UsedInEA = "+(string)UsedInEA);
}