Compare commits

..

22 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
51 changed files with 4064 additions and 1244 deletions
+36 -60
View File
@@ -1,10 +1,12 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#property version "2.05"
#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 EA needs to be *tested in MT5's backtester*
// 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
@@ -20,21 +22,21 @@
#include <AZ-INVEST/SDK/RangeBars.mqh>
//
// To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars)
// and call the Init() method in your EA's OnInit() function.
// Don't forget to release the indicator when you're done by calling the Deinit() method.
// Example shown in OnInit & OnDeinit functions below:
// and call the Init() and Deinit() methods in your EA's OnInit() and OnDeinit() functions.
// Example shown below
//
RangeBars * rangeBars;
RangeBars *rangeBars = NULL;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
rangeBars = new RangeBars();
if(rangeBars == NULL)
return(INIT_FAILED);
{
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
}
rangeBars.Init();
if(rangeBars.GetHandle() == INVALID_HANDLE)
@@ -55,6 +57,7 @@ void OnDeinit(const int reason)
{
rangeBars.Deinit();
delete rangeBars;
rangeBars = NULL;
}
//
@@ -70,8 +73,22 @@ void OnDeinit(const int reason)
//+------------------------------------------------------------------+
//| 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.
@@ -96,7 +113,7 @@ void OnTick()
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))
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
@@ -182,64 +199,23 @@ void OnTick()
}
//
// Getting Donchain channel values is done using the
// GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
// method. Example below:
// 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 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
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.GetDonchian(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
if(rangeBars.GetChannel(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...
// Apply your 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...
//
}
}
}
+26 -15
View File
@@ -1,6 +1,6 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#property version "1.00"
#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"
@@ -8,6 +8,7 @@
// Helper functions for placing market orders.
//
#define DEVELOPER_VERSION
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
//
@@ -39,7 +40,7 @@ ulong currentTicket;
// the RangeBars indicator attached.
//
//#define SHOW_INDICATOR_INPUTS
#define SHOW_INDICATOR_INPUTS
//
// You need to include the RangeBars.mqh header file
@@ -48,22 +49,22 @@ ulong currentTicket;
#include <AZ-INVEST/SDK/RangeBars.mqh>
//
// To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars)
// and call the Init() method in your EA's OnInit() function.
// Don't forget to release the indicator when you're done by calling the Deinit() method.
// Example shown in OnInit & OnDeinit functions below:
// and call the Init() and Deinit() methods in your EA's OnInit() and OnDeinit() functions.
// Example shown below
//
RangeBars * rangeBars;
CMarketOrder * marketOrder;
RangeBars *rangeBars = NULL;
CMarketOrder *marketOrder = NULL;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
rangeBars = new RangeBars();
if(rangeBars == NULL)
return(INIT_FAILED);
{
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
}
rangeBars.Init();
if(rangeBars.GetHandle() == INVALID_HANDLE)
@@ -84,8 +85,12 @@ int OnInit()
params.busyTimeout_ms = InpBusyTimeout_ms;
params.requoteTimeout_ms = InpRequoteTimeout_ms;
}
marketOrder = new CMarketOrder(params);
if(marketOrder == NULL)
{
marketOrder = new CMarketOrder(params);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
@@ -93,10 +98,15 @@ int OnInit()
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
// delete RanegBars class
//
if(rangeBars != NULL)
{
rangeBars.Deinit();
delete rangeBars;
rangeBars = NULL;
}
//
@@ -106,6 +116,7 @@ void OnDeinit(const int reason)
if(marketOrder != NULL)
{
delete marketOrder;
marketOrder = NULL;
}
}
@@ -130,7 +141,7 @@ void OnTick()
//
// Getting SuperTrend values is done using the
// GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
// GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
// method. Example below:
//
@@ -141,7 +152,7 @@ void OnTick()
int startAtBar = 1; // get values starting from the last completed bar.
int numberOfBars = 2; // gat a total of 3 values (for 3 bars starting from bar 1 (last completed))
if(rangeBars.GetSuperTrend(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
if(rangeBars.GetChannel(HighArray,MidArray,LowArray,startAtBar,numberOfBars))
{
//
// Read signal bar's time for optional debug log
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;
}
+205 -78
View File
@@ -1,6 +1,10 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property copyright "Copyright 2018-2020, Level Up Software"
#property link "http://www.az-invest.eu"
#property version "2.02"
#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
@@ -16,8 +20,12 @@ class RangeBarIndicator
bool useAppliedPrice;
ENUM_APPLIED_PRICE applied_price;
bool firstRun;
bool dataReady;
datetime prevTime;
int prevRatesTotal;
public:
datetime Time[];
@@ -31,8 +39,21 @@ class RangeBarIndicator
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();
@@ -41,8 +62,11 @@ class RangeBarIndicator
void SetGetVolumeBreakdownFlag() { this.getVolumeBreakdown = true; };
void SetGetTimeFlag() { this.getTime = true; };
bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &_Time[]);
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:
@@ -64,11 +88,14 @@ class RangeBarIndicator
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();
rangeBars = new RangeBars(UseOnRangeBarChart);
if(rangeBars != NULL)
rangeBars.Init();
@@ -77,6 +104,9 @@ RangeBarIndicator::RangeBarIndicator(void)
getTime = false;
dataReady = false;
firstRun = true;
prevTime = 0;
prevRatesTotal = 0;
}
RangeBarIndicator::~RangeBarIndicator(void)
@@ -99,6 +129,7 @@ bool RangeBarIndicator::CheckStatus(void)
bool RangeBarIndicator::NeedsReload(void)
{
if(rangeBars.Reload())
{
Print("Chart settings changed - reloading indicator with new settings");
@@ -108,17 +139,13 @@ bool RangeBarIndicator::NeedsReload(void)
return false;
}
bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &_Time[])
bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &_Time[], const double &_Close[])
{
static bool firstRun = true;
if(firstRun)
{
Canvas_IsNewBar(_Time);
Canvas_RatesTotalChangedBy(_rates_total);
IsNewBar = rangeBars.IsNewBar();
firstRun = false;
}
if(!CheckStatus())
@@ -126,10 +153,12 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
if(rangeBars != NULL)
delete rangeBars;
rangeBars = new RangeBars();
rangeBars = new RangeBars(UseOnRangeBarChart);
if(rangeBars != NULL)
rangeBars.Init();
Print("CheckStatus block failed");
return false;
}
@@ -145,30 +174,29 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
ArraySetAsSeries(this.Sell_volume,false);
ArraySetAsSeries(this.BuySell_volume,false);
bool needsReload = (NeedsReload() || (!this.dataReady));
if(needsReload)
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;
}
/*
if(needsReload || IsNewBar || canvasIsNewTime || (change != 0))
{
Print("reload="+needsReload+", renkoisnewbar="+IsNewBar+", canvasIsNewTime="+canvasIsNewTime+", change="+change);
GetOLHC(0,_rates_total);
this.prev_calculated = ArraySize(this.Open);
return true;
}
*/
}
bool change = Canvas_RatesTotalChangedBy(_rates_total);
if(change != 0)
{
#ifdef DISPLAY_DEBUG_MSG
Print("rates total changed to:"+_rates_total);
#endif
if(change == 1)
{
#ifdef DISPLAY_DEBUG_MSG
@@ -183,7 +211,8 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
#endif
GetOLHC(0,_rates_total);
}
this.prev_calculated = 0;//_prev_calculated;
this.prev_calculated = 0;
Canvas_IsNewBar(_Time);
return true;
}
@@ -197,7 +226,7 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
return true; ///////// false
return true;
}
OLHCShiftRight();
@@ -210,9 +239,9 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
{
GetOLHC(0,_rates_total);
this.prev_calculated = 0;
firstRun = true;
return true;
}
//
// Only recalculate last bar
@@ -224,6 +253,19 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
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)
@@ -241,6 +283,7 @@ int RangeBarIndicator::GetOLHC(int start, int count)
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;
@@ -286,10 +329,13 @@ void RangeBarIndicator::OLHCShiftRight()
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];
@@ -310,8 +356,10 @@ void RangeBarIndicator::OLHCShiftRight()
if(getTime)
this.Time[0] = 0;
if(useAppliedPrice)
this.Price[0] = 0.0;
if(getVolumes)
{
this.Tick_volume[0] = 0.0;
@@ -339,8 +387,10 @@ void RangeBarIndicator::OLHCResize()
if(getTime)
ArrayResize(this.Time,count+1);
if(useAppliedPrice)
ArrayResize(this.Price,count+1);
if(getVolumes)
{
ArrayResize(this.Tick_volume,count+1);
@@ -362,8 +412,6 @@ bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[])
datetime now = _Time[0];
ArraySetAsSeries(_Time,false);
static datetime prevTime = 0;
if(prevTime != now)
{
prevTime = now;
@@ -375,8 +423,6 @@ bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[])
bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow)
{
static int prevRatesTotal = 0;
if(prevRatesTotal == 0)
prevRatesTotal = ratesTotalNow;
@@ -392,7 +438,6 @@ bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow)
int RangeBarIndicator::Canvas_RatesTotalChangedBy(int ratesTotalNow)
{
int changedBy = 0;
static int prevRatesTotal = 0;
if(prevRatesTotal == 0)
prevRatesTotal = ratesTotalNow;
@@ -450,11 +495,11 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
handle = rangeBars.GetHandle();
if(handle == INVALID_HANDLE)
return -1;
int _count = CopyBuffer(handle,RANGEBAR_OPEN,start,count,temp);
if(_count == -1)
int __count = CopyBuffer(handle,RANGEBAR_OPEN,start,count,temp);
if(__count == -1)
{
int errorCode = GetLastError();
if(errorCode == ERR_INDICATOR_DATA_NOT_FOUND)
if(GetLastError() == ERR_INDICATOR_DATA_NOT_FOUND)
{
Print("Waiting for buffers ready flag");
return -2;
@@ -463,95 +508,109 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
return -1;
}
if(_count < count)
if(__count < count)
{
#ifdef DISPLAY_DEBUG_MSG
Print("Fixing offset (req:"+count+" res:"+_count+")");
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);
ArrayCopy(o,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_LOW,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_LOW,start,__count,temp) == -1)
return -1;
ArrayCopy(l,temp,(count-_count),0);
ArrayCopy(l,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_HIGH,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_HIGH,start,__count,temp) == -1)
return -1;
ArrayCopy(h,temp,(count-_count),0);
ArrayCopy(h,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_CLOSE,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_CLOSE,start,__count,temp) == -1)
return -1;
ArrayCopy(c,temp,(count-_count),0);
ArrayCopy(c,temp,(count-__count),0);
if(getTime)
{
if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,__count,temp) == -1)
return -1;
ArrayCopy(t,temp,(count-_count),0);
ArrayCopy(t,temp,(count-__count),0);
}
if(getVolumes)
{
if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(tickVolume,temp,(count-_count),0);
ArrayCopy(tickVolume,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(realVolume,temp,(count-_count),0);
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)
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp,(count-_count),0);
ArrayCopy(buyVolume,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp,(count-_count),0);
ArrayCopy(sellVolume,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp,(count-_count),0);
ArrayCopy(buySellVolume,temp,(count-__count),0);
}
#else
#endif
#else
if(getVolumeBreakdown)
{
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(buyVolume,temp,(count-_count),0);
ArrayCopy(buyVolume,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(sellVolume,temp,(count-_count),0);
ArrayCopy(sellVolume,temp,(count-__count),0);
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1)
if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,__count,temp) == -1)
return -1;
ArrayCopy(buySellVolume,temp,(count-_count),0);
ArrayCopy(buySellVolume,temp,(count-__count),0);
}
#endif
@@ -560,10 +619,13 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
{
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;
@@ -571,6 +633,7 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
{
if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,count,temp) == -1)
return -1;
ArrayCopy(t,temp);
}
@@ -578,9 +641,12 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
{
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);
}
@@ -590,14 +656,17 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
{
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
@@ -607,14 +676,17 @@ int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h
{
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
@@ -631,11 +703,11 @@ int RangeBarIndicator::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l
{
dataReady = true;
int _count = GetOLHCForIndicatorCalc(o,l,h,c,t,tickVolume,realVolume,buyVolume,sellVolume,buySellVolume,start,count);
if(_count < 0)
int __count = GetOLHCForIndicatorCalc(o,l,h,c,t,tickVolume,realVolume,buyVolume,sellVolume,buySellVolume,start,count);
if(__count < 0)
{
dataReady = false;
return _count;
return __count;
}
if(applied_price == PRICE_CLOSE)
{
@@ -655,22 +727,25 @@ int RangeBarIndicator::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l
}
else
{
if(ArrayResize(price,_count) == -1)
if(ArrayResize(price,__count) == -1)
return -1;
for(int i=0; i<_count; i++)
for(int i=0; i<__count; i++)
{
price[i] = CalcAppliedPrice(o[i],l[i],h[i],c[i],_applied_price);
}
}
return _count;
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);
@@ -698,18 +773,30 @@ ENUM_TIMEFRAMES RangeBarIndicator::TFMigrate(int tf)
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);
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);
if(CopyTime(symbol, timeframe, index, 1, Arr) > 0)
{
return(Arr[0]);
}
else
{
return(-1);
}
}
//
@@ -764,3 +851,43 @@ void RangeBarIndicator::BufferShiftLeft(double &buffer[])
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);
}
}
-345
View File
@@ -1,345 +0,0 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
#include <AZ-INVEST/SDK/CommonSettings.mqh>
#define CUSTOM_CHART_NAME "Range Bars"
#ifdef SHOW_INDICATOR_INPUTS
input int barSizeInTicks = 100; // Range bar size (in points)
input ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
input int atrPeriod = 14; // ATR period
input int atrPercentage = 10; // Use percentage of ATR
ENUM_BOOL useRealVolume = false; // Use real volume ( false for FX )
ENUM_TICK_PRICE_TYPE plotPrice = tickBid; // Build chart using
input int showNumberOfDays = 14; // Show history for number of days
input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
input double TopBottomPaddingPercentage = 0.30; // Use padding top/bottom (0.0 - 1.0)
input ENUM_PIVOT_POINTS showPivots = ppNone; // Show pivot levels
input ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3; // Pivot point calculation method
input color RColor = clrDodgerBlue; // Resistance line color
input color PColor = clrGold; // Pivot line color
input color SColor = clrFireBrick; // Support line color
input color PDHColor = clrHotPink; // Previous day's high
input color PDLColor = clrLightSkyBlue; // Previous day's low
input color PDCColor = clrGainsboro; // Previous day's close
input ENUM_BOOL showNextBarLevels = true; // Show current bar's close projections
input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color
input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color
input ENUM_BOOL showCurrentBarOpenTime = true; // Display chart info and current bar's open time
input color InfoTextColor = clrWhite; // Current bar's open time info color
input ENUM_BOOL UseSoundSignalOnNewBar = false; // Play sound on new bar
input ENUM_BOOL OnlySignalReversalBars = false; // Only signal reversals
input ENUM_BOOL UseAlertWindow = false; // Display Alert window with new bar info
input ENUM_BOOL SendPushNotifications = false; // Send new bar info push notification to smartphone
input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close
input string SoundFileBear = "timeout.wav"; // Use sound file for bearish bar close
input ENUM_BOOL MA1on = false; // Show first MA
input int MA1period = 20; // 1st MA period
input ENUM_MA_METHOD_EXT MA1method = _MODE_SMA; // 1st MA method
input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; // 1st MA apply to
input int MA1shift = 0; // 1st MA shift
input ENUM_BOOL MA2on = false; // Show second MA
input int MA2period = 50; // 2nd MA period
input ENUM_MA_METHOD_EXT MA2method = _MODE_EMA; // 2nd MA method
input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to
input int MA2shift = 0; // 2nd MA shift
input ENUM_BOOL MA3on = false; // Show third MA
input int MA3period = 20; // 3rd MA period
input ENUM_MA_METHOD_EXT MA3method = _VWAP_TICKVOL; // 3rd MA method
input ENUM_APPLIED_PRICE MA3applyTo = PRICE_CLOSE; // 3rd MA apply to
input int MA3shift = 0; // 3rd MA shift
input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel
input string Channel_Settings = "-------------------"; // Channel settings
input int DonchianPeriod = 20; // Donchian Channel period
input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; // Bollinger Bands apply to
input int BollingerBandsPeriod = 20; // Bollinger Bands period
input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations
input int SuperTrendPeriod = 10; // Super Trend period
input double SuperTrendMultiplier=1.7; // Super Trend multiplier
input string Misc_Settings = "-------------------"; // Misc settings
input ENUM_BOOL DisplayAsBarChart = false; // Display as bar chart
input ENUM_BOOL UsedInEA = false; // Indicator used in EA via iCustom()
#else
//
// This block should always be set to the following values
//
double TopBottomPaddingPercentage = 0;
ENUM_PIVOT_POINTS showPivots = ppNone;
ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3;
color RColor = clrNONE;
color PColor = clrNONE;
color SColor = clrNONE;
color PDHColor = clrNONE;
color PDLColor = clrNONE;
color PDCColor = clrNONE;
ENUM_BOOL showNextBarLevels = false;
color HighThresholdIndicatorColor = clrNONE;
color LowThresholdIndicatorColor = clrNONE;
ENUM_BOOL showCurrentBarOpenTime = false;
color InfoTextColor = clrNONE;
ENUM_BOOL UseSoundSignalOnNewBar = false;
ENUM_BOOL OnlySignalReversalBars = false;
ENUM_BOOL UseAlertWindow = false;
ENUM_BOOL SendPushNotifications = false;
string SoundFileBull = "";
string SoundFileBear = "";
ENUM_BOOL DisplayAsBarChart = true;
ENUM_BOOL UsedInEA = true; // This should always be set to TRUE for EAs & Indicators
//
//
//
#endif
struct RANGEBAR_SETTINGS
{
int barSizeInTicks;
ENUM_BOOL atrEnabled;
ENUM_TIMEFRAMES atrTimeFrame;
int atrPeriod;
int atrPercentage;
ENUM_BOOL useRealVolume;
ENUM_TICK_PRICE_TYPE plotPrice;
int showNumberOfDays;
ENUM_BOOL resetOpenOnNewTradingDay;
};
class RangeBarSettings
{
protected:
string settingsFileName;
string chartTypeFileName;
RANGEBAR_SETTINGS settings;
CHART_INDICATOR_SETTINGS chartIndicatorSettings;
ALERT_INFO_SETTINGS alertInfoSettings;
public:
RangeBarSettings(void);
~RangeBarSettings(void);
RANGEBAR_SETTINGS GetRangeBarSettings(void);
ALERT_INFO_SETTINGS GetAlertInfoSettings(void);
CHART_INDICATOR_SETTINGS GetChartIndicatorSettings(void);
void Set(void);
void Save(void);
bool Load(void);
void Delete(void);
bool Changed(void);
};
void RangeBarSettings::RangeBarSettings(void)
{
this.settingsFileName = CUSTOM_CHART_NAME+(string)ChartID()+".set";
this.chartTypeFileName = (string)ChartID()+".id";
}
void RangeBarSettings::~RangeBarSettings(void)
{
}
void RangeBarSettings::Save(void)
{
if(IS_TESTING || this.chartIndicatorSettings.UsedInEA)
return;
this.Delete();
//
// Store indicator settings
//
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN);
uint result = 0;
result += FileWriteStruct(handle,this.settings);
result += FileWriteStruct(handle,this.chartIndicatorSettings);
//FileWriteStruct(handle,this.alertInfoSettings);
FileClose(handle);
//
// Store chart type identifier
//
handle = FileOpen(this.chartTypeFileName,FILE_SHARE_READ|FILE_WRITE|FILE_ANSI);
FileWriteString(handle,CUSTOM_CHART_NAME);
FileClose(handle);
}
void RangeBarSettings::Delete(void)
{
if(IS_TESTING || this.chartIndicatorSettings.UsedInEA)
return;
if(FileIsExist(this.settingsFileName))
FileDelete(this.settingsFileName);
}
bool RangeBarSettings::Load(void)
{
#ifdef SHOW_INDICATOR_INPUTS
Set();
return true;
#else
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
if(handle == INVALID_HANDLE)
return false;
if(FileReadStruct(handle,this.settings) <= 0)
{
Print("Failed loading settings(1)!");
FileClose(handle);
return false;
}
if(FileReadStruct(handle,this.chartIndicatorSettings) <= 0)
{
Print("Failed loading settings(2)!");
FileClose(handle);
return false;
}
/*
if(FileReadStruct(handle,this.alertInfoSettings) <= 0)
{
Print("Failed loading settings(3)!");
FileClose(handle);
return false;
}
*/
FileClose(handle);
return true;
#endif
}
ALERT_INFO_SETTINGS RangeBarSettings::GetAlertInfoSettings(void)
{
return this.alertInfoSettings;
}
CHART_INDICATOR_SETTINGS RangeBarSettings::GetChartIndicatorSettings(void)
{
return this.chartIndicatorSettings;
}
RANGEBAR_SETTINGS RangeBarSettings::GetRangeBarSettings(void)
{
return this.settings;
}
void RangeBarSettings::Set(void)
{
#ifdef SHOW_INDICATOR_INPUTS
settings.barSizeInTicks = barSizeInTicks;
settings.atrEnabled = atrEnabled;
settings.atrTimeFrame = atrTimeFrame;
settings.atrPeriod = atrPeriod;
settings.atrPercentage = atrPercentage;
settings.useRealVolume = useRealVolume;
settings.plotPrice = plotPrice;
settings.showNumberOfDays = showNumberOfDays;
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
//
//
//
chartIndicatorSettings.MA1on = MA1on;
chartIndicatorSettings.MA1period = MA1period;
chartIndicatorSettings.MA1method = MA1method;
chartIndicatorSettings.MA1applyTo = MA1applyTo;
chartIndicatorSettings.MA1shift = MA1shift;
chartIndicatorSettings.MA2on = MA2on;
chartIndicatorSettings.MA2period = MA2period;
chartIndicatorSettings.MA2method = MA2method;
chartIndicatorSettings.MA2applyTo = MA2applyTo;
chartIndicatorSettings.MA2shift = MA2shift;
/*
chartIndicatorSettings.ShowVWAP = ShowVWAP;
chartIndicatorSettings.VWAP_Period = VWAP_Period;
chartIndicatorSettings.VWAPapplyTo = VWAPapplyTo;
chartIndicatorSettings.VWAPvolume = VWAPvolume;
*/
chartIndicatorSettings.MA3on = MA3on;
chartIndicatorSettings.MA3period = MA3period;
chartIndicatorSettings.MA3method = MA3method;
chartIndicatorSettings.MA3applyTo = MA3applyTo;
chartIndicatorSettings.MA3shift = MA3shift;
chartIndicatorSettings.ShowChannel = ShowChannel;
chartIndicatorSettings.DonchianPeriod = DonchianPeriod;
chartIndicatorSettings.BBapplyTo = BBapplyTo;
chartIndicatorSettings.BollingerBandsPeriod = BollingerBandsPeriod;
chartIndicatorSettings.BollingerBandsDeviations = BollingerBandsDeviations;
chartIndicatorSettings.SuperTrendPeriod = SuperTrendPeriod;
chartIndicatorSettings.SuperTrendMultiplier = SuperTrendMultiplier;
chartIndicatorSettings.UsedInEA = UsedInEA;
//
//
//
alertInfoSettings.TopBottomPaddingPercentage = TopBottomPaddingPercentage;
alertInfoSettings.showPiovots = showPivots;
alertInfoSettings.pivotPointCalculationType = pivotPointCalculationType;
alertInfoSettings.Rcolor = RColor;
alertInfoSettings.Pcolor = PColor;
alertInfoSettings.Scolor = SColor;
alertInfoSettings.PDHColor = PDHColor;
alertInfoSettings.PDLColor = PDLColor;
alertInfoSettings.PDCColor = PDCColor;
alertInfoSettings.showNextBarLevels = showNextBarLevels;
alertInfoSettings.HighThresholdIndicatorColor = HighThresholdIndicatorColor;
alertInfoSettings.LowThresholdIndicatorColor = LowThresholdIndicatorColor;
alertInfoSettings.showCurrentBarOpenTime = showCurrentBarOpenTime;
alertInfoSettings.InfoTextColor = InfoTextColor;
alertInfoSettings.UseSoundSignalOnNewBar = UseSoundSignalOnNewBar;
alertInfoSettings.OnlySignalReversalBars = OnlySignalReversalBars;
alertInfoSettings.UseAlertWindow = UseAlertWindow;
alertInfoSettings.SendPushNotifications = SendPushNotifications;
alertInfoSettings.SoundFileBull = SoundFileBull;
alertInfoSettings.SoundFileBear = SoundFileBear;
alertInfoSettings.DisplayAsBarChart = DisplayAsBarChart;
#endif
}
bool RangeBarSettings::Changed(void)
{
if(MQLInfoInteger((int)MQL5_TESTING))
return false;
static datetime prevFileTime = 0;
if(!FileIsExist(this.settingsFileName))
return false;
int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN);
datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE);
FileClose(handle);
if(prevFileTime != currFileTime)
{
prevFileTime = currFileTime;
return true;
}
return false;
}
+253 -112
View File
@@ -1,89 +1,112 @@
//+------------------------------------------------------------------+
//| RangeBars.mqh ver:2.03.0 |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property copyright "Copyright 2018-2020, Level Up Software"
#property link "http://www.az-invest.eu"
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay203"
#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_MA1 05
#define RANGEBAR_MA2 06
#define RANGEBAR_MA3 07
#define RANGEBAR_CHANNEL_HIGH 08
#define RANGEBAR_CHANNEL_MID 09
#define RANGEBAR_CHANNEL_LOW 10
#define RANGEBAR_BAR_OPEN_TIME 11
#define RANGEBAR_TICK_VOLUME 12
#define RANGEBAR_REAL_VOLUME 13
#define RANGEBAR_BUY_VOLUME 14
#define RANGEBAR_SELL_VOLUME 15
#define RANGEBAR_BUYSELL_VOLUME 16
#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/RangeBarSettings.mqh>
#include <az-invest/sdk/RangeBarCustomChartSettings.mqh>
class RangeBars
{
private:
RangeBarSettings * rangeBarSettings;
CRangeBarCustomChartSettigns * rangeBarSettings;
//
// Median renko indicator handle
//
int rangeBarsHandle;
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);
bool IsNewBar();
//
private:
bool GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
int GetIndicatorHandle(void);
bool GetChannelData(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
};
RangeBars::RangeBars(void)
{
#define CONSTRUCTOR1
rangeBarSettings = new RangeBarSettings();
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 RangeBarSettings();
rangeBarSettings = new CRangeBarCustomChartSettigns();
rangeBarsHandle = INVALID_HANDLE;
rangeBarsSymbol = symbol;
usedByIndicatorOnRangeBarChart = false;
prevBarTime = 0;
}
RangeBars::~RangeBars(void)
@@ -92,6 +115,14 @@ RangeBars::~RangeBars(void)
delete rangeBarSettings;
}
void RangeBars::ReleaseHandle()
{
if(rangeBarsHandle != INVALID_HANDLE)
{
IndicatorRelease(rangeBarsHandle);
}
}
//
// Function for initializing the median renko indicator handle
//
@@ -100,6 +131,18 @@ 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)
@@ -121,33 +164,36 @@ int RangeBars::Init()
}
else
{
#ifdef SHOW_INDICATOR_INPUTS
if(usedByIndicatorOnRangeBarChart)
{
//
// Load settings from EA inputs
//
rangeBarSettings.Load();
#else
//
// Save indicator inputs for use by EA attached to same chart.
//
rangeBarSettings.Save();
#endif
// 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.GetRangeBarSettings();
RANGEBAR_SETTINGS s = rangeBarSettings.GetCustomChartSettings();
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
//RangeBarSettings.Debug();
rangeBarsHandle = iCustom(this.rangeBarsSymbol,_Period,RANGEBAR_INDICATOR_NAME,
rangeBarsHandle = iCustom(this.rangeBarsSymbol, _Period, RANGEBAR_INDICATOR_NAME,
s.barSizeInTicks,
s.atrEnabled,
//s.atrTimeFrame,
s.atrPeriod,
s.atrPercentage,
s.showNumberOfDays,
s.resetOpenOnNewTradingDay,
TopBottomPaddingPercentage,
s.showNumberOfDays, s.resetOpenOnNewTradingDay,
TradingSessionTime,
showPivots,
pivotPointCalculationType,
RColor,
@@ -156,52 +202,59 @@ int RangeBars::Init()
PDHColor,
PDLColor,
PDCColor,
showNextBarLevels,
HighThresholdIndicatorColor,
LowThresholdIndicatorColor,
showCurrentBarOpenTime,
InfoTextColor,
UseSoundSignalOnNewBar,
OnlySignalReversalBars,
UseAlertWindow,
SendPushNotifications,
SoundFileBull,
SoundFileBear,
AlertMeWhen,
AlertNotificationType,
cis.MA1on,
cis.MA1lineType,
cis.MA1period,
cis.MA1method,
cis.MA1applyTo,
cis.MA1shift,
cis.MA2on,
cis.MA1priceLabel,
cis.MA2on,
cis.MA2lineType,
cis.MA2period,
cis.MA2method,
cis.MA2applyTo,
cis.MA2shift,
cis.MA3on,
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.DonchianPeriod,
cis.BBapplyTo,
cis.BollingerBandsPeriod,
cis.BollingerBandsDeviations,
cis.SuperTrendPeriod,
cis.SuperTrendMultiplier,
"",
DisplayAsBarChart,
UsedInEA);
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 init failed on error ",GetLastError());
Print(RANGEBAR_INDICATOR_NAME+" indicator init failed on error ",GetLastError());
}
else
{
Print("RangeBar indicator init OK");
Print(RANGEBAR_INDICATOR_NAME+" indicator init OK");
}
return rangeBarsHandle;
@@ -213,14 +266,36 @@ int RangeBars::Init()
bool RangeBars::Reload()
{
if(rangeBarSettings.Changed())
bool actionNeeded = false;
int temp = GetIndicatorHandle();
if(temp != rangeBarsHandle)
{
if(Init() == INVALID_HANDLE)
return false;
return true;
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;
}
@@ -233,10 +308,13 @@ void RangeBars::Deinit()
if(rangeBarsHandle == INVALID_HANDLE)
return;
if(IndicatorRelease(rangeBarsHandle))
Print("RangeBar indicator handle released");
else
Print("Failed to release RangeBar indicator handle");
if(!usedByIndicatorOnRangeBarChart)
{
if(IndicatorRelease(rangeBarsHandle))
Print(RANGEBAR_INDICATOR_NAME+" indicator handle released");
else
Print("Failed to release "+RANGEBAR_INDICATOR_NAME+" indicator handle");
}
}
//
@@ -245,13 +323,13 @@ void RangeBars::Deinit()
bool RangeBars::IsNewBar()
{
MqlRates currentBar[1];
static datetime prevBarTime;
MqlRates currentBar[1];
GetMqlRates(currentBar,0,1);
if(currentBar[0].time == 0)
{
return false;
}
if(prevBarTime < currentBar[0].time)
{
@@ -259,7 +337,8 @@ bool RangeBars::IsNewBar()
return true;
}
return false;}
return false;
}
//
// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar
@@ -342,23 +421,12 @@ bool RangeBars::GetBuySellVolumeBreakdown(double &buy[], double &sell[], double
if(ArrayResize(bs,count) == -1)
return false;
#ifdef P_RANGEBAR_BR
#ifdef P_RANGEBAR_BR_PRO
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1)
return false;
#endif
#else
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1)
return false;
if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1)
return false;
#endif
if(ArrayResize(buy,count) == -1)
return false;
@@ -380,16 +448,48 @@ bool RangeBars::GetBuySellVolumeBreakdown(double &buy[], double &sell[], double
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;
@@ -415,6 +515,8 @@ bool RangeBars::GetMA1(double &MA[], int start, int count)
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;
@@ -440,6 +542,8 @@ bool RangeBars::GetMA2(double &MA[], int start, int count)
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;
@@ -460,12 +564,13 @@ bool RangeBars::GetMA3(double &MA[], int start, int count)
}
//
// Get "count" Renko Donchian channel values into "HighArray[]", "MidArray[]", and "LowArray[]" arrays starting from "start" bar
// 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)
{
return GetChannel(HighArray,MidArray,LowArray,start,count);
Print(__FUNCTION__+" is deprecated, please use GetChannelData instead");
return GetChannelData(HighArray,MidArray,LowArray,start,count);
}
//
@@ -474,7 +579,8 @@ bool RangeBars::GetDonchian(double &HighArray[], double &MidArray[], double &Low
bool RangeBars::GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
{
return GetChannel(HighArray,MidArray,LowArray,start,count);
Print(__FUNCTION__+" is deprecated, please use GetChannelData instead");
return GetChannelData(HighArray,MidArray,LowArray,start,count);
}
//
@@ -483,21 +589,27 @@ bool RangeBars::GetBollingerBands(double &HighArray[], double &MidArray[], doubl
bool RangeBars::GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count)
{
return GetChannel(SuperTrendHighArray,SuperTrendArray,SuperTrendLowArray,start,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::GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
bool RangeBars::GetChannelData(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count)
{
double tempH[], tempM[], tempL[];
#ifdef P_RANGEBAR_BR
return false;
#else
if(ArrayResize(tempH,count) == -1)
return false;
if(ArrayResize(tempM,count) == -1)
@@ -532,6 +644,35 @@ bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowA
ArrayFree(tempL);
return true;
#endif
}
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];
}
+545 -80
View File
@@ -1,11 +1,13 @@
//+------------------------------------------------------------------+
//| TradeFunctions.mqh |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
//
// Copyright 2017-2018, Artur Zas
// https://www.az-invest.eu
// https://www.mql5.com/en/users/arturz
//
#include <Trade\Trade.mqh>
#include <AZ-INVEST/SDK/Normailze.mqh>
#include <AZ-INVEST/SDK/TradingChecks.mqh>
CTradingChecks tradingChecks;
#define POSITION_TYPE_NONE -1
@@ -15,40 +17,58 @@
struct CMarketOrderParameters
{
bool m_async_mode; // trade mode
ulong m_magic; // expert magic number
ulong m_deviation; // deviation default
bool m_async_mode; // trade mode
ulong m_magic; // expert magic number
ulong m_deviation; // deviation default
ENUM_ORDER_TYPE_FILLING m_type_filling;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
};
class CMarketOrder
{
protected:
CTrade * ctrade;
CTrade *ctrade;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
bool initialized;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
public:
CMarketOrder(void);
CMarketOrder(CMarketOrderParameters &params);
~CMarketOrder(void);
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0);
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0);
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0);
bool Initialize(CMarketOrderParameters &params);
bool IsInitialized() {return initialized;};
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0,bool stopsInPips = true, string comment = "");
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0, string comment = "");
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0,bool stopsInPips = true, string comment = "");
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0, string comment = "");
bool PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "");
bool PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "");
bool PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "");
bool PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "");
bool Modify(ulong ticket, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1);
bool Modify(ulong ticket, double priceSL=0,double priceTP=0);
bool ModifyPending(ulong ticket, double entry, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0);
bool ModifyPending(ulong ticket, double entry, double priceSL=0, double priceTP=0, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0);
bool Close(ulong ticket);
bool ClosePartial(ulong ticket, double lots);
bool CloseAll(string symbol = "");
bool Delete(ulong ticket);
bool Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0);
bool Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0);
bool IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0);
@@ -57,8 +77,13 @@ class CMarketOrder
bool IsOpen(ulong &ticket, string symbol, long magicNumber = 0);
bool IsOpen(ulong &ticket, ENUM_POSITION_TYPE &type, string symbol, long magicNumber = 0);
bool GetPositionType(ulong ticket, ENUM_POSITION_TYPE &_pType);
string PositionTypeToString(ENUM_POSITION_TYPE t);
string OrderTypeToString(ENUM_ORDER_TYPE t);
ENUM_ORDER_TYPE TradeBias(ENUM_ORDER_TYPE t);
bool RetryOrderRequest(int retryNumber);
void SetTradeId(ulong tradeId);
private:
@@ -68,19 +93,31 @@ class CMarketOrder
};
CMarketOrder::CMarketOrder(void)
{
ctrade = new CTrade();
this.initialized = false;
}
CMarketOrder::CMarketOrder(CMarketOrderParameters &params)
{
ctrade = new CTrade();
Initialize(params);
}
bool CMarketOrder::Initialize(CMarketOrderParameters &params)
{
ctrade.SetExpertMagicNumber(params.m_magic);
ctrade.SetDeviationInPoints(params.m_deviation);
ctrade.SetTypeFilling(params.m_type_filling);
ctrade.SetAsyncMode(params.m_async_mode);
this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries;
this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms;
this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms;
this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries;
this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms;
this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms;
this.initialized = true;
return this.initialized;
}
CMarketOrder::~CMarketOrder(void)
@@ -89,7 +126,7 @@ CMarketOrder::~CMarketOrder(void)
delete ctrade;
}
bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
int counter = 0;
@@ -97,14 +134,21 @@ bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprof
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : 0.0);
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_BUY,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -121,7 +165,7 @@ bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprof
return false;
}
bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0)
bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0, string comment = "")
{
bool result = false;
int counter = 0;
@@ -130,8 +174,15 @@ bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double price
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_BUY,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -148,7 +199,7 @@ bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double price
return false;
}
bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
int counter = 0;
@@ -156,14 +207,21 @@ bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takepro
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : 0.0);
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_SELL,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -180,7 +238,7 @@ bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takepro
return false;
}
bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0)
bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0, string comment = "")
{
bool result = false;
int counter = 0;
@@ -189,8 +247,15 @@ bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double pric
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_SELL,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -207,24 +272,202 @@ bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double pric
return false;
}
bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0)
bool CMarketOrder::PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to place buy
if(orderType == ORDER_TYPE_BUY_LIMIT)
result = ctrade.BuyLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_BUY_STOP)
result = ctrade.BuyStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
if(orderType == ORDER_TYPE_BUY_LIMIT)
result = ctrade.BuyLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_BUY_STOP)
result = ctrade.BuyStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
if(orderType == ORDER_TYPE_SELL_LIMIT)
result = ctrade.SellLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_SELL_STOP)
result = ctrade.SellStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
if(orderType == ORDER_TYPE_SELL_LIMIT)
result = ctrade.SellLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_SELL_STOP)
result = ctrade.SellStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::Modify(ulong ticket, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double priceSL;
double priceTP;
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP));
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
priceSL = (stoploss < 0)
? PositionGetDouble(POSITION_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,price - stoploss*point);
priceTP = (takeprofit < 0)
? PositionGetDouble(POSITION_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,price + takeprofit*point);
// priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL));
// priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP));
}
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP));
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{
// priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL));
// priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP));
priceSL = (stoploss < 0)
? PositionGetDouble(POSITION_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,price + stoploss*point);
priceTP = (takeprofit < 0)
? PositionGetDouble(POSITION_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,price - takeprofit*point);
}
else
return false;
@@ -232,15 +475,25 @@ bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0)
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyPosition(symbol,ticket,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(_IsNettingAccount())
result = ctrade.PositionModify(symbol,priceSL,priceTP);
else
result = ctrade.PositionModify(ticket,priceSL,priceTP);
if(result)
{
@@ -263,21 +516,167 @@ bool CMarketOrder::Modify(ulong ticket, double priceSL=0,double priceTP=0)
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
//double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyPosition(symbol,ticket,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(_IsNettingAccount())
result = ctrade.PositionModify(symbol,priceSL,priceTP);
else
result = ctrade.PositionModify(ticket,priceSL,priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::ModifyPending(ulong ticket, double entry, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0)
{
if(!OrderSelect(ticket))
return false;
string symbol = OrderGetString(ORDER_SYMBOL);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
if(entry == 0)
entry = OrderGetDouble(ORDER_PRICE_OPEN);
double priceSL;
double priceTP;
if((OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP_LIMIT))
{
priceSL = (stoploss < 0)
? OrderGetDouble(ORDER_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,entry - stoploss*point);
priceTP = (takeprofit < 0)
? OrderGetDouble(ORDER_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,entry + takeprofit*point);
}
else if((OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP_LIMIT))
{
priceSL = (stoploss < 0)
? OrderGetDouble(ORDER_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,entry + stoploss*point);
priceTP = (takeprofit < 0)
? OrderGetDouble(ORDER_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,entry - takeprofit*point);
}
else
return false;
//there's no change in parameters - do nothing!
if (priceSL == OrderGetDouble(ORDER_SL)
&& priceTP == OrderGetDouble(ORDER_TP)
&& entry == OrderGetDouble(ORDER_PRICE_OPEN)
&& orderTypeTime == OrderGetInteger(ORDER_TYPE_TIME)
&& expires == OrderGetInteger(ORDER_TIME_EXPIRATION))
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyOrder(symbol,ticket,entry,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.OrderModify(ticket,entry,priceSL,priceTP,orderTypeTime,expires);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::ModifyPending(ulong ticket, double entry, double priceSL=0, double priceTP=0, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0)
{
if(!OrderSelect(ticket))
return false;
string symbol = OrderGetString(ORDER_SYMBOL);
if(entry == 0)
entry = OrderGetDouble(ORDER_PRICE_OPEN);
//there's no change in parameters - do nothing!
if (priceSL == OrderGetDouble(ORDER_SL)
&& priceTP == OrderGetDouble(ORDER_TP)
&& entry == OrderGetDouble(ORDER_PRICE_OPEN)
&& orderTypeTime == OrderGetInteger(ORDER_TYPE_TIME)
&& expires == OrderGetInteger(ORDER_TIME_EXPIRATION))
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyOrder(symbol,ticket,entry,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.OrderModify(ticket,entry,priceSL,priceTP,orderTypeTime,expires);
if(result)
{
@@ -350,6 +749,11 @@ bool CMarketOrder::ClosePartial(ulong ticket, double lots)
return false;
}
bool CMarketOrder::Delete(ulong ticket)
{
return ctrade.OrderDelete(ticket);
}
bool CMarketOrder::Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0)
{
if(!PositionSelectByTicket(ticket))
@@ -420,6 +824,44 @@ bool CMarketOrder::IsOpen(ulong &ticket, string symbol, long magicNumber = 0)
return this._IsOpen(ticket,symbol,magicNumber);
}
bool CMarketOrder::CloseAll(string symbol = "")
{
int positions=PositionsTotal();
ulong ticketsToClose[];
int ticketsToCloseCounter = 0;
if(positions > 0)
ArrayResize(ticketsToClose,positions);
else
return false;
for(int i=0;i<positions;i++)
{
// ResetLastError();
ulong _ticket=PositionGetTicket(i);
if(_ticket!=0)
{
if(PositionSelectByTicket(_ticket))
{
if((PositionGetString(POSITION_SYMBOL) == symbol) || (symbol == ""))
{
ticketsToClose[ticketsToCloseCounter] = _ticket;
ticketsToCloseCounter++;
}
}
}
}
ArrayResize(ticketsToClose,ticketsToCloseCounter);
for(int i=0;i<ticketsToCloseCounter;i++)
{
this.Close(ticketsToClose[i]);
}
return true;
}
bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,long magicNumber=0)
{
int positions=PositionsTotal();
@@ -458,6 +900,15 @@ bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,l
}
bool CMarketOrder::GetPositionType(ulong ticket, ENUM_POSITION_TYPE &_pType)
{
if(!PositionSelectByTicket(ticket))
return false;
_pType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
return true;
}
bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber)
{
int positions=PositionsTotal();
@@ -546,8 +997,43 @@ string CMarketOrder::PositionTypeToString(ENUM_POSITION_TYPE t)
return "-";
}
string CMarketOrder::OrderTypeToString(ENUM_ORDER_TYPE t)
{
if(t == ORDER_TYPE_BUY)
return "Buy";
else if(t == ORDER_TYPE_BUY_LIMIT)
return "Buy Limit";
else if(t == ORDER_TYPE_BUY_STOP)
return "Buy Stop";
else if(t == ORDER_TYPE_BUY_STOP_LIMIT)
return "Buy Stop Limit";
else if(t == ORDER_TYPE_SELL)
return "Sell";
else if(t == ORDER_TYPE_SELL_LIMIT)
return "Sell Limit";
else if(t == ORDER_TYPE_SELL_STOP)
return "Sell Stop";
else if(t == ORDER_TYPE_SELL_STOP_LIMIT)
return "Sell Stop Limit";
else
return "-";
}
ENUM_ORDER_TYPE CMarketOrder::TradeBias(ENUM_ORDER_TYPE t)
{
if((t == ORDER_TYPE_BUY) ||
(t == ORDER_TYPE_BUY_LIMIT) ||
(t == ORDER_TYPE_BUY_STOP) ||
(t == ORDER_TYPE_BUY_STOP_LIMIT))
return ORDER_TYPE_BUY;
else
return ORDER_TYPE_SELL;
}
bool CMarketOrder::RetryOrderRequest(int retryNumber)
{
Print(ctrade.ResultRetcodeDescription());
if(retryNumber >= this.numberOfRetries)
{
PrintFormat("Giving up on maximum number of retries (%d)",this.numberOfRetries);
@@ -575,37 +1061,16 @@ bool CMarketOrder::RetryOrderRequest(int retryNumber)
break;
default:
MessageBox(ctrade.ResultRetcodeDescription(),"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
//+------------------------------------------------------------------+
//| Normalizing |
//+------------------------------------------------------------------+
double NormalizeLots(string symbol, double InputLots)
void CMarketOrder::SetTradeId(ulong tradeId)
{
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
if(InputLots < lotsMin)
InputLots = lotsMin;
if(InputLots > lotsMax)
InputLots = lotsMax;
return NormalizeDouble(InputLots, lotsDigits);
ctrade.SetExpertMagicNumber(tradeId);
}
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);
}
+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);
}
Binary file not shown.
+10 -34
View File
@@ -45,7 +45,7 @@ int ExtADXPeriod;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -99,39 +99,15 @@ int OnCalculate(const int rates_total,
const int &Spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
//--- checking for bars count
@@ -151,11 +127,11 @@ int OnCalculate(const int rates_total,
for(int i=start;i<rates_total && !IsStopped();i++)
{
//--- get some data
double Hi =rangeBarsIndicator.High[i];
double prevHi=rangeBarsIndicator.High[i-1];
double Lo =rangeBarsIndicator.Low[i];
double prevLo=rangeBarsIndicator.Low[i-1];
double prevCl=rangeBarsIndicator.Close[i-1];
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;
+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.
+24 -20
View File
@@ -8,6 +8,7 @@
#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
@@ -34,7 +35,7 @@ double ExtCCIBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -50,7 +51,7 @@ void OnInit()
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
//
rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
customChartIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
//
//
@@ -100,33 +101,36 @@ int OnCalculate(const int rates_total,const int prev_calculated,
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
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:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
// customChartIndicator.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[]
// 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[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
// 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
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
// 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
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
// 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 = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -150,13 +154,13 @@ int OnCalculate(const int rates_total,const int prev_calculated,
for(i=pos;i<rates_total && !IsStopped();i++)
{
//--- SMA on price buffer
ExtSPBuffer[i]=SimpleMA(i,ExtCCIPeriod,rangeBarsIndicator.Price);
ExtSPBuffer[i]=SimpleMA(i,ExtCCIPeriod,customChartIndicator.Price);
//--- calculate D
dTmp=0.0;
for(j=0;j<ExtCCIPeriod;j++) dTmp+=MathAbs(rangeBarsIndicator.Price[i-j]-ExtSPBuffer[i]);
for(j=0;j<ExtCCIPeriod;j++) dTmp+=MathAbs(customChartIndicator.Price[i-j]-ExtSPBuffer[i]);
ExtDBuffer[i]=dTmp*dMul;
//--- calculate M
ExtMBuffer[i]=rangeBarsIndicator.Price[i]-ExtSPBuffer[i];
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;
Binary file not shown.
+10 -34
View File
@@ -26,7 +26,7 @@ int ExtArrowShift=-10;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -66,39 +66,15 @@ int OnCalculate(const int rates_total,const int prev_calculated,
const int &Spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
//
//
//
int i,limit;
@@ -118,13 +94,13 @@ int OnCalculate(const int rates_total,const int prev_calculated,
for(i=limit; i<rates_total-3 && !IsStopped();i++)
{
//---- Upper Fractal
if(rangeBarsIndicator.High[i]>rangeBarsIndicator.High[i+1] && rangeBarsIndicator.High[i]>rangeBarsIndicator.High[i+2] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-1] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-2])
ExtUpperBuffer[i]=rangeBarsIndicator.High[i];
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(rangeBarsIndicator.Low[i]<rangeBarsIndicator.Low[i+1] && rangeBarsIndicator.Low[i]<rangeBarsIndicator.Low[i+2] && rangeBarsIndicator.Low[i]<=rangeBarsIndicator.Low[i-1] && rangeBarsIndicator.Low[i]<=rangeBarsIndicator.Low[i-2])
ExtLowerBuffer[i]=rangeBarsIndicator.Low[i];
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.
@@ -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]);
}
@@ -36,7 +36,7 @@ int period;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -97,42 +97,18 @@ int OnCalculate(const int rates_total,
if(rates_total<period+1)return(0);
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
ArraySetAsSeries(rangeBarsIndicator.Close,true);
ArraySetAsSeries(customChartIndicator.Close,true);
//---
int limit;
if(rates_total<_prev_calculated || _prev_calculated<=0)
@@ -154,8 +130,8 @@ int OnCalculate(const int rates_total,
{
TrendBuffer[i]=TrendBuffer[i+1];
//---
if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)>NormalizeDouble(MaHighBuffer[i+1],_Digits)) TrendBuffer[i]=1;
if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)<NormalizeDouble(MaLowBuffer[i+1],_Digits)) TrendBuffer[i]=-1;
if(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)
{
Binary file not shown.
+13 -35
View File
@@ -25,7 +25,7 @@ double ExtColorBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -67,36 +67,14 @@ int OnCalculate(const int rates_total,
int i,limit;
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -106,10 +84,10 @@ int OnCalculate(const int rates_total,
if(_prev_calculated==0)
{
//--- set first candle
ExtLBuffer[0]=rangeBarsIndicator.Low[0];
ExtHBuffer[0]=rangeBarsIndicator.High[0];
ExtOBuffer[0]=rangeBarsIndicator.Open[0];
ExtCBuffer[0]=rangeBarsIndicator.Close[0];
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;
@@ -118,9 +96,9 @@ int OnCalculate(const int rates_total,
for(i=limit;i<rates_total && !IsStopped();i++)
{
double haOpen=(ExtOBuffer[i-1]+ExtCBuffer[i-1])/2;
double haClose=(rangeBarsIndicator.Open[i]+rangeBarsIndicator.High[i]+rangeBarsIndicator.Low[i]+rangeBarsIndicator.Close[i])/4;
double haHigh=MathMax(rangeBarsIndicator.High[i],MathMax(haOpen,haClose));
double haLow=MathMin(rangeBarsIndicator.Low[i],MathMin(haOpen,haClose));
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;
+13 -34
View File
@@ -6,6 +6,7 @@
#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
@@ -38,7 +39,7 @@ double ExtChikouBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -115,36 +116,14 @@ int OnCalculate(const int rates_total,
const int &spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -157,20 +136,20 @@ int OnCalculate(const int rates_total,
//---
for(int i=limit;i<rates_total && !IsStopped();i++)
{
ExtChikouBuffer[i]=rangeBarsIndicator.Close[i];
ExtChikouBuffer[i]=customChartIndicator.Close[i];
//--- tenkan sen
double _high=Highest(rangeBarsIndicator.High,InpTenkan,i);
double _low=Lowest(rangeBarsIndicator.Low,InpTenkan,i);
double _high=Highest(customChartIndicator.High,InpTenkan,i);
double _low=Lowest(customChartIndicator.Low,InpTenkan,i);
ExtTenkanBuffer[i]=(_high+_low)/2.0;
//--- kijun sen
_high=Highest(rangeBarsIndicator.High,InpKijun,i);
_low=Lowest(rangeBarsIndicator.Low,InpKijun,i);
_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(rangeBarsIndicator.High,InpSenkou,i);
_low=Lowest(rangeBarsIndicator.Low,InpSenkou,i);
_high=Highest(customChartIndicator.High,InpSenkou,i);
_low=Lowest(customChartIndicator.Low,InpSenkou,i);
ExtSpanBBuffer[i]=(_high+_low)/2.0;
}
//--- done
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);
}
//+------------------------------------------------------------------+
+10 -34
View File
@@ -26,7 +26,7 @@ double ExtLineBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -169,7 +169,7 @@ void OnInit()
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
//
rangeBarsIndicator.SetUseAppliedPriceFlag(InpAppliedPrice);
customChartIndicator.SetUseAppliedPriceFlag(InpAppliedPrice);
//
//
@@ -197,40 +197,16 @@ int OnCalculate(const int rates_total,const int prev_calculated,
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _begin = 0;
//
//
//
//--- check for bars count
@@ -246,10 +222,10 @@ int OnCalculate(const int rates_total,const int prev_calculated,
//--- calculation
switch(InpMAMethod)
{
case MODE_EMA: CalculateEMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
case MODE_LWMA: CalculateLWMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
case MODE_SMMA: CalculateSmoothedMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
case MODE_SMA: CalculateSimpleMA(rates_total,_prev_calculated,_begin,rangeBarsIndicator.Price); break;
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);
+21 -36
View File
@@ -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[];
//
//
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
//
//
//
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))
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:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _rates_total = customChartIndicator.GetRatesTotal();
//
//
//
//--- check for data
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);
}
//+------------------------------------------------------------------+
+9 -33
View File
@@ -26,7 +26,7 @@ int ExtMomentumPeriod;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -40,7 +40,7 @@ void OnInit()
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
//
rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
customChartIndicator.SetUseAppliedPriceFlag(InpApplyToPrice);
//
//
@@ -88,39 +88,15 @@ int OnCalculate(const int rates_total,const int prev_calculated,
static int begin = 0;
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
//--- start calculation
@@ -137,8 +113,8 @@ int OnCalculate(const int rates_total,const int prev_calculated,
//--- main cycle
for(int i=pos;i<rates_total && !IsStopped();i++)
{
if(rangeBarsIndicator.Price[i-ExtMomentumPeriod] > 0)
ExtMomentumBuffer[i]=rangeBarsIndicator.Price[i]*100/rangeBarsIndicator.Price[i-ExtMomentumPeriod];
if(customChartIndicator.Price[i-ExtMomentumPeriod] > 0)
ExtMomentumBuffer[i]=customChartIndicator.Price[i]*100/customChartIndicator.Price[i-ExtMomentumPeriod];
}
//--- OnCalculate done. Return new prev_calculated.
+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];
}
}
}
//+------------------------------------------------------------------+
+25 -48
View File
@@ -5,6 +5,7 @@
//+------------------------------------------------------------------+
#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
@@ -29,7 +30,7 @@ double ExtSarMaximum;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -91,39 +92,15 @@ int OnCalculate(const int rates_total,
return(0);
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
//
//
//
//--- detect current position
@@ -135,12 +112,12 @@ int OnCalculate(const int rates_total,
pos=1;
ExtAFBuffer[0]=ExtSarStep;
ExtAFBuffer[1]=ExtSarStep;
ExtSARBuffer[0]=rangeBarsIndicator.High[0];
ExtSARBuffer[0]=customChartIndicator.High[0];
ExtLastRevPos=0;
ExtDirectionLong=false;
ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,rangeBarsIndicator.High);
ExtEPBuffer[0]=rangeBarsIndicator.Low[pos];
ExtEPBuffer[1]=rangeBarsIndicator.Low[pos];
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++)
@@ -148,24 +125,24 @@ int OnCalculate(const int rates_total,
//--- check for reverse
if(ExtDirectionLong)
{
if(ExtSARBuffer[i]>rangeBarsIndicator.Low[i])
if(ExtSARBuffer[i]>customChartIndicator.Low[i])
{
//--- switch to SHORT
ExtDirectionLong=false;
ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,rangeBarsIndicator.High);
ExtEPBuffer[i]=rangeBarsIndicator.Low[i];
ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,customChartIndicator.High);
ExtEPBuffer[i]=customChartIndicator.Low[i];
ExtLastRevPos=i;
ExtAFBuffer[i]=ExtSarStep;
}
}
else
{
if(ExtSARBuffer[i]<rangeBarsIndicator.High[i])
if(ExtSARBuffer[i]<customChartIndicator.High[i])
{
//--- switch to LONG
ExtDirectionLong=true;
ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,rangeBarsIndicator.Low);
ExtEPBuffer[i]=rangeBarsIndicator.High[i];
ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,customChartIndicator.Low);
ExtEPBuffer[i]=customChartIndicator.High[i];
ExtLastRevPos=i;
ExtAFBuffer[i]=ExtSarStep;
}
@@ -174,9 +151,9 @@ int OnCalculate(const int rates_total,
if(ExtDirectionLong)
{
//--- check for new High
if(rangeBarsIndicator.High[i]>ExtEPBuffer[i-1] && i!=ExtLastRevPos)
if(customChartIndicator.High[i]>ExtEPBuffer[i-1] && i!=ExtLastRevPos)
{
ExtEPBuffer[i]=rangeBarsIndicator.High[i];
ExtEPBuffer[i]=customChartIndicator.High[i];
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
if(ExtAFBuffer[i]>ExtSarMaximum)
ExtAFBuffer[i]=ExtSarMaximum;
@@ -193,15 +170,15 @@ int OnCalculate(const int rates_total,
//--- calculate SAR for tomorrow
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
//--- check for SAR
if(ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i] || ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i-1])
ExtSARBuffer[i+1]=MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.Low[i-1]);
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(rangeBarsIndicator.Low[i]<ExtEPBuffer[i-1] && i!=ExtLastRevPos)
if(customChartIndicator.Low[i]<ExtEPBuffer[i-1] && i!=ExtLastRevPos)
{
ExtEPBuffer[i]=rangeBarsIndicator.Low[i];
ExtEPBuffer[i]=customChartIndicator.Low[i];
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
if(ExtAFBuffer[i]>ExtSarMaximum)
ExtAFBuffer[i]=ExtSarMaximum;
@@ -218,8 +195,8 @@ int OnCalculate(const int rates_total,
//--- calculate SAR for tomorrow
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
//--- check for SAR
if(ExtSARBuffer[i+1]<rangeBarsIndicator.High[i] || ExtSARBuffer[i+1]<rangeBarsIndicator.High[i-1])
ExtSARBuffer[i+1]=MathMax(rangeBarsIndicator.High[i],rangeBarsIndicator.High[i-1]);
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.
+8 -30
View File
@@ -24,7 +24,7 @@ int ExtRocPeriod;
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -57,7 +57,7 @@ void OnInit()
// Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class
//
rangeBarsIndicator.SetUseAppliedPriceFlag(PRICE_CLOSE);
customChartIndicator.SetUseAppliedPriceFlag(PRICE_CLOSE);
//
//
@@ -80,36 +80,14 @@ int OnCalculate(const int rates_total,const int prev_calculated,
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -125,10 +103,10 @@ int OnCalculate(const int rates_total,const int prev_calculated,
//--- the main loop of calculations
for(int i=pos;i<rates_total && !IsStopped();i++)
{
if(rangeBarsIndicator.Price[i]==0.0)
if(customChartIndicator.Price[i]==0.0)
ExtRocBuffer[i]=0.0;
else
ExtRocBuffer[i]=(rangeBarsIndicator.Price[i]-rangeBarsIndicator.Price[i-ExtRocPeriod])/rangeBarsIndicator.Price[i]*100;
ExtRocBuffer[i]=(customChartIndicator.Price[i]-customChartIndicator.Price[i-ExtRocPeriod])/customChartIndicator.Price[i]*100;
}
//--- OnCalculate done. Return new prev_calculated.
return(rates_total);
+8 -32
View File
@@ -30,7 +30,7 @@ double ExtNegBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -78,39 +78,15 @@ int OnCalculate(const int rates_total,const int prev_calculated,
const int &Spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(Close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
int i,pos;
@@ -122,7 +98,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
ArraySetAsSeries(ExtRSIBuffer,false);
ArraySetAsSeries(ExtPosBuffer,false);
ArraySetAsSeries(ExtNegBuffer,false);
ArraySetAsSeries(rangeBarsIndicator.Close,false);
ArraySetAsSeries(customChartIndicator.Close,false);
//--- preliminary calculations
pos=_prev_calculated-1;
if(pos<=InpRSIPeriod)
@@ -138,7 +114,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
ExtRSIBuffer[i]=0.0;
ExtPosBuffer[i]=0.0;
ExtNegBuffer[i]=0.0;
diff=rangeBarsIndicator.Close[i]-rangeBarsIndicator.Close[i-1];
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
if(diff>0)
sump+=diff;
else
@@ -162,7 +138,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
//--- the main loop of calculations
for(i=pos; i<rates_total && !IsStopped(); i++)
{
diff=rangeBarsIndicator.Close[i]-rangeBarsIndicator.Close[i-1];
diff=customChartIndicator.Close[i]-customChartIndicator.Close[i-1];
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(diff>0.0?diff:0.0))/InpRSIPeriod;
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(diff<0.0?-diff:0.0))/InpRSIPeriod;
if(ExtNegBuffer[i]!=0.0)
+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);
}
//+------------------------------------------------------------------+
@@ -5,6 +5,7 @@
//+------------------------------------------------------------------+
#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
@@ -30,7 +31,7 @@ double ExtLowesBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -82,11 +83,13 @@ int OnCalculate(const int rates_total,const int prev_calculated,
//
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
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();
//
//
@@ -116,8 +119,8 @@ int OnCalculate(const int rates_total,const int prev_calculated,
double dmax=-1000000.0;
for(k=i-InpKPeriod+1;k<=i;k++)
{
if(dmin>rangeBarsIndicator.Low[k]) dmin=rangeBarsIndicator.Low[k];
if(dmax<rangeBarsIndicator.High[k]) dmax=rangeBarsIndicator.High[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;
@@ -137,7 +140,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
double sumhigh=0.0;
for(k=(i-InpSlowing+1);k<=i;k++)
{
sumlow +=(rangeBarsIndicator.Close[k]-ExtLowesBuffer[k]);
sumlow +=(customChartIndicator.Close[k]-ExtLowesBuffer[k]);
sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
}
if(sumhigh==0.0) ExtMainBuffer[i]=100.0;
+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);
}
@@ -67,7 +67,7 @@ double Level[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -98,7 +98,7 @@ int OnInit()
IndicatorSetString(INDICATOR_SHORTNAME," VEMA Wilder's DMI ("+string(AdxPeriod)+")");
rangeBarsIndicator.SetGetVolumesFlag();
customChartIndicator.SetGetVolumesFlag();
return(0);
}
@@ -136,39 +136,15 @@ int OnCalculate(const int rates_total,
const int& spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
//
// Make the following modifications in the code below:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
if (ArrayRange(averages,0)!=rates_total) ArrayResize(averages,rates_total);
@@ -182,16 +158,16 @@ int OnCalculate(const int rates_total,
double sf = 1.0/(double)AdxPeriod;
for (int i=(int)MathMax(_prev_calculated-1,1); i<rates_total; i++)
{
double currTR = MathMax(rangeBarsIndicator.High[i],rangeBarsIndicator.Close[i-1])-MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.Close[i-1]);
double DeltaHi = rangeBarsIndicator.High[i] - rangeBarsIndicator.High[i-1];
double DeltaLo = rangeBarsIndicator.Low[i-1] - rangeBarsIndicator.Low[i];
double 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)rangeBarsIndicator.Tick_volume[i]; break;
case vol_real: vol = (double)rangeBarsIndicator.Real_volume[i]; break;
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;
+34 -54
View File
@@ -61,7 +61,7 @@ enum PRICE_TYPE
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
#define VWAP_Daily "cc__VWAP_Daily"
#define VWAP_Weekly "cc__VWAP_Weekly"
@@ -169,8 +169,8 @@ int OnInit()
ObjectSetString(0,VWAP_Monthly,OBJPROP_TEXT," ");
}
rangeBarsIndicator.SetGetVolumesFlag();
rangeBarsIndicator.SetGetTimeFlag();
customChartIndicator.SetGetVolumesFlag();
customChartIndicator.SetGetTimeFlag();
return(INIT_SUCCEEDED);
}
@@ -199,36 +199,16 @@ int OnCalculate(const int rates_total,
{
//
// Process data through MedianRenko indicator
// Process data through Tick Chat indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
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:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
//
// rangeBarsIndicator.Open[] should be used instead of open[]
// rangeBarsIndicator.Low[] should be used instead of low[]
// rangeBarsIndicator.High[] should be used instead of high[]
// rangeBarsIndicator.Close[] should be used instead of close[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
//
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -240,7 +220,7 @@ int OnCalculate(const int rates_total,
LastTimePeriod=PERIOD_CURRENT;
}
if(rates_total>_prev_calculated || bIsFirstRun || Calc_Every_Tick || (_prev_calculated == 0) || rangeBarsIndicator.IsNewBar)
if(rates_total>_prev_calculated || bIsFirstRun || Calc_Every_Tick || (_prev_calculated == 0) ||customChartIndicator.IsNewBar)
{
nIdxDaily = 0;
nIdxWeekly = 0;
@@ -260,22 +240,22 @@ int OnCalculate(const int rates_total,
VWAP_Buffer_Weekly[nIdx]=EMPTY_VALUE;
VWAP_Buffer_Monthly[nIdx]=EMPTY_VALUE;
if(rangeBarsIndicator.Time[nIdx] < 86400)
if(customChartIndicator.Time[nIdx] < 86400)
continue;
if(CreateDateTime(DAILY,rangeBarsIndicator.Time[nIdx])!=dtLastDay)
if(CreateDateTime(DAILY,customChartIndicator.Time[nIdx])!=dtLastDay)
{
nIdxDaily=nIdx;
nSumDailyTPV = 0;
nSumDailyVol = 0;
}
if(CreateDateTime(WEEKLY,rangeBarsIndicator.Time[nIdx])!=dtLastWeek)
if(CreateDateTime(WEEKLY,customChartIndicator.Time[nIdx])!=dtLastWeek)
{
nIdxWeekly=nIdx;
nSumWeeklyTPV = 0;
nSumWeeklyVol = 0;
}
if(CreateDateTime(MONTHLY,rangeBarsIndicator.Time[nIdx])!=dtLastMonth)
if(CreateDateTime(MONTHLY,customChartIndicator.Time[nIdx])!=dtLastMonth)
{
nIdxMonthly=nIdx;
nSumMonthlyTPV = 0;
@@ -289,45 +269,45 @@ int OnCalculate(const int rates_total,
switch(Price_Type)
{
case OPEN:
nPriceArr[nIdx]=rangeBarsIndicator.Open[nIdx];
nPriceArr[nIdx]=customChartIndicator.Open[nIdx];
break;
case CLOSE:
nPriceArr[nIdx]=rangeBarsIndicator.Close[nIdx];
nPriceArr[nIdx]=customChartIndicator.Close[nIdx];
break;
case HIGH:
nPriceArr[nIdx]=rangeBarsIndicator.High[nIdx];
nPriceArr[nIdx]=customChartIndicator.High[nIdx];
break;
case LOW:
nPriceArr[nIdx]=rangeBarsIndicator.Low[nIdx];
nPriceArr[nIdx]=customChartIndicator.Low[nIdx];
break;
case HIGH_LOW:
nPriceArr[nIdx]=(rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/2;
nPriceArr[nIdx]=(customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/2;
break;
case OPEN_CLOSE:
nPriceArr[nIdx]=(rangeBarsIndicator.Open[nIdx]+rangeBarsIndicator.Close[nIdx])/2;
nPriceArr[nIdx]=(customChartIndicator.Open[nIdx]+customChartIndicator.Close[nIdx])/2;
break;
case CLOSE_HIGH_LOW:
nPriceArr[nIdx]=(rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/3;
nPriceArr[nIdx]=(customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/3;
break;
case OPEN_CLOSE_HIGH_LOW:
nPriceArr[nIdx]=(rangeBarsIndicator.Open[nIdx]+rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/4;
nPriceArr[nIdx]=(customChartIndicator.Open[nIdx]+customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/4;
break;
default:
nPriceArr[nIdx]=(rangeBarsIndicator.Close[nIdx]+rangeBarsIndicator.High[nIdx]+rangeBarsIndicator.Low[nIdx])/3;
nPriceArr[nIdx]=(customChartIndicator.Close[nIdx]+customChartIndicator.High[nIdx]+customChartIndicator.Low[nIdx])/3;
break;
}
if((rangeBarsIndicator.Tick_volume[nIdx] > 0) && (rangeBarsIndicator.Real_volume[nIdx] == 0))
if((customChartIndicator.Tick_volume[nIdx] > 0) && (customChartIndicator.Real_volume[nIdx] == 0))
{
// Print("tick vol = "+rangeBarsIndicator.Tick_volume[nIdx]);
nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Tick_volume[nIdx]);
nTotalVol[nIdx] = (double)rangeBarsIndicator.Tick_volume[nIdx];
// Print("tick vol = "+customChartIndicator.Tick_volume[nIdx]);
nTotalTPV[nIdx] = (nPriceArr[nIdx] * customChartIndicator.Tick_volume[nIdx]);
nTotalVol[nIdx] = (double)customChartIndicator.Tick_volume[nIdx];
}
else if(rangeBarsIndicator.Real_volume[nIdx] && rangeBarsIndicator.Tick_volume[nIdx] )
else if(customChartIndicator.Real_volume[nIdx] && customChartIndicator.Tick_volume[nIdx] )
{
// Print("real vol = "+rangeBarsIndicator.Real_volume[nIdx]);
nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Real_volume[nIdx]);
nTotalVol[nIdx] = (double)rangeBarsIndicator.Real_volume[nIdx];
// 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))
@@ -375,9 +355,9 @@ int OnCalculate(const int rates_total,
}
}
dtLastDay=CreateDateTime(DAILY,rangeBarsIndicator.Time[nIdx]);
dtLastWeek=CreateDateTime(WEEKLY,rangeBarsIndicator.Time[nIdx]);
dtLastMonth=CreateDateTime(MONTHLY,rangeBarsIndicator.Time[nIdx]);
dtLastDay=CreateDateTime(DAILY,customChartIndicator.Time[nIdx]);
dtLastWeek=CreateDateTime(WEEKLY,customChartIndicator.Time[nIdx]);
dtLastMonth=CreateDateTime(MONTHLY,customChartIndicator.Time[nIdx]);
}
bIsFirstRun=false;
Binary file not shown.
+15 -16
View File
@@ -31,7 +31,7 @@ double deviation; // deviation in points
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -132,16 +132,15 @@ int OnCalculate(const int rates_total,
const int &spread[])
{
//
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
//
int i=0;
@@ -204,12 +203,12 @@ int OnCalculate(const int rates_total,
//--- searching High and Low
for(shift=limit;shift<rates_total && !IsStopped();shift++)
{
val=rangeBarsIndicator.Low[iLowest(rangeBarsIndicator.Low,ExtDepth,shift)];
val=customChartIndicator.Low[iLowest(customChartIndicator.Low,ExtDepth,shift)];
if(val==lastlow) val=0.0;
else
{
lastlow=val;
if((rangeBarsIndicator.Low[shift]-val)>deviation) val=0.0;
if((customChartIndicator.Low[shift]-val)>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
@@ -219,14 +218,14 @@ int OnCalculate(const int rates_total,
}
}
}
if(rangeBarsIndicator.Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
if(customChartIndicator.Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
//--- high
val=rangeBarsIndicator.High[iHighest(rangeBarsIndicator.High,ExtDepth,shift)];
val=customChartIndicator.High[iHighest(customChartIndicator.High,ExtDepth,shift)];
if(val==lasthigh) val=0.0;
else
{
lasthigh=val;
if((val-rangeBarsIndicator.High[shift])>deviation) val=0.0;
if((val-customChartIndicator.High[shift])>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
@@ -236,7 +235,7 @@ int OnCalculate(const int rates_total,
}
}
}
if(rangeBarsIndicator.High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
if(customChartIndicator.High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
}
//--- last preparation
@@ -262,7 +261,7 @@ int OnCalculate(const int rates_total,
{
if(HighMapBuffer[shift]!=0)
{
lasthigh=rangeBarsIndicator.High[shift];
lasthigh=customChartIndicator.High[shift];
lasthighpos=shift;
whatlookfor=Sill;
ZigzagBuffer[shift]=lasthigh;
@@ -270,7 +269,7 @@ int OnCalculate(const int rates_total,
}
if(LowMapBuffer[shift]!=0)
{
lastlow=rangeBarsIndicator.Low[shift];
lastlow=customChartIndicator.Low[shift];
lastlowpos=shift;
whatlookfor=Pike;
ZigzagBuffer[shift]=lastlow;
@@ -60,7 +60,7 @@ double dtosf2[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
@@ -110,33 +110,36 @@ int OnCalculate(const int rates_total,const int prev_calculated,
// Process data through MedianRenko indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time))
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:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
// customChartIndicator.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[]
// 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[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
// 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
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
// 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
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
// 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 = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -155,7 +158,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
for (int i=(int)MathMax(_prev_calculated-1,0); i<rates_total; i++)
{
rsibuf[i] = iRsi(rangeBarsIndicator.Close[i],RsiPeriod,i,rates_total);
rsibuf[i] = iRsi(customChartIndicator.Close[i],RsiPeriod,i,rates_total);
double min = rsibuf[i];
double max = rsibuf[i];
Binary file not shown.
+30 -23
View File
@@ -5,6 +5,8 @@
//+------------------------------------------------------------------+
#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
@@ -12,7 +14,7 @@
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 Green,Red
#property indicator_style1 0
#property indicator_width1 1
#property indicator_width1 2
#property indicator_minimum 0.0
//--- input data
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes
@@ -25,11 +27,12 @@ double ExtColorsBuffer[];
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator rangeBarsIndicator;
RangeBarIndicator customChartIndicator;
//
//
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
@@ -43,7 +46,7 @@ void OnInit()
//---- indicator digits
IndicatorSetInteger(INDICATOR_DIGITS,0);
rangeBarsIndicator.SetGetVolumesFlag();
customChartIndicator.SetGetVolumesFlag();
//----
}
//+------------------------------------------------------------------+
@@ -63,38 +66,41 @@ int OnCalculate(const int rates_total,
//---check for rates total
if(rates_total<2)
return(0);
//
// Process data through MedianRenko indicator
// Process data through XTickChart indicator
//
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
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:
//
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
// customChartIndicator.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[]
// 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[]
//
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
// customChartIndicator.IsNewBar (true/false) informs you if a bar has completed
//
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
// 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
//
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
// 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
//
// rangeBarsIndicator.Price[] should be used instead of Price[]
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
// 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 = rangeBarsIndicator.GetPrevCalculated();
int _prev_calculated = customChartIndicator.GetPrevCalculated();
//
//
@@ -105,10 +111,11 @@ int OnCalculate(const int rates_total,
//--- correct position
if(start<1) start=1;
//--- main cycle
if(InpVolumeType==VOLUME_TICK)
CalculateVolume(start,rates_total,rangeBarsIndicator.Tick_volume);
CalculateVolume(start,rates_total,customChartIndicator.Tick_volume);
else
CalculateVolume(start,rates_total,rangeBarsIndicator.Real_volume);
CalculateVolume(start,rates_total,customChartIndicator.Real_volume);
//--- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
+5
View File
@@ -22,3 +22,8 @@ All folders (Experts, Include & Indicators) & sub-folders should be placed in th
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.