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;
|
||||
}
|
||||
Reference in New Issue
Block a user