Update to version 2.02
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "2.03"
|
||||
#property version "2.05"
|
||||
#property description "Example EA showing the way to use the RangeBars class defined in RangeBars.mqh"
|
||||
|
||||
//
|
||||
@@ -11,14 +11,13 @@
|
||||
// the RangeBars indicator attached.
|
||||
//
|
||||
|
||||
#define SHOW_INDICATOR_INPUTS
|
||||
//#define SHOW_INDICATOR_INPUTS
|
||||
|
||||
//
|
||||
// You need to include the rangeBars.mqh header file
|
||||
// You need to include the RangeBars.mqh header file
|
||||
//
|
||||
|
||||
#include <RangeBars.mqh>
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBars.mqh>
|
||||
//
|
||||
// To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars)
|
||||
// and call the Init() method in your EA's OnInit() function.
|
||||
@@ -64,7 +63,7 @@ void OnDeinit(const int reason)
|
||||
}
|
||||
|
||||
//
|
||||
// At this point you may use the rangebars data fetching methods in your EA.
|
||||
// At this point you may use the range bars data fetching methods in your EA.
|
||||
// Brief demonstration presented below in the OnTick() function:
|
||||
//
|
||||
|
||||
@@ -107,7 +106,8 @@ void OnTick()
|
||||
// MA1[2] contains the 1st moving average value for the 2nd bar to the left from the latest (uncompleted) bar
|
||||
// MA1[3]..MA1[n] do not exist since we retrieved the values for 3 bars (defined by "numnberOfBars")
|
||||
//
|
||||
// The values for the 2nd moving average are stored in MA2[] and are accessed identically to values of MA1[] (shown above)
|
||||
// The values for the 2nd and 3rd moving average are stored in MA2[] & MA3[]
|
||||
// and are accessed identically to values of MA1[] (shown above)
|
||||
}
|
||||
|
||||
//
|
||||
@@ -117,25 +117,68 @@ void OnTick()
|
||||
//
|
||||
|
||||
MqlRates RangeBarRatesInfoArray[]; // This array will store the MqlRates data for range bars
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
numberOfBars = 2; // gat a total of 2 MqlRates values (for 2 bars starting from bar 1 (last completed))
|
||||
startAtBar = 0; // get values starting from the last completed bar.
|
||||
numberOfBars = 3; // gat a total of 3 MqlRates values (for 3 bars starting from bar 0 (current uncompleted))
|
||||
|
||||
if(rangeBars.GetMqlRates(RangeBarRatesInfoArray,startAtBar,numberOfBars))
|
||||
{
|
||||
{
|
||||
//
|
||||
// Check if a range bars reversal bar has formed
|
||||
// Check if a range bar reversal bar has formed
|
||||
//
|
||||
|
||||
string infoString;
|
||||
|
||||
if((RangeBarRatesInfoArray[0].open < RangeBarRatesInfoArray[0].close) &&
|
||||
(RangeBarRatesInfoArray[1].open > RangeBarRatesInfoArray[1].close))
|
||||
if((RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close) &&
|
||||
(RangeBarRatesInfoArray[2].open > RangeBarRatesInfoArray[2].close))
|
||||
{
|
||||
// bullish reversal
|
||||
infoString = "Previous bar formed bullish reversal";
|
||||
}
|
||||
else if((RangeBarRatesInfoArray[0].open > RangeBarRatesInfoArray[0].close) &&
|
||||
(RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close))
|
||||
else if((RangeBarRatesInfoArray[1].open > RangeBarRatesInfoArray[1].close) &&
|
||||
(RangeBarRatesInfoArray[2].open < RangeBarRatesInfoArray[2].close))
|
||||
{
|
||||
// bearish reversal
|
||||
infoString = "Previous bar formed bearish reversal";
|
||||
}
|
||||
else
|
||||
{
|
||||
infoString = "";
|
||||
}
|
||||
|
||||
//
|
||||
// Output some data to chart
|
||||
//
|
||||
|
||||
Comment("\nNew bar opened on "+(string)RangeBarRatesInfoArray[0].time+
|
||||
"\nPrevious bar OPEN price:"+DoubleToString(RangeBarRatesInfoArray[1].open,_Digits)+", bar opened on "+(string)RangeBarRatesInfoArray[1].time+
|
||||
"\n"+infoString+
|
||||
"\n");
|
||||
}
|
||||
|
||||
//
|
||||
// All charts that contain real volume information (i.e. stocks, futures, ...)
|
||||
// also contain the brekdown of volume into BUY, SELL and BUY/SELL volume.
|
||||
// This data is accessed using the
|
||||
// GetBuySellVolumeBreakdown(long &buy[], long &sell[], long &buySell[], int start, int count)
|
||||
// method. Example below:
|
||||
|
||||
double buyVolume[]; // This array will store the values of the BUY volume
|
||||
double sellVolume[]; // This array will store the values of the SELL volume
|
||||
double buySellVolume[]; // This array will store the values of the BUY/SELL volume
|
||||
|
||||
// When you add BUY, SELL and BUY/SELL volume numbers for a bar they will be equal
|
||||
// to the Real Volume number that can be accessed using the
|
||||
// GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
|
||||
// metod described above.
|
||||
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
numberOfBars = 2; // gat a total of 2 values (for 2 bars starting from bar 1 (last completed))
|
||||
|
||||
if(rangeBars.GetBuySellVolumeBreakdown(buyVolume,sellVolume,buySellVolume,startAtBar,numberOfBars))
|
||||
{
|
||||
//
|
||||
// Apply your real volume analysis logic here...
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
@@ -147,7 +190,8 @@ void OnTick()
|
||||
double HighArray[]; // This array will store the values of the high band
|
||||
double MidArray[]; // This array will store the values of the middle band
|
||||
double LowArray[]; // This array will store the values of the low band
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
numberOfBars = 20; // gat a total of 20 values (for 20 bars starting from bar 1 (last completed))
|
||||
|
||||
if(rangeBars.GetDonchian(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
|
||||
@@ -167,7 +211,7 @@ void OnTick()
|
||||
// MidArray[] array will store the values of the middle band
|
||||
// LowArray[] array will store the values of the low band
|
||||
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
numberOfBars = 10; // gat a total of 10 values (for 10 bars starting from bar 1 (last completed))
|
||||
|
||||
if(rangeBars.GetBollingerBands(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
|
||||
@@ -187,7 +231,7 @@ void OnTick()
|
||||
// MidArray[] array will store the values of the SuperTrend value
|
||||
// LowArray[] array will store the values of the low SuperTrend line
|
||||
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
startAtBar = 1; // get values starting from the last completed bar.
|
||||
numberOfBars = 3; // gat a total of 3 values (for 3 bars starting from bar 1 (last completed))
|
||||
|
||||
if(rangeBars.GetSuperTrend(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
|
||||
@@ -0,0 +1,233 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "1.00"
|
||||
#property description "Example EA: Trading based on RangeBars SuperTrend signals."
|
||||
#property description "One trade at a time. Each trade has TP & SL"
|
||||
|
||||
//
|
||||
// Helper functions for placing market orders.
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
||||
|
||||
//
|
||||
// Inputs
|
||||
//
|
||||
|
||||
input double InpLotSize = 0.1;
|
||||
input int InpSLPoints = 200;
|
||||
input int InpTPPoints = 600;
|
||||
|
||||
input ulong InpMagicNumber=5150;
|
||||
input ulong InpDeviationPoints = 0;
|
||||
input int InpNumberOfRetries = 50;
|
||||
input int InpBusyTimeout_ms = 1000;
|
||||
input int InpRequoteTimeout_ms = 250;
|
||||
|
||||
//
|
||||
// Globa variables
|
||||
//
|
||||
|
||||
ENUM_POSITION_TYPE Signal;
|
||||
ulong currentTicket;
|
||||
|
||||
//
|
||||
// SHOW_INDICATOR_INPUTS *NEEDS* to be defined, if the EA needs to be *tested in MT5's backtester*
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Using '#define SHOW_INDICATOR_INPUTS' will show the RangeBars indicator's inputs
|
||||
// NOT using the '#define SHOW_INDICATOR_INPUTS' statement will read the settigns a chart with
|
||||
// the RangeBars indicator attached.
|
||||
//
|
||||
|
||||
//#define SHOW_INDICATOR_INPUTS
|
||||
|
||||
//
|
||||
// You need to include the RangeBars.mqh header file
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBars.mqh>
|
||||
//
|
||||
// To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars)
|
||||
// and call the Init() method in your EA's OnInit() function.
|
||||
// Don't forget to release the indicator when you're done by calling the Deinit() method.
|
||||
// Example shown in OnInit & OnDeinit functions below:
|
||||
//
|
||||
|
||||
RangeBars * rangeBars;
|
||||
CMarketOrder * marketOrder;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
rangeBars = new RangeBars();
|
||||
if(rangeBars == NULL)
|
||||
return(INIT_FAILED);
|
||||
|
||||
rangeBars.Init();
|
||||
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
||||
return(INIT_FAILED);
|
||||
|
||||
//
|
||||
// Init MarketOrder class - used for placing market ortders.
|
||||
//
|
||||
|
||||
CMarketOrderParameters params;
|
||||
{
|
||||
params.m_async_mode = false;
|
||||
params.m_magic = InpMagicNumber;
|
||||
params.m_deviation = InpDeviationPoints;
|
||||
params.m_type_filling = ORDER_FILLING_FOK;
|
||||
|
||||
params.numberOfRetries = InpNumberOfRetries;
|
||||
params.busyTimeout_ms = InpBusyTimeout_ms;
|
||||
params.requoteTimeout_ms = InpRequoteTimeout_ms;
|
||||
}
|
||||
marketOrder = new CMarketOrder(params);
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if(rangeBars != NULL)
|
||||
{
|
||||
rangeBars.Deinit();
|
||||
delete rangeBars;
|
||||
}
|
||||
|
||||
//
|
||||
// delete MarketOrder class
|
||||
//
|
||||
|
||||
if(marketOrder != NULL)
|
||||
{
|
||||
delete marketOrder;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// At this point you may use the range bar data fetching methods in your EA.
|
||||
// Brief demonstration presented below in the OnTick() function:
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
// It is considered good trading & EA coding practice to perform calculations
|
||||
// when a new bar is fully formed.
|
||||
// The IsNewBar() method is used for checking if a new range bar has formed
|
||||
//
|
||||
|
||||
if(rangeBars.IsNewBar())
|
||||
{
|
||||
|
||||
//
|
||||
// Getting SuperTrend values is done using the
|
||||
// GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
|
||||
// method. Example below:
|
||||
//
|
||||
|
||||
double HighArray[]; // This array will store the values of the high SuperTrend line
|
||||
double MidArray[]; // This array will store the values of the middle SuperTrend line
|
||||
double LowArray[]; // This array will store the values of the low SuperTrend line
|
||||
|
||||
int startAtBar = 1; // get values starting from the last completed bar.
|
||||
int numberOfBars = 2; // gat a total of 3 values (for 3 bars starting from bar 1 (last completed))
|
||||
|
||||
if(rangeBars.GetSuperTrend(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
|
||||
{
|
||||
//
|
||||
// Read signal bar's time for optional debug log
|
||||
//
|
||||
|
||||
string barTime = "";
|
||||
MqlRates RangeBarRatesInfoArray[]; // This array will store the MqlRates data for range bars
|
||||
if(rangeBars.GetMqlRates(RangeBarRatesInfoArray,startAtBar,numberOfBars))
|
||||
barTime = (string)RangeBarRatesInfoArray[0].time;
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if(SuperTrendSignal(HighArray,MidArray,LowArray,Signal,barTime))
|
||||
{
|
||||
if(Signal == POSITION_TYPE_NONE)
|
||||
return;
|
||||
|
||||
//
|
||||
// Trade signal on the SuperTrend indicator
|
||||
// Open trade only if there are currntly no active trades
|
||||
//
|
||||
|
||||
if(!marketOrder.IsOpen(currentTicket,_Symbol,InpMagicNumber))
|
||||
{
|
||||
if(Signal == POSITION_TYPE_BUY)
|
||||
{
|
||||
Print("BUY signal at "+barTime); // optional debug log
|
||||
|
||||
if(marketOrder.Long(_Symbol,InpLotSize,InpSLPoints,InpTPPoints))
|
||||
Print("Long position opened.");
|
||||
}
|
||||
else if(Signal == POSITION_TYPE_SELL)
|
||||
{
|
||||
Print("SELL singal at "+barTime); // optional debug log
|
||||
|
||||
if(marketOrder.Short(_Symbol,InpLotSize,InpSLPoints,InpTPPoints))
|
||||
Print("Short position opened.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Function determines the trade signal on the SuperTrend indicator
|
||||
//
|
||||
|
||||
bool SuperTrendSignal(double &H[], double &M[], double &L[], ENUM_POSITION_TYPE &signal,string time)
|
||||
{
|
||||
if((H[1] == 0) && (L[1] == 0)) // no data to process
|
||||
{
|
||||
signal = POSITION_TYPE_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Uncomment line below for optional debug output:
|
||||
//Print(time+": H[1] = "+DoubleToString(H[1],_Digits)+" L[0] = "+DoubleToString(L[0],_Digits)+" | L[1] = "+DoubleToString(L[1],_Digits)+" H[0] = "+DoubleToString(H[0],_Digits));
|
||||
|
||||
if((H[1] == M[1]) && (L[0] == M[0]))
|
||||
{
|
||||
//
|
||||
// Super trend shifted from Low to High band => Buy Signal
|
||||
//
|
||||
|
||||
signal = POSITION_TYPE_BUY;
|
||||
return true;
|
||||
}
|
||||
else if((L[1] == M[1]) && (H[0] == M[0]))
|
||||
{
|
||||
//
|
||||
// Super trend shifted from High to Low band => Sell Signal
|
||||
//
|
||||
|
||||
signal = POSITION_TYPE_SELL;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// No signal detected
|
||||
//
|
||||
|
||||
signal = POSITION_TYPE_NONE;
|
||||
return false;
|
||||
}
|
||||
Binary file not shown.
@@ -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];
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 ¶ms);
|
||||
~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 ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| ADX.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Average Directional Movement Index"
|
||||
#include <MovingAverages.mqh>
|
||||
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 3
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 LightSeaGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 YellowGreen
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 Wheat
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
#property indicator_label1 "ADX"
|
||||
#property indicator_label2 "+DI"
|
||||
#property indicator_label3 "-DI"
|
||||
//--- input parameters
|
||||
input int InpPeriodADX=14; // Period
|
||||
//---- buffers
|
||||
double ExtADXBuffer[];
|
||||
double ExtPDIBuffer[];
|
||||
double ExtNDIBuffer[];
|
||||
double ExtPDBuffer[];
|
||||
double ExtNDBuffer[];
|
||||
double ExtTmpBuffer[];
|
||||
//--- global variables
|
||||
int ExtADXPeriod;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- check for input parameters
|
||||
if(InpPeriodADX>=100 || InpPeriodADX<=0)
|
||||
{
|
||||
ExtADXPeriod=14;
|
||||
printf("Incorrect value for input variable Period_ADX=%d. Indicator will use value=%d for calculations.",InpPeriodADX,ExtADXPeriod);
|
||||
}
|
||||
else ExtADXPeriod=InpPeriodADX;
|
||||
//---- indicator buffers
|
||||
SetIndexBuffer(0,ExtADXBuffer);
|
||||
SetIndexBuffer(1,ExtPDIBuffer);
|
||||
SetIndexBuffer(2,ExtNDIBuffer);
|
||||
SetIndexBuffer(3,ExtPDBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4,ExtNDBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(5,ExtTmpBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- indicator digits
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
||||
//--- set draw begin
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtADXPeriod<<1);
|
||||
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtADXPeriod);
|
||||
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtADXPeriod);
|
||||
//--- indicator short name
|
||||
string short_name="ADX("+string(ExtADXPeriod)+")";
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
//--- change 1-st index label
|
||||
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||
//---- end of initialization function
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- checking for bars count
|
||||
if(rates_total<ExtADXPeriod)
|
||||
return(0);
|
||||
//--- detect start position
|
||||
int start;
|
||||
if(_prev_calculated>1) start=_prev_calculated-1;
|
||||
else
|
||||
{
|
||||
start=1;
|
||||
ExtPDIBuffer[0]=0.0;
|
||||
ExtNDIBuffer[0]=0.0;
|
||||
ExtADXBuffer[0]=0.0;
|
||||
}
|
||||
//--- main cycle
|
||||
for(int i=start;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
//--- get some data
|
||||
double Hi =rangeBarsIndicator.High[i];
|
||||
double prevHi=rangeBarsIndicator.High[i-1];
|
||||
double Lo =rangeBarsIndicator.Low[i];
|
||||
double prevLo=rangeBarsIndicator.Low[i-1];
|
||||
double prevCl=rangeBarsIndicator.Close[i-1];
|
||||
//--- fill main positive and main negative buffers
|
||||
double dTmpP=Hi-prevHi;
|
||||
double dTmpN=prevLo-Lo;
|
||||
if(dTmpP<0.0) dTmpP=0.0;
|
||||
if(dTmpN<0.0) dTmpN=0.0;
|
||||
if(dTmpP>dTmpN) dTmpN=0.0;
|
||||
else
|
||||
{
|
||||
if(dTmpP<dTmpN) dTmpP=0.0;
|
||||
else
|
||||
{
|
||||
dTmpP=0.0;
|
||||
dTmpN=0.0;
|
||||
}
|
||||
}
|
||||
//--- define TR
|
||||
double tr=MathMax(MathMax(MathAbs(Hi-Lo),MathAbs(Hi-prevCl)),MathAbs(Lo-prevCl));
|
||||
//---
|
||||
if(tr!=0.0)
|
||||
{
|
||||
ExtPDBuffer[i]=100.0*dTmpP/tr;
|
||||
ExtNDBuffer[i]=100.0*dTmpN/tr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtPDBuffer[i]=0.0;
|
||||
ExtNDBuffer[i]=0.0;
|
||||
}
|
||||
//--- fill smoothed positive and negative buffers
|
||||
ExtPDIBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtPDIBuffer[i-1],ExtPDBuffer);
|
||||
ExtNDIBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtNDIBuffer[i-1],ExtNDBuffer);
|
||||
//--- fill ADXTmp buffer
|
||||
double dTmp=ExtPDIBuffer[i]+ExtNDIBuffer[i];
|
||||
if(dTmp!=0.0)
|
||||
dTmp=100.0*MathAbs((ExtPDIBuffer[i]-ExtNDIBuffer[i])/dTmp);
|
||||
else
|
||||
dTmp=0.0;
|
||||
ExtTmpBuffer[i]=dTmp;
|
||||
//--- fill smoothed ADX buffer
|
||||
ExtADXBuffer[i]=ExponentialMA(i,ExtADXPeriod,ExtADXBuffer[i-1],ExtTmpBuffer);
|
||||
}
|
||||
//---- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,168 @@
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| CCI.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Commodity Channel Index"
|
||||
#include <MovingAverages.mqh>
|
||||
//---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 LightSeaGreen
|
||||
#property indicator_level1 -100.0
|
||||
#property indicator_level2 100.0
|
||||
#property indicator_applied_price PRICE_TYPICAL
|
||||
//--- input parametrs
|
||||
input int InpCCIPeriod=14; // Period
|
||||
input ENUM_APPLIED_PRICE InpApplyToPrice= PRICE_CLOSE; // Apply to
|
||||
//--- global variable
|
||||
int ExtCCIPeriod;
|
||||
//---- indicator buffer
|
||||
double ExtSPBuffer[];
|
||||
double ExtDBuffer[];
|
||||
double ExtMBuffer[];
|
||||
double ExtCCIBuffer[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
|
||||
//
|
||||
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||
//
|
||||
|
||||
rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- check for input value of period
|
||||
if(InpCCIPeriod<=0)
|
||||
{
|
||||
ExtCCIPeriod=14;
|
||||
printf("Incorrect value for input variable InpCCIPeriod=%d. Indicator will use value=%d for calculations.",InpCCIPeriod,ExtCCIPeriod);
|
||||
}
|
||||
else ExtCCIPeriod=InpCCIPeriod;
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0,ExtCCIBuffer);
|
||||
SetIndexBuffer(1,ExtDBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2,ExtMBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3,ExtSPBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"CCI("+string(ExtCCIPeriod)+")");
|
||||
//--- indexes draw begin settings
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtCCIPeriod-1);
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
||||
//---- OnInit done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
/*
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const int begin,
|
||||
const double &price[])
|
||||
{
|
||||
*/
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- variables
|
||||
int i,j;
|
||||
double dTmp,dMul=0.015/ExtCCIPeriod;
|
||||
//--- start calculation
|
||||
int StartCalcPosition=(ExtCCIPeriod-1);//+begin;
|
||||
//--- check for bars count
|
||||
if(rates_total<StartCalcPosition)
|
||||
return(0);
|
||||
//--- correct draw begin
|
||||
// if(begin>0) PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(ExtCCIPeriod-1));
|
||||
//--- calculate position
|
||||
int pos=_prev_calculated-1;
|
||||
if(pos<StartCalcPosition)
|
||||
pos=StartCalcPosition;
|
||||
//--- main cycle
|
||||
for(i=pos;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
//--- SMA on price buffer
|
||||
ExtSPBuffer[i]=SimpleMA(i,ExtCCIPeriod,rangeBarsIndicator.Price);
|
||||
//--- calculate D
|
||||
dTmp=0.0;
|
||||
for(j=0;j<ExtCCIPeriod;j++) dTmp+=MathAbs(rangeBarsIndicator.Price[i-j]-ExtSPBuffer[i]);
|
||||
ExtDBuffer[i]=dTmp*dMul;
|
||||
//--- calculate M
|
||||
ExtMBuffer[i]=rangeBarsIndicator.Price[i]-ExtSPBuffer[i];
|
||||
//--- calculate CCI
|
||||
if(ExtDBuffer[i]!=0.0) ExtCCIBuffer[i]=ExtMBuffer[i]/ExtDBuffer[i];
|
||||
else ExtCCIBuffer[i]=0.0;
|
||||
//---
|
||||
}
|
||||
//---- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,134 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fractals.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color1 Gray
|
||||
#property indicator_color2 Gray
|
||||
#property indicator_label1 "Fractal Up"
|
||||
#property indicator_label2 "Fractal Down"
|
||||
//---- indicator buffers
|
||||
double ExtUpperBuffer[];
|
||||
double ExtLowerBuffer[];
|
||||
//--- 10 pixels upper from high price
|
||||
int ExtArrowShift=-10;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//---- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtUpperBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ExtLowerBuffer,INDICATOR_DATA);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//---- sets first bar from what index will be drawn
|
||||
PlotIndexSetInteger(0,PLOT_ARROW,217);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW,218);
|
||||
//---- arrow shifts when drawing
|
||||
PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,ExtArrowShift);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-ExtArrowShift);
|
||||
//---- sets drawing line empty value--
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
||||
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
||||
//---- initialization done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Accelerator/Decelerator Oscillator |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int i,limit;
|
||||
//---
|
||||
if(rates_total<5)
|
||||
return(0);
|
||||
//---
|
||||
if(_prev_calculated<7)
|
||||
{
|
||||
limit=2;
|
||||
//--- clean up arrays
|
||||
ArrayInitialize(ExtUpperBuffer,EMPTY_VALUE);
|
||||
ArrayInitialize(ExtLowerBuffer,EMPTY_VALUE);
|
||||
}
|
||||
else limit=rates_total-5;
|
||||
|
||||
for(i=limit; i<rates_total-3 && !IsStopped();i++)
|
||||
{
|
||||
//---- Upper Fractal
|
||||
if(rangeBarsIndicator.High[i]>rangeBarsIndicator.High[i+1] && rangeBarsIndicator.High[i]>rangeBarsIndicator.High[i+2] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-1] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-2])
|
||||
ExtUpperBuffer[i]=rangeBarsIndicator.High[i];
|
||||
else ExtUpperBuffer[i]=EMPTY_VALUE;
|
||||
|
||||
//---- Lower Fractal
|
||||
if(rangeBarsIndicator.Low[i]<rangeBarsIndicator.Low[i+1] && rangeBarsIndicator.Low[i]<rangeBarsIndicator.Low[i+2] && rangeBarsIndicator.Low[i]<=rangeBarsIndicator.Low[i-1] && rangeBarsIndicator.Low[i]<=rangeBarsIndicator.Low[i-2])
|
||||
ExtLowerBuffer[i]=rangeBarsIndicator.Low[i];
|
||||
else ExtLowerBuffer[i]=EMPTY_VALUE;
|
||||
}
|
||||
//--- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,175 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gann_Hi_Lo_Activator_SSL.mq5 |
|
||||
//| avoitenko |
|
||||
//| https://login.mql5.com/en/users/avoitenko |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright ""
|
||||
#property link "https://login.mql5.com/en/users/avoitenko"
|
||||
#property version "1.00"
|
||||
#property description "Author: Kalenzo"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 1
|
||||
//--- output line
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrDodgerBlue, clrOrangeRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
#property indicator_label1 "GHL (13, SMMA)"
|
||||
//--- input parameters
|
||||
input uint InpPeriod=13; // Period
|
||||
input ENUM_MA_METHOD InpMethod=MODE_SMMA;// Method
|
||||
//--- buffers
|
||||
double GannBuffer[];
|
||||
double ColorBuffer[];
|
||||
double MaHighBuffer[];
|
||||
double MaLowBuffer[];
|
||||
double TrendBuffer[];
|
||||
//--- global vars
|
||||
int ma_high_handle;
|
||||
int ma_low_handle;
|
||||
int period;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check period
|
||||
period=(int)fmax(InpPeriod,2);
|
||||
//--- set buffers
|
||||
SetIndexBuffer(0,GannBuffer);
|
||||
SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
|
||||
SetIndexBuffer(2,MaHighBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3,MaLowBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4,TrendBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- set direction
|
||||
ArraySetAsSeries(GannBuffer,true);
|
||||
ArraySetAsSeries(ColorBuffer,true);
|
||||
ArraySetAsSeries(MaHighBuffer,true);
|
||||
ArraySetAsSeries(MaLowBuffer,true);
|
||||
ArraySetAsSeries(TrendBuffer,true);
|
||||
//--- get handles
|
||||
ma_high_handle=iMA(NULL,0,period,0,InpMethod,PRICE_HIGH);
|
||||
ma_low_handle =iMA(NULL,0,period,0,InpMethod,PRICE_LOW);
|
||||
if(ma_high_handle==INVALID_HANDLE || ma_low_handle==INVALID_HANDLE)
|
||||
{
|
||||
Print("Unable to create handle for iMA");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
//--- set indicator properties
|
||||
string short_name=StringFormat("Gann High-Low Activator SSL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5));
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- set label
|
||||
short_name=StringFormat("GHL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5));
|
||||
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||
//--- done
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
|
||||
if(rates_total<period+1)return(0);
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
ArraySetAsSeries(rangeBarsIndicator.Close,true);
|
||||
//---
|
||||
int limit;
|
||||
if(rates_total<_prev_calculated || _prev_calculated<=0)
|
||||
{
|
||||
limit=rates_total-period-1;
|
||||
ArrayInitialize(GannBuffer,EMPTY_VALUE);
|
||||
ArrayInitialize(ColorBuffer,0);
|
||||
ArrayInitialize(MaHighBuffer,0);
|
||||
ArrayInitialize(MaLowBuffer,0);
|
||||
ArrayInitialize(TrendBuffer,0);
|
||||
}
|
||||
else
|
||||
limit=rates_total-_prev_calculated;
|
||||
//--- get MA
|
||||
if(CopyBuffer(ma_high_handle,0,0,limit+1,MaHighBuffer)!=limit+1)return(0);
|
||||
if(CopyBuffer(ma_low_handle,0,0,limit+1,MaLowBuffer)!=limit+1)return(0);
|
||||
//--- main cycle
|
||||
for(int i=limit; i>=0 && !_StopFlag; i--)
|
||||
{
|
||||
TrendBuffer[i]=TrendBuffer[i+1];
|
||||
//---
|
||||
if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)>NormalizeDouble(MaHighBuffer[i+1],_Digits)) TrendBuffer[i]=1;
|
||||
if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)<NormalizeDouble(MaLowBuffer[i+1],_Digits)) TrendBuffer[i]=-1;
|
||||
//---
|
||||
if(TrendBuffer[i]<0)
|
||||
{
|
||||
GannBuffer[i]=MaHighBuffer[i];
|
||||
ColorBuffer[i]=1;
|
||||
}
|
||||
//---
|
||||
if(TrendBuffer[i]>0)
|
||||
{
|
||||
GannBuffer[i]=MaLowBuffer[i];
|
||||
ColorBuffer[i]=0;
|
||||
}
|
||||
}
|
||||
//--- done
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,137 @@
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Heiken_Ashi.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||
#property indicator_color1 DodgerBlue, Red
|
||||
#property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
|
||||
//--- indicator buffers
|
||||
double ExtOBuffer[];
|
||||
double ExtHBuffer[];
|
||||
double ExtLBuffer[];
|
||||
double ExtCBuffer[];
|
||||
double ExtColorBuffer[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX);
|
||||
//---
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- sets first bar from what index will be drawn
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi");
|
||||
//--- sets drawing line empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
//--- initialization done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Heiken Ashi |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
int i,limit;
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- preliminary calculations
|
||||
if(_prev_calculated==0)
|
||||
{
|
||||
//--- set first candle
|
||||
ExtLBuffer[0]=rangeBarsIndicator.Low[0];
|
||||
ExtHBuffer[0]=rangeBarsIndicator.High[0];
|
||||
ExtOBuffer[0]=rangeBarsIndicator.Open[0];
|
||||
ExtCBuffer[0]=rangeBarsIndicator.Close[0];
|
||||
limit=1;
|
||||
}
|
||||
else limit=_prev_calculated-1;
|
||||
|
||||
//--- the main loop of calculations
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
double haOpen=(ExtOBuffer[i-1]+ExtCBuffer[i-1])/2;
|
||||
double haClose=(rangeBarsIndicator.Open[i]+rangeBarsIndicator.High[i]+rangeBarsIndicator.Low[i]+rangeBarsIndicator.Close[i])/4;
|
||||
double haHigh=MathMax(rangeBarsIndicator.High[i],MathMax(haOpen,haClose));
|
||||
double haLow=MathMin(rangeBarsIndicator.Low[i],MathMin(haOpen,haClose));
|
||||
|
||||
ExtLBuffer[i]=haLow;
|
||||
ExtHBuffer[i]=haHigh;
|
||||
ExtOBuffer[i]=haOpen;
|
||||
ExtCBuffer[i]=haClose;
|
||||
|
||||
//--- set candle color
|
||||
if(haOpen<haClose) ExtColorBuffer[i]=0.0; // set color DodgerBlue
|
||||
else ExtColorBuffer[i]=1.0; // set color Red
|
||||
}
|
||||
//--- done
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,179 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Ichimoku.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Ichimoku Kinko Hyo"
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 4
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_type3 DRAW_FILLING
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color1 Red
|
||||
#property indicator_color2 Blue
|
||||
#property indicator_color3 SandyBrown,Thistle
|
||||
#property indicator_color4 Lime
|
||||
#property indicator_label1 "Tenkan-sen"
|
||||
#property indicator_label2 "Kijun-sen"
|
||||
#property indicator_label3 "Senkou Span A;Senkou Span B"
|
||||
#property indicator_label4 "Chikou Span"
|
||||
//--- input parameters
|
||||
input int InpTenkan=9; // Tenkan-sen
|
||||
input int InpKijun=26; // Kijun-sen
|
||||
input int InpSenkou=52; // Senkou Span B
|
||||
//--- indicator buffers
|
||||
double ExtTenkanBuffer[];
|
||||
double ExtKijunBuffer[];
|
||||
double ExtSpanABuffer[];
|
||||
double ExtSpanBBuffer[];
|
||||
double ExtChikouBuffer[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtTenkanBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ExtKijunBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,ExtSpanABuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,ExtSpanBBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(4,ExtChikouBuffer,INDICATOR_DATA);
|
||||
//---
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||
//--- sets first bar from what index will be drawn
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpTenkan);
|
||||
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpKijun);
|
||||
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,InpSenkou-1);
|
||||
//--- lines shifts when drawing
|
||||
PlotIndexSetInteger(2,PLOT_SHIFT,InpKijun);
|
||||
PlotIndexSetInteger(3,PLOT_SHIFT,-InpKijun);
|
||||
//--- change labels for DataWindow
|
||||
PlotIndexSetString(0,PLOT_LABEL,"Tenkan-sen("+string(InpTenkan)+")");
|
||||
PlotIndexSetString(1,PLOT_LABEL,"Kijun-sen("+string(InpKijun)+")");
|
||||
PlotIndexSetString(2,PLOT_LABEL,"Senkou Span A;Senkou Span B("+string(InpSenkou)+")");
|
||||
//--- initialization done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| get highest value for range |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double&array[],int range,int fromIndex)
|
||||
{
|
||||
double res=0;
|
||||
//---
|
||||
res=array[fromIndex];
|
||||
for(int i=fromIndex;i>fromIndex-range && i>=0;i--)
|
||||
{
|
||||
if(res<array[i]) res=array[i];
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| get lowest value for range |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double&array[],int range,int fromIndex)
|
||||
{
|
||||
double res=0;
|
||||
//---
|
||||
res=array[fromIndex];
|
||||
for(int i=fromIndex;i>fromIndex-range && i>=0;i--)
|
||||
{
|
||||
if(res>array[i]) res=array[i];
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Ichimoku Kinko Hyo |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int limit;
|
||||
//---
|
||||
if(_prev_calculated==0) limit=0;
|
||||
else limit=_prev_calculated-1;
|
||||
//---
|
||||
for(int i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
ExtChikouBuffer[i]=rangeBarsIndicator.Close[i];
|
||||
//--- tenkan sen
|
||||
double _high=Highest(rangeBarsIndicator.High,InpTenkan,i);
|
||||
double _low=Lowest(rangeBarsIndicator.Low,InpTenkan,i);
|
||||
ExtTenkanBuffer[i]=(_high+_low)/2.0;
|
||||
//--- kijun sen
|
||||
_high=Highest(rangeBarsIndicator.High,InpKijun,i);
|
||||
_low=Lowest(rangeBarsIndicator.Low,InpKijun,i);
|
||||
ExtKijunBuffer[i]=(_high+_low)/2.0;
|
||||
//--- senkou span a
|
||||
ExtSpanABuffer[i]=(ExtTenkanBuffer[i]+ExtKijunBuffer[i])/2.0;
|
||||
//--- senkou span b
|
||||
_high=Highest(rangeBarsIndicator.High,InpSenkou,i);
|
||||
_low=Lowest(rangeBarsIndicator.Low,InpSenkou,i);
|
||||
ExtSpanBBuffer[i]=(_high+_low)/2.0;
|
||||
}
|
||||
//--- done
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,257 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom Moving Average.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 Red
|
||||
//--- input parameters
|
||||
input int InpMAPeriod=13; // Period
|
||||
input int InpMAShift=0; // Shift
|
||||
input ENUM_MA_METHOD InpMAMethod=MODE_SMMA; // Method
|
||||
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtLineBuffer[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| simple moving average |
|
||||
//+------------------------------------------------------------------+
|
||||
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
||||
{
|
||||
int i,limit;
|
||||
//--- first calculation or number of bars was changed
|
||||
if(prev_calculated==0)// first calculation
|
||||
{
|
||||
limit=InpMAPeriod+begin;
|
||||
//--- set empty value for first limit bars
|
||||
for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;
|
||||
//--- calculate first visible value
|
||||
double firstValue=0;
|
||||
for(i=begin;i<limit;i++)
|
||||
firstValue+=price[i];
|
||||
firstValue/=InpMAPeriod;
|
||||
ExtLineBuffer[limit-1]=firstValue;
|
||||
}
|
||||
else limit=prev_calculated-1;
|
||||
//--- main loop
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod;
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| exponential moving average |
|
||||
//+------------------------------------------------------------------+
|
||||
void CalculateEMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
||||
{
|
||||
int i,limit;
|
||||
double SmoothFactor=2.0/(1.0+InpMAPeriod);
|
||||
//--- first calculation or number of bars was changed
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
limit=InpMAPeriod+begin;
|
||||
ExtLineBuffer[begin]=price[begin];
|
||||
for(i=begin+1;i<limit;i++)
|
||||
ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
|
||||
}
|
||||
else limit=prev_calculated-1;
|
||||
//--- main loop
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| linear weighted moving average |
|
||||
//+------------------------------------------------------------------+
|
||||
void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
||||
{
|
||||
int i,limit;
|
||||
static int weightsum;
|
||||
double sum;
|
||||
//--- first calculation or number of bars was changed
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
weightsum=0;
|
||||
limit=InpMAPeriod+begin;
|
||||
//--- set empty value for first limit bars
|
||||
for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0;
|
||||
//--- calculate first visible value
|
||||
double firstValue=0;
|
||||
for(i=begin;i<limit;i++)
|
||||
{
|
||||
int k=i-begin+1;
|
||||
weightsum+=k;
|
||||
firstValue+=k*price[i];
|
||||
}
|
||||
firstValue/=(double)weightsum;
|
||||
ExtLineBuffer[limit-1]=firstValue;
|
||||
}
|
||||
else limit=prev_calculated-1;
|
||||
//--- main loop
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
sum=0;
|
||||
for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j];
|
||||
ExtLineBuffer[i]=sum/weightsum;
|
||||
}
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| smoothed moving average |
|
||||
//+------------------------------------------------------------------+
|
||||
void CalculateSmoothedMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
||||
{
|
||||
int i,limit;
|
||||
//--- first calculation or number of bars was changed
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
limit=InpMAPeriod+begin;
|
||||
//--- set empty value for first limit bars
|
||||
for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;
|
||||
//--- calculate first visible value
|
||||
double firstValue=0;
|
||||
for(i=begin;i<limit;i++)
|
||||
firstValue+=price[i];
|
||||
firstValue/=InpMAPeriod;
|
||||
ExtLineBuffer[limit-1]=firstValue;
|
||||
}
|
||||
else limit=prev_calculated-1;
|
||||
//--- main loop
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
ExtLineBuffer[i]=(ExtLineBuffer[i-1]*(InpMAPeriod-1)+price[i])/InpMAPeriod;
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
|
||||
//--- set accuracy
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||
//--- sets first bar from what index will be drawn
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod);
|
||||
//---- line shifts when drawing
|
||||
PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
|
||||
//--- name for DataWindow
|
||||
string short_name="unknown ma";
|
||||
switch(InpMAMethod)
|
||||
{
|
||||
case MODE_EMA : short_name="EMA"; break;
|
||||
case MODE_LWMA : short_name="LWMA"; break;
|
||||
case MODE_SMA : short_name="SMA"; break;
|
||||
case MODE_SMMA : short_name="SMMA"; break;
|
||||
}
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(InpMAPeriod)+")");
|
||||
//---- sets drawing line empty value--
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
|
||||
//
|
||||
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||
//
|
||||
|
||||
rangeBarsIndicator.SetUseAppliedPriceFlag(InpAppliedPrice);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//---- initialization done
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving Average |
|
||||
//+------------------------------------------------------------------+
|
||||
/*int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const int begin,
|
||||
const double &price[])
|
||||
{*/
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
int _begin = 0;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- check for bars count
|
||||
if(rates_total<InpMAPeriod-1+_begin)
|
||||
return(0);// not enough bars for calculation
|
||||
|
||||
//--- first calculation or number of bars was changed
|
||||
if(_prev_calculated==0)
|
||||
ArrayInitialize(ExtLineBuffer,0);
|
||||
//--- sets first bar from what index will be draw
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod-1+_begin);
|
||||
|
||||
//--- calculation
|
||||
switch(InpMAMethod)
|
||||
{
|
||||
case MODE_EMA: CalculateEMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
|
||||
case MODE_LWMA: CalculateLWMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
|
||||
case MODE_SMMA: CalculateSmoothedMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
|
||||
case MODE_SMA: CalculateSimpleMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -36,17 +36,17 @@ double ExtSlowMaBuffer[];
|
||||
double ExtMacdBuffer[];
|
||||
|
||||
//
|
||||
// Initialize MedianRenko indicator for data processing
|
||||
// according to settings of the MedianRenko indicator already on chart
|
||||
//
|
||||
//
|
||||
|
||||
#include <RangeBarIndicator.mqh>
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -84,7 +84,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(rangeBarsIndicator.GetPrevCalculated());
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Momentum.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---- indicator settings
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 DodgerBlue
|
||||
//---- input parameters
|
||||
input int InpMomentumPeriod=14; // Period
|
||||
input ENUM_APPLIED_PRICE InpApplyToPrice= PRICE_CLOSE; // Apply to
|
||||
//---- indicator buffers
|
||||
double ExtMomentumBuffer[];
|
||||
//--- global variable
|
||||
int ExtMomentumPeriod;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//
|
||||
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||
//
|
||||
|
||||
rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- check for input value
|
||||
if(InpMomentumPeriod<0)
|
||||
{
|
||||
ExtMomentumPeriod=14;
|
||||
Print("Input parameter InpMomentumPeriod has wrong value. Indicator will use value ",ExtMomentumPeriod);
|
||||
}
|
||||
else ExtMomentumPeriod=InpMomentumPeriod;
|
||||
//---- buffers
|
||||
SetIndexBuffer(0,ExtMomentumBuffer,INDICATOR_DATA);
|
||||
//---- name for DataWindow and indicator subwindow label
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"Momentum"+"("+string(ExtMomentumPeriod)+")");
|
||||
//--- sets first bar from what index will be drawn
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtMomentumPeriod-1);
|
||||
//--- sets drawing line empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
//--- digits
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Momentum |
|
||||
//+------------------------------------------------------------------+
|
||||
/*
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const int begin,
|
||||
const double &price[])
|
||||
{
|
||||
*/
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
|
||||
static int begin = 0;
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- start calculation
|
||||
int StartCalcPosition=(ExtMomentumPeriod-1)+begin;
|
||||
//---- insufficient data
|
||||
if(rates_total<StartCalcPosition)
|
||||
return(0);
|
||||
//--- correct draw begin
|
||||
if(begin>0) PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(ExtMomentumPeriod-1));
|
||||
//--- start working, detect position
|
||||
int pos=_prev_calculated-1;
|
||||
if(pos<StartCalcPosition)
|
||||
pos=begin+ExtMomentumPeriod;
|
||||
//--- main cycle
|
||||
for(int i=pos;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
if(rangeBarsIndicator.Price[i-ExtMomentumPeriod] > 0)
|
||||
ExtMomentumBuffer[i]=rangeBarsIndicator.Price[i]*100/rangeBarsIndicator.Price[i-ExtMomentumPeriod];
|
||||
|
||||
}
|
||||
//--- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,248 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ParabolicSAR.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 DodgerBlue
|
||||
//--- External parametrs
|
||||
input double InpSARStep=0.02; // Step
|
||||
input double InpSARMaximum=0.2; // Maximum
|
||||
//---- buffers
|
||||
double ExtSARBuffer[];
|
||||
double ExtEPBuffer[];
|
||||
double ExtAFBuffer[];
|
||||
//--- global variables
|
||||
int ExtLastRevPos;
|
||||
bool ExtDirectionLong;
|
||||
double ExtSarStep;
|
||||
double ExtSarMaximum;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- checking input data
|
||||
if(InpSARStep<0.0)
|
||||
{
|
||||
ExtSarStep=0.02;
|
||||
Print("Input parametr InpSARStep has incorrect value. Indicator will use value",
|
||||
ExtSarStep,"for calculations.");
|
||||
}
|
||||
else ExtSarStep=InpSARStep;
|
||||
if(InpSARMaximum<0.0)
|
||||
{
|
||||
ExtSarMaximum=0.2;
|
||||
Print("Input parametr InpSARMaximum has incorrect value. Indicator will use value",
|
||||
ExtSarMaximum,"for calculations.");
|
||||
}
|
||||
else ExtSarMaximum=InpSARMaximum;
|
||||
//---- indicator buffers
|
||||
SetIndexBuffer(0,ExtSARBuffer);
|
||||
SetIndexBuffer(1,ExtEPBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2,ExtAFBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- set arrow symbol
|
||||
PlotIndexSetInteger(0,PLOT_ARROW,159);
|
||||
//--- set indicator digits
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- set label name
|
||||
PlotIndexSetString(0,PLOT_LABEL,"SAR("+
|
||||
DoubleToString(ExtSarStep,2)+","+
|
||||
DoubleToString(ExtSarMaximum,2)+")");
|
||||
//--- set global variables
|
||||
ExtLastRevPos=0;
|
||||
ExtDirectionLong=false;
|
||||
//----
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- check for minimum rates count
|
||||
if(rates_total<3)
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- detect current position
|
||||
int pos=_prev_calculated-1;
|
||||
//--- correct position
|
||||
if(pos<1)
|
||||
{
|
||||
//--- first pass, set as SHORT
|
||||
pos=1;
|
||||
ExtAFBuffer[0]=ExtSarStep;
|
||||
ExtAFBuffer[1]=ExtSarStep;
|
||||
ExtSARBuffer[0]=rangeBarsIndicator.High[0];
|
||||
ExtLastRevPos=0;
|
||||
ExtDirectionLong=false;
|
||||
ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,rangeBarsIndicator.High);
|
||||
ExtEPBuffer[0]=rangeBarsIndicator.Low[pos];
|
||||
ExtEPBuffer[1]=rangeBarsIndicator.Low[pos];
|
||||
}
|
||||
//---main cycle
|
||||
for(int i=pos;i<rates_total-1 && !IsStopped();i++)
|
||||
{
|
||||
//--- check for reverse
|
||||
if(ExtDirectionLong)
|
||||
{
|
||||
if(ExtSARBuffer[i]>rangeBarsIndicator.Low[i])
|
||||
{
|
||||
//--- switch to SHORT
|
||||
ExtDirectionLong=false;
|
||||
ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,rangeBarsIndicator.High);
|
||||
ExtEPBuffer[i]=rangeBarsIndicator.Low[i];
|
||||
ExtLastRevPos=i;
|
||||
ExtAFBuffer[i]=ExtSarStep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ExtSARBuffer[i]<rangeBarsIndicator.High[i])
|
||||
{
|
||||
//--- switch to LONG
|
||||
ExtDirectionLong=true;
|
||||
ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,rangeBarsIndicator.Low);
|
||||
ExtEPBuffer[i]=rangeBarsIndicator.High[i];
|
||||
ExtLastRevPos=i;
|
||||
ExtAFBuffer[i]=ExtSarStep;
|
||||
}
|
||||
}
|
||||
//--- continue calculations
|
||||
if(ExtDirectionLong)
|
||||
{
|
||||
//--- check for new High
|
||||
if(rangeBarsIndicator.High[i]>ExtEPBuffer[i-1] && i!=ExtLastRevPos)
|
||||
{
|
||||
ExtEPBuffer[i]=rangeBarsIndicator.High[i];
|
||||
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
|
||||
if(ExtAFBuffer[i]>ExtSarMaximum)
|
||||
ExtAFBuffer[i]=ExtSarMaximum;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- when we haven't reversed
|
||||
if(i!=ExtLastRevPos)
|
||||
{
|
||||
ExtAFBuffer[i]=ExtAFBuffer[i-1];
|
||||
ExtEPBuffer[i]=ExtEPBuffer[i-1];
|
||||
}
|
||||
}
|
||||
//--- calculate SAR for tomorrow
|
||||
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
|
||||
//--- check for SAR
|
||||
if(ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i] || ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i-1])
|
||||
ExtSARBuffer[i+1]=MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.Low[i-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- check for new Low
|
||||
if(rangeBarsIndicator.Low[i]<ExtEPBuffer[i-1] && i!=ExtLastRevPos)
|
||||
{
|
||||
ExtEPBuffer[i]=rangeBarsIndicator.Low[i];
|
||||
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
|
||||
if(ExtAFBuffer[i]>ExtSarMaximum)
|
||||
ExtAFBuffer[i]=ExtSarMaximum;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- when we haven't reversed
|
||||
if(i!=ExtLastRevPos)
|
||||
{
|
||||
ExtAFBuffer[i]=ExtAFBuffer[i-1];
|
||||
ExtEPBuffer[i]=ExtEPBuffer[i-1];
|
||||
}
|
||||
}
|
||||
//--- calculate SAR for tomorrow
|
||||
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
|
||||
//--- check for SAR
|
||||
if(ExtSARBuffer[i+1]<rangeBarsIndicator.High[i] || ExtSARBuffer[i+1]<rangeBarsIndicator.High[i-1])
|
||||
ExtSARBuffer[i+1]=MathMax(rangeBarsIndicator.High[i],rangeBarsIndicator.High[i-1]);
|
||||
}
|
||||
}
|
||||
//---- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Find highest price from start to current position |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetHigh(int nPosition,int nStartPeriod,const double &HiData[])
|
||||
{
|
||||
//--- calculate
|
||||
double result=HiData[nStartPeriod];
|
||||
for(int i=nStartPeriod;i<=nPosition;i++) if(result<HiData[i]) result=HiData[i];
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Find lowest price from start to current position |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetLow(int nPosition,int nStartPeriod,const double &LoData[])
|
||||
{
|
||||
//--- calculate
|
||||
double result=LoData[nStartPeriod];
|
||||
for(int i=nStartPeriod;i<=nPosition;i++) if(result>LoData[i]) result=LoData[i];
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,136 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ROC.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Rate of Change"
|
||||
//--- indicator settings
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 LightSeaGreen
|
||||
//--- input parameters
|
||||
input int InpRocPeriod=12; // Period
|
||||
//--- indicator buffers
|
||||
double ExtRocBuffer[];
|
||||
//--- global variable
|
||||
int ExtRocPeriod;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Rate of Change initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- check for input
|
||||
if(InpRocPeriod<1)
|
||||
{
|
||||
ExtRocPeriod=12;
|
||||
Print("Incorrect value for input variable InpRocPeriod =",InpRocPeriod,
|
||||
"Indicator will use value =",ExtRocPeriod,"for calculations.");
|
||||
}
|
||||
else ExtRocPeriod=InpRocPeriod;
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ExtRocBuffer,INDICATOR_DATA);
|
||||
//--- set accuracy
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
||||
//--- name for DataWindow and indicator subwindow label
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"ROC("+string(ExtRocPeriod)+")");
|
||||
//--- sets first bar from what index will be drawn
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtRocPeriod);
|
||||
//--- initialization done
|
||||
|
||||
//
|
||||
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||
//
|
||||
|
||||
rangeBarsIndicator.SetUseAppliedPriceFlag(PRICE_CLOSE);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Rate of Change |
|
||||
//+------------------------------------------------------------------+
|
||||
//int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- check for rates count
|
||||
if(rates_total<ExtRocPeriod)
|
||||
return(0);
|
||||
//--- preliminary calculations
|
||||
int pos=_prev_calculated-1; // set calc position
|
||||
if(pos<ExtRocPeriod)
|
||||
pos=ExtRocPeriod;
|
||||
//--- the main loop of calculations
|
||||
for(int i=pos;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
if(rangeBarsIndicator.Price[i]==0.0)
|
||||
ExtRocBuffer[i]=0.0;
|
||||
else
|
||||
ExtRocBuffer[i]=(rangeBarsIndicator.Price[i]-rangeBarsIndicator.Price[i-ExtRocPeriod])/rangeBarsIndicator.Price[i]*100;
|
||||
}
|
||||
//--- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -26,14 +26,12 @@ double ExtPosBuffer[];
|
||||
double ExtNegBuffer[];
|
||||
|
||||
//
|
||||
// Initialize MedianRenko indicator for data processing
|
||||
// according to settings of the MedianRenko indicator already on chart
|
||||
//
|
||||
//
|
||||
|
||||
#include <RangeBarIndicator.mqh>
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -79,26 +77,36 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
|
||||
//
|
||||
// Precoess data through MedianRenko indicator
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(rates_total);
|
||||
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// medianRenkoIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
// medianRenkoIndicator.Open[] should be used instead of open[]
|
||||
// medianRenkoIndicator.Low[] should be used instead of low[]
|
||||
// medianRenkoIndicator.High[] should be used instead of high[]
|
||||
// medianRenkoIndicator.Close[] should be used instead of close[]
|
||||
// if applied_price is used
|
||||
// medianRenkoIndicator.Price[] should be used instead of price[]
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
+6
-17
@@ -26,14 +26,12 @@ double ExtHighesBuffer[];
|
||||
double ExtLowesBuffer[];
|
||||
|
||||
//
|
||||
// Initialize MedianRenko indicator for data processing
|
||||
// according to settings of the MedianRenko indicator already on chart
|
||||
//
|
||||
//
|
||||
|
||||
#include <RangeBarIndicator.mqh>
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -79,23 +77,14 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
|
||||
|
||||
//
|
||||
// Precoess data through MedianRenko indicator
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(rates_total);
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// medianRenkoIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
// medianRenkoIndicator.Open[] should be used instead of open[]
|
||||
// medianRenkoIndicator.Low[] should be used instead of low[]
|
||||
// medianRenkoIndicator.High[] should be used instead of high[]
|
||||
// medianRenkoIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
//------------------------------------------------------------------
|
||||
#property copyright "mladen"
|
||||
#property link "www.forex-tsd.com"
|
||||
//------------------------------------------------------------------
|
||||
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 4
|
||||
|
||||
#property indicator_label1 "ADX trend"
|
||||
#property indicator_type1 DRAW_FILLING
|
||||
#property indicator_color1 C'200,255,180',clrMistyRose
|
||||
#property indicator_label2 "ADX"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrLimeGreen
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
#property indicator_label3 "ADXR"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGold
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 2
|
||||
#property indicator_label4 "Level"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrSilver
|
||||
#property indicator_style4 STYLE_DOT
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
enum enVolume
|
||||
{
|
||||
vol_noVolume, // do not use volume
|
||||
vol_ticks, // use ticks
|
||||
vol_real // use real volume
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
input int AdxPeriod = 14; // ADX (DMI) period
|
||||
input double AdxLevel = 20; // ADX level
|
||||
input bool ShowADX = true; // ADX visible
|
||||
input bool ShowADXR = false; // ADXR visible
|
||||
input enVolume VolumeType = vol_ticks; // Volume to use
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double DIp[];
|
||||
double DIm[];
|
||||
double ADX[];
|
||||
double ADXR[];
|
||||
double Level[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer(0,DIp,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,DIm,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,ADX,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,ADXR,INDICATOR_DATA);
|
||||
SetIndexBuffer(4,Level,INDICATOR_DATA);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
IndicatorSetString(INDICATOR_SHORTNAME," VEMA Wilder's DMI ("+string(AdxPeriod)+")");
|
||||
|
||||
rangeBarsIndicator.SetGetVolumesFlag();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
double averages[][9];
|
||||
#define _Vol 0
|
||||
#define _DIp 1
|
||||
#define _DIm 2
|
||||
#define _TR 3
|
||||
#define _Adx 4
|
||||
#define _DIpa 5
|
||||
#define _DIma 6
|
||||
#define _TRa 7
|
||||
#define _Adxa 8
|
||||
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime& time[],
|
||||
const double& open[],
|
||||
const double& high[],
|
||||
const double& low[],
|
||||
const double& close[],
|
||||
const long& tick_volume[],
|
||||
const long& volume[],
|
||||
const int& spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if (ArrayRange(averages,0)!=rates_total) ArrayResize(averages,rates_total);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double sf = 1.0/(double)AdxPeriod;
|
||||
for (int i=(int)MathMax(_prev_calculated-1,1); i<rates_total; i++)
|
||||
{
|
||||
double currTR = MathMax(rangeBarsIndicator.High[i],rangeBarsIndicator.Close[i-1])-MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.Close[i-1]);
|
||||
double DeltaHi = rangeBarsIndicator.High[i] - rangeBarsIndicator.High[i-1];
|
||||
double DeltaLo = rangeBarsIndicator.Low[i-1] - rangeBarsIndicator.Low[i];
|
||||
double plusDM = 0.00;
|
||||
double minusDM = 0.00;
|
||||
double vol;
|
||||
switch(VolumeType)
|
||||
{
|
||||
case vol_ticks: vol = (double)rangeBarsIndicator.Tick_volume[i]; break;
|
||||
case vol_real: vol = (double)rangeBarsIndicator.Real_volume[i]; break;
|
||||
default: vol = 1;
|
||||
}
|
||||
if ((DeltaHi > DeltaLo) && (DeltaHi > 0)) plusDM = DeltaHi;
|
||||
if ((DeltaLo > DeltaHi) && (DeltaLo > 0)) minusDM = DeltaLo;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
averages[i][_Vol] = averages[i-1][_Vol] + sf*(vol - averages[i-1][_Vol]);
|
||||
averages[i][_DIp] = averages[i-1][_DIp] + sf*(vol*plusDM - averages[i-1][_DIp]);
|
||||
averages[i][_DIm] = averages[i-1][_DIm] + sf*(vol*minusDM - averages[i-1][_DIm]);
|
||||
averages[i][_TR] = averages[i-1][_TR] + sf*(vol*currTR - averages[i-1][_TR]);
|
||||
averages[i][_DIpa] = averages[i][_DIp]/MathMax(averages[i][_Vol],1);
|
||||
averages[i][_DIma] = averages[i][_DIm]/MathMax(averages[i][_Vol],1);
|
||||
averages[i][_TRa] = averages[i][_TR] /MathMax(averages[i][_Vol],1);
|
||||
Level[i] = AdxLevel;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
DIp[i] = 0.00;
|
||||
DIm[i] = 0.00;
|
||||
ADX[i] = EMPTY_VALUE;
|
||||
ADXR[i] = EMPTY_VALUE;
|
||||
if (averages[i][_TRa] > 0)
|
||||
{
|
||||
DIp[i] = 100.00 * averages[i][_DIpa]/averages[i][_TRa];
|
||||
DIm[i] = 100.00 * averages[i][_DIma]/averages[i][_TRa];
|
||||
}
|
||||
|
||||
if(ShowADX)
|
||||
{
|
||||
double DX;
|
||||
if((DIp[i] + DIm[i])>0)
|
||||
DX = 100*MathAbs(DIp[i] - DIm[i])/(DIp[i] + DIm[i]);
|
||||
else DX = 0.00;
|
||||
averages[i][_Adx] = averages[i-1][_Adx]+ sf*(vol*DX - averages[i-1][_Adx]);
|
||||
averages[i][_Adxa] = averages[i][_Adx]/MathMax(averages[i][_Vol],1);
|
||||
ADX[i] = averages[i][_Adxa];
|
||||
if(ShowADXR && i>=AdxPeriod)
|
||||
ADXR[i] = 0.5*(ADX[i] + ADX[i-AdxPeriod]);
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| VWAP_Lite.mq5 |
|
||||
//| Copyright 2016, SOL Digital Consultoria LTDA |
|
||||
//| http://www.soldigitalconsultoria.com.br |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016, SOL Digital Consultoria LTDA"
|
||||
#property link "http://www.soldigitalconsultoria.com.br"
|
||||
#property version "1.49"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
|
||||
#property indicator_label1 "VWAP Daily"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRed
|
||||
#property indicator_style1 STYLE_DASH
|
||||
#property indicator_width1 2
|
||||
|
||||
#property indicator_label2 "VWAP Weekly"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrBlue
|
||||
#property indicator_style2 STYLE_DASH
|
||||
#property indicator_width2 2
|
||||
|
||||
#property indicator_label3 "VWAP Monthly"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGreen
|
||||
#property indicator_style3 STYLE_DASH
|
||||
#property indicator_width3 2
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
enum DATE_TYPE
|
||||
{
|
||||
DAILY,
|
||||
WEEKLY,
|
||||
MONTHLY
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
enum PRICE_TYPE
|
||||
{
|
||||
OPEN,
|
||||
CLOSE,
|
||||
HIGH,
|
||||
LOW,
|
||||
OPEN_CLOSE,
|
||||
HIGH_LOW,
|
||||
CLOSE_HIGH_LOW,
|
||||
OPEN_CLOSE_HIGH_LOW
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
#define VWAP_Daily "cc__VWAP_Daily"
|
||||
#define VWAP_Weekly "cc__VWAP_Weekly"
|
||||
#define VWAP_Monthly "cc__VWAP_Monthly"
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
datetime CreateDateTime(DATE_TYPE nReturnType=DAILY,datetime dtDay=D'2000.01.01 00:00:00',int pHour=0,int pMinute=0,int pSecond=0)
|
||||
{
|
||||
datetime dtReturnDate;
|
||||
MqlDateTime timeStruct;
|
||||
|
||||
TimeToStruct(dtDay,timeStruct);
|
||||
timeStruct.hour = pHour;
|
||||
timeStruct.min = pMinute;
|
||||
timeStruct.sec = pSecond;
|
||||
dtReturnDate=(StructToTime(timeStruct));
|
||||
|
||||
if(nReturnType==WEEKLY)
|
||||
{
|
||||
while(timeStruct.day_of_week!=0)
|
||||
{
|
||||
dtReturnDate=(dtReturnDate-86400);
|
||||
TimeToStruct(dtReturnDate,timeStruct);
|
||||
}
|
||||
}
|
||||
|
||||
if(nReturnType==MONTHLY)
|
||||
{
|
||||
timeStruct.day=1;
|
||||
dtReturnDate=(StructToTime(timeStruct));
|
||||
}
|
||||
|
||||
return dtReturnDate;
|
||||
}
|
||||
|
||||
sinput string Indicator_Name = "Volume Weighted Average Price (VWAP)";
|
||||
input PRICE_TYPE Price_Type = CLOSE_HIGH_LOW;
|
||||
input bool Calc_Every_Tick = false;
|
||||
input bool Enable_Daily = true;
|
||||
input bool Show_Daily_Value = true;
|
||||
input bool Enable_Weekly = false;
|
||||
input bool Show_Weekly_Value = false;
|
||||
input bool Enable_Monthly = false;
|
||||
input bool Show_Monthly_Value = false;
|
||||
|
||||
double VWAP_Buffer_Daily[],VWAP_Buffer_Weekly[],VWAP_Buffer_Monthly[];
|
||||
double nPriceArr[],nTotalTPV[],nTotalVol[];
|
||||
double nSumDailyTPV = 0, nSumWeeklyTPV = 0, nSumMonthlyTPV = 0;
|
||||
double nSumDailyVol = 0, nSumWeeklyVol = 0, nSumMonthlyVol = 0;
|
||||
int nIdxDaily=0,nIdxWeekly=0,nIdxMonthly=0,nIdx=0;
|
||||
bool bIsFirstRun=true;
|
||||
string sDailyStr = "", sWeeklyStr = "", sMonthlyStr = "";
|
||||
datetime dtLastDay = CreateDateTime(DAILY), dtLastWeek = CreateDateTime(WEEKLY), dtLastMonth = CreateDateTime(MONTHLY);
|
||||
ENUM_TIMEFRAMES LastTimePeriod=PERIOD_MN1;
|
||||
int nStringYDistance=50;
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
|
||||
SetIndexBuffer(0,VWAP_Buffer_Daily,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,VWAP_Buffer_Weekly,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,VWAP_Buffer_Monthly,INDICATOR_DATA);
|
||||
|
||||
if(Show_Daily_Value)
|
||||
{
|
||||
ObjectCreate(0,VWAP_Daily,OBJ_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,VWAP_Daily,OBJPROP_CORNER,CORNER_LEFT_LOWER);
|
||||
ObjectSetInteger(0,VWAP_Daily,OBJPROP_XDISTANCE,10);//180);
|
||||
ObjectSetInteger(0,VWAP_Daily,OBJPROP_YDISTANCE,nStringYDistance);
|
||||
ObjectSetInteger(0,VWAP_Daily,OBJPROP_COLOR,indicator_color1);
|
||||
ObjectSetInteger(0,VWAP_Daily,OBJPROP_FONTSIZE,7);
|
||||
ObjectSetString(0,VWAP_Daily,OBJPROP_FONT,"Verdana");
|
||||
ObjectSetString(0,VWAP_Daily,OBJPROP_TEXT," ");
|
||||
nStringYDistance=nStringYDistance+20;
|
||||
}
|
||||
|
||||
if(Show_Weekly_Value)
|
||||
{
|
||||
ObjectCreate(0,VWAP_Weekly,OBJ_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,VWAP_Weekly,OBJPROP_CORNER,CORNER_LEFT_LOWER);
|
||||
ObjectSetInteger(0,VWAP_Weekly,OBJPROP_XDISTANCE,10);//180);
|
||||
ObjectSetInteger(0,VWAP_Weekly,OBJPROP_YDISTANCE,nStringYDistance);
|
||||
ObjectSetInteger(0,VWAP_Weekly,OBJPROP_COLOR,indicator_color2);
|
||||
ObjectSetInteger(0,VWAP_Weekly,OBJPROP_FONTSIZE,7);
|
||||
ObjectSetString(0,VWAP_Weekly,OBJPROP_FONT,"Verdana");
|
||||
ObjectSetString(0,VWAP_Weekly,OBJPROP_TEXT," ");
|
||||
nStringYDistance=nStringYDistance+20;
|
||||
}
|
||||
|
||||
if(Show_Monthly_Value)
|
||||
{
|
||||
ObjectCreate(0,VWAP_Monthly,OBJ_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,VWAP_Monthly,OBJPROP_CORNER,CORNER_LEFT_LOWER);
|
||||
ObjectSetInteger(0,VWAP_Monthly,OBJPROP_XDISTANCE,10);//180);
|
||||
ObjectSetInteger(0,VWAP_Monthly,OBJPROP_YDISTANCE,nStringYDistance);
|
||||
ObjectSetInteger(0,VWAP_Monthly,OBJPROP_COLOR,indicator_color3);
|
||||
ObjectSetInteger(0,VWAP_Monthly,OBJPROP_FONTSIZE,7);
|
||||
ObjectSetString(0,VWAP_Monthly,OBJPROP_FONT,"Verdana");
|
||||
ObjectSetString(0,VWAP_Monthly,OBJPROP_TEXT," ");
|
||||
}
|
||||
|
||||
rangeBarsIndicator.SetGetVolumesFlag();
|
||||
rangeBarsIndicator.SetGetTimeFlag();
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int pReason)
|
||||
{
|
||||
if(Show_Daily_Value) ObjectDelete(0,VWAP_Daily);
|
||||
if(Show_Weekly_Value) ObjectDelete(0,VWAP_Weekly);
|
||||
if(Show_Monthly_Value) ObjectDelete(0,VWAP_Monthly);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if(PERIOD_CURRENT!=LastTimePeriod)
|
||||
{
|
||||
bIsFirstRun=true;
|
||||
LastTimePeriod=PERIOD_CURRENT;
|
||||
}
|
||||
|
||||
if(rates_total>_prev_calculated || bIsFirstRun || Calc_Every_Tick || (_prev_calculated == 0) || rangeBarsIndicator.IsNewBar)
|
||||
{
|
||||
nIdxDaily = 0;
|
||||
nIdxWeekly = 0;
|
||||
nIdxMonthly = 0;
|
||||
|
||||
ArrayResize(nPriceArr,rates_total);
|
||||
ArrayResize(nTotalTPV,rates_total);
|
||||
ArrayResize(nTotalVol,rates_total);
|
||||
|
||||
if(Enable_Daily) {nIdx = nIdxDaily; nSumDailyTPV = 0; nSumDailyVol = 0;}
|
||||
if(Enable_Weekly) {nIdx = nIdxWeekly; nSumWeeklyTPV = 0; nSumWeeklyVol = 0;}
|
||||
if(Enable_Monthly) {nIdx = nIdxMonthly; nSumMonthlyTPV = 0; nSumMonthlyVol = 0;}
|
||||
|
||||
for(; nIdx<rates_total; nIdx++)
|
||||
{
|
||||
VWAP_Buffer_Daily[nIdx]=EMPTY_VALUE;
|
||||
VWAP_Buffer_Weekly[nIdx]=EMPTY_VALUE;
|
||||
VWAP_Buffer_Monthly[nIdx]=EMPTY_VALUE;
|
||||
|
||||
if(rangeBarsIndicator.Time[nIdx] < 86400)
|
||||
continue;
|
||||
|
||||
if(CreateDateTime(DAILY,rangeBarsIndicator.Time[nIdx])!=dtLastDay)
|
||||
{
|
||||
nIdxDaily=nIdx;
|
||||
nSumDailyTPV = 0;
|
||||
nSumDailyVol = 0;
|
||||
}
|
||||
if(CreateDateTime(WEEKLY,rangeBarsIndicator.Time[nIdx])!=dtLastWeek)
|
||||
{
|
||||
nIdxWeekly=nIdx;
|
||||
nSumWeeklyTPV = 0;
|
||||
nSumWeeklyVol = 0;
|
||||
}
|
||||
if(CreateDateTime(MONTHLY,rangeBarsIndicator.Time[nIdx])!=dtLastMonth)
|
||||
{
|
||||
nIdxMonthly=nIdx;
|
||||
nSumMonthlyTPV = 0;
|
||||
nSumMonthlyVol = 0;
|
||||
}
|
||||
|
||||
nPriceArr[nIdx] = 0;
|
||||
nTotalTPV[nIdx] = 0;
|
||||
nTotalVol[nIdx] = 0;
|
||||
|
||||
switch(Price_Type)
|
||||
{
|
||||
case OPEN:
|
||||
nPriceArr[nIdx]=rangeBarsIndicator.Open[nIdx];
|
||||
break;
|
||||
case CLOSE:
|
||||
nPriceArr[nIdx]=rangeBarsIndicator.Close[nIdx];
|
||||
break;
|
||||
case HIGH:
|
||||
nPriceArr[nIdx]=rangeBarsIndicator.High[nIdx];
|
||||
break;
|
||||
case LOW:
|
||||
nPriceArr[nIdx]=rangeBarsIndicator.Low[nIdx];
|
||||
break;
|
||||
case HIGH_LOW:
|
||||
nPriceArr[nIdx]=(rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/2;
|
||||
break;
|
||||
case OPEN_CLOSE:
|
||||
nPriceArr[nIdx]=(rangeBarsIndicator.Open[nIdx]+rangeBarsIndicator.Close[nIdx])/2;
|
||||
break;
|
||||
case CLOSE_HIGH_LOW:
|
||||
nPriceArr[nIdx]=(rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/3;
|
||||
break;
|
||||
case OPEN_CLOSE_HIGH_LOW:
|
||||
nPriceArr[nIdx]=(rangeBarsIndicator.Open[nIdx]+rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/4;
|
||||
break;
|
||||
default:
|
||||
nPriceArr[nIdx]=(rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/3;
|
||||
break;
|
||||
}
|
||||
|
||||
if((rangeBarsIndicator.Tick_volume[nIdx] > 0) && (rangeBarsIndicator.Real_volume[nIdx] == 0))
|
||||
{
|
||||
// Print("tick vol = "+rangeBarsIndicator.Tick_volume[nIdx]);
|
||||
nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Tick_volume[nIdx]);
|
||||
nTotalVol[nIdx] = (double)rangeBarsIndicator.Tick_volume[nIdx];
|
||||
}
|
||||
else if(rangeBarsIndicator.Real_volume[nIdx] && rangeBarsIndicator.Tick_volume[nIdx] )
|
||||
{
|
||||
// Print("real vol = "+rangeBarsIndicator.Real_volume[nIdx]);
|
||||
nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Real_volume[nIdx]);
|
||||
nTotalVol[nIdx] = (double)rangeBarsIndicator.Real_volume[nIdx];
|
||||
}
|
||||
|
||||
if(Enable_Daily && (nIdx>=nIdxDaily))
|
||||
{
|
||||
nSumDailyTPV += nTotalTPV[nIdx];
|
||||
nSumDailyVol += nTotalVol[nIdx];
|
||||
|
||||
if(nSumDailyVol)
|
||||
VWAP_Buffer_Daily[nIdx]=(nSumDailyTPV/nSumDailyVol);
|
||||
|
||||
if((sDailyStr!="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits)) && Show_Daily_Value)
|
||||
{
|
||||
sDailyStr="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits);
|
||||
ObjectSetString(0,VWAP_Daily,OBJPROP_TEXT,sDailyStr);
|
||||
}
|
||||
}
|
||||
|
||||
if(Enable_Weekly && (nIdx>=nIdxWeekly))
|
||||
{
|
||||
nSumWeeklyTPV += nTotalTPV[nIdx];
|
||||
nSumWeeklyVol += nTotalVol[nIdx];
|
||||
|
||||
if(nSumWeeklyVol)
|
||||
VWAP_Buffer_Weekly[nIdx]=(nSumWeeklyTPV/nSumWeeklyVol);
|
||||
|
||||
if((sWeeklyStr!="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits)) && Show_Weekly_Value)
|
||||
{
|
||||
sWeeklyStr="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits);
|
||||
ObjectSetString(0,VWAP_Weekly,OBJPROP_TEXT,sWeeklyStr);
|
||||
}
|
||||
}
|
||||
|
||||
if(Enable_Monthly && (nIdx>=nIdxMonthly))
|
||||
{
|
||||
nSumMonthlyTPV += nTotalTPV[nIdx];
|
||||
nSumMonthlyVol += nTotalVol[nIdx];
|
||||
|
||||
if(nSumMonthlyVol)
|
||||
VWAP_Buffer_Monthly[nIdx]=(nSumMonthlyTPV/nSumMonthlyVol);
|
||||
|
||||
if((sMonthlyStr!="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits)) && Show_Monthly_Value)
|
||||
{
|
||||
sMonthlyStr="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits);
|
||||
ObjectSetString(0,VWAP_Monthly,OBJPROP_TEXT,sMonthlyStr);
|
||||
}
|
||||
}
|
||||
|
||||
dtLastDay=CreateDateTime(DAILY,rangeBarsIndicator.Time[nIdx]);
|
||||
dtLastWeek=CreateDateTime(WEEKLY,rangeBarsIndicator.Time[nIdx]);
|
||||
dtLastMonth=CreateDateTime(MONTHLY,rangeBarsIndicator.Time[nIdx]);
|
||||
}
|
||||
|
||||
bIsFirstRun=false;
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,322 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 1
|
||||
//---- plot Zigzag
|
||||
#property indicator_label1 "Zigzag"
|
||||
#property indicator_type1 DRAW_SECTION
|
||||
#property indicator_color1 Red
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- input parameters
|
||||
input int ExtDepth=12;
|
||||
input int ExtDeviation=5;
|
||||
input int ExtBackstep=3;
|
||||
//--- indicator buffers
|
||||
double ZigzagBuffer[]; // main buffer
|
||||
double HighMapBuffer[]; // highs
|
||||
double LowMapBuffer[]; // lows
|
||||
int level=3; // recounting depth
|
||||
double deviation; // deviation in points
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- set short name and digits
|
||||
PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- set empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
//--- to use in cycle
|
||||
deviation=ExtDeviation*_Point;
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| searching index of the highest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int iHighest(const double &array[],
|
||||
int depth,
|
||||
int startPos)
|
||||
{
|
||||
int index=startPos;
|
||||
//--- start index validation
|
||||
if(startPos<0)
|
||||
{
|
||||
Print("Invalid parameter in the function iHighest, startPos =",startPos);
|
||||
return 0;
|
||||
}
|
||||
int size=ArraySize(array);
|
||||
//--- depth correction if need
|
||||
if(startPos-depth<0) depth=startPos;
|
||||
double max=array[startPos];
|
||||
//--- start searching
|
||||
for(int i=startPos;i>startPos-depth;i--)
|
||||
{
|
||||
if(array[i]>max)
|
||||
{
|
||||
index=i;
|
||||
max=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the highest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| searching index of the lowest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int iLowest(const double &array[],
|
||||
int depth,
|
||||
int startPos)
|
||||
{
|
||||
int index=startPos;
|
||||
//--- start index validation
|
||||
if(startPos<0)
|
||||
{
|
||||
Print("Invalid parameter in the function iLowest, startPos =",startPos);
|
||||
return 0;
|
||||
}
|
||||
int size=ArraySize(array);
|
||||
//--- depth correction if need
|
||||
if(startPos-depth<0) depth=startPos;
|
||||
double min=array[startPos];
|
||||
//--- start searching
|
||||
for(int i=startPos;i>startPos-depth;i--)
|
||||
{
|
||||
if(array[i]<min)
|
||||
{
|
||||
index=i;
|
||||
min=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the lowest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int i=0;
|
||||
int limit=0,counterZ=0,whatlookfor=0;
|
||||
int shift=0,back=0,lasthighpos=0,lastlowpos=0;
|
||||
double val=0,res=0;
|
||||
double curlow=0,curhigh=0,lasthigh=0,lastlow=0;
|
||||
//--- auxiliary enumeration
|
||||
enum looling_for
|
||||
{
|
||||
Pike=1, // searching for next high
|
||||
Sill=-1 // searching for next low
|
||||
};
|
||||
//--- initializing
|
||||
if(_prev_calculated==0)
|
||||
{
|
||||
ArrayInitialize(ZigzagBuffer,0.0);
|
||||
ArrayInitialize(HighMapBuffer,0.0);
|
||||
ArrayInitialize(LowMapBuffer,0.0);
|
||||
}
|
||||
//---
|
||||
if(rates_total<100) return(0);
|
||||
//--- set start position for calculations
|
||||
if(_prev_calculated==0) limit=ExtDepth;
|
||||
|
||||
//--- ZigZag was already counted before
|
||||
if(_prev_calculated>0)
|
||||
{
|
||||
i=rates_total-1;
|
||||
//--- searching third extremum from the last uncompleted bar
|
||||
while(counterZ<level && i>rates_total-100)
|
||||
{
|
||||
res=ZigzagBuffer[i];
|
||||
if(res!=0) counterZ++;
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
limit=i;
|
||||
|
||||
//--- what type of exremum we are going to find
|
||||
if(LowMapBuffer[i]!=0)
|
||||
{
|
||||
curlow=LowMapBuffer[i];
|
||||
whatlookfor=Pike;
|
||||
}
|
||||
else
|
||||
{
|
||||
curhigh=HighMapBuffer[i];
|
||||
whatlookfor=Sill;
|
||||
}
|
||||
//--- chipping
|
||||
for(i=limit+1;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
ZigzagBuffer[i]=0.0;
|
||||
LowMapBuffer[i]=0.0;
|
||||
HighMapBuffer[i]=0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//--- searching High and Low
|
||||
for(shift=limit;shift<rates_total && !IsStopped();shift++)
|
||||
{
|
||||
val=rangeBarsIndicator.Low[iLowest(rangeBarsIndicator.Low,ExtDepth,shift)];
|
||||
if(val==lastlow) val=0.0;
|
||||
else
|
||||
{
|
||||
lastlow=val;
|
||||
if((rangeBarsIndicator.Low[shift]-val)>deviation) val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1;back<=ExtBackstep;back++)
|
||||
{
|
||||
res=LowMapBuffer[shift-back];
|
||||
if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(rangeBarsIndicator.Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
|
||||
//--- high
|
||||
val=rangeBarsIndicator.High[iHighest(rangeBarsIndicator.High,ExtDepth,shift)];
|
||||
if(val==lasthigh) val=0.0;
|
||||
else
|
||||
{
|
||||
lasthigh=val;
|
||||
if((val-rangeBarsIndicator.High[shift])>deviation) val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1;back<=ExtBackstep;back++)
|
||||
{
|
||||
res=HighMapBuffer[shift-back];
|
||||
if((res!=0) && (res<val)) HighMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(rangeBarsIndicator.High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
|
||||
}
|
||||
|
||||
//--- last preparation
|
||||
if(whatlookfor==0)// uncertain quantity
|
||||
{
|
||||
lastlow=0;
|
||||
lasthigh=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastlow=curlow;
|
||||
lasthigh=curhigh;
|
||||
}
|
||||
|
||||
//--- final rejection
|
||||
for(shift=limit;shift<rates_total && !IsStopped();shift++)
|
||||
{
|
||||
res=0.0;
|
||||
switch(whatlookfor)
|
||||
{
|
||||
case 0: // search for peak or lawn
|
||||
if(lastlow==0 && lasthigh==0)
|
||||
{
|
||||
if(HighMapBuffer[shift]!=0)
|
||||
{
|
||||
lasthigh=rangeBarsIndicator.High[shift];
|
||||
lasthighpos=shift;
|
||||
whatlookfor=Sill;
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
res=1;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0)
|
||||
{
|
||||
lastlow=rangeBarsIndicator.Low[shift];
|
||||
lastlowpos=shift;
|
||||
whatlookfor=Pike;
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Pike: // search for peak
|
||||
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagBuffer[lastlowpos]=0.0;
|
||||
lastlowpos=shift;
|
||||
lastlow=LowMapBuffer[shift];
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
res=1;
|
||||
}
|
||||
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
lasthigh=HighMapBuffer[shift];
|
||||
lasthighpos=shift;
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
whatlookfor=Sill;
|
||||
res=1;
|
||||
}
|
||||
break;
|
||||
case Sill: // search for lawn
|
||||
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagBuffer[lasthighpos]=0.0;
|
||||
lasthighpos=shift;
|
||||
lasthigh=HighMapBuffer[shift];
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
lastlow=LowMapBuffer[shift];
|
||||
lastlowpos=shift;
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
whatlookfor=Pike;
|
||||
}
|
||||
break;
|
||||
default: return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
//--- return value of _prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,247 @@
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| DT oscillator.mq5 |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "www.forex-tsd.com"
|
||||
#property link "www.forex-tsd.com"
|
||||
#property version "1.00"
|
||||
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 3
|
||||
#property indicator_level1 70
|
||||
#property indicator_level2 30
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#property indicator_type1 DRAW_FILLING
|
||||
#property indicator_color1 PowderBlue,MistyRose
|
||||
#property indicator_label1 "DT oscillator filling"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 DeepSkyBlue
|
||||
#property indicator_width2 2
|
||||
#property indicator_label2 "DT oscillator"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 PaleVioletRed
|
||||
#property indicator_width3 1
|
||||
#property indicator_label3 "DT oscillator signal"
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
input int RsiPeriod = 13; // Rsi period
|
||||
input int StochPeriod = 8; // Stochastic period
|
||||
input int SlowingPeriod = 5; // Slowing
|
||||
input int SignalPeriod = 3; // Signal period
|
||||
input bool TapeVisible = true; // Tape visibility
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double dtosc[];
|
||||
double dtoss[];
|
||||
double dtosf1[];
|
||||
double dtosf2[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer( 0,dtosf1,INDICATOR_DATA);
|
||||
SetIndexBuffer( 1,dtosf2,INDICATOR_DATA);
|
||||
SetIndexBuffer( 2,dtosc ,INDICATOR_DATA);
|
||||
SetIndexBuffer( 3,dtoss ,INDICATOR_DATA);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double rsibuf[];
|
||||
double stobuf[];
|
||||
|
||||
int OnCalculate(const int rates_total,const int prev_calculated,
|
||||
const datetime &Time[],
|
||||
const double &Open[],
|
||||
const double &High[],
|
||||
const double &Low[],
|
||||
const double &Close[],
|
||||
const long &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if (ArraySize(rsibuf)!=rates_total) ArrayResize(rsibuf,rates_total);
|
||||
if (ArraySize(stobuf)!=rates_total) ArrayResize(stobuf,rates_total);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
for (int i=(int)MathMax(_prev_calculated-1,0); i<rates_total; i++)
|
||||
{
|
||||
rsibuf[i] = iRsi(rangeBarsIndicator.Close[i],RsiPeriod,i,rates_total);
|
||||
|
||||
double min = rsibuf[i];
|
||||
double max = rsibuf[i];
|
||||
for (int k=1; k<StochPeriod && (i-k)>=0; k++)
|
||||
{
|
||||
min = MathMin(rsibuf[i-k],min);
|
||||
max = MathMax(rsibuf[i-k],max);
|
||||
}
|
||||
if (max!=min)
|
||||
stobuf[i] = 100*(rsibuf[i]-min)/(max-min);
|
||||
else stobuf[i] = 0;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
dtosc[i] = 0; for (int k=0; k<SlowingPeriod && (i-k)>=0; k++) dtosc[i] += stobuf[i-k]; dtosc[i] /= SlowingPeriod;
|
||||
dtoss[i] = 0; for (int k=0; k<SignalPeriod && (i-k)>=0; k++) dtoss[i] += dtosc[i-k]; dtoss[i] /= SignalPeriod;
|
||||
if (TapeVisible)
|
||||
{ dtosf1[i] = dtosc[i]; dtosf2[i] = dtoss[i]; }
|
||||
else { dtosf1[i] = EMPTY_VALUE; dtosf2[i] = EMPTY_VALUE; }
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double rsiWork[][3];
|
||||
#define _price 0
|
||||
#define _chgAvg 1
|
||||
#define _totChg 2
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double iRsi(double price, double period, int i, int bars)
|
||||
{
|
||||
if (ArrayRange(rsiWork,0)!=bars) ArrayResize(rsiWork,bars);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
rsiWork[i][_price] = price;
|
||||
if (i==0)
|
||||
{
|
||||
rsiWork[i][_chgAvg] = 0;
|
||||
rsiWork[i][_totChg] = 0;
|
||||
return(50);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double sf = 1.0 / period;
|
||||
double change = rsiWork[i][_price]-rsiWork[i-1][_price];
|
||||
|
||||
rsiWork[i][_chgAvg] = rsiWork[i-1][_chgAvg] + sf*( change -rsiWork[i-1][_chgAvg]);
|
||||
rsiWork[i][_totChg] = rsiWork[i-1][_totChg] + sf*(MathAbs(change)-rsiWork[i-1][_totChg]);
|
||||
|
||||
double changeRatio = (rsiWork[i][_totChg]!=0 ? rsiWork[i][_chgAvg]/rsiWork[i][_totChg] : 0 );
|
||||
return(50.0*(changeRatio+1.0));
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,139 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Volumes.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---- indicator settings
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_COLOR_HISTOGRAM
|
||||
#property indicator_color1 Green,Red
|
||||
#property indicator_style1 0
|
||||
#property indicator_width1 1
|
||||
#property indicator_minimum 0.0
|
||||
//--- input data
|
||||
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes
|
||||
//---- indicator buffers
|
||||
double ExtVolumesBuffer[];
|
||||
double ExtColorsBuffer[];
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//---- buffers
|
||||
SetIndexBuffer(0,ExtVolumesBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ExtColorsBuffer,INDICATOR_COLOR_INDEX);
|
||||
//---- name for DataWindow and indicator subwindow label
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"Volumes");
|
||||
//---- indicator digits
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||
|
||||
rangeBarsIndicator.SetGetVolumesFlag();
|
||||
//----
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Volumes |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//---check for rates total
|
||||
if(rates_total<2)
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- starting work
|
||||
int start=_prev_calculated-1;
|
||||
//--- correct position
|
||||
if(start<1) start=1;
|
||||
//--- main cycle
|
||||
if(InpVolumeType==VOLUME_TICK)
|
||||
CalculateVolume(start,rates_total,rangeBarsIndicator.Tick_volume);
|
||||
else
|
||||
CalculateVolume(start,rates_total,rangeBarsIndicator.Real_volume);
|
||||
//--- OnCalculate done. Return new prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void CalculateVolume(const int nPosition,
|
||||
const int nRatesCount,
|
||||
const long &SrcBuffer[])
|
||||
{
|
||||
ExtVolumesBuffer[0]=(double)SrcBuffer[0];
|
||||
ExtColorsBuffer[0]=0.0;
|
||||
//---
|
||||
for(int i=nPosition;i<nRatesCount && !IsStopped();i++)
|
||||
{
|
||||
//--- get some data from src buffer
|
||||
double dCurrVolume=(double)SrcBuffer[i];
|
||||
double dPrevVolume=(double)SrcBuffer[i-1];
|
||||
//--- calculate indicator
|
||||
ExtVolumesBuffer[i]=dCurrVolume;
|
||||
if(dCurrVolume>dPrevVolume)
|
||||
ExtColorsBuffer[i]=0.0;
|
||||
else
|
||||
ExtColorsBuffer[i]=1.0;
|
||||
}
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user