Compare commits

..

25 Commits

Author SHA1 Message Date
Artur a73e2c0713 Updated for compatibility with ver 3.11 2020-09-29 11:26:32 +02:00
9nix6 3175f594f1 Update README.md 2020-05-21 20:48:41 +02:00
Artur 5327473eaf Updated for RangeBars ver. 3.04 2020-03-17 23:34:45 +01:00
unknown 8035947476 Updated for RangeBars ver. 3.03 2020-03-11 17:04:08 +01:00
unknown acba19e38f Updated for RangeBars ver. 3.02 2020-02-25 18:25:11 +01:00
unknown 0d51499dcf Updated for RangeBars ver. 3.01 2020-02-23 23:23:36 +01:00
unknown e6121f7487 Updated for RangeBars ver. 3.00 2020-02-23 16:21:15 +01:00
unknown bd957ab1af updated Smoothalgorithms.mqh 2020-01-15 22:30:38 +01:00
unknown 0ba2c53a35 Merge branch 'master' of https://github.com/9nix6/Range-Bars-Charting 2019-09-30 13:03:01 +02:00
unknown dde1849bb0 added OBV indicator 2019-09-30 13:02:46 +02:00
9nix6 e4e0bb483a Fixed RageBar indicator path 2019-08-28 20:59:48 +02:00
unknown b784e9556d Merge branch 'master' of https://github.com/9nix6/Range-Bars-Charting 2019-08-25 22:22:29 +02:00
unknown 695a66b812 update for version 2.13 2019-08-25 22:20:16 +02:00
9nix6 bd3a18958e Fixed error on line 99 2019-07-12 22:43:13 +02:00
9nix6 dd2f769c89 Update for version 2.11 2019-05-14 17:22:40 +02:00
9nix6 38937ddce1 new version update 2018-12-13 00:19:34 +01:00
9nix6 75a0f76352 Added MACD Line indicator 2018-07-16 12:51:08 +02:00
9nix6 4f56445d60 Updated TimeLine indicator 2018-06-01 17:01:39 +02:00
9nix6 a23213f3e1 Added time line indicator 2018-05-28 19:38:04 +02:00
9nix6 91e99e93cc Update to version 2.04 2018-05-15 19:27:24 +02:00
9nix6 a19c291525 Added AwesomeOscillator 2018-03-14 13:17:04 +01:00
9nix6 60a4d0ad07 Added missing dependency: smoothalgorithms.mqh 2018-03-07 21:56:20 +01:00
9nix6 62032b5f8b Updated readme.md file 2017-12-05 13:21:40 +01:00
9nix6 32af8d84a2 Update to version 2.02 2017-12-05 13:16:14 +01:00
9nix6 ec6cab350b Added RSI & Stochastic indicators 2017-09-01 23:14:50 +02:00
54 changed files with 9069 additions and 1433 deletions
-201
View File
@@ -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...
//
}
}
}
+221
View File
@@ -0,0 +1,221 @@
#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 = NULL;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(rangeBars == NULL)
{
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
}
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;
rangeBars = NULL;
}
//
// 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...
//
}
}
}
+244
View File
@@ -0,0 +1,244 @@
#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.
//
#define DEVELOPER_VERSION
#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 = NULL;
CMarketOrder *marketOrder = NULL;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(rangeBars == NULL)
{
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
}
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;
}
if(marketOrder == NULL)
{
marketOrder = new CMarketOrder(params);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
// delete RanegBars class
//
if(rangeBars != NULL)
{
rangeBars.Deinit();
delete rangeBars;
rangeBars = NULL;
}
//
// delete MarketOrder class
//
if(marketOrder != NULL)
{
delete marketOrder;
marketOrder = NULL;
}
}
//
// 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.
+53
View File
@@ -0,0 +1,53 @@
//
// 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));
int lotsDigits = (int)MathAbs(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 = 100; // 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;
}
+893
View File
@@ -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);
}
}
+678
View File
@@ -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
+932
View File
@@ -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);
}
-309
View File
@@ -1,309 +0,0 @@
//+------------------------------------------------------------------+
//| RangeBarIndicator.mq5 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property library
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#property version "1.10"
#include <RangeBars.mqh>
class RangeBarIndicator
{
private:
RangeBars * rangeBars;
int rates_total;
int prev_calculated;
bool useAppliedPrice;
ENUM_APPLIED_PRICE applied_price;
public:
double Open[];
double Low[];
double High[];
double Close[];
double Price[];
RangeBarIndicator();
~RangeBarIndicator();
void SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) { this.useAppliedPrice = true; this.applied_price = _applied_price; };
bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &Time[]);
int GetPrevCalculated() { return prev_calculated; };
private:
bool CheckStatus();
bool NeedsReload();
int GetOLHC(int start, int count);
void OLHCShiftRight();
void OLHCResize();
bool Canvas_IsNewBar(const datetime &_Time[]);
bool Canvas_IsRatesTotalChanged(int ratesTotalNow);
ENUM_TIMEFRAMES TFMigrate(int tf);
datetime iTime(string symbol,int tf,int index);
};
RangeBarIndicator::RangeBarIndicator(void)
{
rangeBars = new RangeBars();
if(rangeBars != NULL)
rangeBars.Init();
useAppliedPrice = false;
}
RangeBarIndicator::~RangeBarIndicator(void)
{
if(rangeBars != NULL)
{
rangeBars.Deinit();
delete rangeBars;
}
}
bool RangeBarIndicator::CheckStatus(void)
{
int handle = rangeBars.GetHandle();
if(handle == INVALID_HANDLE)
return false;
return true;
}
bool RangeBarIndicator::NeedsReload(void)
{
if(rangeBars.Reload())
{
Print("Chart settings changed - reloading indicator with new settings");
return true;
}
return false;
}
bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &Time[])
{
static bool firstRun = true;
if(firstRun)
{
Canvas_IsRatesTotalChanged(_rates_total);
firstRun = false;
}
if(!CheckStatus())
return false;
ArraySetAsSeries(this.Open,false);
ArraySetAsSeries(this.High,false);
ArraySetAsSeries(this.Low,false);
ArraySetAsSeries(this.Close,false);
ArraySetAsSeries(this.Price,false);
if(Canvas_IsRatesTotalChanged(_rates_total))
{
OLHCResize();
this.prev_calculated = prev_calculated;
Canvas_IsNewBar(Time);
return true;
}
else if(Canvas_IsNewBar(Time))
{
//Print("Got Canvas_IsNewBar");
//GetOLHC(0,0);
if(ArraySize(this.Open) == 0)
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
//Print("canvas new bar ZERO elements -> getting new : ArraySize of Open = "+ArraySize(this.Open));
return false;
}
OLHCShiftRight();
this.prev_calculated = prev_calculated;
return true;
}
if(NeedsReload() || rangeBars.IsNewBar())
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return false;
}
//
// Recalculate lst bar
//
GetOLHC(0,0);
this.prev_calculated = prev_calculated;
return true;
}
int RangeBarIndicator::GetOLHC(int start, int count)
{
if((start == 0) && (count == 0))
{
MqlRates tempRates[1];
int last = ArraySize(Open)-1;
if(last < 0)
return 0;
rangeBars.GetMqlRates(tempRates,0,1);
this.Open[last] = tempRates[0].open;
this.Low[last] = tempRates[0].low;
this.High[last] = tempRates[0].high;
this.Close[last] = tempRates[0].close;
if(useAppliedPrice)
{
this.Price[last] = rangeBars.CalcAppliedPrice(tempRates[0],this.applied_price);
}
return 1;
}
else
{
if(useAppliedPrice)
return rangeBars.GetOLHCAndApplPriceForIndicatorCalc(this.Open,this.Low,this.High,this.Close,this.Price,this.applied_price,0,count);
else
return rangeBars.GetOLHCForIndicatorCalc(this.Open,this.Low,this.High,this.Close,0,count);
}
}
void RangeBarIndicator::OLHCShiftRight()
{
int count = ArraySize(this.Open);
if(count <= 0)
return;
count--;
for(int i=count; i>0; i--)
{
this.Open[i] = this.Open[i-1];
this.High[i] = this.High[i-1];
this.Low[i] = this.Low[i-1];
this.Close[i] = this.Close[i-1];
this.Price[i] = this.Price[i-1];
}
this.Open[0] = 0.0;
this.High[0] = 0.0;
this.Low[0] = 0.0;
this.Close[0] = 0.0;
this.Price[0] = 0.0;
}
void RangeBarIndicator::OLHCResize()
{
int count = ArraySize(this.Open);
if(count <= 0)
return;
ArrayResize(this.Open,count+1);
ArrayResize(this.Low,count+1);
ArrayResize(this.High,count+1);
ArrayResize(this.Close,count+1);
ArrayResize(this.Price,count+1);
OLHCShiftRight();
}
bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[])
{
ArraySetAsSeries(_Time,true);
datetime now = _Time[0];
ArraySetAsSeries(_Time,false);
static datetime prevTime = 0;
if(prevTime != now)
{
prevTime = now;
return true;
}
return false;
}
bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow)
{
static int prevRatesTotal = 0;
if(prevRatesTotal == 0)
prevRatesTotal = ratesTotalNow;
if(prevRatesTotal != ratesTotalNow)
{
prevRatesTotal = ratesTotalNow;
return true;
}
return false;
}
ENUM_TIMEFRAMES RangeBarIndicator::TFMigrate(int tf)
{
switch(tf)
{
case 0: return(PERIOD_CURRENT);
case 1: return(PERIOD_M1);
case 5: return(PERIOD_M5);
case 15: return(PERIOD_M15);
case 30: return(PERIOD_M30);
case 60: return(PERIOD_H1);
case 240: return(PERIOD_H4);
case 1440: return(PERIOD_D1);
case 10080: return(PERIOD_W1);
case 43200: return(PERIOD_MN1);
case 2: return(PERIOD_M2);
case 3: return(PERIOD_M3);
case 4: return(PERIOD_M4);
case 6: return(PERIOD_M6);
case 10: return(PERIOD_M10);
case 12: return(PERIOD_M12);
case 16385: return(PERIOD_H1);
case 16386: return(PERIOD_H2);
case 16387: return(PERIOD_H3);
case 16388: return(PERIOD_H4);
case 16390: return(PERIOD_H6);
case 16392: return(PERIOD_H8);
case 16396: return(PERIOD_H12);
case 16408: return(PERIOD_D1);
case 32769: return(PERIOD_W1);
case 49153: return(PERIOD_MN1);
default: return(PERIOD_CURRENT);
}
}
datetime RangeBarIndicator::iTime(string symbol,int tf,int index)
{
if(index < 0) return(-1);
ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
datetime Arr[];
if(CopyTime(symbol, timeframe, index, 1, Arr)>0)
return(Arr[0]);
else return(-1);
}
-318
View File
@@ -1,318 +0,0 @@
//+------------------------------------------------------------------+
//| RangeBarSettings.mqh ver 1.04 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
enum ENUM_CHANNEL_TYPE
{
None = 0, // None
Donchian_Channel, // Donchian Channel
Bollinger_Bands, // Bollinger Bands
SuperTrend, // Super Trend
// VWAP,
};
#ifdef SHOW_INDICATOR_INPUTS
input int barSizeInTicks = 100; // Range bar size (in points)
double customBarSize = barSizeInTicks * Point();
bool useTickVolume = true; // Use tick volume (for FX)
input datetime _startFromDateTime = 0; // Start building chart from date/time
datetime startFromDateTime = 0;
input bool resetOpenOnNewTradingDay = false; // Synchronize first bar's open on new day
input bool showNextBarLevels = true; // Show current bar's close projections
input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color
input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color
input bool showCurrentBarOpenTime = true; // Display chart info and current bar's open time
input color InfoTextColor = clrWhite; // Current bar's open time info color
input bool UseSoundSignalOnNewBar = false; // Play sound on new bar
input bool OnlySignalReversalBars = false; // Only signal reversals
input bool UseAlertWindow = false; // Display Alert window with new bar info
input bool SendPushNotifications = false; // Send new bar info push notification to smartphone
input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close
input string SoundFileBear = "news.wav"; // Use sound file for bearish bar close
input bool MA1on = false; // Show first MA
input int MA1period = 20; // 1st MA period
input ENUM_MA_METHOD MA1method = MODE_EMA; // 1st MA metod
input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; //1st MA apply to
input int MA1shift = 0; //1st MA shift
input bool MA2on = false; // Show second MA
input int MA2period = 50; // 2nd MA period
input ENUM_MA_METHOD MA2method = MODE_EMA; // 2nd MA method
input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to
input int MA2shift = 0; //2nd MA shift
input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel
input string Channel_Settings = "--------------------------"; // Channel settings
input int DonchianPeriod = 20; // Donchian Channel period
input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; //Bollinger Bands apply to
input int BollingerBandsPeriod = 20; // Bollinger Bands period
input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations
input int SuperTrendPeriod = 10; // Super Trend period
input double SuperTrendMultiplier=1.7; // Super Trend multiplier
input string Misc_Settings = "--------------------------"; // Misc settings
input bool UsedInEA = false; // Indicator used in EA via iCustom()
#else
int barSizeInTicks;
bool useTickVolume = true;
datetime startFromDateTime;
datetime _startFromDateTime = 0;
bool resetOpenOnNewTradingDay;
//
// This block should always be set to the follwong values
//
bool showNextBarLevels = false;
color HighThresholdIndicatorColor = clrNONE;
color LowThresholdIndicatorColor = clrNONE;
bool showCurrentBarOpenTime = false;
color InfoTextColor = clrNONE;
bool UseSoundSignalOnNewBar = false;
bool OnlySignalReversalBars = false;
bool UseAlertWindow = false;
bool SendPushNotifications = false;
string SoundFileBull = "";
string SoundFileBear = "";
bool UsedInEA = true; // This should always be set to TRUE for EAs & Indicators
//
//
//
bool MA1on;
int MA1period;
ENUM_MA_METHOD MA1method;
ENUM_APPLIED_PRICE MA1applyTo;
int MA1shift;
bool MA2on;
int MA2period;
ENUM_MA_METHOD MA2method;
ENUM_APPLIED_PRICE MA2applyTo;
int MA2shift;
ENUM_CHANNEL_TYPE ShowChannel;
int DonchianPeriod;
ENUM_APPLIED_PRICE BBapplyTo;
int BollingerBandsPeriod;
double BollingerBandsDeviations;
int SuperTrendPeriod = 10;
double SuperTrendMultiplier=1.7;
#endif
struct RANGEBAR_SETTINGS
{
int barSizeInTicks;
bool useTickVolume;
datetime _startFromDateTime;
bool resetOpenOnNewTradingDay;
bool MA1on;
int MA1period;
ENUM_MA_METHOD MA1method;
ENUM_APPLIED_PRICE MA1applyTo;
int MA1shift;
bool MA2on;
int MA2period;
ENUM_MA_METHOD MA2method;
ENUM_APPLIED_PRICE MA2applyTo;
int MA2shift;
ENUM_CHANNEL_TYPE ShowChannel;
int DonchianPeriod;
ENUM_APPLIED_PRICE BBapplyTo;
int BollingerBandsPeriod;
double BollingerBandsDeviations;
int SuperTrendPeriod;
double SuperTrendMultiplier;
};
class RangeBarSettings
{
protected:
string settingsFileName;
RANGEBAR_SETTINGS settings;
public:
RangeBarSettings(void);
~RangeBarSettings(void);
void Save(void);
bool Load(void);
void Delete(void);
bool Changed(void);
RANGEBAR_SETTINGS Get(void);
void Debug(void);
};
void RangeBarSettings::RangeBarSettings(void)
{
this.settingsFileName = "RangeBars"+(string)ChartID()+".set";
}
void RangeBarSettings::~RangeBarSettings(void)
{
}
void RangeBarSettings::Save(void)
{
settings.barSizeInTicks = barSizeInTicks;
settings.useTickVolume = useTickVolume;
settings._startFromDateTime = startFromDateTime;
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
settings.MA1on = MA1on;
settings.MA1period = MA1period;
settings.MA1method = MA1method;
settings.MA1applyTo = MA1applyTo;
settings.MA1shift = MA1shift;
settings.MA2on = MA2on;
settings.MA2period = MA2period;
settings.MA2method = MA2method;
settings.MA2applyTo = MA2applyTo;
settings.MA2shift = MA2shift;
settings.ShowChannel = ShowChannel;
settings.DonchianPeriod = DonchianPeriod;
settings.BBapplyTo = BBapplyTo;
settings.BollingerBandsPeriod = BollingerBandsPeriod;
settings.BollingerBandsDeviations = BollingerBandsDeviations;
settings.SuperTrendPeriod = SuperTrendPeriod;
settings.SuperTrendMultiplier = SuperTrendMultiplier;
if(MQLInfoInteger((int)MQL5_TESTING))
return;
this.Delete();
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN);
FileWriteStruct(handle,this.settings);
FileClose(handle);
}
void RangeBarSettings::Delete(void)
{
if(FileIsExist(this.settingsFileName))
FileDelete(this.settingsFileName);
}
bool RangeBarSettings::Load(void)
{
#ifdef SHOW_INDICATOR_INPUTS
this.settings.barSizeInTicks = barSizeInTicks;
this.settings.useTickVolume = useTickVolume;
this.settings._startFromDateTime = _startFromDateTime;
this.settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
this.settings.MA1on = MA1on;
this.settings.MA1period = MA1period;
this.settings.MA1method = MA1method;
this.settings.MA1applyTo = MA1applyTo;
this.settings.MA1shift = MA1shift;
this.settings.MA2on = MA2on;
this.settings.MA2period = MA2period;
this.settings.MA2method = MA2method;
this.settings.MA2applyTo = MA2applyTo;
this.settings.MA2shift = MA2shift;
this.settings.ShowChannel = ShowChannel;
this.settings.DonchianPeriod = DonchianPeriod;
this.settings.BBapplyTo = BBapplyTo;
this.settings.BollingerBandsPeriod = BollingerBandsPeriod;
this.settings.BollingerBandsDeviations = BollingerBandsDeviations;
this.settings.SuperTrendPeriod = SuperTrendPeriod;
this.settings.SuperTrendMultiplier = SuperTrendMultiplier;
return true;
#else
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
if(handle == INVALID_HANDLE)
return false;
if(FileReadStruct(handle,this.settings) <= 0)
{
Print("Failed loading settigns!");
FileClose(handle);
return false;
}
// this.Debug();
FileClose(handle);
return true;
#endif
}
RANGEBAR_SETTINGS RangeBarSettings::Get(void)
{
this.Debug();
return this.settings;
}
bool RangeBarSettings::Changed(void)
{
if(MQLInfoInteger((int)MQL5_TESTING))
return false;
static datetime prevFileTime = 0;
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE);
FileClose(handle);
if(prevFileTime != currFileTime)
{
prevFileTime = currFileTime;
return true;
}
return false;
}
void RangeBarSettings::Debug(void)
{
Print("RangeBars settings:");
Print("barSizeInTicks = "+(string)settings.barSizeInTicks);
Print("useTickVolume = "+(string)settings.useTickVolume);
Print("startFromDateTime = "+(string)settings._startFromDateTime);
Print("resetOpenOnNewTradingDay = "+(string)settings.resetOpenOnNewTradingDay);
Print("MA1on = "+(string)settings.MA1on);
Print("MA1period = "+(string)settings.MA1period);
Print("MA1method = "+(string)settings.MA1method);
Print("MA1applyTo = "+(string)settings.MA1applyTo);
Print("MA1shift = "+(string)settings.MA1shift);
Print("MA2on = "+(string)settings.MA2on);
Print("MA2period = "+(string)settings.MA2period);
Print("MA2method = "+(string)settings.MA2method);
Print("MA2applyTo = "+(string)settings.MA2applyTo);
Print("MA2shift = "+(string)settings.MA1shift);
Print("ShowChannel = "+(string)settings.ShowChannel);
Print("DonchianPeriod = "+(string)settings.DonchianPeriod);
Print("BBapplyTo = "+(string)settings.BBapplyTo);
Print("BBperiod = "+(string)settings.BollingerBandsPeriod);
Print("BBdeviations = "+(string)settings.BollingerBandsDeviations);
Print("SuperTrendPeriod = "+(string)settings.SuperTrendPeriod);
Print("SuperTrendMultiplier = "+(string)settings.SuperTrendMultiplier);
Print("UsedInEA = "+(string)UsedInEA);
}
-565
View File
@@ -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.
+179
View File
@@ -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);
}
//+------------------------------------------------------------------+
+121
View File
@@ -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.
+172
View File
@@ -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.
+110
View File
@@ -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);
}
//+------------------------------------------------------------------+
+158
View File
@@ -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);
}
//+------------------------------------------------------------------+
+233
View File
@@ -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 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
@@ -35,17 +37,8 @@ double ExtFastMaBuffer[];
double ExtSlowMaBuffer[];
double ExtMacdBuffer[];
//
// Initialize MedianRenko indicator for data processing
// according to settings of the MedianRenko indicator already on chart
//
#include <RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
//
//
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator customChartIndicator;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
@@ -79,53 +72,44 @@ int OnCalculate(const int rates_total,const int prev_calculated,
const long &Volume[],
const int &Spread[])
{
//
// Precoess data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
return(rangeBarsIndicator.GetPrevCalculated());
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _rates_total = customChartIndicator.GetRatesTotal();
//
//
//
//--- check for data
if(rates_total<InpSignalSMA)
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;
if(_prev_calculated>_rates_total || _prev_calculated<0) to_copy=_rates_total;
else
{
to_copy=rates_total-_prev_calculated;
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,rangeBarsIndicator.Close,ExtFastMaBuffer);
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,rangeBarsIndicator.Close,ExtSlowMaBuffer);
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++)
for(int i=limit;i<_rates_total && !IsStopped();i++)
{
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
if(ExtMacdBuffer[i] > 0)
@@ -140,8 +124,9 @@ int OnCalculate(const int rates_total,const int prev_calculated,
}
}
//--- 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.
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);
}
//+------------------------------------------------------------------+
+123
View File
@@ -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);
}
//+------------------------------------------------------------------+
+213
View File
@@ -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);
}
//+------------------------------------------------------------------+
+124
View File
@@ -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);
}
//+------------------------------------------------------------------+
+114
View File
@@ -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);
}
//+------------------------------------------------------------------+
+157
View File
@@ -0,0 +1,157 @@
//+------------------------------------------------------------------+
//| RSI.mq4 |
//| Copyright 2005-2014, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2005-2014, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property description "Relative Strength Index"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 1
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_color1 DodgerBlue
#property indicator_level1 30.0
#property indicator_level2 70.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT
//--- input parameters
input int InpRSIPeriod=14; // RSI Period
//--- buffers
double ExtRSIBuffer[];
double ExtPosBuffer[];
double ExtNegBuffer[];
//
//
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator customChartIndicator;
//
//
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
string short_name;
//--- 2 additional buffers are used for counting
SetIndexBuffer(0,ExtRSIBuffer);
SetIndexBuffer(1,ExtPosBuffer);
SetIndexBuffer(2,ExtNegBuffer);
//--- indicator line
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
SetIndexBuffer(0,ExtRSIBuffer);
//--- name for DataWindow and indicator subwindow label
short_name="RSI("+string(InpRSIPeriod)+")";
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- check for input
if(InpRSIPeriod<2)
{
Print("Incorrect value for input variable InpRSIPeriod = ",InpRSIPeriod);
return(INIT_FAILED);
}
//---
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpRSIPeriod);
//--- initialization done
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Relative Strength Index |
//+------------------------------------------------------------------+
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,pos;
double diff;
//---
if(Bars(_Symbol,_Period)<=InpRSIPeriod || InpRSIPeriod<2)
return(0);
//--- counting from 0 to rates_total
ArraySetAsSeries(ExtRSIBuffer,false);
ArraySetAsSeries(ExtPosBuffer,false);
ArraySetAsSeries(ExtNegBuffer,false);
ArraySetAsSeries(customChartIndicator.Close,false);
//--- preliminary calculations
pos=_prev_calculated-1;
if(pos<=InpRSIPeriod)
{
//--- first RSIPeriod values of the indicator are not calculated
ExtRSIBuffer[0]=0.0;
ExtPosBuffer[0]=0.0;
ExtNegBuffer[0]=0.0;
double sump=0.0;
double sumn=0.0;
for(i=1; i<=InpRSIPeriod; i++)
{
ExtRSIBuffer[i]=0.0;
ExtPosBuffer[i]=0.0;
ExtNegBuffer[i]=0.0;
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
if(diff>0)
sump+=diff;
else
sumn-=diff;
}
//--- calculate first visible value
ExtPosBuffer[InpRSIPeriod]=sump/InpRSIPeriod;
ExtNegBuffer[InpRSIPeriod]=sumn/InpRSIPeriod;
if(ExtNegBuffer[InpRSIPeriod]!=0.0)
ExtRSIBuffer[InpRSIPeriod]=100.0-(100.0/(1.0+ExtPosBuffer[InpRSIPeriod]/ExtNegBuffer[InpRSIPeriod]));
else
{
if(ExtPosBuffer[InpRSIPeriod]!=0.0)
ExtRSIBuffer[InpRSIPeriod]=100.0;
else
ExtRSIBuffer[InpRSIPeriod]=50.0;
}
//--- prepare the position value for main calculation
pos=InpRSIPeriod+1;
}
//--- the main loop of calculations
for(i=pos; i<rates_total && !IsStopped(); i++)
{
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
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;
if(ExtNegBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
else
{
if(ExtPosBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0;
else
ExtRSIBuffer[i]=50.0;
}
}
//---
return(rates_total);
}
//+------------------------------------------------------------------+
+157
View File
@@ -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);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,166 @@
//+------------------------------------------------------------------+
//| Stochastic.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, 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 4
#property indicator_plots 2
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
#property indicator_color1 LightSeaGreen
#property indicator_color2 Red
#property indicator_style2 STYLE_DOT
//--- input parameters
input int InpKPeriod=5; // K period
input int InpDPeriod=3; // D period
input int InpSlowing=3; // Slowing
//--- indicator buffers
double ExtMainBuffer[];
double ExtSignalBuffer[];
double ExtHighesBuffer[];
double ExtLowesBuffer[];
//
//
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator customChartIndicator;
//
//
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtMainBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtSignalBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ExtHighesBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,ExtLowesBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- set levels
IndicatorSetInteger(INDICATOR_LEVELS,2);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,20);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,80);
//--- set maximum and minimum for subwindow
IndicatorSetDouble(INDICATOR_MINIMUM,0);
IndicatorSetDouble(INDICATOR_MAXIMUM,100);
//--- name for DataWindow and indicator subwindow label
IndicatorSetString(INDICATOR_SHORTNAME,"Stoch("+(string)InpKPeriod+","+(string)InpDPeriod+","+(string)InpSlowing+")");
PlotIndexSetString(0,PLOT_LABEL,"Main");
PlotIndexSetString(1,PLOT_LABEL,"Signal");
//--- sets first bar from what index will be drawn
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpKPeriod+InpSlowing-2);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpKPeriod+InpDPeriod);
//--- initialization done
}
//+------------------------------------------------------------------+
//| Stochastic 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,k,start;
//--- check for bars count
if(rates_total<=InpKPeriod+InpDPeriod+InpSlowing)
return(0);
//---
start=InpKPeriod-1;
if(start+1<_prev_calculated) start=_prev_calculated-2;
else
{
for(i=0;i<start;i++)
{
ExtLowesBuffer[i]=0.0;
ExtHighesBuffer[i]=0.0;
}
}
//--- calculate HighesBuffer[] and ExtHighesBuffer[]
for(i=start;i<rates_total && !IsStopped();i++)
{
double dmin=1000000.0;
double dmax=-1000000.0;
for(k=i-InpKPeriod+1;k<=i;k++)
{
if(dmin>customChartIndicator.Low[k]) dmin=customChartIndicator.Low[k];
if(dmax<customChartIndicator.High[k]) dmax=customChartIndicator.High[k];
}
ExtLowesBuffer[i]=dmin;
ExtHighesBuffer[i]=dmax;
}
//--- %K
start=InpKPeriod-1+InpSlowing-1;
if(start+1<_prev_calculated) start=_prev_calculated-2;
else
{
for(i=0;i<start;i++) ExtMainBuffer[i]=0.0;
}
//--- main cycle
for(i=start;i<rates_total && !IsStopped();i++)
{
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i-InpSlowing+1);k<=i;k++)
{
sumlow +=(customChartIndicator.Close[k]-ExtLowesBuffer[k]);
sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
}
if(sumhigh==0.0) ExtMainBuffer[i]=100.0;
else ExtMainBuffer[i]=sumlow/sumhigh*100;
}
//--- signal
start=InpDPeriod-1;
if(start+1<_prev_calculated) start=_prev_calculated-2;
else
{
for(i=0;i<start;i++) ExtSignalBuffer[i]=0.0;
}
for(i=start;i<rates_total && !IsStopped();i++)
{
double sum=0.0;
for(k=0;k<InpDPeriod;k++) sum+=ExtMainBuffer[i-k];
ExtSignalBuffer[i]=sum/InpDPeriod;
}
//--- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
+254
View File
@@ -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.
+321
View File
@@ -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.
+146
View File
@@ -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;
}
//---
}
//+------------------------------------------------------------------+
+9 -2
View File
@@ -6,17 +6,24 @@ used on the chart to the RangeBars settings that should be used in the EA.
## The files
**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.
**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
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
The RangeBars indicator for MT5 can be downloaded from https://www.mql5.com/en/market/product/16762
A version for MT4 is available from https://www.az-invest.eu/rangebars-plug-in-for-metatrader4
## Disclaimer:
All of the EAs and indicators presented in this repository are solely for educational and informational purposes and should not be regarded as advice or an invitation to trade.
Application of the techniques, ideas, and suggestions presented in the videos and files of this repository is done at the users sole discretion and risk.