Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| acba19e38f | |||
| 0d51499dcf | |||
| e6121f7487 | |||
| bd957ab1af | |||
| 0ba2c53a35 | |||
| dde1849bb0 | |||
| e4e0bb483a | |||
| b784e9556d | |||
| 695a66b812 | |||
| bd3a18958e | |||
| dd2f769c89 | |||
| 38937ddce1 | |||
| 75a0f76352 | |||
| 4f56445d60 | |||
| a23213f3e1 | |||
| 91e99e93cc | |||
| a19c291525 | |||
| 60a4d0ad07 | |||
| 62032b5f8b | |||
| 32af8d84a2 |
@@ -1,201 +0,0 @@
|
|||||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
|
||||||
#property link "http://www.az-invest.eu"
|
|
||||||
#property version "2.03"
|
|
||||||
#property description "Example EA showing the way to use the RangeBars class defined in RangeBars.mqh"
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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 <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;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert initialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
rangeBars = new RangeBars();
|
|
||||||
if(rangeBars == NULL)
|
|
||||||
return(INIT_FAILED);
|
|
||||||
|
|
||||||
rangeBars.Init();
|
|
||||||
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
|
||||||
return(INIT_FAILED);
|
|
||||||
|
|
||||||
//
|
|
||||||
// your custom code goes here...
|
|
||||||
//
|
|
||||||
|
|
||||||
return(INIT_SUCCEEDED);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert deinitialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
if(rangeBars != NULL)
|
|
||||||
{
|
|
||||||
rangeBars.Deinit();
|
|
||||||
delete rangeBars;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// your custom code goes here...
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// At this point you may use the rangebars 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())
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// There are two methods for getting the Moving Average values.
|
|
||||||
// The example below gets the moving average values for 3 latest bars
|
|
||||||
// counting to the left from the most current (uncompleted) bar.
|
|
||||||
//
|
|
||||||
|
|
||||||
int startAtBar = 0; // get value starting from the most current (uncompleted) bar.
|
|
||||||
int numberOfBars = 3; // gat a total of 3 MA values (for the 3 latest bars)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Values will be stored in 2 arrays defined below
|
|
||||||
//
|
|
||||||
|
|
||||||
double MA1[]; // array to be filled by values of the first moving average
|
|
||||||
double MA2[]; // array to be filled by values of the second moving average
|
|
||||||
|
|
||||||
if(rangeBars.GetMA1(MA1,startAtBar,numberOfBars) && rangeBars.GetMA1(MA2,startAtBar,numberOfBars))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Values are stored in the MA1 and MA2 arrays and are now ready for use
|
|
||||||
//
|
|
||||||
// MA1[0] contains the 1st moving average value for the latest (uncompleted) bar
|
|
||||||
// MA1[1] contains the 1st moving average value for the 1st bar to the left from the latest (uncompleted) bar
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Getting the MqlRates info for range bars is done using the
|
|
||||||
// GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
|
|
||||||
// method. Example below:
|
|
||||||
//
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
if(rangeBars.GetMqlRates(RangeBarRatesInfoArray,startAtBar,numberOfBars))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Check if a range bars reversal bar has formed
|
|
||||||
//
|
|
||||||
|
|
||||||
if((RangeBarRatesInfoArray[0].open < RangeBarRatesInfoArray[0].close) &&
|
|
||||||
(RangeBarRatesInfoArray[1].open > RangeBarRatesInfoArray[1].close))
|
|
||||||
{
|
|
||||||
// bullish reversal
|
|
||||||
}
|
|
||||||
else if((RangeBarRatesInfoArray[0].open > RangeBarRatesInfoArray[0].close) &&
|
|
||||||
(RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close))
|
|
||||||
{
|
|
||||||
// bearish reversal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Getting Donchain channel values is done using the
|
|
||||||
// GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
|
||||||
// method. Example below:
|
|
||||||
//
|
|
||||||
|
|
||||||
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.
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Apply your Donchian channel logic here...
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Getting Bollinger Bands values is done using the
|
|
||||||
// GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
|
||||||
// method. Example below:
|
|
||||||
//
|
|
||||||
|
|
||||||
// HighArray[] array will store the values of the high band
|
|
||||||
// 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.
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Apply your Bollinger Bands logic here...
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Getting SuperTrend values is done using the
|
|
||||||
// GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
|
|
||||||
// method. Example below:
|
|
||||||
//
|
|
||||||
|
|
||||||
// HighArray[] array will store the values of the high SuperTrend line
|
|
||||||
// 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.
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Apply your SuperTrend logic here...
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#property copyright "Copyright 2017-2020, Level Up Software"
|
||||||
|
#property link "https://www.az-invest.eu"
|
||||||
|
#property version "2.07"
|
||||||
|
#property description "Example EA showing the way to use the RangeBars class defined in RangeBars.mqh"
|
||||||
|
|
||||||
|
input int InpRSIPeriod = 14; // RSI period
|
||||||
|
|
||||||
|
//
|
||||||
|
// SHOW_INDICATOR_INPUTS *NEEDS* to be defined, if the sEA 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() and Deinit() methods in your EA's OnInit() and OnDeinit() functions.
|
||||||
|
// Example shown below
|
||||||
|
//
|
||||||
|
|
||||||
|
RangeBars rangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
rangeBars.Init();
|
||||||
|
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
||||||
|
return(INIT_FAILED);
|
||||||
|
|
||||||
|
//
|
||||||
|
// your custom code goes here...
|
||||||
|
//
|
||||||
|
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
rangeBars.Deinit();
|
||||||
|
|
||||||
|
//
|
||||||
|
// your custom code goes here...
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// At this point you may use the range bars data fetching methods in your EA.
|
||||||
|
// Brief demonstration presented below in the OnTick() function:
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
int rsiHandle = INVALID_HANDLE; // Handle for the external RSI indicator
|
||||||
|
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Initialize all additional indicators here! (not in the OnInit() function).
|
||||||
|
// Otherwise they will not work in the backtest.
|
||||||
|
// When backtesting please select the "Daily" timeframe.
|
||||||
|
//
|
||||||
|
|
||||||
|
if(rsiHandle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
rsiHandle = iCustom(_Symbol, _Period, "RangeBars\\RangeBars_RSI", InpRSIPeriod, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// There are two methods for getting the Moving Average values.
|
||||||
|
// The example below gets the moving average values for 3 latest bars
|
||||||
|
// counting to the left from the most current (uncompleted) bar.
|
||||||
|
//
|
||||||
|
|
||||||
|
int startAtBar = 0; // get value starting from the most current (uncompleted) bar.
|
||||||
|
int numberOfBars = 3; // gat a total of 3 MA values (for the 3 latest bars)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Values will be stored in 2 arrays defined below
|
||||||
|
//
|
||||||
|
|
||||||
|
double MA1[]; // array to be filled by values of the first moving average
|
||||||
|
double MA2[]; // array to be filled by values of the second moving average
|
||||||
|
|
||||||
|
if(rangeBars.GetMA(RANGEBAR_MA1, MA1, startAtBar, numberOfBars) && rangeBars.GetMA(RANGEBAR_MA2, MA2, startAtBar, numberOfBars))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Values are stored in the MA1 and MA2 arrays and are now ready for use
|
||||||
|
//
|
||||||
|
// MA1[0] contains the 1st moving average value for the latest (uncompleted) bar
|
||||||
|
// MA1[1] contains the 1st moving average value for the 1st bar to the left from the latest (uncompleted) bar
|
||||||
|
// 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 and 3rd moving average are stored in MA2[] & MA3[]
|
||||||
|
// and are accessed identically to values of MA1[] (shown above)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Getting the MqlRates info for range bars is done using the
|
||||||
|
// GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
|
||||||
|
// method. Example below:
|
||||||
|
//
|
||||||
|
|
||||||
|
MqlRates RangeBarRatesInfoArray[]; // This array will store the MqlRates data for range bars
|
||||||
|
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 bar reversal bar has formed
|
||||||
|
//
|
||||||
|
|
||||||
|
string infoString;
|
||||||
|
|
||||||
|
if((RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close) &&
|
||||||
|
(RangeBarRatesInfoArray[2].open > RangeBarRatesInfoArray[2].close))
|
||||||
|
{
|
||||||
|
// bullish reversal
|
||||||
|
infoString = "Previous bar formed bullish reversal";
|
||||||
|
}
|
||||||
|
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...
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Getting the values of the channel indicator (Donchain, Bullinger Bands, Keltner or Super Trend) is done using
|
||||||
|
// GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
||||||
|
// Example below:
|
||||||
|
//
|
||||||
|
|
||||||
|
double HighArray[]; // This array will store the values of the channel's high band
|
||||||
|
double MidArray[]; // This array will store the values of the channel's middle band
|
||||||
|
double LowArray[]; // This array will store the values of the channel's low band
|
||||||
|
|
||||||
|
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.GetChannel(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Apply your logic here...
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
#property copyright "Copyright 2017-2020, Level Up Software"
|
||||||
|
#property link "https://www.az-invest.eu"
|
||||||
|
#property version "1.11"
|
||||||
|
#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() and Deinit() methods in your EA's OnInit() and OnDeinit() functions.
|
||||||
|
// Example shown below
|
||||||
|
//
|
||||||
|
|
||||||
|
RangeBars rangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
CMarketOrder * marketOrder;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
rangeBars.Deinit();
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], 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.GetChannel(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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2017-2018, Artur Zas
|
||||||
|
// https://www.az-invest.eu
|
||||||
|
// https://www.mql5.com/en/users/arturz
|
||||||
|
//
|
||||||
|
// Normalizing functions
|
||||||
|
//
|
||||||
|
|
||||||
|
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 VtcNormalizeLots(string symbol, double lotsToNormalize)
|
||||||
|
{
|
||||||
|
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
|
||||||
|
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
|
||||||
|
double lotsStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
|
||||||
|
|
||||||
|
if (lotsToNormalize == 0)
|
||||||
|
return lotsMin;
|
||||||
|
|
||||||
|
int a = (int)(lotsToNormalize / lotsStep);
|
||||||
|
double normalizedLots = a * lotsStep;
|
||||||
|
|
||||||
|
if(normalizedLots < lotsMin)
|
||||||
|
normalizedLots = lotsMin;
|
||||||
|
if(normalizedLots > lotsMax)
|
||||||
|
normalizedLots = lotsMax;
|
||||||
|
|
||||||
|
return normalizedLots;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
#include <AZ-INVEST/SDK/CommonSettings.mqh>
|
||||||
|
|
||||||
|
#ifdef DEVELOPER_VERSION
|
||||||
|
#define CUSTOM_CHART_NAME "RangeBars_TEST"
|
||||||
|
#else
|
||||||
|
#define CUSTOM_CHART_NAME "Range Bars"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tick chart specific settings
|
||||||
|
//
|
||||||
|
#ifdef SHOW_INDICATOR_INPUTS
|
||||||
|
#ifdef MQL5_MARKET_DEMO // hardcoded values
|
||||||
|
|
||||||
|
int barSizeInTicks = 180; // Range bar size (in ticks)
|
||||||
|
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
|
||||||
|
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
|
||||||
|
int atrPeriod = 14; // ATR period
|
||||||
|
int atrPercentage = 10; // Use percentage of ATR
|
||||||
|
int showNumberOfDays = 7; // Show history for number of days
|
||||||
|
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
|
|
||||||
|
#else // user defined settings
|
||||||
|
|
||||||
|
|
||||||
|
input int barSizeInTicks = 20; // Range bar size (in ticks)
|
||||||
|
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
|
||||||
|
|
||||||
|
input int showNumberOfDays = 5; // Show history for number of days
|
||||||
|
input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#else // don't SHOW_INDICATOR_INPUTS
|
||||||
|
int barSizeInTicks = 180; // Range bar size (in ticks)
|
||||||
|
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
|
||||||
|
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
|
||||||
|
int atrPeriod = 14; // ATR period
|
||||||
|
int atrPercentage = 10; // Use percentage of ATR
|
||||||
|
int showNumberOfDays = 7; // Show history for number of days
|
||||||
|
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remaining settings are located in the include file below.
|
||||||
|
// These are common for all custom charts
|
||||||
|
//
|
||||||
|
#include <az-invest/sdk/CustomChartSettingsBase.mqh>
|
||||||
|
|
||||||
|
struct RANGEBAR_SETTINGS
|
||||||
|
{
|
||||||
|
int barSizeInTicks;
|
||||||
|
ENUM_BOOL atrEnabled;
|
||||||
|
ENUM_TIMEFRAMES atrTimeFrame;
|
||||||
|
int atrPeriod;
|
||||||
|
int atrPercentage;
|
||||||
|
int showNumberOfDays;
|
||||||
|
ENUM_BOOL resetOpenOnNewTradingDay;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CRangeBarCustomChartSettigns : public CCustomChartSettingsBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
RANGEBAR_SETTINGS settings;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CRangeBarCustomChartSettigns();
|
||||||
|
~CRangeBarCustomChartSettigns();
|
||||||
|
|
||||||
|
RANGEBAR_SETTINGS GetCustomChartSettings() { return this.settings; };
|
||||||
|
|
||||||
|
virtual void SetCustomChartSettings();
|
||||||
|
virtual string GetSettingsFileName();
|
||||||
|
virtual uint CustomChartSettingsToFile(int handle);
|
||||||
|
virtual uint CustomChartSettingsFromFile(int handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
void CRangeBarCustomChartSettigns::CRangeBarCustomChartSettigns()
|
||||||
|
{
|
||||||
|
settingsFileName = GetSettingsFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRangeBarCustomChartSettigns::~CRangeBarCustomChartSettigns()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string CRangeBarCustomChartSettigns::GetSettingsFileName()
|
||||||
|
{
|
||||||
|
return CUSTOM_CHART_NAME+(string)ChartID()+".set";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint CRangeBarCustomChartSettigns::CustomChartSettingsToFile(int file_handle)
|
||||||
|
{
|
||||||
|
return FileWriteStruct(file_handle,this.settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint CRangeBarCustomChartSettigns::CustomChartSettingsFromFile(int file_handle)
|
||||||
|
{
|
||||||
|
return FileReadStruct(file_handle,this.settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRangeBarCustomChartSettigns::SetCustomChartSettings()
|
||||||
|
{
|
||||||
|
settings.barSizeInTicks = barSizeInTicks;
|
||||||
|
|
||||||
|
settings.atrEnabled = atrEnabled;
|
||||||
|
settings.atrTimeFrame = atrTimeFrame;
|
||||||
|
settings.atrPeriod = atrPeriod;
|
||||||
|
settings.atrPercentage = atrPercentage;
|
||||||
|
settings.showNumberOfDays = showNumberOfDays;
|
||||||
|
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
|
||||||
|
}
|
||||||
@@ -0,0 +1,893 @@
|
|||||||
|
#property copyright "Copyright 2018-2020, Level Up Software"
|
||||||
|
#property link "http://www.az-invest.eu"
|
||||||
|
#property version "3.00"
|
||||||
|
|
||||||
|
input bool UseOnRangeBarChart = true; // Use this indicator on RangeBar chart
|
||||||
|
|
||||||
|
//#define DEVELOPER_VERSION
|
||||||
|
#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 firstRun;
|
||||||
|
bool dataReady;
|
||||||
|
|
||||||
|
datetime prevTime;
|
||||||
|
int prevRatesTotal;
|
||||||
|
|
||||||
|
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[];
|
||||||
|
|
||||||
|
datetime GetTime(int index) { return GetArrayValueDateTime(Time, index); };
|
||||||
|
double GetOpen(int index) { return GetArrayValueDouble(Open, index); };
|
||||||
|
double GetLow(int index) { return GetArrayValueDouble(Low, index); };
|
||||||
|
double GetHigh(int index) { return GetArrayValueDouble(High, index); };
|
||||||
|
double GetClose(int index) { return GetArrayValueDouble(Close, index); };
|
||||||
|
double GetPrice(int index) { return GetArrayValueDouble(Price, index); };
|
||||||
|
long GetTick_volume(int index) { return GetArrayValueLong(Tick_volume, index); };
|
||||||
|
long GetReal_volume(int index) { return GetArrayValueLong(Real_volume, index); };
|
||||||
|
double GetBuy_volume(int index) { return GetArrayValueDouble(Buy_volume, index); };
|
||||||
|
double GetSell_volume(int index) { return GetArrayValueDouble(Sell_volume, index); };
|
||||||
|
double GetBuySell_volume(int index) { return GetArrayValueDouble(BuySell_volume, index); };
|
||||||
|
|
||||||
|
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[], const double &_Close[]);
|
||||||
|
void OnDeinit(const int reason);
|
||||||
|
bool BufferSynchronizationCheck(const double &buffer[]);
|
||||||
|
int GetPrevCalculated() { return prev_calculated; };
|
||||||
|
int GetRatesTotal() { return ArraySize(Open); };
|
||||||
|
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);
|
||||||
|
double GetArrayValueDouble(double &arr[], int index);
|
||||||
|
long GetArrayValueLong(long &arr[], int index);
|
||||||
|
datetime GetArrayValueDateTime(datetime &arr[], int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
RangeBarIndicator::RangeBarIndicator(void)
|
||||||
|
{
|
||||||
|
rangeBars = new RangeBars(UseOnRangeBarChart);
|
||||||
|
if(rangeBars != NULL)
|
||||||
|
rangeBars.Init();
|
||||||
|
|
||||||
|
useAppliedPrice = false;
|
||||||
|
getVolumes = false;
|
||||||
|
getTime = false;
|
||||||
|
|
||||||
|
dataReady = false;
|
||||||
|
firstRun = true;
|
||||||
|
prevTime = 0;
|
||||||
|
prevRatesTotal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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[], const double &_Close[])
|
||||||
|
{
|
||||||
|
if(firstRun)
|
||||||
|
{
|
||||||
|
Canvas_IsNewBar(_Time);
|
||||||
|
Canvas_RatesTotalChangedBy(_rates_total);
|
||||||
|
IsNewBar = rangeBars.IsNewBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!CheckStatus())
|
||||||
|
{
|
||||||
|
if(rangeBars != NULL)
|
||||||
|
delete rangeBars;
|
||||||
|
|
||||||
|
rangeBars = new RangeBars(UseOnRangeBarChart);
|
||||||
|
if(rangeBars != NULL)
|
||||||
|
rangeBars.Init();
|
||||||
|
|
||||||
|
Print("CheckStatus block failed");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(firstRun)
|
||||||
|
{
|
||||||
|
GetOLHC(0,_rates_total);
|
||||||
|
firstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NeedsReload() || !this.dataReady)
|
||||||
|
{
|
||||||
|
GetOLHC(0,_rates_total);
|
||||||
|
this.prev_calculated = 0;
|
||||||
|
firstRun = true;
|
||||||
|
ChartSetSymbolPeriod(ChartID(), _Symbol, _Period); // try to force reload
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
OLHCShiftRight();
|
||||||
|
this.prev_calculated = _prev_calculated;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsNewBar = rangeBars.IsNewBar();
|
||||||
|
if(IsNewBar)
|
||||||
|
{
|
||||||
|
GetOLHC(0,_rates_total);
|
||||||
|
this.prev_calculated = 0;
|
||||||
|
firstRun = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only recalculate last bar
|
||||||
|
//
|
||||||
|
|
||||||
|
GetOLHC(0,0);
|
||||||
|
this.prev_calculated = _prev_calculated;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RangeBarIndicator::BufferSynchronizationCheck(const double &buffer[])
|
||||||
|
{
|
||||||
|
if(ArraySize(buffer) != ArraySize(Close))
|
||||||
|
{
|
||||||
|
#ifdef DEVELOPER_VERSION
|
||||||
|
Print("### buffers out of synch - refreshing...");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(prevTime != now)
|
||||||
|
{
|
||||||
|
prevTime = now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow)
|
||||||
|
{
|
||||||
|
if(prevRatesTotal == 0)
|
||||||
|
prevRatesTotal = ratesTotalNow;
|
||||||
|
|
||||||
|
if(prevRatesTotal != ratesTotalNow)
|
||||||
|
{
|
||||||
|
prevRatesTotal = ratesTotalNow;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RangeBarIndicator::Canvas_RatesTotalChangedBy(int ratesTotalNow)
|
||||||
|
{
|
||||||
|
int changedBy = 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)
|
||||||
|
{
|
||||||
|
if(GetLastError() == 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TFMigrate:
|
||||||
|
// https://www.mql5.com/en/forum/2842#comment_39496
|
||||||
|
//
|
||||||
|
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];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
long RangeBarIndicator::GetArrayValueLong(long &arr[], int index)
|
||||||
|
{
|
||||||
|
int size = ArraySize(arr);
|
||||||
|
if(index < size)
|
||||||
|
{
|
||||||
|
return(arr[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double RangeBarIndicator::GetArrayValueDouble(double &arr[], int index)
|
||||||
|
{
|
||||||
|
int size = ArraySize(arr);
|
||||||
|
if(index < size)
|
||||||
|
{
|
||||||
|
return(arr[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datetime RangeBarIndicator::GetArrayValueDateTime(datetime &arr[], int index)
|
||||||
|
{
|
||||||
|
int size = ArraySize(arr);
|
||||||
|
if(index < size)
|
||||||
|
{
|
||||||
|
return(arr[index]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,678 @@
|
|||||||
|
#property copyright "Copyright 2018-2020, Level Up Software"
|
||||||
|
#property link "http://www.az-invest.eu"
|
||||||
|
|
||||||
|
#ifdef DEVELOPER_VERSION
|
||||||
|
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay300"
|
||||||
|
#else
|
||||||
|
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RANGEBAR_OPEN 00
|
||||||
|
#define RANGEBAR_HIGH 01
|
||||||
|
#define RANGEBAR_LOW 02
|
||||||
|
#define RANGEBAR_CLOSE 03
|
||||||
|
#define RANGEBAR_BAR_COLOR 04
|
||||||
|
#define RANGEBAR_SESSION_RECT_H 05
|
||||||
|
#define RANGEBAR_SESSION_RECT_L 06
|
||||||
|
#define RANGEBAR_MA1 07
|
||||||
|
#define RANGEBAR_MA2 08
|
||||||
|
#define RANGEBAR_MA3 09
|
||||||
|
#define RANGEBAR_MA4 10
|
||||||
|
#define RANGEBAR_CHANNEL_HIGH 11
|
||||||
|
#define RANGEBAR_CHANNEL_MID 12
|
||||||
|
#define RANGEBAR_CHANNEL_LOW 13
|
||||||
|
#define RANGEBAR_BAR_OPEN_TIME 14
|
||||||
|
#define RANGEBAR_TICK_VOLUME 15
|
||||||
|
#define RANGEBAR_REAL_VOLUME 16
|
||||||
|
#define RANGEBAR_BUY_VOLUME 17
|
||||||
|
#define RANGEBAR_SELL_VOLUME 18
|
||||||
|
#define RANGEBAR_BUYSELL_VOLUME 19
|
||||||
|
#define RANGEBAR_RUNTIME_ID 20
|
||||||
|
|
||||||
|
#include <az-invest/sdk/RangeBarCustomChartSettings.mqh>
|
||||||
|
|
||||||
|
class RangeBars
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
CRangeBarCustomChartSettigns * rangeBarSettings;
|
||||||
|
|
||||||
|
int rangeBarsHandle; // range bar indicator handle
|
||||||
|
string rangeBarsSymbol;
|
||||||
|
bool usedByIndicatorOnRangeBarChart;
|
||||||
|
|
||||||
|
datetime prevBarTime;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RangeBars();
|
||||||
|
RangeBars(bool isUsedByIndicatorOnRangeBarChart);
|
||||||
|
RangeBars(string symbol);
|
||||||
|
~RangeBars(void);
|
||||||
|
|
||||||
|
int Init();
|
||||||
|
void Deinit();
|
||||||
|
bool Reload();
|
||||||
|
void ReleaseHandle();
|
||||||
|
|
||||||
|
int GetHandle(void) { return rangeBarsHandle; };
|
||||||
|
double GetRuntimeId();
|
||||||
|
|
||||||
|
bool IsNewBar();
|
||||||
|
|
||||||
|
bool GetMqlRates(MqlRates &ratesInfoArray[], int start, int count);
|
||||||
|
bool GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count);
|
||||||
|
bool GetMA(int MaBufferId, double &MA[], int start, int count);
|
||||||
|
bool GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
|
||||||
|
|
||||||
|
// The following 6 functions are deprecated, please use GetMA & GetChannelData functions instead
|
||||||
|
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);
|
||||||
|
//
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int GetIndicatorHandle(void);
|
||||||
|
bool GetChannelData(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
|
||||||
|
};
|
||||||
|
|
||||||
|
RangeBars::RangeBars(void)
|
||||||
|
{
|
||||||
|
#define CONSTRUCTOR1
|
||||||
|
rangeBarSettings = new CRangeBarCustomChartSettigns();
|
||||||
|
rangeBarsHandle = INVALID_HANDLE;
|
||||||
|
rangeBarsSymbol = _Symbol;
|
||||||
|
usedByIndicatorOnRangeBarChart = false;
|
||||||
|
prevBarTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeBars::RangeBars(bool isUsedByIndicatorOnRangeBarChart)
|
||||||
|
{
|
||||||
|
rangeBarSettings = new CRangeBarCustomChartSettigns();
|
||||||
|
rangeBarsHandle = INVALID_HANDLE;
|
||||||
|
rangeBarsSymbol = _Symbol;
|
||||||
|
usedByIndicatorOnRangeBarChart = isUsedByIndicatorOnRangeBarChart;
|
||||||
|
prevBarTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeBars::RangeBars(string symbol)
|
||||||
|
{
|
||||||
|
#define CONSTRUCTOR2
|
||||||
|
rangeBarSettings = new CRangeBarCustomChartSettigns();
|
||||||
|
rangeBarsHandle = INVALID_HANDLE;
|
||||||
|
rangeBarsSymbol = symbol;
|
||||||
|
usedByIndicatorOnRangeBarChart = false;
|
||||||
|
prevBarTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeBars::~RangeBars(void)
|
||||||
|
{
|
||||||
|
if(rangeBarSettings != NULL)
|
||||||
|
delete rangeBarSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RangeBars::ReleaseHandle()
|
||||||
|
{
|
||||||
|
if(rangeBarsHandle != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
IndicatorRelease(rangeBarsHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function for initializing the median renko indicator handle
|
||||||
|
//
|
||||||
|
|
||||||
|
int RangeBars::Init()
|
||||||
|
{
|
||||||
|
if(!MQLInfoInteger((int)MQL5_TESTING))
|
||||||
|
{
|
||||||
|
if(usedByIndicatorOnRangeBarChart)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Indicator on RangeBar chart uses the values of the RangeBar chart for calculations
|
||||||
|
//
|
||||||
|
|
||||||
|
IndicatorRelease(rangeBarsHandle);
|
||||||
|
|
||||||
|
rangeBarsHandle = GetIndicatorHandle();
|
||||||
|
return rangeBarsHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rangeBarSettings.Load())
|
||||||
|
{
|
||||||
|
if(rangeBarsHandle != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
// could not read new settings - keep old settings
|
||||||
|
|
||||||
|
return rangeBarsHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("Failed to load indicator settings - RangeBar indicator not on chart");
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rangeBarsHandle != INVALID_HANDLE)
|
||||||
|
Deinit();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(usedByIndicatorOnRangeBarChart)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Indicator on RangeBar chart uses the values of the RangeBar chart for calculations
|
||||||
|
//
|
||||||
|
rangeBarsHandle = GetIndicatorHandle();
|
||||||
|
return rangeBarsHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef SHOW_INDICATOR_INPUTS
|
||||||
|
//
|
||||||
|
// Load settings from EA inputs
|
||||||
|
//
|
||||||
|
rangeBarSettings.Load();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RANGEBAR_SETTINGS s = rangeBarSettings.GetCustomChartSettings();
|
||||||
|
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
|
||||||
|
|
||||||
|
rangeBarsHandle = iCustom(this.rangeBarsSymbol, _Period, RANGEBAR_INDICATOR_NAME,
|
||||||
|
s.barSizeInTicks,
|
||||||
|
s.atrEnabled,
|
||||||
|
//s.atrTimeFrame,
|
||||||
|
s.atrPeriod,
|
||||||
|
s.atrPercentage,
|
||||||
|
s.showNumberOfDays, s.resetOpenOnNewTradingDay,
|
||||||
|
TradingSessionTime,
|
||||||
|
showPivots,
|
||||||
|
pivotPointCalculationType,
|
||||||
|
RColor,
|
||||||
|
PColor,
|
||||||
|
SColor,
|
||||||
|
PDHColor,
|
||||||
|
PDLColor,
|
||||||
|
PDCColor,
|
||||||
|
AlertMeWhen,
|
||||||
|
AlertNotificationType,
|
||||||
|
cis.MA1on,
|
||||||
|
cis.MA1lineType,
|
||||||
|
cis.MA1period,
|
||||||
|
cis.MA1method,
|
||||||
|
cis.MA1applyTo,
|
||||||
|
cis.MA1shift,
|
||||||
|
cis.MA1priceLabel,
|
||||||
|
cis.MA2on,
|
||||||
|
cis.MA2lineType,
|
||||||
|
cis.MA2period,
|
||||||
|
cis.MA2method,
|
||||||
|
cis.MA2applyTo,
|
||||||
|
cis.MA2shift,
|
||||||
|
cis.MA2priceLabel,
|
||||||
|
cis.MA3on,
|
||||||
|
cis.MA3lineType,
|
||||||
|
cis.MA3period,
|
||||||
|
cis.MA3method,
|
||||||
|
cis.MA3applyTo,
|
||||||
|
cis.MA3shift,
|
||||||
|
cis.MA3priceLabel,
|
||||||
|
cis.MA4on,
|
||||||
|
cis.MA4lineType,
|
||||||
|
cis.MA4period,
|
||||||
|
cis.MA4method,
|
||||||
|
cis.MA4applyTo,
|
||||||
|
cis.MA4shift,
|
||||||
|
cis.MA4priceLabel,
|
||||||
|
cis.ShowChannel,
|
||||||
|
cis.ChannelPeriod,
|
||||||
|
cis.ChannelAtrPeriod,
|
||||||
|
cis.ChannelAppliedPrice,
|
||||||
|
cis.ChannelMultiplier,
|
||||||
|
cis.ChannelBandsDeviations,
|
||||||
|
cis.ChannelPriceLabel,
|
||||||
|
cis.ChannelMidPriceLabel,
|
||||||
|
true); // used in EA
|
||||||
|
// TopBottomPaddingPercentage,
|
||||||
|
// showCurrentBarOpenTime,
|
||||||
|
// SoundFileBull,
|
||||||
|
// SoundFileBear,
|
||||||
|
// DisplayAsBarChart
|
||||||
|
// ShiftObj; all letft at defaults
|
||||||
|
|
||||||
|
if(rangeBarsHandle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
Print(RANGEBAR_INDICATOR_NAME+" indicator init failed on error ",GetLastError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print(RANGEBAR_INDICATOR_NAME+" indicator init OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rangeBarsHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function for reloading the Median Renko indicator if needed
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::Reload()
|
||||||
|
{
|
||||||
|
bool actionNeeded = false;
|
||||||
|
int temp = GetIndicatorHandle();
|
||||||
|
|
||||||
|
if(temp != rangeBarsHandle)
|
||||||
|
{
|
||||||
|
IndicatorRelease(rangeBarsHandle);
|
||||||
|
rangeBarsHandle = INVALID_HANDLE;
|
||||||
|
|
||||||
|
actionNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rangeBarSettings.Changed(GetRuntimeId()))
|
||||||
|
{
|
||||||
|
actionNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(actionNeeded)
|
||||||
|
{
|
||||||
|
if(rangeBarsHandle != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
IndicatorRelease(rangeBarsHandle);
|
||||||
|
rangeBarsHandle = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Init() == INVALID_HANDLE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function for releasing the Median Renko indicator hanlde - free resources
|
||||||
|
//
|
||||||
|
|
||||||
|
void RangeBars::Deinit()
|
||||||
|
{
|
||||||
|
if(rangeBarsHandle == INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!usedByIndicatorOnRangeBarChart)
|
||||||
|
{
|
||||||
|
if(IndicatorRelease(rangeBarsHandle))
|
||||||
|
Print(RANGEBAR_INDICATOR_NAME+" indicator handle released");
|
||||||
|
else
|
||||||
|
Print("Failed to release "+RANGEBAR_INDICATOR_NAME+" indicator handle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function for detecting a new Renko bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::IsNewBar()
|
||||||
|
{
|
||||||
|
MqlRates currentBar[1];
|
||||||
|
GetMqlRates(currentBar,0,1);
|
||||||
|
|
||||||
|
if(currentBar[0].time == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevBarTime < currentBar[0].time)
|
||||||
|
{
|
||||||
|
prevBarTime = currentBar[0].time;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
|
||||||
|
{
|
||||||
|
double o[],l[],h[],c[],barColor[],time[],tick_volume[],real_volume[];
|
||||||
|
|
||||||
|
if(ArrayResize(o,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(l,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(h,count) == -1)
|
||||||
|
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)
|
||||||
|
return false;
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,count,l) == -1)
|
||||||
|
return false;
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,count,h) == -1)
|
||||||
|
return false;
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,count,c) == -1)
|
||||||
|
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;
|
||||||
|
|
||||||
|
int tempOffset = count-1;
|
||||||
|
for(int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
ratesInfoArray[tempOffset-i].open = o[i];
|
||||||
|
ratesInfoArray[tempOffset-i].low = l[i];
|
||||||
|
ratesInfoArray[tempOffset-i].high = h[i];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
bool RangeBars::GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if(ArrayResize(buy,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(sell,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(buySell,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int tempOffset = count-1;
|
||||||
|
for(int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
buy[tempOffset-i] = b[i];
|
||||||
|
sell[tempOffset-i] = s[i];
|
||||||
|
buySell[tempOffset-i] = bs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayFree(b);
|
||||||
|
ArrayFree(s);
|
||||||
|
ArrayFree(bs);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get "count" values for MaBufferId buffer into "MA[]" array starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetMA(int MaBufferId, double &MA[], int start, int count)
|
||||||
|
{
|
||||||
|
double tempMA[];
|
||||||
|
if(ArrayResize(tempMA, count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(ArrayResize(MA, count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(MaBufferId != RANGEBAR_MA1 && MaBufferId != RANGEBAR_MA2 && MaBufferId != RANGEBAR_MA3 && MaBufferId != RANGEBAR_MA4)
|
||||||
|
{
|
||||||
|
Print("Incorrect MA buffer id specified in "+__FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CopyBuffer(rangeBarsHandle, MaBufferId,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" MovingAverage1 values into "MA[]" array starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetMA1(double &MA[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetMA instead");
|
||||||
|
|
||||||
|
double tempMA[];
|
||||||
|
if(ArrayResize(tempMA,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(ArrayResize(MA,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_MA1,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" MovingAverage2 values into "MA[]" starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetMA2(double &MA[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetMA instead");
|
||||||
|
|
||||||
|
double tempMA[];
|
||||||
|
if(ArrayResize(tempMA,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(ArrayResize(MA,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_MA2,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" MovingAverage3 values into "MA[]" starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetMA3(double &MA[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetMA instead");
|
||||||
|
|
||||||
|
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" Donchian channel values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetChannelData instead");
|
||||||
|
return GetChannelData(HighArray,MidArray,LowArray,start,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get "count" Bollinger band values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetChannelData instead");
|
||||||
|
return GetChannelData(HighArray,MidArray,LowArray,start,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get "count" SuperTrend values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__+" is deprecated, please use GetChannel function instead");
|
||||||
|
return GetChannelData(SuperTrendHighArray,SuperTrendArray,SuperTrendLowArray,start,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get Channel values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
||||||
|
{
|
||||||
|
return GetChannelData(HighArray,MidArray,LowArray,start,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private function used by GetRenkoDonchian and GetRenkoBollingerBands functions to get data
|
||||||
|
//
|
||||||
|
|
||||||
|
bool RangeBars::GetChannelData(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
||||||
|
{
|
||||||
|
double tempH[], tempM[], tempL[];
|
||||||
|
|
||||||
|
if(ArrayResize(tempH,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(tempM,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(tempL,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(ArrayResize(HighArray,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(MidArray,count) == -1)
|
||||||
|
return false;
|
||||||
|
if(ArrayResize(LowArray,count) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_HIGH,start,count,tempH) == -1)
|
||||||
|
return false;
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_MID,start,count,tempM) == -1)
|
||||||
|
return false;
|
||||||
|
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_LOW,start,count,tempL) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int tempOffset = count-1;
|
||||||
|
for(int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
HighArray[tempOffset-i] = tempH[i];
|
||||||
|
MidArray[tempOffset-i] = tempM[i];
|
||||||
|
LowArray[tempOffset-i] = tempL[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayFree(tempH);
|
||||||
|
ArrayFree(tempM);
|
||||||
|
ArrayFree(tempL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RangeBars::GetIndicatorHandle(void)
|
||||||
|
{
|
||||||
|
int i = ChartIndicatorsTotal(0,0);
|
||||||
|
int j=0;
|
||||||
|
string iName;
|
||||||
|
|
||||||
|
while(j < i)
|
||||||
|
{
|
||||||
|
iName = ChartIndicatorName(0,0,j);
|
||||||
|
if(StringFind(iName,CUSTOM_CHART_NAME) != -1)
|
||||||
|
{
|
||||||
|
return ChartIndicatorGet(0,0,iName);
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("Failed getting handle of "+CUSTOM_CHART_NAME);
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
double RangeBars::GetRuntimeId()
|
||||||
|
{
|
||||||
|
double runtimeId[1];
|
||||||
|
|
||||||
|
if(CopyBuffer(rangeBarsHandle, RANGEBAR_RUNTIME_ID, 0, 1, runtimeId) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return runtimeId[0];
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,932 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2018, Artur Zas
|
||||||
|
// https://www.az-invest.eu
|
||||||
|
// https://www.mql5.com/en/users/arturz
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
//--- class for performing trade operations
|
||||||
|
#include <Trade\Trade.mqh>
|
||||||
|
CTrade trade;
|
||||||
|
//--- class for working with orders
|
||||||
|
#include <Trade\OrderInfo.mqh>
|
||||||
|
COrderInfo orderinfo;
|
||||||
|
//--- class for working with positions
|
||||||
|
#include <Trade\PositionInfo.mqh>
|
||||||
|
CPositionInfo positioninfo;
|
||||||
|
|
||||||
|
//--- introduce the predefined variables from MQL4 for versatility of the code
|
||||||
|
#define Ask SymbolInfoDouble(_symbol,SYMBOL_ASK)
|
||||||
|
#define Bid SymbolInfoDouble(_symbol,SYMBOL_BID)
|
||||||
|
|
||||||
|
bool suppressLogOutput = false;
|
||||||
|
|
||||||
|
void SuppressGlobalLogOutput() { suppressLogOutput = true; };
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _point SymbolInfoDouble(_symbol,SYMBOL_POINT)
|
||||||
|
|
||||||
|
//--- redefine the order types from MQL5 to MQL4 for use in common code
|
||||||
|
#ifdef __MQL4__
|
||||||
|
#define ORDER_TYPE_BUY OP_BUY
|
||||||
|
#define ORDER_TYPE_SELL OP_SELL
|
||||||
|
#define ORDER_TYPE_BUY_LIMIT OP_BUYLIMIT
|
||||||
|
#define ORDER_TYPE_SELL_LIMIT OP_SELLLIMIT
|
||||||
|
#define ORDER_TYPE_BUY_STOP OP_BUYSTOP
|
||||||
|
#define ORDER_TYPE_SELL_STOP OP_SELLSTOP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum ENUM_TC_ERROR
|
||||||
|
{
|
||||||
|
tcErrorNONE = 0,
|
||||||
|
tcErrorNotEnoughMoney,
|
||||||
|
tcErrorInvalidStops,
|
||||||
|
tcErrorOrderLimitReached,
|
||||||
|
tcErrorFreezeLevel,
|
||||||
|
tcErrorNothingChanged,
|
||||||
|
tcErrorInvalidPrice,
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTradingChecks
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
ENUM_TC_ERROR _err;
|
||||||
|
bool _suppressLogOutput;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CTradingChecks();
|
||||||
|
~CTradingChecks();
|
||||||
|
|
||||||
|
string GetCheckErrorToString();
|
||||||
|
void SuppressLogOutput() { _suppressLogOutput = true; };
|
||||||
|
|
||||||
|
bool OkToOpenOrder(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice, double sl, double tp);
|
||||||
|
bool OkToModifyOrder(string _symbol,ulong ticket,double price, double sl, double tp);
|
||||||
|
#ifdef __MQL5__
|
||||||
|
bool OkToOpenPosition(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice, double sl, double tp);
|
||||||
|
bool OkToModifyPosition(string _symbol,ulong ticket, double sl, double tp);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
CTradingChecks::CTradingChecks(void)
|
||||||
|
{
|
||||||
|
suppressLogOutput = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTradingChecks::~CTradingChecks(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
string CTradingChecks::GetCheckErrorToString(void)
|
||||||
|
{
|
||||||
|
switch(_err)
|
||||||
|
{
|
||||||
|
case tcErrorNONE:
|
||||||
|
return "No Error";
|
||||||
|
case tcErrorNotEnoughMoney:
|
||||||
|
return "Not enough money (check previous message in Experts log)";
|
||||||
|
case tcErrorInvalidStops:
|
||||||
|
return "Invalid stops (check previous message in Experts log)";
|
||||||
|
case tcErrorOrderLimitReached:
|
||||||
|
return "Maximum order limit reached";
|
||||||
|
case tcErrorFreezeLevel:
|
||||||
|
return "Freeze level (check previous message in Experts log)";
|
||||||
|
case tcErrorNothingChanged:
|
||||||
|
return "Nothing to change";
|
||||||
|
case tcErrorInvalidPrice:
|
||||||
|
return "Invalid entry price for this order type";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradingChecks::OkToOpenOrder(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice,double sl, double tp)
|
||||||
|
{
|
||||||
|
if(!IsNewPendingOrderAllowed())
|
||||||
|
{
|
||||||
|
_err = tcErrorOrderLimitReached;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!CheckStopLoss_Takeprofit(_symbol,type,entryPrice,sl,tp))
|
||||||
|
{
|
||||||
|
_err = tcErrorInvalidStops;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_err = tcErrorNONE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
bool CTradingChecks::OkToOpenPosition(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice,double sl, double tp)
|
||||||
|
{
|
||||||
|
#ifdef __MQL5__
|
||||||
|
if(!CheckMoneyForTrade(_symbol,lots,type))
|
||||||
|
{
|
||||||
|
_err = tcErrorNotEnoughMoney;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if(NewOrderAllowedVolume(_symbol) < lots)
|
||||||
|
// return false;
|
||||||
|
#else
|
||||||
|
if(!CheckMoneyForTrade(_symbol,lots,(int)type))
|
||||||
|
{
|
||||||
|
_err = tcErrorNotEnoughMoney;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!IsNewPendingOrderAllowed())
|
||||||
|
{
|
||||||
|
_err = tcErrorOrderLimitReached;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!CheckStopLoss_Takeprofit(_symbol,type,entryPrice,sl,tp))
|
||||||
|
{
|
||||||
|
_err = tcErrorInvalidStops;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_err = tcErrorNONE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif;
|
||||||
|
|
||||||
|
bool CTradingChecks::OkToModifyOrder(string _symbol, ulong ticket,double price, double sl, double tp)
|
||||||
|
{
|
||||||
|
#ifdef __MQL5__
|
||||||
|
if(!OrderModifyCheck(ticket,price,sl,tp))
|
||||||
|
{
|
||||||
|
_err = tcErrorNothingChanged;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!CheckOrderForFREEZE_LEVEL(_symbol,ticket))
|
||||||
|
{
|
||||||
|
_err = tcErrorFreezeLevel;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(!OrderModifyCheck((int)ticket,price,sl,tp))
|
||||||
|
{
|
||||||
|
_err = tcErrorNothingChanged;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!CheckOrderForFREEZE_LEVEL(_symbol,(int)ticket))
|
||||||
|
{
|
||||||
|
_err = tcErrorFreezeLevel;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!CheckPendingOrderEntryChange(_symbol,ticket,price))
|
||||||
|
{
|
||||||
|
_err = tcErrorInvalidPrice;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_err = tcErrorNONE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
bool CTradingChecks::OkToModifyPosition(string _symbol, ulong ticket,double sl,double tp)
|
||||||
|
{
|
||||||
|
if(!PositionModifyCheck(ticket,sl,tp))
|
||||||
|
{
|
||||||
|
_err = tcErrorNothingChanged;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!CheckPositionForFREEZE_LEVEL(_symbol,ticket))
|
||||||
|
{
|
||||||
|
_err = tcErrorFreezeLevel;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_err = tcErrorNONE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Helper functions from https://www.mql5.com/en/articles/2555
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
|
||||||
|
{
|
||||||
|
//--- Getting the opening price
|
||||||
|
MqlTick mqltick;
|
||||||
|
SymbolInfoTick(symb,mqltick);
|
||||||
|
double price=mqltick.ask;
|
||||||
|
if(type==ORDER_TYPE_SELL)
|
||||||
|
price=mqltick.bid;
|
||||||
|
//--- values of the required and free margin
|
||||||
|
double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
|
||||||
|
//--- call of the checking function
|
||||||
|
if(!OrderCalcMargin(type,symb,lots,price,margin))
|
||||||
|
{
|
||||||
|
//--- something went wrong, report and return false
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
Print("Error in ",__FUNCTION__," code=",GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- if there are insufficient funds to perform the operation
|
||||||
|
if(margin>free_margin)
|
||||||
|
{
|
||||||
|
//--- report the error and return false
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
|
||||||
|
Print("Required margin:"+DoubleToString(margin,2)+"; free margin:"+DoubleToString(free_margin,2));
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- checking successful
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool CheckMoneyForTrade(string symb, double lots,int type)
|
||||||
|
{
|
||||||
|
double free_margin=AccountFreeMarginCheck(symb,type, lots);
|
||||||
|
//-- if there is not enough money
|
||||||
|
if(free_margin<0)
|
||||||
|
{
|
||||||
|
string oper=(type==OP_BUY)? "Buy":"Sell";
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
Print("Not enough money for ", oper," ",lots, " ", symb, " Error code=",GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- checking successful
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check if another order can be placed |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsNewPendingOrderAllowed()
|
||||||
|
{
|
||||||
|
//--- get the number of pending orders allowed on the account
|
||||||
|
int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
|
||||||
|
|
||||||
|
//--- if there is no limitation, return true; you can send an order
|
||||||
|
if(max_allowed_orders==0) return(true);
|
||||||
|
|
||||||
|
//--- if we passed to this line, then there is a limitation; find out how many orders are already placed
|
||||||
|
int orders=OrdersTotal();
|
||||||
|
|
||||||
|
//--- return the result of comparing
|
||||||
|
return(orders<max_allowed_orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Return the size of position on the specified symbol |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double PositionVolume(string symbol)
|
||||||
|
{
|
||||||
|
//--- try to select position by a symbol
|
||||||
|
bool selected=PositionSelect(symbol);
|
||||||
|
//--- there is a position
|
||||||
|
if(selected)
|
||||||
|
//--- return volume of the position
|
||||||
|
return(PositionGetDouble(POSITION_VOLUME));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- report a failure to select position
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__," Failed to perform PositionSelect() for symbol ",
|
||||||
|
symbol," Error ",GetLastError());
|
||||||
|
}
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| returns the volume of current pending order by a symbol |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double PendingsVolume(string symbol)
|
||||||
|
{
|
||||||
|
double volume_on_symbol=0;
|
||||||
|
ulong ticket;
|
||||||
|
//--- get the number of all currently placed orders by all symbols
|
||||||
|
int all_orders=OrdersTotal();
|
||||||
|
|
||||||
|
//--- get over all orders in the loop
|
||||||
|
for(int i=0;i<all_orders;i++)
|
||||||
|
{
|
||||||
|
//--- get the ticket of an order by its position in the list
|
||||||
|
ticket = OrderGetTicket(i);
|
||||||
|
if((bool)ticket)
|
||||||
|
{
|
||||||
|
//--- if our symbol is specified in the order, add the volume of this order
|
||||||
|
if(symbol==OrderGetString(ORDER_SYMBOL))
|
||||||
|
volume_on_symbol+=OrderGetDouble(ORDER_VOLUME_INITIAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- return the total volume of currently placed pending orders for a specified symbol
|
||||||
|
return(volume_on_symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Return the maximum allowed volume for an order on the symbol |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double NewOrderAllowedVolume(string symbol)
|
||||||
|
{
|
||||||
|
double allowed_volume=0;
|
||||||
|
//--- get the limitation on the maximal volume of an order
|
||||||
|
double symbol_max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
|
||||||
|
//--- get the limitation on the volume by a symbol
|
||||||
|
double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_LIMIT);
|
||||||
|
|
||||||
|
//--- get the volume of the open position by a symbol
|
||||||
|
double opened_volume=PositionVolume(symbol);
|
||||||
|
if(opened_volume>=0)
|
||||||
|
{
|
||||||
|
//--- if we have exhausted the volume
|
||||||
|
if(max_volume-opened_volume<=0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//--- volume of the open position doesn't exceed max_volume
|
||||||
|
double orders_volume_on_symbol=PendingsVolume(symbol);
|
||||||
|
allowed_volume=max_volume-opened_volume-orders_volume_on_symbol;
|
||||||
|
if(allowed_volume>symbol_max_volume) allowed_volume=symbol_max_volume;
|
||||||
|
}
|
||||||
|
return(allowed_volume);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check the correctness of StopLoss and TakeProfit |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CheckStopLoss_Takeprofit(string _symbol, ENUM_ORDER_TYPE type,double price,double SL,double TP)
|
||||||
|
{
|
||||||
|
//--- get the SYMBOL_TRADE_STOPS_LEVEL level
|
||||||
|
int stops_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_STOPS_LEVEL);
|
||||||
|
if(stops_level!=0)
|
||||||
|
{
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must"+
|
||||||
|
" not be nearer than %d points from the closing price",stops_level,stops_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
bool SL_check=false,TP_check=false;
|
||||||
|
//--- check the order type
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
//--- Buy operation
|
||||||
|
case ORDER_TYPE_BUY:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : (Bid-SL>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
|
||||||
|
" (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,Bid-stops_level*_point,Bid,stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : (TP-Bid>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
|
||||||
|
" (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,Bid+stops_level*_point,Bid,stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
//--- Sell operation
|
||||||
|
case ORDER_TYPE_SELL:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : (SL-Ask>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
|
||||||
|
" (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,Ask+stops_level*_point,Ask,stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : (Ask-TP>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
|
||||||
|
" (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,Ask-stops_level*_point,Ask,stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(TP_check&&SL_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case ORDER_TYPE_BUY_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : ((price-SL)>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
|
||||||
|
" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,price-stops_level*_point,(int)((price-SL)/_point),stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : ((TP-price)>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
|
||||||
|
" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,price+stops_level*_point,(int)((TP-price)/_point),stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
//--- SellLimit pending order
|
||||||
|
case ORDER_TYPE_SELL_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : ((SL-price)>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
|
||||||
|
" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,price+stops_level*_point,(int)((SL-price)/_point),stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : ((price-TP)>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
|
||||||
|
" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,price-stops_level*_point,(int)((price-TP)/_point),stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(TP_check&&SL_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- BuyStop pending order
|
||||||
|
case ORDER_TYPE_BUY_STOP:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : ((price-SL)>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
|
||||||
|
" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,price-stops_level*_point,(int)((price-SL)/_point),stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : ((TP-price)>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
|
||||||
|
" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,price-stops_level*_point,(int)((TP-price)/_point),stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
//--- SellStop pending order
|
||||||
|
case ORDER_TYPE_SELL_STOP:
|
||||||
|
{
|
||||||
|
//--- check the StopLoss
|
||||||
|
SL_check= (SL==0) ? true : ((SL-price)>stops_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
|
||||||
|
" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),SL,price+stops_level*_point,(int)((SL-price)/_point),stops_level);
|
||||||
|
//--- check the TakeProfit
|
||||||
|
TP_check= (TP==0) ? true : ((price-TP)>stops_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
|
||||||
|
" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
||||||
|
EnumToString(type),TP,price-stops_level*_point,(int)((price-TP)/_point),stops_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(TP_check&&SL_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Checking the new values of levels before order modification |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
|
||||||
|
{
|
||||||
|
//--- select order by ticket
|
||||||
|
if(orderinfo.Select(ticket))
|
||||||
|
{
|
||||||
|
//--- point size and name of the symbol, for which a pending order was placed
|
||||||
|
string symbol=orderinfo.Symbol();
|
||||||
|
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
|
||||||
|
int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
|
||||||
|
//--- check if there are changes in the Open price
|
||||||
|
bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
|
||||||
|
//--- check if there are changes in the StopLoss level
|
||||||
|
bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
|
||||||
|
//--- check if there are changes in the Takeprofit level
|
||||||
|
bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-tp)>point);
|
||||||
|
//--- if there are any changes in levels
|
||||||
|
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
|
||||||
|
return(true); // order can be modified
|
||||||
|
//--- there are no changes in the Open, StopLoss and Takeprofit levels
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- notify about the error
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
|
||||||
|
ticket,orderinfo.PriceOpen(),orderinfo.StopLoss(),orderinfo.TakeProfit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- came to the end, no changes for the order
|
||||||
|
return(false); // no point in modifying
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Checking the new values of levels before order modification |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool PositionModifyCheck(ulong ticket,double sl,double tp)
|
||||||
|
{
|
||||||
|
//--- select order by ticket
|
||||||
|
if(positioninfo.SelectByTicket(ticket))
|
||||||
|
{
|
||||||
|
//--- point size and name of the symbol, for which a pending order was placed
|
||||||
|
string symbol=positioninfo.Symbol();
|
||||||
|
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
|
||||||
|
//--- check if there are changes in the StopLoss level
|
||||||
|
bool StopLossChanged=(MathAbs(positioninfo.StopLoss()-sl)>point);
|
||||||
|
//--- check if there are changes in the Takeprofit level
|
||||||
|
bool TakeProfitChanged=(MathAbs(positioninfo.TakeProfit()-tp)>point);
|
||||||
|
//--- if there are any changes in levels
|
||||||
|
if(StopLossChanged || TakeProfitChanged)
|
||||||
|
return(true); // position can be modified
|
||||||
|
//--- there are no changes in the StopLoss and Takeprofit levels
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- notify about the error
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
|
||||||
|
ticket,orderinfo.PriceOpen(),orderinfo.StopLoss(),orderinfo.TakeProfit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- came to the end, no changes for the order
|
||||||
|
return(false); // no point in modifying
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Checking the new values of levels before order modification |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool OrderModifyCheck(int ticket,double price,double sl,double tp)
|
||||||
|
{
|
||||||
|
//--- select order by ticket
|
||||||
|
if(OrderSelect(ticket,SELECT_BY_TICKET))
|
||||||
|
{
|
||||||
|
//--- point size and name of the symbol, for which a pending order was placed
|
||||||
|
string symbol=OrderSymbol();
|
||||||
|
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
|
||||||
|
//--- check if there are changes in the Open price
|
||||||
|
bool PriceOpenChanged=true;
|
||||||
|
int type=OrderType();
|
||||||
|
if(!(type==OP_BUY || type==OP_SELL))
|
||||||
|
{
|
||||||
|
PriceOpenChanged=(MathAbs(OrderOpenPrice()-price)>point);
|
||||||
|
}
|
||||||
|
//--- check if there are changes in the StopLoss level
|
||||||
|
bool StopLossChanged=(MathAbs(OrderStopLoss()-sl)>point);
|
||||||
|
//--- check if there are changes in the Takeprofit level
|
||||||
|
bool TakeProfitChanged=(MathAbs(OrderTakeProfit()-tp)>point);
|
||||||
|
//--- if there are any changes in levels
|
||||||
|
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
|
||||||
|
return(true); // order can be modified
|
||||||
|
//--- there are no changes in the Open, StopLoss and Takeprofit levels
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- notify about the error
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
|
||||||
|
ticket,OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- came to the end, no changes for the order
|
||||||
|
return(false); // no point in modifying
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __MQL5__
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check the distance from opening price to activation price |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CheckOrderForFREEZE_LEVEL(string _symbol, ulong ticket)
|
||||||
|
{
|
||||||
|
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
|
||||||
|
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
|
||||||
|
if(freeze_level!=0)
|
||||||
|
{
|
||||||
|
if(suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
|
||||||
|
" nearer than %d points from the activation price",freeze_level,freeze_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- select order for working
|
||||||
|
if(!OrderSelect(ticket))
|
||||||
|
{
|
||||||
|
//--- failed to select order
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- get the order data
|
||||||
|
double price=OrderGetDouble(ORDER_PRICE_OPEN);
|
||||||
|
double sl=OrderGetDouble(ORDER_SL);
|
||||||
|
double tp=OrderGetDouble(ORDER_TP);
|
||||||
|
ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
|
||||||
|
//--- result of checking
|
||||||
|
bool check=false;
|
||||||
|
//--- check the order type
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case ORDER_TYPE_BUY_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((Ask-price)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
EnumToString(type),ticket,(int)((Ask-price)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case ORDER_TYPE_SELL_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((price-Bid)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified: Open-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
EnumToString(type),ticket,(int)((price-Bid)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- BuyStop pending order
|
||||||
|
case ORDER_TYPE_BUY_STOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((price-Ask)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
EnumToString(type),ticket,(int)((price-Ask)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- SellStop pending order
|
||||||
|
case ORDER_TYPE_SELL_STOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((Bid-price)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified: Bid-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
EnumToString(type),ticket,(int)((Bid-price)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//--- order did not pass the check
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check if the TP and SL are too close to activation price |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CheckPositionForFREEZE_LEVEL(string _symbol, ulong ticket)
|
||||||
|
{
|
||||||
|
|
||||||
|
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
|
||||||
|
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
|
||||||
|
if(freeze_level!=0 && suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
|
||||||
|
" nearer than %d points from the activation price",freeze_level,freeze_level);
|
||||||
|
}
|
||||||
|
//--- select position for working
|
||||||
|
if(!PositionSelectByTicket(ticket))
|
||||||
|
{
|
||||||
|
//--- failed to select position
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- get the order data
|
||||||
|
ENUM_POSITION_TYPE pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||||||
|
double sl=PositionGetDouble(POSITION_SL);
|
||||||
|
double tp=PositionGetDouble(POSITION_TP);
|
||||||
|
//--- result of checking StopLoss and TakeProfit
|
||||||
|
bool SL_check=false,TP_check=false;
|
||||||
|
//--- position type
|
||||||
|
switch(pos_type)
|
||||||
|
{
|
||||||
|
//--- buy
|
||||||
|
case POSITION_TYPE_BUY:
|
||||||
|
{
|
||||||
|
SL_check=(sl == 0) ? true: (Bid-sl>freeze_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Position %s #%d cannot be modified: Bid-StopLoss=%d points"+
|
||||||
|
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
|
||||||
|
EnumToString(pos_type),ticket,(int)((Bid-sl)/_point),freeze_level);
|
||||||
|
TP_check=(tp == 0) ? true: (tp-Bid>freeze_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Position %s #%d cannot be modified: TakeProfit-Bid=%d points"+
|
||||||
|
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
|
||||||
|
EnumToString(pos_type),ticket,(int)((tp-Bid)/_point),freeze_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- sell
|
||||||
|
case POSITION_TYPE_SELL:
|
||||||
|
{
|
||||||
|
SL_check=(sl == 0) ? true: (sl-Ask>freeze_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Position %s cannot be modified: StopLoss-Ask=%d points"+
|
||||||
|
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
|
||||||
|
EnumToString(pos_type),(int)((sl-Ask)/_point),freeze_level);
|
||||||
|
TP_check=(tp == 0) ? true: (Ask-tp>freeze_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Position %s cannot be modified: Ask-TakeProfit=%d points"+
|
||||||
|
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
|
||||||
|
EnumToString(pos_type),(int)((Ask-tp)/_point),freeze_level);
|
||||||
|
//--- return the result of checking
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//--- position did not pass the check
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool CheckOrderForFREEZE_LEVEL(string _symbol,int ticket)
|
||||||
|
{
|
||||||
|
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
|
||||||
|
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
|
||||||
|
if(freeze_level!=0 && suppressLogOutput == false)
|
||||||
|
{
|
||||||
|
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
|
||||||
|
" nearer than %d points from the activation price",freeze_level,freeze_level);
|
||||||
|
}
|
||||||
|
//--- select order for working
|
||||||
|
if(!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
|
||||||
|
{
|
||||||
|
//--- failed to select order
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
//--- get the order data
|
||||||
|
double price=OrderOpenPrice();
|
||||||
|
double sl=OrderStopLoss();
|
||||||
|
double tp=OrderTakeProfit();
|
||||||
|
int type=OrderType();
|
||||||
|
//--- result of checking
|
||||||
|
bool check=false;
|
||||||
|
//--- check the order type
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case OP_BUYLIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((Ask-price)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_BUYLIMIT #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((Ask-price)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case OP_SELLLIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((price-Bid)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_SELLLIMIT #%d cannot be modified: Open-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((price-Bid)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- BuyStop pending order
|
||||||
|
case OP_BUYSTOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((price-Ask)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_BUYSTOP #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((price-Ask)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- SellStop pending order
|
||||||
|
case OP_SELLSTOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=((Bid-price)>freeze_level*_point);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_SELLSTOP #%d cannot be modified: Bid-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((Bid-price)/_point),freeze_level);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- checking opened Buy order
|
||||||
|
case OP_BUY:
|
||||||
|
{
|
||||||
|
//--- check TakeProfit distance to the activation price
|
||||||
|
bool TP_check=(tp == 0) ? true: (tp-Bid>freeze_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((tp-Bid)/_point),freeze_level);
|
||||||
|
//--- check TakeProfit distance to the activation price
|
||||||
|
bool SL_check=(sl == 0) ? true: (Bid-sl>freeze_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((Bid-sl)/_point),freeze_level);
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- checking opened Sell order
|
||||||
|
case OP_SELL:
|
||||||
|
{
|
||||||
|
//--- check TakeProfit distance to the activation price
|
||||||
|
bool TP_check=(tp == 0) ? true: (Ask-tp>freeze_level*_point);
|
||||||
|
if(!TP_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_SELL %d cannot be modified: Ask-TakeProfit=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((Ask-tp)/_point),freeze_level);
|
||||||
|
//--- check TakeProfit distance to the activation price
|
||||||
|
bool SL_check=(sl == 0) ? true: (sl-Ask>freeze_level*_point);
|
||||||
|
if(!SL_check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
|
||||||
|
ticket,(int)((sl-Ask)/_point),freeze_level);
|
||||||
|
return(SL_check&&TP_check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//--- order did not pass the check
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool CheckPendingOrderEntryChange(string _symbol, ulong ticket, double newEntryPrice)
|
||||||
|
{
|
||||||
|
//--- select order for working
|
||||||
|
if(!OrderSelect(ticket))
|
||||||
|
{
|
||||||
|
//--- failed to select order
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- get the order data
|
||||||
|
ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
|
||||||
|
//--- result of checking
|
||||||
|
bool check=false;
|
||||||
|
//--- check the order type
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case ORDER_TYPE_BUY_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check= (newEntryPrice < Ask);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified",
|
||||||
|
EnumToString(type),ticket);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- BuyLimit pending order
|
||||||
|
case ORDER_TYPE_SELL_LIMIT:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=(newEntryPrice > Bid);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified",
|
||||||
|
EnumToString(type),ticket);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
//--- BuyStop pending order
|
||||||
|
case ORDER_TYPE_BUY_STOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=(newEntryPrice > Ask);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified",
|
||||||
|
EnumToString(type),ticket);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
//--- SellStop pending order
|
||||||
|
case ORDER_TYPE_SELL_STOP:
|
||||||
|
{
|
||||||
|
//--- check the distance from the opening price to the activation price
|
||||||
|
check=(newEntryPrice < Bid);
|
||||||
|
if(!check && suppressLogOutput == false)
|
||||||
|
PrintFormat("Order %s #%d cannot be modified",
|
||||||
|
EnumToString(type),ticket);
|
||||||
|
return(check);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//--- order did not pass the check
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,565 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| RangeBars.mqh ver:1.47.0 |
|
|
||||||
//| Copyright 2017, AZ-iNVEST |
|
|
||||||
//| http://www.az-invest.eu |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
|
||||||
#property link "http://www.az-invest.eu"
|
|
||||||
|
|
||||||
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
#include <RangeBarSettings.mqh>
|
|
||||||
|
|
||||||
class RangeBars
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
RangeBarSettings * rangeBarSettings;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Median renko indicator handle
|
|
||||||
//
|
|
||||||
|
|
||||||
int rangeBarsHandle;
|
|
||||||
string rangeBarsSymbol;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
RangeBars();
|
|
||||||
RangeBars(string symbol);
|
|
||||||
~RangeBars(void);
|
|
||||||
|
|
||||||
int Init();
|
|
||||||
void Deinit();
|
|
||||||
bool Reload();
|
|
||||||
|
|
||||||
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 GetMA1(double &MA[], int start, int count);
|
|
||||||
bool GetMA2(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:
|
|
||||||
|
|
||||||
bool GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
RangeBars::RangeBars(void)
|
|
||||||
{
|
|
||||||
rangeBarSettings = new RangeBarSettings();
|
|
||||||
rangeBarsHandle = INVALID_HANDLE;
|
|
||||||
rangeBarsSymbol = _Symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
RangeBars::RangeBars(string symbol)
|
|
||||||
{
|
|
||||||
rangeBarSettings = new RangeBarSettings();
|
|
||||||
rangeBarsHandle = INVALID_HANDLE;
|
|
||||||
rangeBarsSymbol = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
RangeBars::~RangeBars(void)
|
|
||||||
{
|
|
||||||
if(rangeBarSettings != NULL)
|
|
||||||
delete rangeBarSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function for initializing the median renko indicator handle
|
|
||||||
//
|
|
||||||
|
|
||||||
int RangeBars::Init()
|
|
||||||
{
|
|
||||||
if(!MQLInfoInteger((int)MQL5_TESTING))
|
|
||||||
{
|
|
||||||
if(!rangeBarSettings.Load())
|
|
||||||
{
|
|
||||||
if(rangeBarsHandle != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
// could not read new settings - keep old settings
|
|
||||||
|
|
||||||
return rangeBarsHandle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Print("Failed to load indicator settings.");
|
|
||||||
Alert("You need to put the Median Renko indicator on your chart first!");
|
|
||||||
return INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rangeBarsHandle != INVALID_HANDLE)
|
|
||||||
Deinit();
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef SHOW_INDICATOR_INPUTS
|
|
||||||
//
|
|
||||||
// Load settings from EA inputs
|
|
||||||
//
|
|
||||||
rangeBarSettings.Load();
|
|
||||||
#else
|
|
||||||
//
|
|
||||||
// Save indicator inputs for use by EA attached to same chart.
|
|
||||||
//
|
|
||||||
rangeBarSettings.Save();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
RANGEBAR_SETTINGS s = rangeBarSettings.Get();
|
|
||||||
|
|
||||||
//RangeBarSettings.Debug();
|
|
||||||
|
|
||||||
rangeBarsHandle = iCustom(this.rangeBarsSymbol,PERIOD_M1,RANGEBAR_INDICATOR_NAME,
|
|
||||||
s.barSizeInTicks,
|
|
||||||
s._startFromDateTime,
|
|
||||||
s.resetOpenOnNewTradingDay,
|
|
||||||
showNextBarLevels,
|
|
||||||
HighThresholdIndicatorColor,
|
|
||||||
LowThresholdIndicatorColor,
|
|
||||||
showCurrentBarOpenTime,
|
|
||||||
InfoTextColor,
|
|
||||||
UseSoundSignalOnNewBar,
|
|
||||||
OnlySignalReversalBars,
|
|
||||||
UseAlertWindow,
|
|
||||||
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,
|
|
||||||
"",
|
|
||||||
s.DonchianPeriod,
|
|
||||||
s.BBapplyTo,
|
|
||||||
s.BollingerBandsPeriod,
|
|
||||||
s.BollingerBandsDeviations,
|
|
||||||
s.SuperTrendPeriod,
|
|
||||||
s.SuperTrendMultiplier,
|
|
||||||
"",
|
|
||||||
UsedInEA);
|
|
||||||
|
|
||||||
if(rangeBarsHandle == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
Print("RangeBars indicator init failed on error ",GetLastError());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Print("RangeBars indicator init OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
return rangeBarsHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function for reloading the Median Renko indicator if needed
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::Reload()
|
|
||||||
{
|
|
||||||
if(rangeBarSettings.Changed())
|
|
||||||
{
|
|
||||||
if(Init() == INVALID_HANDLE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function for releasing the Median Renko indicator hanlde - free resources
|
|
||||||
//
|
|
||||||
|
|
||||||
void RangeBars::Deinit()
|
|
||||||
{
|
|
||||||
if(rangeBarsHandle == INVALID_HANDLE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(IndicatorRelease(rangeBarsHandle))
|
|
||||||
Print("RangeBars indicator handle released");
|
|
||||||
else
|
|
||||||
Print("Failed to release RangeBars indicator handle");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function for detecting a new Renko bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::IsNewBar()
|
|
||||||
{
|
|
||||||
MqlRates currentRenko[1];
|
|
||||||
static MqlRates prevRenko;
|
|
||||||
|
|
||||||
GetMqlRates(currentRenko,1,1);
|
|
||||||
|
|
||||||
if((prevRenko.open != currentRenko[0].open) ||
|
|
||||||
(prevRenko.high != currentRenko[0].high) ||
|
|
||||||
(prevRenko.low != currentRenko[0].low) ||
|
|
||||||
(prevRenko.close != currentRenko[0].close))
|
|
||||||
{
|
|
||||||
prevRenko.open = currentRenko[0].open;
|
|
||||||
prevRenko.high = currentRenko[0].high;
|
|
||||||
prevRenko.low = currentRenko[0].low;
|
|
||||||
prevRenko.close = currentRenko[0].close;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count)
|
|
||||||
{
|
|
||||||
double o[],l[],h[],c[],time[],tick_volume[];
|
|
||||||
|
|
||||||
if(ArrayResize(o,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(l,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(h,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(c,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(time,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(tick_volume,count) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,count,l) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,count,h) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,count,c) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BAR_OPEN_TIME,start,count,time) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_TICK_VOLUME,start,count,tick_volume) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(ArrayResize(ratesInfoArray,count) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int tempOffset = count-1;
|
|
||||||
for(int i=0; i<count; i++)
|
|
||||||
{
|
|
||||||
ratesInfoArray[tempOffset-i].open = o[i];
|
|
||||||
ratesInfoArray[tempOffset-i].low = l[i];
|
|
||||||
ratesInfoArray[tempOffset-i].high = h[i];
|
|
||||||
ratesInfoArray[tempOffset-i].close = c[i];
|
|
||||||
ratesInfoArray[tempOffset-i].time = (datetime)time[i];
|
|
||||||
ratesInfoArray[tempOffset-i].tick_volume = (long)tick_volume[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayFree(o);
|
|
||||||
ArrayFree(l);
|
|
||||||
ArrayFree(h);
|
|
||||||
ArrayFree(c);
|
|
||||||
ArrayFree(time);
|
|
||||||
ArrayFree(tick_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)
|
|
||||||
{
|
|
||||||
if(ArrayResize(o,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)
|
|
||||||
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(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)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get "count" MovingAverage1 values into "MA[]" array starting from "start" bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetMA1(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_MA1,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" MovingAverage2 values into "MA[]" starting from "start" bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetMA2(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_MA2,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
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
|
||||||
{
|
|
||||||
return GetChannel(HighArray,MidArray,LowArray,start,count);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get "count" Bollinger band values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
|
||||||
{
|
|
||||||
return GetChannel(HighArray,MidArray,LowArray,start,count);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get "count" SuperTrend values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
|
|
||||||
{
|
|
||||||
return GetChannel(SuperTrendHighArray,SuperTrendArray,SuperTrendLowArray,start,count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Private function used by GetRenkoDonchian and GetRenkoBollingerBands functions to get data
|
|
||||||
//
|
|
||||||
|
|
||||||
bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
|
|
||||||
{
|
|
||||||
double tempH[], tempM[], tempL[];
|
|
||||||
|
|
||||||
if(ArrayResize(tempH,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(tempM,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(tempL,count) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(ArrayResize(HighArray,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(MidArray,count) == -1)
|
|
||||||
return false;
|
|
||||||
if(ArrayResize(LowArray,count) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_HIGH,start,count,tempH) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_MID,start,count,tempM) == -1)
|
|
||||||
return false;
|
|
||||||
if(CopyBuffer(rangeBarsHandle,RANGEBAR_CHANNEL_LOW,start,count,tempL) == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int tempOffset = count-1;
|
|
||||||
for(int i=0; i<count; i++)
|
|
||||||
{
|
|
||||||
HighArray[tempOffset-i] = tempH[i];
|
|
||||||
MidArray[tempOffset-i] = tempM[i];
|
|
||||||
LowArray[tempOffset-i] = tempL[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayFree(tempH);
|
|
||||||
ArrayFree(tempM);
|
|
||||||
ArrayFree(tempL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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 =customChartIndicator.High[i];
|
||||||
|
double prevHi=customChartIndicator.High[i-1];
|
||||||
|
double Lo =customChartIndicator.Low[i];
|
||||||
|
double prevLo=customChartIndicator.Low[i-1];
|
||||||
|
double prevCl=customChartIndicator.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);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| ATR.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 "Average True Range"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
//--- indicator settings
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 2
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 DodgerBlue
|
||||||
|
#property indicator_label1 "ATR"
|
||||||
|
//--- input parameters
|
||||||
|
input int InpAtrPeriod=14; // ATR period
|
||||||
|
//--- indicator buffers
|
||||||
|
double ExtATRBuffer[];
|
||||||
|
double ExtTRBuffer[];
|
||||||
|
//--- global variable
|
||||||
|
int ExtPeriodATR;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- check for input value
|
||||||
|
if(InpAtrPeriod<=0)
|
||||||
|
{
|
||||||
|
ExtPeriodATR=14;
|
||||||
|
printf("Incorrect input parameter InpAtrPeriod = %d. Indicator will use value %d for calculations.",InpAtrPeriod,ExtPeriodATR);
|
||||||
|
}
|
||||||
|
else ExtPeriodATR=InpAtrPeriod;
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,ExtATRBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,ExtTRBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//---
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||||
|
//--- sets first bar from what index will be drawn
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpAtrPeriod);
|
||||||
|
//--- name for DataWindow and indicator subwindow label
|
||||||
|
string short_name="ATR("+string(ExtPeriodATR)+")";
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||||
|
//--- initialization done
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Average True Range |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
int i,limit;
|
||||||
|
//--- check for bars count
|
||||||
|
if(rates_total<=ExtPeriodATR)
|
||||||
|
return(0); // not enough bars for calculation
|
||||||
|
//--- preliminary calculations
|
||||||
|
if(_prev_calculated==0)
|
||||||
|
{
|
||||||
|
ExtTRBuffer[0]=0.0;
|
||||||
|
ExtATRBuffer[0]=0.0;
|
||||||
|
//--- filling out the array of True Range values for each period
|
||||||
|
for(i=1;i<rates_total && !IsStopped();i++)
|
||||||
|
ExtTRBuffer[i]=MathMax(customChartIndicator.High[i],customChartIndicator.Close[i-1])-MathMin(customChartIndicator.Low[i],customChartIndicator.Close[i-1]);
|
||||||
|
//--- first AtrPeriod values of the indicator are not calculated
|
||||||
|
double firstValue=0.0;
|
||||||
|
for(i=1;i<=ExtPeriodATR;i++)
|
||||||
|
{
|
||||||
|
ExtATRBuffer[i]=0.0;
|
||||||
|
firstValue+=ExtTRBuffer[i];
|
||||||
|
}
|
||||||
|
//--- calculating the first value of the indicator
|
||||||
|
firstValue/=ExtPeriodATR;
|
||||||
|
ExtATRBuffer[ExtPeriodATR]=firstValue;
|
||||||
|
limit=ExtPeriodATR+1;
|
||||||
|
}
|
||||||
|
else limit=_prev_calculated-1;
|
||||||
|
//--- the main loop of calculations
|
||||||
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtTRBuffer[i]=MathMax(customChartIndicator.High[i],customChartIndicator.Close[i-1])-MathMin(customChartIndicator.Low[i],customChartIndicator.Close[i-1]);
|
||||||
|
ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-ExtPeriodATR])/ExtPeriodATR;
|
||||||
|
}
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
@@ -0,0 +1,112 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Awesome_Oscillator.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 4
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_COLOR_HISTOGRAM
|
||||||
|
#property indicator_color1 Green,Red
|
||||||
|
#property indicator_width1 1
|
||||||
|
#property indicator_label1 "AO"
|
||||||
|
//--- indicator buffers
|
||||||
|
double ExtAOBuffer[];
|
||||||
|
double ExtColorBuffer[];
|
||||||
|
double ExtFastBuffer[];
|
||||||
|
double ExtSlowBuffer[];
|
||||||
|
//--- bars minimum for calculation
|
||||||
|
#define DATA_LIMIT 33
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//---- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,ExtAOBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,ExtColorBuffer,INDICATOR_COLOR_INDEX);
|
||||||
|
SetIndexBuffer(2,ExtFastBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(3,ExtSlowBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//--- set accuracy
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||||
|
//--- sets first bar from what index will be drawn
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,33);
|
||||||
|
//--- name for DataWindow
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"AO");
|
||||||
|
//--- get handles
|
||||||
|
//ExtFastSMAHandle=iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN);
|
||||||
|
//ExtSlowSMAHandle=iMA(NULL,0,34,0,MODE_SMA,PRICE_MEDIAN);
|
||||||
|
// -- Set applied price to MEDIAN as required by AO indicator
|
||||||
|
customChartIndicator.SetUseAppliedPriceFlag(PRICE_MEDIAN);
|
||||||
|
//---- initialization done
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Awesome 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 &tick_volume[],
|
||||||
|
const long &volume[],
|
||||||
|
const int &spread[])
|
||||||
|
{
|
||||||
|
|
||||||
|
//--- check for rates total
|
||||||
|
if(rates_total<=DATA_LIMIT)
|
||||||
|
return(0);// not enough bars for calculation
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//--- get Fast MA buffer
|
||||||
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,5,customChartIndicator.Price,ExtFastBuffer);
|
||||||
|
//--- get Slow MA buffer
|
||||||
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,35,customChartIndicator.Price,ExtSlowBuffer);
|
||||||
|
|
||||||
|
//--- first calculation or number of bars was changed
|
||||||
|
int i,limit;
|
||||||
|
if(_prev_calculated<=DATA_LIMIT)
|
||||||
|
{
|
||||||
|
for(i=0;i<DATA_LIMIT;i++)
|
||||||
|
ExtAOBuffer[i]=0.0;
|
||||||
|
limit=DATA_LIMIT;
|
||||||
|
}
|
||||||
|
else limit=_prev_calculated-1;
|
||||||
|
//--- main loop of calculations
|
||||||
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtAOBuffer[i]=ExtFastBuffer[i]-ExtSlowBuffer[i];
|
||||||
|
if(ExtAOBuffer[i]>ExtAOBuffer[i-1])ExtColorBuffer[i]=0.0; // set color Green
|
||||||
|
else ExtColorBuffer[i]=1.0; // set color Red
|
||||||
|
}
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,172 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
#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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||||
|
//
|
||||||
|
|
||||||
|
customChartIndicator.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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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,customChartIndicator.Price);
|
||||||
|
//--- calculate D
|
||||||
|
dTmp=0.0;
|
||||||
|
for(j=0;j<ExtCCIPeriod;j++) dTmp+=MathAbs(customChartIndicator.Price[i-j]-ExtSPBuffer[i]);
|
||||||
|
ExtDBuffer[i]=dTmp*dMul;
|
||||||
|
//--- calculate M
|
||||||
|
ExtMBuffer[i]=customChartIndicator.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,110 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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(customChartIndicator.High[i]>customChartIndicator.High[i+1] && customChartIndicator.High[i]>customChartIndicator.High[i+2] && customChartIndicator.High[i]>=customChartIndicator.High[i-1] && customChartIndicator.High[i]>=customChartIndicator.High[i-2])
|
||||||
|
ExtUpperBuffer[i]=customChartIndicator.High[i];
|
||||||
|
else ExtUpperBuffer[i]=EMPTY_VALUE;
|
||||||
|
|
||||||
|
//---- Lower Fractal
|
||||||
|
if(customChartIndicator.Low[i]<customChartIndicator.Low[i+1] && customChartIndicator.Low[i]<customChartIndicator.Low[i+2] && customChartIndicator.Low[i]<=customChartIndicator.Low[i-1] && customChartIndicator.Low[i]<=customChartIndicator.Low[i-2])
|
||||||
|
ExtLowerBuffer[i]=customChartIndicator.Low[i];
|
||||||
|
else ExtLowerBuffer[i]=EMPTY_VALUE;
|
||||||
|
}
|
||||||
|
//--- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,402 @@
|
|||||||
|
//------------------------------------------------------------------
|
||||||
|
#property copyright "mladen"
|
||||||
|
#property link "www.forex-tsd.com"
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 6
|
||||||
|
#property indicator_plots 3
|
||||||
|
#property indicator_label1 "Gann zone"
|
||||||
|
#property indicator_type1 DRAW_FILLING
|
||||||
|
#property indicator_color1 clrGainsboro,clrGainsboro
|
||||||
|
#property indicator_label2 "Gann middle"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_style2 STYLE_DOT
|
||||||
|
#property indicator_color2 clrGray
|
||||||
|
#property indicator_label3 "Gann high/low"
|
||||||
|
#property indicator_type3 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color3 clrDimGray,clrLimeGreen,clrDarkOrange
|
||||||
|
#property indicator_width3 2
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
enum enMaTypes
|
||||||
|
{
|
||||||
|
ma_sma, // Simple moving average
|
||||||
|
ma_ema, // Exponential moving average
|
||||||
|
ma_smma, // Smoothed MA
|
||||||
|
ma_lwma // Linear weighted MA
|
||||||
|
};
|
||||||
|
enum enFilterWhat
|
||||||
|
{
|
||||||
|
flt_prc, // Filter the prices
|
||||||
|
flt_val, // Filter the averages value
|
||||||
|
flt_all // Filter all
|
||||||
|
};
|
||||||
|
ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame
|
||||||
|
input int AvgPeriod = 10; // Average period
|
||||||
|
input enMaTypes AvgType = ma_sma; // Average method
|
||||||
|
input double Filter = 0; // Filter to use (<=0 for no filter)
|
||||||
|
input enFilterWhat FilterOn = flt_prc; // Filter :
|
||||||
|
input bool alertsOn = false; // Turn alerts on?
|
||||||
|
input bool alertsOnCurrent = true; // Alert on current bar?
|
||||||
|
input bool alertsMessage = true; // Display messageas on alerts?
|
||||||
|
input bool alertsSound = false; // Play sound on alerts?
|
||||||
|
input bool alertsEmail = false; // Send email on alerts?
|
||||||
|
input bool alertsNotify = false; // Send push notification on alerts?
|
||||||
|
input bool Interpolate = true; // Interpolate mtf data ?
|
||||||
|
|
||||||
|
double sup[],supc[],mid[],fup[],fdn[],_count[];
|
||||||
|
ENUM_TIMEFRAMES timeFrame;
|
||||||
|
string indName;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
SetIndexBuffer(0,fup,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,fdn,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2,mid,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(3,sup,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(4,supc,INDICATOR_COLOR_INDEX);
|
||||||
|
SetIndexBuffer(5,_count,INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
customChartIndicator.SetGetTimeFlag();
|
||||||
|
|
||||||
|
// timeFrame = MathMax(_Period,TimeFrame);
|
||||||
|
indName = getIndicatorName();
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,periodToString(timeFrame)+" Gann high/low activator("+string(AvgPeriod)+")");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
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 (Bars(_Symbol,_Period)<rates_total) return(-1);
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
|
||||||
|
double pfilter = Filter; if (FilterOn==flt_val) pfilter=0;
|
||||||
|
double vfilter = Filter; if (FilterOn==flt_prc) vfilter=0;
|
||||||
|
|
||||||
|
for (int i=(int)MathMax(_prev_calculated-1,1); i<rates_total && !IsStopped(); i++)
|
||||||
|
{
|
||||||
|
fup[i] = iFilter(iCustomMa(AvgType,iFilter(customChartIndicator.High[i-1],pfilter,AvgPeriod,i,rates_total,0),AvgPeriod,i,rates_total,0),vfilter,AvgPeriod,i,rates_total,1);
|
||||||
|
fdn[i] = iFilter(iCustomMa(AvgType,iFilter(customChartIndicator.Low[i-1] ,pfilter,AvgPeriod,i,rates_total,2),AvgPeriod,i,rates_total,1),vfilter,AvgPeriod,i,rates_total,3);
|
||||||
|
mid[i] = (fup[i]+fdn[i])/2.0;
|
||||||
|
double pclose = iFilter(customChartIndicator.Close[i],pfilter,AvgPeriod,i,rates_total,4);
|
||||||
|
supc[i] = (pclose>fup[i]) ? 1 : (pclose<fdn[i]) ? 2 : supc[i-1];
|
||||||
|
sup[i] = (supc[i]==1) ? fdn[i] : (supc[i]==2) ? fup[i] : pclose;
|
||||||
|
}
|
||||||
|
manageAlerts(customChartIndicator.Time,supc,rates_total);
|
||||||
|
_count[rates_total-1] = MathMax(rates_total-_prev_calculated+1,1);
|
||||||
|
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#define _filterInstances 5
|
||||||
|
double workFil[][_filterInstances*3];
|
||||||
|
|
||||||
|
#define _fchange 0
|
||||||
|
#define _fachang 1
|
||||||
|
#define _fvalue 2
|
||||||
|
|
||||||
|
double iFilter(double value, double filter, int period, int i, int bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
if (filter<=0 || period<=0) return(value);
|
||||||
|
if (ArrayRange(workFil,0)!= bars) ArrayResize(workFil,bars); instanceNo*=3;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
workFil[i][instanceNo+_fvalue] = value;
|
||||||
|
if (i>0)
|
||||||
|
{
|
||||||
|
workFil[i][instanceNo+_fchange] = MathAbs(workFil[i][instanceNo+_fvalue]-workFil[i-1][instanceNo+_fvalue]);
|
||||||
|
workFil[i][instanceNo+_fachang] = workFil[i][instanceNo+_fchange];
|
||||||
|
|
||||||
|
double fdev=0, fdif=0;
|
||||||
|
for (int k=1; k<period && (i-k)>=0; k++) workFil[i][instanceNo+_fachang] += workFil[i-k][instanceNo+_fchange]; workFil[i][instanceNo+_fachang] /= (double)period;
|
||||||
|
for (int k=0; k<period && (i-k)>=0; k++) fdev += MathPow(workFil[i-k][instanceNo+_fchange]-workFil[i-k][instanceNo+_fachang],2); fdev = MathSqrt(fdev/(double)period); fdif = filter*fdev;
|
||||||
|
if (MathAbs(workFil[i][instanceNo+_fvalue]-workFil[i-1][instanceNo+_fvalue])<fdif)
|
||||||
|
workFil[i][instanceNo+_fvalue]=workFil[i-1][instanceNo+_fvalue];
|
||||||
|
}
|
||||||
|
return(workFil[i][instanceNo+_fvalue]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
void manageAlerts(const datetime& time[], double& trend[], int bars)
|
||||||
|
{
|
||||||
|
if (!alertsOn) return;
|
||||||
|
int whichBar = bars-1; if (!alertsOnCurrent) whichBar = bars-2; datetime time1 = time[whichBar];
|
||||||
|
if (trend[whichBar] != trend[whichBar-1])
|
||||||
|
{
|
||||||
|
if (trend[whichBar] == 1) doAlert(time1,"up");
|
||||||
|
if (trend[whichBar] == 2) doAlert(time1,"down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
void doAlert(datetime forTime, string doWhat)
|
||||||
|
{
|
||||||
|
static string previousAlert="nothing";
|
||||||
|
static datetime previousTime;
|
||||||
|
string message;
|
||||||
|
|
||||||
|
if (previousAlert != doWhat || previousTime != forTime)
|
||||||
|
{
|
||||||
|
previousAlert = doWhat;
|
||||||
|
previousTime = forTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
message = periodToString(_Period)+" "+_Symbol+" at "+TimeToString(TimeLocal(),TIME_SECONDS)+" Gann high/low activator state changed to "+doWhat;
|
||||||
|
if (alertsMessage) Alert(message);
|
||||||
|
if (alertsEmail) SendMail(_Symbol+" Gann high/low activator",message);
|
||||||
|
if (alertsNotify) SendNotification(message);
|
||||||
|
if (alertsSound) PlaySound("alert2.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#define _maInstances 2
|
||||||
|
#define _maWorkBufferx1 1*_maInstances
|
||||||
|
#define _maWorkBufferx2 2*_maInstances
|
||||||
|
|
||||||
|
double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ma_sma : return(iSma(price,(int)length,r,bars,instanceNo));
|
||||||
|
case ma_ema : return(iEma(price,length,r,bars,instanceNo));
|
||||||
|
case ma_smma : return(iSmma(price,(int)length,r,bars,instanceNo));
|
||||||
|
case ma_lwma : return(iLwma(price,(int)length,r,bars,instanceNo));
|
||||||
|
default : return(price);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
double workSma[][_maWorkBufferx2];
|
||||||
|
double iSma(double price, int period, int r, int _bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
if (period<=1) return(price);
|
||||||
|
if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars); instanceNo *= 2; int k;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
workSma[r][instanceNo+0] = price;
|
||||||
|
workSma[r][instanceNo+1] = price; for(k=1; k<period && (r-k)>=0; k++) workSma[r][instanceNo+1] += workSma[r-k][instanceNo+0];
|
||||||
|
workSma[r][instanceNo+1] /= 1.0*k;
|
||||||
|
return(workSma[r][instanceNo+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
double workEma[][_maWorkBufferx1];
|
||||||
|
double iEma(double price, double period, int r, int _bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
if (period<=1) return(price);
|
||||||
|
if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
workEma[r][instanceNo] = price;
|
||||||
|
double alpha = 2.0 / (1.0+period);
|
||||||
|
if (r>0)
|
||||||
|
workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]);
|
||||||
|
return(workEma[r][instanceNo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
double workSmma[][_maWorkBufferx1];
|
||||||
|
double iSmma(double price, double period, int r, int _bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
if (period<=1) return(price);
|
||||||
|
if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
if (r<period)
|
||||||
|
workSmma[r][instanceNo] = price;
|
||||||
|
else workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period;
|
||||||
|
return(workSmma[r][instanceNo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
double workLwma[][_maWorkBufferx1];
|
||||||
|
double iLwma(double price, double period, int r, int _bars, int instanceNo=0)
|
||||||
|
{
|
||||||
|
if (period<=1) return(price);
|
||||||
|
if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
workLwma[r][instanceNo] = price;
|
||||||
|
double sumw = period;
|
||||||
|
double sum = period*price;
|
||||||
|
|
||||||
|
for(int k=1; k<period && (r-k)>=0; k++)
|
||||||
|
{
|
||||||
|
double weight = period-k;
|
||||||
|
sumw += weight;
|
||||||
|
sum += weight*workLwma[r-k][instanceNo];
|
||||||
|
}
|
||||||
|
return(sum/sumw);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
string getIndicatorName()
|
||||||
|
{
|
||||||
|
string progPath = MQL5InfoString(MQL5_PROGRAM_PATH); int start=-1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int foundAt = StringFind(progPath,"\\",start+1);
|
||||||
|
if (foundAt>=0)
|
||||||
|
start = foundAt;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string indicatorName = StringSubstr(progPath,start+1);
|
||||||
|
indicatorName = StringSubstr(indicatorName,0,StringLen(indicatorName)-4);
|
||||||
|
return(indicatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
int _tfsPer[]={PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
|
||||||
|
string _tfsStr[]={"1 minute","2 minutes","3 minutes","4 minutes","5 minutes","6 minutes","10 minutes","12 minutes","15 minutes","20 minutes","30 minutes","1 hour","2 hours","3 hours","4 hours","6 hours","8 hours","12 hours","daily","weekly","monthly"};
|
||||||
|
string periodToString(int period)
|
||||||
|
{
|
||||||
|
if (period==PERIOD_CURRENT)
|
||||||
|
period = _Period;
|
||||||
|
int i; for(i=0;i<ArraySize(_tfsPer);i++) if(period==_tfsPer[i]) break;
|
||||||
|
return(_tfsStr[i]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
ArraySetAsSeries(customChartIndicator.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(customChartIndicator.Close[i],_Digits)>NormalizeDouble(MaHighBuffer[i+1],_Digits)) TrendBuffer[i]=1;
|
||||||
|
if(NormalizeDouble(customChartIndicator.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,115 @@
|
|||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//--- preliminary calculations
|
||||||
|
if(_prev_calculated==0)
|
||||||
|
{
|
||||||
|
//--- set first candle
|
||||||
|
ExtLBuffer[0]=customChartIndicator.Low[0];
|
||||||
|
ExtHBuffer[0]=customChartIndicator.High[0];
|
||||||
|
ExtOBuffer[0]=customChartIndicator.Open[0];
|
||||||
|
ExtCBuffer[0]=customChartIndicator.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=(customChartIndicator.Open[i]+customChartIndicator.High[i]+customChartIndicator.Low[i]+customChartIndicator.Close[i])/4;
|
||||||
|
double haHigh=MathMax(customChartIndicator.High[i],MathMax(haOpen,haClose));
|
||||||
|
double haLow=MathMin(customChartIndicator.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,158 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
//--- 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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]=customChartIndicator.Close[i];
|
||||||
|
//--- tenkan sen
|
||||||
|
double _high=Highest(customChartIndicator.High,InpTenkan,i);
|
||||||
|
double _low=Lowest(customChartIndicator.Low,InpTenkan,i);
|
||||||
|
ExtTenkanBuffer[i]=(_high+_low)/2.0;
|
||||||
|
//--- kijun sen
|
||||||
|
_high=Highest(customChartIndicator.High,InpKijun,i);
|
||||||
|
_low=Lowest(customChartIndicator.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(customChartIndicator.High,InpSenkou,i);
|
||||||
|
_low=Lowest(customChartIndicator.Low,InpSenkou,i);
|
||||||
|
ExtSpanBBuffer[i]=(_high+_low)/2.0;
|
||||||
|
}
|
||||||
|
//--- done
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
|
|||||||
|
#property description "Linear Regression"
|
||||||
|
#property description "https://www.mql5.com/en/articles/270"
|
||||||
|
#property copyright "ds2"
|
||||||
|
#property version "1.0"
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 1
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 Cyan
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
input int LRPeriod = 20; // Bars in regression
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
// The main buffer - drawing a line on a chart
|
||||||
|
double ExtLRBuffer[];
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
SetIndexBuffer(0, ExtLRBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, LRPeriod-1);
|
||||||
|
|
||||||
|
IndicatorSetString (INDICATOR_SHORTNAME,"Linear Regression");
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||||
|
|
||||||
|
customChartIndicator.SetUseAppliedPriceFlag(PRICE_CLOSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (rates_total < LRPeriod)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int limit = _prev_calculated ? _prev_calculated-1 : LRPeriod-1;
|
||||||
|
|
||||||
|
// The cycle along the calculated bars
|
||||||
|
for (int bar = limit; bar < rates_total; bar++)
|
||||||
|
{
|
||||||
|
double lrvalue = 0; // the linear regression value in this bar
|
||||||
|
double Sx=0, Sy=0, Sxy=0, Sxx=0;
|
||||||
|
|
||||||
|
// Finding intermediate values-sums
|
||||||
|
Sx = 0;
|
||||||
|
Sy = 0;
|
||||||
|
Sxx = 0;
|
||||||
|
Sxy = 0;
|
||||||
|
for (int x = 1; x <= LRPeriod; x++)
|
||||||
|
{
|
||||||
|
double y = customChartIndicator.GetPrice(bar-LRPeriod+x);
|
||||||
|
Sx += x;
|
||||||
|
Sy += y;
|
||||||
|
Sxx += x*x;
|
||||||
|
Sxy += x*y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regression ratios
|
||||||
|
double a = (LRPeriod * Sxy - Sx * Sy) / (LRPeriod * Sxx - Sx * Sx);
|
||||||
|
double b = (Sy - a * Sx) / LRPeriod;
|
||||||
|
|
||||||
|
lrvalue = a*LRPeriod + b;
|
||||||
|
|
||||||
|
// Saving regression results
|
||||||
|
ExtLRBuffer[bar] = lrvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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
|
||||||
|
//
|
||||||
|
|
||||||
|
customChartIndicator.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[])
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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,customChartIndicator.Price); break;
|
||||||
|
case MODE_LWMA: CalculateLWMA(rates_total,_prev_calculated,_begin,customChartIndicator.Price); break;
|
||||||
|
case MODE_SMMA: CalculateSmoothedMA(rates_total,_prev_calculated,_begin,customChartIndicator.Price); break;
|
||||||
|
case MODE_SMA: CalculateSimpleMA(rates_total,_prev_calculated,_begin,customChartIndicator.Price); break;
|
||||||
|
}
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
#property copyright "2009, MetaQuotes Software Corp."
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Moving Average Convergence/Divergence"
|
#property description "Moving Average Convergence/Divergence"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
|
||||||
#include <MovingAverages.mqh>
|
#include <MovingAverages.mqh>
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
@@ -35,17 +37,8 @@ double ExtFastMaBuffer[];
|
|||||||
double ExtSlowMaBuffer[];
|
double ExtSlowMaBuffer[];
|
||||||
double ExtMacdBuffer[];
|
double ExtMacdBuffer[];
|
||||||
|
|
||||||
//
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
// Initialize MedianRenko indicator for data processing
|
RangeBarIndicator customChartIndicator;
|
||||||
// according to settings of the MedianRenko indicator already on chart
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <RangeBarIndicator.mqh>
|
|
||||||
RangeBarIndicator rangeBarsIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Custom indicator initialization function |
|
//| Custom indicator initialization function |
|
||||||
@@ -79,53 +72,44 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
const long &Volume[],
|
const long &Volume[],
|
||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Precoess data through MedianRenko indicator
|
|
||||||
//
|
|
||||||
|
|
||||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(rangeBarsIndicator.GetPrevCalculated());
|
return(0);
|
||||||
|
|
||||||
//
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
// Make the following modifications in the code below:
|
return(0);
|
||||||
//
|
|
||||||
// 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[]
|
|
||||||
//
|
|
||||||
|
|
||||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
int _rates_total = customChartIndicator.GetRatesTotal();
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
//--- check for data
|
//--- check for data
|
||||||
if(rates_total<InpSignalSMA)
|
if(_rates_total<InpSignalSMA)
|
||||||
return(0);
|
return(0);
|
||||||
//--- we can copy not all data
|
//--- we can copy not all data
|
||||||
int to_copy;
|
int to_copy;
|
||||||
if(_prev_calculated>rates_total || _prev_calculated<0) to_copy=rates_total;
|
if(_prev_calculated>_rates_total || _prev_calculated<0) to_copy=_rates_total;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to_copy=rates_total-_prev_calculated;
|
to_copy=_rates_total-_prev_calculated;
|
||||||
if(_prev_calculated>0) to_copy++;
|
if(_prev_calculated>0) to_copy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- get Fast EMA buffer
|
//--- get Fast EMA buffer
|
||||||
if(IsStopped()) return(0); //Checking for stop flag
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,rangeBarsIndicator.Close,ExtFastMaBuffer);
|
ExponentialMAOnBuffer(_rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
||||||
//--- get SlowSMA buffer
|
//--- get SlowSMA buffer
|
||||||
if(IsStopped()) return(0); //Checking for stop flag
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpSlowEMA,rangeBarsIndicator.Close,ExtSlowMaBuffer);
|
ExponentialMAOnBuffer(_rates_total,_prev_calculated,0,InpSlowEMA,customChartIndicator.Close,ExtSlowMaBuffer);
|
||||||
//---
|
//---
|
||||||
int limit;
|
int limit;
|
||||||
if(_prev_calculated==0)
|
if(_prev_calculated==0)
|
||||||
limit=0;
|
limit=0;
|
||||||
else limit=_prev_calculated-1;
|
else limit=_prev_calculated-1;
|
||||||
//--- calculate MACD
|
//--- calculate MACD
|
||||||
for(int i=limit;i<rates_total && !IsStopped();i++)
|
|
||||||
|
for(int i=limit;i<_rates_total && !IsStopped();i++)
|
||||||
{
|
{
|
||||||
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||||
if(ExtMacdBuffer[i] > 0)
|
if(ExtMacdBuffer[i] > 0)
|
||||||
@@ -140,8 +124,9 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//--- calculate Signal
|
//--- calculate Signal
|
||||||
SimpleMAOnBuffer(rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
SimpleMAOnBuffer(_rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
||||||
//--- OnCalculate done. Return new _prev_calculated.
|
//--- OnCalculate done. Return new _prev_calculated.
|
||||||
|
|
||||||
return(rates_total);
|
return(rates_total);
|
||||||
}
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| MACD.mq5 |
|
||||||
|
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||||
|
//| http://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
|
#property link "http://www.mql5.com"
|
||||||
|
#property description "Moving Average Convergence/Divergence"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
//--- indicator settings
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 4
|
||||||
|
#property indicator_plots 2
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color1 clrMagenta
|
||||||
|
#property indicator_color2 clrBlue
|
||||||
|
#property indicator_width1 2
|
||||||
|
#property indicator_width2 2
|
||||||
|
#property indicator_label1 "Main"
|
||||||
|
#property indicator_label2 "Signal"
|
||||||
|
//--- input parameters
|
||||||
|
input int InpFastEMA=12; // Fast EMA period
|
||||||
|
input int InpSlowEMA=26; // Slow EMA period
|
||||||
|
input int InpSignalSMA=9; // Signal SMA period
|
||||||
|
//--- indicator buffers
|
||||||
|
//double ExtMacdBufferUp[];
|
||||||
|
//double ExtMacdBufferDn[];
|
||||||
|
double ExtSignalBuffer[];
|
||||||
|
double ExtFastMaBuffer[];
|
||||||
|
double ExtSlowMaBuffer[];
|
||||||
|
double ExtMacdBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,ExtMacdBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,ExtSignalBuffer,INDICATOR_DATA);
|
||||||
|
//SetIndexBuffer(2,ExtSignalBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2,ExtFastMaBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(3,ExtSlowMaBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//SetIndexBuffer(4,ExtMacdBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//--- sets first bar from what index will be drawn
|
||||||
|
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,InpSignalSMA-1);
|
||||||
|
//--- name for Dindicator subwindow label
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"MACD("+string(InpFastEMA)+","+string(InpSlowEMA)+","+string(InpSignalSMA)+")");
|
||||||
|
//--- initialization done
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Moving Averages Convergence/Divergence |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Precoess data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
int _rates_total = customChartIndicator.GetRatesTotal();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//--- check for data
|
||||||
|
if(rates_total<InpSignalSMA)
|
||||||
|
return(0);
|
||||||
|
//--- we can copy not all data
|
||||||
|
int to_copy;
|
||||||
|
if(_prev_calculated>rates_total || _prev_calculated<0) to_copy=rates_total;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_copy=rates_total-_prev_calculated;
|
||||||
|
if(_prev_calculated>0) to_copy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--- get Fast EMA buffer
|
||||||
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
||||||
|
//--- get SlowSMA buffer
|
||||||
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpSlowEMA,customChartIndicator.Close,ExtSlowMaBuffer);
|
||||||
|
//---
|
||||||
|
int limit;
|
||||||
|
if(_prev_calculated==0)
|
||||||
|
limit=0;
|
||||||
|
else limit=_prev_calculated-1;
|
||||||
|
//--- calculate MACD
|
||||||
|
for(int i=limit;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||||
|
/*
|
||||||
|
if(ExtMacdBuffer[i] > 0)
|
||||||
|
{
|
||||||
|
ExtMacdBufferUp[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||||
|
ExtMacdBufferDn[i] = 0;
|
||||||
|
}
|
||||||
|
else if(ExtMacdBuffer[i] < 0)
|
||||||
|
{
|
||||||
|
ExtMacdBufferDn[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||||
|
ExtMacdBufferUp[i] = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
//--- calculate Signal
|
||||||
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
||||||
|
//--- OnCalculate done. Return new _prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
|
||||||
|
//
|
||||||
|
|
||||||
|
customChartIndicator.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;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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(customChartIndicator.Price[i-ExtMomentumPeriod] > 0)
|
||||||
|
ExtMomentumBuffer[i]=customChartIndicator.Price[i]*100/customChartIndicator.Price[i-ExtMomentumPeriod];
|
||||||
|
|
||||||
|
}
|
||||||
|
//--- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| iNRTR.mq5 |
|
||||||
|
//| MetaQuotes Software Corp. |
|
||||||
|
//| http://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "MetaQuotes Software Corp."
|
||||||
|
#property link "http://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 6
|
||||||
|
#property indicator_plots 4
|
||||||
|
//--- plot Support
|
||||||
|
#property indicator_label1 "Support"
|
||||||
|
#property indicator_type1 DRAW_ARROW
|
||||||
|
#property indicator_color1 DodgerBlue
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
//--- plot Resistance
|
||||||
|
#property indicator_label2 "Resistance"
|
||||||
|
#property indicator_type2 DRAW_ARROW
|
||||||
|
#property indicator_color2 Red
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 2
|
||||||
|
//--- plot UpTarget
|
||||||
|
#property indicator_label3 "UpTarget"
|
||||||
|
#property indicator_type3 DRAW_ARROW
|
||||||
|
#property indicator_color3 RoyalBlue
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 2
|
||||||
|
//--- plot DnTarget
|
||||||
|
#property indicator_label4 "DnTarget"
|
||||||
|
#property indicator_type4 DRAW_ARROW
|
||||||
|
#property indicator_color4 Crimson
|
||||||
|
#property indicator_style4 STYLE_SOLID
|
||||||
|
#property indicator_width4 2
|
||||||
|
//--- input parameters
|
||||||
|
input int period = 40; /*period*/ // ATR period in bars
|
||||||
|
input double k = 2.0; /*k*/ // ATR change coefficient
|
||||||
|
//--- indicator buffers
|
||||||
|
double SupportBuffer[];
|
||||||
|
double ResistanceBuffer[];
|
||||||
|
double UpTargetBuffer[];
|
||||||
|
double DnTargetBuffer[];
|
||||||
|
double Trend[];
|
||||||
|
double ATRBuffer[];
|
||||||
|
int Handle;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,SupportBuffer,INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(0,PLOT_ARROW,159);
|
||||||
|
|
||||||
|
SetIndexBuffer(1,ResistanceBuffer,INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(1,PLOT_ARROW,159);
|
||||||
|
|
||||||
|
SetIndexBuffer(2,UpTargetBuffer,INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(2,PLOT_ARROW,158);
|
||||||
|
|
||||||
|
SetIndexBuffer(3,DnTargetBuffer,INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(3,PLOT_ARROW,158);
|
||||||
|
|
||||||
|
SetIndexBuffer(4,Trend,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(5,ATRBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
|
||||||
|
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0);
|
||||||
|
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0);
|
||||||
|
PlotIndexSetDouble(4,PLOT_EMPTY_VALUE,0);
|
||||||
|
PlotIndexSetDouble(5,PLOT_EMPTY_VALUE,0);
|
||||||
|
|
||||||
|
Handle=iATR(_Symbol,PERIOD_CURRENT,period);
|
||||||
|
|
||||||
|
//---
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
static bool error=true;
|
||||||
|
int start;
|
||||||
|
if(_prev_calculated==0)
|
||||||
|
{
|
||||||
|
error=true;
|
||||||
|
}
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
ArrayInitialize(Trend,0);
|
||||||
|
ArrayInitialize(UpTargetBuffer,0);
|
||||||
|
ArrayInitialize(DnTargetBuffer,0);
|
||||||
|
ArrayInitialize(SupportBuffer,0);
|
||||||
|
ArrayInitialize(ResistanceBuffer,0);
|
||||||
|
start=period;
|
||||||
|
error=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start=_prev_calculated-1;
|
||||||
|
}
|
||||||
|
if(CopyBuffer(Handle,0,0,rates_total-start,ATRBuffer)==-1)
|
||||||
|
{
|
||||||
|
error=true;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
for(int i=start;i<rates_total;i++)
|
||||||
|
{
|
||||||
|
Trend[i]=Trend[i-1];
|
||||||
|
UpTargetBuffer[i]=UpTargetBuffer[i-1];
|
||||||
|
DnTargetBuffer[i]=DnTargetBuffer[i-1];
|
||||||
|
SupportBuffer[i]=SupportBuffer[i-1];
|
||||||
|
ResistanceBuffer[i]=ResistanceBuffer[i-1];
|
||||||
|
switch((int)Trend[i])
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if(customChartIndicator.Low[i]>UpTargetBuffer[i])
|
||||||
|
{
|
||||||
|
UpTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
SupportBuffer[i]=customChartIndicator.Close[i]-k*ATRBuffer[i];
|
||||||
|
}
|
||||||
|
if(customChartIndicator.Close[i]<SupportBuffer[i])
|
||||||
|
{
|
||||||
|
DnTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
ResistanceBuffer[i]=customChartIndicator.Close[i]+k*ATRBuffer[i];
|
||||||
|
Trend[i]=3;
|
||||||
|
UpTargetBuffer[i]=0;
|
||||||
|
SupportBuffer[i]=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(customChartIndicator.High[i]<DnTargetBuffer[i])
|
||||||
|
{
|
||||||
|
DnTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
ResistanceBuffer[i]=customChartIndicator.Close[i]+k*ATRBuffer[i];
|
||||||
|
}
|
||||||
|
if(customChartIndicator.Close[i]>ResistanceBuffer[i])
|
||||||
|
{
|
||||||
|
UpTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
SupportBuffer[i]=customChartIndicator.Close[i]-k*ATRBuffer[i];
|
||||||
|
Trend[i]=2;
|
||||||
|
DnTargetBuffer[i]=0;
|
||||||
|
ResistanceBuffer[i]=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
UpTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
DnTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
Trend[i]=1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(customChartIndicator.Low[i]>UpTargetBuffer[i])
|
||||||
|
{
|
||||||
|
UpTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
SupportBuffer[i]=customChartIndicator.Close[i]-k*ATRBuffer[i];
|
||||||
|
Trend[i]=2;
|
||||||
|
DnTargetBuffer[i]=0;
|
||||||
|
}
|
||||||
|
if(customChartIndicator.High[i]<DnTargetBuffer[i])
|
||||||
|
{
|
||||||
|
DnTargetBuffer[i]=customChartIndicator.Close[i];
|
||||||
|
ResistanceBuffer[i]=customChartIndicator.Close[i]+k*ATRBuffer[i];
|
||||||
|
Trend[i]=3;
|
||||||
|
UpTargetBuffer[i]=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| OBV.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 "On Balance Volume"
|
||||||
|
//--- indicator settings
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 1
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 DodgerBlue
|
||||||
|
#property indicator_label1 "OBV"
|
||||||
|
//--- input parametrs
|
||||||
|
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes
|
||||||
|
//---- indicator buffer
|
||||||
|
double ExtOBVBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize RangeBar indicator for data processing
|
||||||
|
// according to settings of the RangeBar indicator already on chart
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| On Balance Volume initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- define indicator buffer
|
||||||
|
SetIndexBuffer(0,ExtOBVBuffer);
|
||||||
|
//--- set indicator digits
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
//---- OnInit done
|
||||||
|
|
||||||
|
customChartIndicator.SetGetVolumesFlag();
|
||||||
|
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| On Balance Volume |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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 RangeBar indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//--- variables
|
||||||
|
int pos;
|
||||||
|
//--- check for bars count
|
||||||
|
if(rates_total<2)
|
||||||
|
return(0);
|
||||||
|
//--- starting calculation
|
||||||
|
pos=_prev_calculated-1;
|
||||||
|
//--- correct position, when it's first iteration
|
||||||
|
if(pos<1)
|
||||||
|
{
|
||||||
|
pos=1;
|
||||||
|
if(InpVolumeType==VOLUME_TICK)
|
||||||
|
ExtOBVBuffer[0]=(double)customChartIndicator.Tick_volume[0];
|
||||||
|
else ExtOBVBuffer[0]=(double)customChartIndicator.Real_volume[0];
|
||||||
|
}
|
||||||
|
//--- main cycle
|
||||||
|
if(InpVolumeType==VOLUME_TICK)
|
||||||
|
CalculateOBV(pos,rates_total,customChartIndicator.Close,customChartIndicator.Tick_volume);
|
||||||
|
else
|
||||||
|
CalculateOBV(pos,rates_total,customChartIndicator.Close,customChartIndicator.Real_volume);
|
||||||
|
//---- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Calculate OBV by volume argument |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CalculateOBV(int StartPosition,
|
||||||
|
int RatesCount,
|
||||||
|
const double &ClBuffer[],
|
||||||
|
const long &VolBuffer[])
|
||||||
|
{
|
||||||
|
for(int i=StartPosition;i<RatesCount && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
//--- get some data
|
||||||
|
double Volume=(double)VolBuffer[i];
|
||||||
|
double PrevClose=ClBuffer[i-1];
|
||||||
|
double CurrClose=ClBuffer[i];
|
||||||
|
//--- fill ExtOBVBuffer
|
||||||
|
if(CurrClose<PrevClose) ExtOBVBuffer[i]=ExtOBVBuffer[i-1]-Volume;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(CurrClose>PrevClose) ExtOBVBuffer[i]=ExtOBVBuffer[i-1]+Volume;
|
||||||
|
else ExtOBVBuffer[i]=ExtOBVBuffer[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
//--- 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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]=customChartIndicator.High[0];
|
||||||
|
ExtLastRevPos=0;
|
||||||
|
ExtDirectionLong=false;
|
||||||
|
ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,customChartIndicator.High);
|
||||||
|
ExtEPBuffer[0]=customChartIndicator.Low[pos];
|
||||||
|
ExtEPBuffer[1]=customChartIndicator.Low[pos];
|
||||||
|
}
|
||||||
|
//---main cycle
|
||||||
|
for(int i=pos;i<rates_total-1 && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
//--- check for reverse
|
||||||
|
if(ExtDirectionLong)
|
||||||
|
{
|
||||||
|
if(ExtSARBuffer[i]>customChartIndicator.Low[i])
|
||||||
|
{
|
||||||
|
//--- switch to SHORT
|
||||||
|
ExtDirectionLong=false;
|
||||||
|
ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,customChartIndicator.High);
|
||||||
|
ExtEPBuffer[i]=customChartIndicator.Low[i];
|
||||||
|
ExtLastRevPos=i;
|
||||||
|
ExtAFBuffer[i]=ExtSarStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(ExtSARBuffer[i]<customChartIndicator.High[i])
|
||||||
|
{
|
||||||
|
//--- switch to LONG
|
||||||
|
ExtDirectionLong=true;
|
||||||
|
ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,customChartIndicator.Low);
|
||||||
|
ExtEPBuffer[i]=customChartIndicator.High[i];
|
||||||
|
ExtLastRevPos=i;
|
||||||
|
ExtAFBuffer[i]=ExtSarStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- continue calculations
|
||||||
|
if(ExtDirectionLong)
|
||||||
|
{
|
||||||
|
//--- check for new High
|
||||||
|
if(customChartIndicator.High[i]>ExtEPBuffer[i-1] && i!=ExtLastRevPos)
|
||||||
|
{
|
||||||
|
ExtEPBuffer[i]=customChartIndicator.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]>customChartIndicator.Low[i] || ExtSARBuffer[i+1]>customChartIndicator.Low[i-1])
|
||||||
|
ExtSARBuffer[i+1]=MathMin(customChartIndicator.Low[i],customChartIndicator.Low[i-1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- check for new Low
|
||||||
|
if(customChartIndicator.Low[i]<ExtEPBuffer[i-1] && i!=ExtLastRevPos)
|
||||||
|
{
|
||||||
|
ExtEPBuffer[i]=customChartIndicator.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]<customChartIndicator.High[i] || ExtSARBuffer[i+1]<customChartIndicator.High[i-1])
|
||||||
|
ExtSARBuffer[i+1]=MathMax(customChartIndicator.High[i],customChartIndicator.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,114 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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
|
||||||
|
//
|
||||||
|
|
||||||
|
customChartIndicator.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[])
|
||||||
|
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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(customChartIndicator.Price[i]==0.0)
|
||||||
|
ExtRocBuffer[i]=0.0;
|
||||||
|
else
|
||||||
|
ExtRocBuffer[i]=(customChartIndicator.Price[i]-customChartIndicator.Price[i-ExtRocPeriod])/customChartIndicator.Price[i]*100;
|
||||||
|
}
|
||||||
|
//--- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -26,13 +26,11 @@ double ExtPosBuffer[];
|
|||||||
double ExtNegBuffer[];
|
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;
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -79,30 +77,16 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
const long &Volume[],
|
const long &Volume[],
|
||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
|
|
||||||
//
|
|
||||||
// Precoess data through MedianRenko indicator
|
|
||||||
//
|
//
|
||||||
|
|
||||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(rates_total);
|
return(0);
|
||||||
|
|
||||||
//
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
// Make the following modifications in the code below:
|
return(0);
|
||||||
//
|
|
||||||
// medianRenkoIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
// 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[]
|
|
||||||
//
|
|
||||||
|
|
||||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
int i,pos;
|
int i,pos;
|
||||||
@@ -114,7 +98,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
ArraySetAsSeries(ExtRSIBuffer,false);
|
ArraySetAsSeries(ExtRSIBuffer,false);
|
||||||
ArraySetAsSeries(ExtPosBuffer,false);
|
ArraySetAsSeries(ExtPosBuffer,false);
|
||||||
ArraySetAsSeries(ExtNegBuffer,false);
|
ArraySetAsSeries(ExtNegBuffer,false);
|
||||||
ArraySetAsSeries(rangeBarsIndicator.Close,false);
|
ArraySetAsSeries(customChartIndicator.Close,false);
|
||||||
//--- preliminary calculations
|
//--- preliminary calculations
|
||||||
pos=_prev_calculated-1;
|
pos=_prev_calculated-1;
|
||||||
if(pos<=InpRSIPeriod)
|
if(pos<=InpRSIPeriod)
|
||||||
@@ -130,7 +114,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
ExtRSIBuffer[i]=0.0;
|
ExtRSIBuffer[i]=0.0;
|
||||||
ExtPosBuffer[i]=0.0;
|
ExtPosBuffer[i]=0.0;
|
||||||
ExtNegBuffer[i]=0.0;
|
ExtNegBuffer[i]=0.0;
|
||||||
diff=rangeBarsIndicator.Close[i]-rangeBarsIndicator.Close[i-1];
|
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
|
||||||
if(diff>0)
|
if(diff>0)
|
||||||
sump+=diff;
|
sump+=diff;
|
||||||
else
|
else
|
||||||
@@ -154,7 +138,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
//--- the main loop of calculations
|
//--- the main loop of calculations
|
||||||
for(i=pos; i<rates_total && !IsStopped(); i++)
|
for(i=pos; i<rates_total && !IsStopped(); i++)
|
||||||
{
|
{
|
||||||
diff=rangeBarsIndicator.Close[i]-rangeBarsIndicator.Close[i-1];
|
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
|
||||||
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(diff>0.0?diff:0.0))/InpRSIPeriod;
|
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(diff>0.0?diff:0.0))/InpRSIPeriod;
|
||||||
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(diff<0.0?-diff:0.0))/InpRSIPeriod;
|
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(diff<0.0?-diff:0.0))/InpRSIPeriod;
|
||||||
if(ExtNegBuffer[i]!=0.0)
|
if(ExtNegBuffer[i]!=0.0)
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| StdDev.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 "Standard Deviation"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 2
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 MediumSeaGreen
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
//--- input parametrs
|
||||||
|
input int InpStdDevPeriod=20; // Period
|
||||||
|
input int InpStdDevShift=0; // Shift
|
||||||
|
input ENUM_MA_METHOD InpMAMethod=MODE_SMA; // Method
|
||||||
|
input ENUM_APPLIED_PRICE InpPrice=PRICE_CLOSE; // Apply to
|
||||||
|
//---- buffers
|
||||||
|
double ExtStdDevBuffer[];
|
||||||
|
double ExtMABuffer[];
|
||||||
|
//--- global variables
|
||||||
|
int ExtStdDevPeriod,ExtStdDevShift;
|
||||||
|
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- check for input values
|
||||||
|
if(InpStdDevPeriod<=1)
|
||||||
|
{
|
||||||
|
ExtStdDevPeriod=20;
|
||||||
|
printf("Incorrect value for input variable InpStdDevPeriod=%d. Indicator will use value=%d for calculations.",InpStdDevPeriod,ExtStdDevPeriod);
|
||||||
|
}
|
||||||
|
else ExtStdDevPeriod=InpStdDevPeriod;
|
||||||
|
if(InpStdDevShift<0)
|
||||||
|
{
|
||||||
|
ExtStdDevShift=0;
|
||||||
|
printf("Incorrect value for input variable InpStdDevShift=%d. Indicator will use value=%d for calculations.",InpStdDevShift,ExtStdDevShift);
|
||||||
|
}
|
||||||
|
else ExtStdDevShift=InpStdDevShift;
|
||||||
|
//--- set indicator short name
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"StdDev("+string(ExtStdDevPeriod)+")");
|
||||||
|
//---- define indicator buffers as indexes
|
||||||
|
SetIndexBuffer(0,ExtStdDevBuffer);
|
||||||
|
SetIndexBuffer(1,ExtMABuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//--- set index label
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"StdDev("+string(ExtStdDevPeriod)+")");
|
||||||
|
//--- set index shift
|
||||||
|
PlotIndexSetInteger(0,PLOT_SHIFT,ExtStdDevShift);
|
||||||
|
//----
|
||||||
|
|
||||||
|
customChartIndicator.SetUseAppliedPriceFlag(InpPrice);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//--- variables of indicator
|
||||||
|
int pos;
|
||||||
|
//--- set draw begin
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtStdDevPeriod-1);//+begin);
|
||||||
|
//--- check for rates count
|
||||||
|
if(rates_total<ExtStdDevPeriod)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
int _rates_total = customChartIndicator.GetRatesTotal();
|
||||||
|
|
||||||
|
//--- starting work
|
||||||
|
pos=_prev_calculated-1;
|
||||||
|
//--- correct position for first iteration
|
||||||
|
if(pos<ExtStdDevPeriod)
|
||||||
|
{
|
||||||
|
pos=ExtStdDevPeriod-1;
|
||||||
|
ArrayInitialize(ExtStdDevBuffer,0.0);
|
||||||
|
ArrayInitialize(ExtMABuffer,0.0);
|
||||||
|
}
|
||||||
|
//--- main cycle
|
||||||
|
switch(InpMAMethod)
|
||||||
|
{
|
||||||
|
case MODE_EMA :
|
||||||
|
for(int i=pos;i<_rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
if(i==InpStdDevPeriod-1)
|
||||||
|
ExtMABuffer[i]=SimpleMA(i,InpStdDevPeriod, customChartIndicator.Price);
|
||||||
|
else
|
||||||
|
ExtMABuffer[i]=ExponentialMA(i,InpStdDevPeriod,ExtMABuffer[i-1], customChartIndicator.Price);
|
||||||
|
//--- Calculate StdDev
|
||||||
|
ExtStdDevBuffer[i]=StdDevFunc(customChartIndicator.Price, ExtMABuffer,i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_SMMA :
|
||||||
|
for(int i=pos;i<_rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
if(i==InpStdDevPeriod-1)
|
||||||
|
ExtMABuffer[i]=SimpleMA(i,InpStdDevPeriod,customChartIndicator.Price);
|
||||||
|
else
|
||||||
|
ExtMABuffer[i]=SmoothedMA(i,InpStdDevPeriod,ExtMABuffer[i-1],customChartIndicator.Price);
|
||||||
|
//--- Calculate StdDev
|
||||||
|
ExtStdDevBuffer[i]=StdDevFunc(customChartIndicator.Price,ExtMABuffer,i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_LWMA :
|
||||||
|
for(int i=pos;i<_rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtMABuffer[i]=LinearWeightedMA(i,InpStdDevPeriod,customChartIndicator.Price);
|
||||||
|
ExtStdDevBuffer[i]=StdDevFunc(customChartIndicator.Price,ExtMABuffer,i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
for(int i=pos;i<_rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtMABuffer[i]=SimpleMA(i,InpStdDevPeriod,customChartIndicator.Price);
|
||||||
|
//--- Calculate StdDev
|
||||||
|
ExtStdDevBuffer[i]=StdDevFunc(customChartIndicator.Price,ExtMABuffer,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(_rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Calculate Standard Deviation |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double StdDevFunc(const double &price[],const double &MAprice[],int position)
|
||||||
|
{
|
||||||
|
double dTmp=0.0;
|
||||||
|
for(int i=0;i<ExtStdDevPeriod;i++) dTmp+=MathPow(price[position-i]-MAprice[position],2);
|
||||||
|
dTmp=MathSqrt(dTmp/ExtStdDevPeriod);
|
||||||
|
return(dTmp);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
+18
-26
@@ -5,6 +5,7 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "2009, MetaQuotes Software Corp."
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
#property indicator_buffers 4
|
#property indicator_buffers 4
|
||||||
@@ -26,13 +27,11 @@ double ExtHighesBuffer[];
|
|||||||
double ExtLowesBuffer[];
|
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;
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -79,25 +78,18 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
const long &Volume[],
|
const long &Volume[],
|
||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
|
|
||||||
//
|
|
||||||
// Precoess data through MedianRenko indicator
|
|
||||||
//
|
|
||||||
|
|
||||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
|
|
||||||
return(rates_total);
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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();
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -127,8 +119,8 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
double dmax=-1000000.0;
|
double dmax=-1000000.0;
|
||||||
for(k=i-InpKPeriod+1;k<=i;k++)
|
for(k=i-InpKPeriod+1;k<=i;k++)
|
||||||
{
|
{
|
||||||
if(dmin>rangeBarsIndicator.Low[k]) dmin=rangeBarsIndicator.Low[k];
|
if(dmin>customChartIndicator.Low[k]) dmin=customChartIndicator.Low[k];
|
||||||
if(dmax<rangeBarsIndicator.High[k]) dmax=rangeBarsIndicator.High[k];
|
if(dmax<customChartIndicator.High[k]) dmax=customChartIndicator.High[k];
|
||||||
}
|
}
|
||||||
ExtLowesBuffer[i]=dmin;
|
ExtLowesBuffer[i]=dmin;
|
||||||
ExtHighesBuffer[i]=dmax;
|
ExtHighesBuffer[i]=dmax;
|
||||||
@@ -148,7 +140,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
double sumhigh=0.0;
|
double sumhigh=0.0;
|
||||||
for(k=(i-InpSlowing+1);k<=i;k++)
|
for(k=(i-InpSlowing+1);k<=i;k++)
|
||||||
{
|
{
|
||||||
sumlow +=(rangeBarsIndicator.Close[k]-ExtLowesBuffer[k]);
|
sumlow +=(customChartIndicator.Close[k]-ExtLowesBuffer[k]);
|
||||||
sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
|
sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
|
||||||
}
|
}
|
||||||
if(sumhigh==0.0) ExtMainBuffer[i]=100.0;
|
if(sumhigh==0.0) ExtMainBuffer[i]=100.0;
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
#property copyright "Copyright 2018-2020, Level Up Software"
|
||||||
|
#property link "https://www.az-invest.eu"
|
||||||
|
#property description "A timescale indicator for use on X Tick Chart."
|
||||||
|
#property version "1.03"
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_plots 0
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
RangeBarIndicator customChartIndicator;
|
||||||
|
|
||||||
|
#define PREFIX_SEED "6D4E6"
|
||||||
|
|
||||||
|
static long __chartId = ChartID();
|
||||||
|
static int __subWinId = ChartWindowFind();
|
||||||
|
|
||||||
|
enum ENUM_DISPLAY_FORMAT
|
||||||
|
{
|
||||||
|
DisplayFormat1 = 0, // 25 Jan 10:55
|
||||||
|
DisplayFormat2, // 25.01 10:55
|
||||||
|
};
|
||||||
|
|
||||||
|
input color InpTextColor = clrBlack; // Font color
|
||||||
|
input int InpFontSize = 9; // Font size
|
||||||
|
input int InpSpacing = 3; // Date/Time spacing factor
|
||||||
|
input ENUM_DISPLAY_FORMAT InpDispFormat = DisplayFormat1; // Display format
|
||||||
|
|
||||||
|
int __spacing = InpSpacing;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"\n");
|
||||||
|
IndicatorSetDouble(INDICATOR_MINIMUM,0);
|
||||||
|
IndicatorSetDouble(INDICATOR_MAXIMUM, 9);
|
||||||
|
IndicatorSetInteger(INDICATOR_HEIGHT,16);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
//---
|
||||||
|
|
||||||
|
customChartIndicator.SetGetTimeFlag();
|
||||||
|
|
||||||
|
RecalcSpacing();
|
||||||
|
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDeinit(const int r)
|
||||||
|
{
|
||||||
|
ObjectsDeleteAll(__chartId,PREFIX_SEED);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int start = customChartIndicator.GetPrevCalculated() - 1;
|
||||||
|
//--- correct position
|
||||||
|
if(start<0)
|
||||||
|
start=0;
|
||||||
|
|
||||||
|
if((start == 0) || customChartIndicator.IsNewBar)
|
||||||
|
{
|
||||||
|
DrawTimeLine(0,customChartIndicator.GetRatesTotal(),time);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RecalcSpacing()
|
||||||
|
{
|
||||||
|
static int __prevScale = 5;
|
||||||
|
int __currentScale = (int)ChartGetInteger(0, CHART_SCALE);
|
||||||
|
|
||||||
|
if(__prevScale == __currentScale)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(__currentScale)
|
||||||
|
{
|
||||||
|
case 5: __spacing = InpSpacing;
|
||||||
|
break;
|
||||||
|
case 4: __spacing = InpSpacing * 2;
|
||||||
|
break;
|
||||||
|
case 3: __spacing = InpSpacing * 4;
|
||||||
|
break;
|
||||||
|
case 2: __spacing = InpSpacing * 8;
|
||||||
|
break;
|
||||||
|
case 1: __spacing = InpSpacing * 16;
|
||||||
|
break;
|
||||||
|
case 0: __spacing = InpSpacing * 32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__prevScale = __currentScale;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void DrawTimeLine(const int nPosition, const int nRatesCount, const datetime &canvasTime[])
|
||||||
|
{
|
||||||
|
datetime curBarTime = 0;
|
||||||
|
bool _start = false;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
ObjectsDeleteAll(__chartId,PREFIX_SEED);
|
||||||
|
|
||||||
|
for(int i=nPosition; i<nRatesCount; i++)
|
||||||
|
{
|
||||||
|
curBarTime = customChartIndicator.GetTime(i);
|
||||||
|
if(curBarTime == 0)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
_start = true;
|
||||||
|
|
||||||
|
if(c%__spacing == 0)
|
||||||
|
DrawDateTimeMarker(i,curBarTime,canvasTime[i]);
|
||||||
|
|
||||||
|
if(_start)
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChartRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DrawDateTimeMarker(const int ix, const datetime timeStamp, const datetime canvasTime)
|
||||||
|
{
|
||||||
|
if(timeStamp == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TextCreate(__chartId,PREFIX_SEED+(string)timeStamp,__subWinId,canvasTime,9,NormalizeTime(timeStamp),"Calibri",InpFontSize,InpTextColor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string NormalizeTime(datetime _dt)
|
||||||
|
{
|
||||||
|
static string __months[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
|
||||||
|
MqlDateTime dt;
|
||||||
|
|
||||||
|
TimeToStruct(_dt,dt);
|
||||||
|
string minute = (dt.min<10) ? ("0"+(string)dt.min) : (string)dt.min;
|
||||||
|
string hour = (dt.hour<10) ? ("0"+(string)dt.hour) : (string)dt.hour;
|
||||||
|
|
||||||
|
if((dt.mon-1) < 0 || (dt.mon-1) > 11)
|
||||||
|
return "*";
|
||||||
|
|
||||||
|
if(InpDispFormat == DisplayFormat1)
|
||||||
|
return ( "'"+(string)dt.day+" "+__months[dt.mon-1]+" "+hour+":"+minute );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string month = (dt.mon<10) ? ("0"+(string)dt.mon) : (string)dt.mon;
|
||||||
|
return ( "'"+(string)dt.day+"."+month+" "+hour+":"+minute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| ChartEvent function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnChartEvent(const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(id==CHARTEVENT_CHART_CHANGE)
|
||||||
|
{
|
||||||
|
if(RecalcSpacing() == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
datetime __time[];
|
||||||
|
CopyTime(_Symbol,_Period,0,Bars(_Symbol,_Period),__time);
|
||||||
|
|
||||||
|
DrawTimeLine(0,customChartIndicator.GetRatesTotal(),__time);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// GUI wrapper function
|
||||||
|
// https://www.mql5.com/en/docs/constants/objectconstants/enum_object/obj_text
|
||||||
|
//
|
||||||
|
|
||||||
|
bool TextCreate(const long chart_ID=0, // chart's ID
|
||||||
|
const string name="Text", // object name
|
||||||
|
const int sub_window=0, // subwindow index
|
||||||
|
datetime time=0, // anchor point time
|
||||||
|
double price=0, // anchor point price
|
||||||
|
const string text="Text", // the text itself
|
||||||
|
const string font="Calibri", // font
|
||||||
|
const int font_size=9, // font size
|
||||||
|
const color clr=clrWhiteSmoke, // color
|
||||||
|
const double angle=0.0, // text slope
|
||||||
|
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // anchor type
|
||||||
|
const bool back=false, // in the background
|
||||||
|
const bool selection=false, // highlight to move
|
||||||
|
const bool hidden=true, // hidden in the object list
|
||||||
|
const long z_order=0) // priority for mouse click
|
||||||
|
{
|
||||||
|
//--- reset the error value
|
||||||
|
ResetLastError();
|
||||||
|
//--- create Text object
|
||||||
|
if(!ObjectCreate(chart_ID,name,OBJ_TEXT,sub_window,time,price))
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__,": failed to create \"Text\" object! Error code = ",GetLastError());
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- set the text
|
||||||
|
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
|
||||||
|
//--- set text font
|
||||||
|
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
|
||||||
|
//--- set font size
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
|
||||||
|
//--- set the slope angle of the text
|
||||||
|
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
|
||||||
|
//--- set anchor type
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
|
||||||
|
//--- set color
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
|
||||||
|
//--- display in the foreground (false) or background (true)
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
|
||||||
|
//--- enable (true) or disable (false) the mode of moving the object by mouse
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
|
||||||
|
//--- hide (true) or display (false) graphical object name in the object list
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
|
||||||
|
//--- set the priority for receiving the event of a mouse click in the chart
|
||||||
|
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
|
||||||
|
//--- switch off tooltips
|
||||||
|
ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,"\n");
|
||||||
|
//--- successful execution
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
//------------------------------------------------------------------
|
||||||
|
#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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
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)+")");
|
||||||
|
|
||||||
|
customChartIndicator.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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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(customChartIndicator.High[i],customChartIndicator.Close[i-1])-MathMin(customChartIndicator.Low[i],customChartIndicator.Close[i-1]);
|
||||||
|
double DeltaHi = customChartIndicator.High[i] - customChartIndicator.High[i-1];
|
||||||
|
double DeltaLo = customChartIndicator.Low[i-1] - customChartIndicator.Low[i];
|
||||||
|
double plusDM = 0.00;
|
||||||
|
double minusDM = 0.00;
|
||||||
|
double vol;
|
||||||
|
switch(VolumeType)
|
||||||
|
{
|
||||||
|
case vol_ticks: vol = (double)customChartIndicator.Tick_volume[i]; break;
|
||||||
|
case vol_real: vol = (double)customChartIndicator.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,368 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
#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," ");
|
||||||
|
}
|
||||||
|
|
||||||
|
customChartIndicator.SetGetVolumesFlag();
|
||||||
|
customChartIndicator.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 Tick Chat indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
if(PERIOD_CURRENT!=LastTimePeriod)
|
||||||
|
{
|
||||||
|
bIsFirstRun=true;
|
||||||
|
LastTimePeriod=PERIOD_CURRENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rates_total>_prev_calculated || bIsFirstRun || Calc_Every_Tick || (_prev_calculated == 0) ||customChartIndicator.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(customChartIndicator.Time[nIdx] < 86400)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(CreateDateTime(DAILY,customChartIndicator.Time[nIdx])!=dtLastDay)
|
||||||
|
{
|
||||||
|
nIdxDaily=nIdx;
|
||||||
|
nSumDailyTPV = 0;
|
||||||
|
nSumDailyVol = 0;
|
||||||
|
}
|
||||||
|
if(CreateDateTime(WEEKLY,customChartIndicator.Time[nIdx])!=dtLastWeek)
|
||||||
|
{
|
||||||
|
nIdxWeekly=nIdx;
|
||||||
|
nSumWeeklyTPV = 0;
|
||||||
|
nSumWeeklyVol = 0;
|
||||||
|
}
|
||||||
|
if(CreateDateTime(MONTHLY,customChartIndicator.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]=customChartIndicator.Open[nIdx];
|
||||||
|
break;
|
||||||
|
case CLOSE:
|
||||||
|
nPriceArr[nIdx]=customChartIndicator.Close[nIdx];
|
||||||
|
break;
|
||||||
|
case HIGH:
|
||||||
|
nPriceArr[nIdx]=customChartIndicator.High[nIdx];
|
||||||
|
break;
|
||||||
|
case LOW:
|
||||||
|
nPriceArr[nIdx]=customChartIndicator.Low[nIdx];
|
||||||
|
break;
|
||||||
|
case HIGH_LOW:
|
||||||
|
nPriceArr[nIdx]=(customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/2;
|
||||||
|
break;
|
||||||
|
case OPEN_CLOSE:
|
||||||
|
nPriceArr[nIdx]=(customChartIndicator.Open[nIdx]+customChartIndicator.Close[nIdx])/2;
|
||||||
|
break;
|
||||||
|
case CLOSE_HIGH_LOW:
|
||||||
|
nPriceArr[nIdx]=(customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/3;
|
||||||
|
break;
|
||||||
|
case OPEN_CLOSE_HIGH_LOW:
|
||||||
|
nPriceArr[nIdx]=(customChartIndicator.Open[nIdx]+customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nPriceArr[nIdx]=(customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((customChartIndicator.Tick_volume[nIdx] > 0) && (customChartIndicator.Real_volume[nIdx] == 0))
|
||||||
|
{
|
||||||
|
// Print("tick vol = "+customChartIndicator.Tick_volume[nIdx]);
|
||||||
|
nTotalTPV[nIdx] = (nPriceArr[nIdx] * customChartIndicator.Tick_volume[nIdx]);
|
||||||
|
nTotalVol[nIdx] = (double)customChartIndicator.Tick_volume[nIdx];
|
||||||
|
}
|
||||||
|
else if(customChartIndicator.Real_volume[nIdx] && customChartIndicator.Tick_volume[nIdx] )
|
||||||
|
{
|
||||||
|
// Print("real vol = "+customChartIndicator.Real_volume[nIdx]);
|
||||||
|
nTotalTPV[nIdx] = (nPriceArr[nIdx] * customChartIndicator.Real_volume[nIdx]);
|
||||||
|
nTotalVol[nIdx] = (double)customChartIndicator.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,customChartIndicator.Time[nIdx]);
|
||||||
|
dtLastWeek=CreateDateTime(WEEKLY,customChartIndicator.Time[nIdx]);
|
||||||
|
dtLastMonth=CreateDateTime(MONTHLY,customChartIndicator.Time[nIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bIsFirstRun=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
@@ -0,0 +1,321 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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=customChartIndicator.Low[iLowest(customChartIndicator.Low,ExtDepth,shift)];
|
||||||
|
if(val==lastlow) val=0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastlow=val;
|
||||||
|
if((customChartIndicator.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(customChartIndicator.Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
|
||||||
|
//--- high
|
||||||
|
val=customChartIndicator.High[iHighest(customChartIndicator.High,ExtDepth,shift)];
|
||||||
|
if(val==lasthigh) val=0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lasthigh=val;
|
||||||
|
if((val-customChartIndicator.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(customChartIndicator.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=customChartIndicator.High[shift];
|
||||||
|
lasthighpos=shift;
|
||||||
|
whatlookfor=Sill;
|
||||||
|
ZigzagBuffer[shift]=lasthigh;
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
|
if(LowMapBuffer[shift]!=0)
|
||||||
|
{
|
||||||
|
lastlow=customChartIndicator.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,250 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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(customChartIndicator.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,146 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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"
|
||||||
|
#property description "Adapted for use with TickChart by Artur Zas."
|
||||||
|
|
||||||
|
//---- 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 2
|
||||||
|
#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 customChartIndicator;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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);
|
||||||
|
|
||||||
|
customChartIndicator.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 XTickChart indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a bar has completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the tick chart bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.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,customChartIndicator.Tick_volume);
|
||||||
|
else
|
||||||
|
CalculateVolume(start,rates_total,customChartIndicator.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;
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -6,15 +6,17 @@ used on the chart to the RangeBars settings that should be used in the EA.
|
|||||||
## The files
|
## The files
|
||||||
**RangeBars.mqh** - The header file for including in the EA code. It contains the definition and implementation of the RangeBars class
|
**RangeBars.mqh** - The header file for including in the EA code. It contains the definition and implementation of the RangeBars class
|
||||||
|
|
||||||
**RangeBarSettings.mqh** - This header file is used by the **RangeBars** class to automatically read the EA settings used on the RangeBars chart where the EA should be attached.
|
**CommonSettings.mqh** & **RangeBarSettings.mqh** - These header files are used by the **RangeBars** class to automatically read the EA settings used on the Renko chart where the EA should be attached.
|
||||||
|
|
||||||
**RangeBarIndicator.mqh** - This helper header file includes a **RangeBarIndicator** class which is used to patch MQL5 indicators to work directly on the RangeBars charts and use the RangeBar's OLHC values for calculation.
|
**RangeBarIndicator.mqh** - This helper header file includes a **RangeBarIndicator** class which is used to patch MQL5 indicators to work directly on the RangeBars charts and use the RangeBar's OLHC values for calculation.
|
||||||
|
|
||||||
**ExampleEA.mq5** - An example EA skeleton showing the use of methods included in the RangeBars class library
|
**ExampleEA.mq5** - An example EA skeleton showing the use of methods included in the RangeBars class library
|
||||||
|
|
||||||
|
**ExampleEA2.mq5** - An example EA utilizing the Super Trend indicator on RangeBars to make trading decisions also showing the use of methods included in the RangeBars class library.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
All folders (Experts, Include & Indicators) should be placed in the **MQL5** sub-folder of your Metatrader's Data Folder.
|
All folders (Experts, Include & Indicators) & sub-folders should be placed in the **MQL5** sub-folder of your Metatrader's Data Folder.
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
The RangeBars indicator for MT5 can be downloaded from https://www.mql5.com/en/market/product/16762
|
The RangeBars indicator for MT5 can be downloaded from https://www.mql5.com/en/market/product/16762
|
||||||
|
|||||||
Reference in New Issue
Block a user