Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b784e9556d | |||
| 695a66b812 | |||
| bd3a18958e | |||
| dd2f769c89 | |||
| 38937ddce1 | |||
| 75a0f76352 | |||
| 4f56445d60 | |||
| a23213f3e1 | |||
| 91e99e93cc | |||
| a19c291525 | |||
| 60a4d0ad07 |
@@ -1,6 +1,6 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property copyright "Copyright 2017-18, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "2.05"
|
||||
#property version "2.06"
|
||||
#property description "Example EA showing the way to use the RangeBars class defined in RangeBars.mqh"
|
||||
|
||||
//
|
||||
@@ -32,7 +32,7 @@ RangeBars * rangeBars;
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
rangeBars = new RangeBars();
|
||||
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||
if(rangeBars == NULL)
|
||||
return(INIT_FAILED);
|
||||
|
||||
@@ -96,7 +96,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.GetMA1(MA1,startAtBar,numberOfBars) && rangeBars.GetMA2(MA2,startAtBar,numberOfBars))
|
||||
{
|
||||
//
|
||||
// Values are stored in the MA1 and MA2 arrays and are now ready for use
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property copyright "Copyright 2017-18, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "1.00"
|
||||
#property version "1.10"
|
||||
#property description "Example EA: Trading based on RangeBars SuperTrend signals."
|
||||
#property description "One trade at a time. Each trade has TP & SL"
|
||||
|
||||
@@ -61,7 +61,7 @@ CMarketOrder * marketOrder;
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
rangeBars = new RangeBars();
|
||||
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||
if(rangeBars == NULL)
|
||||
return(INIT_FAILED);
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Copyright 2017-2018, Artur Zas
|
||||
// https://www.az-invest.eu
|
||||
// https://www.mql5.com/en/users/arturz
|
||||
//
|
||||
// Normalizing functions
|
||||
//
|
||||
|
||||
double NormalizeLots(string symbol, double InputLots)
|
||||
{
|
||||
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
|
||||
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
|
||||
int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
|
||||
|
||||
if(InputLots < lotsMin)
|
||||
InputLots = lotsMin;
|
||||
if(InputLots > lotsMax)
|
||||
InputLots = lotsMax;
|
||||
|
||||
return NormalizeDouble(InputLots, lotsDigits);
|
||||
}
|
||||
|
||||
double VtcNormalizeLots(string symbol, double lotsToNormalize)
|
||||
{
|
||||
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
|
||||
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
|
||||
double lotsStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
|
||||
|
||||
if (lotsToNormalize == 0)
|
||||
return lotsMin;
|
||||
|
||||
int a = (int)(lotsToNormalize / lotsStep);
|
||||
double normalizedLots = a * lotsStep;
|
||||
|
||||
if(normalizedLots < lotsMin)
|
||||
normalizedLots = lotsMin;
|
||||
if(normalizedLots > lotsMax)
|
||||
normalizedLots = lotsMax;
|
||||
|
||||
return normalizedLots;
|
||||
}
|
||||
|
||||
double NormalizePrice(string symbol, double price, double tick = 0)
|
||||
{
|
||||
double _tick = tick ? tick : SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
|
||||
int _digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
|
||||
|
||||
if (tick)
|
||||
return NormalizeDouble(MathRound(price/_tick)*_tick,_digits);
|
||||
else
|
||||
return NormalizeDouble(price,_digits);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "2.02"
|
||||
|
||||
input bool UseOnRangeBarChart = true; // Use this indicator on RangeBar chart
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBars.mqh>
|
||||
|
||||
class RangeBarIndicator
|
||||
@@ -68,7 +71,7 @@ class RangeBarIndicator
|
||||
|
||||
RangeBarIndicator::RangeBarIndicator(void)
|
||||
{
|
||||
rangeBars = new RangeBars();
|
||||
rangeBars = new RangeBars(UseOnRangeBarChart);
|
||||
if(rangeBars != NULL)
|
||||
rangeBars.Init();
|
||||
|
||||
@@ -99,6 +102,7 @@ bool RangeBarIndicator::CheckStatus(void)
|
||||
|
||||
bool RangeBarIndicator::NeedsReload(void)
|
||||
{
|
||||
|
||||
if(rangeBars.Reload())
|
||||
{
|
||||
Print("Chart settings changed - reloading indicator with new settings");
|
||||
@@ -117,8 +121,6 @@ bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calcu
|
||||
Canvas_IsNewBar(_Time);
|
||||
Canvas_RatesTotalChangedBy(_rates_total);
|
||||
IsNewBar = rangeBars.IsNewBar();
|
||||
|
||||
firstRun = false;
|
||||
}
|
||||
|
||||
if(!CheckStatus())
|
||||
@@ -126,10 +128,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,14 +149,24 @@ 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;
|
||||
NeedsReload();
|
||||
}
|
||||
|
||||
if(NeedsReload() || !this.dataReady)
|
||||
{
|
||||
GetOLHC(0,_rates_total);
|
||||
this.prev_calculated = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(NeedsReload() || !this.dataReady)
|
||||
{
|
||||
Print("NeedsReload/DataReady block failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(needsReload || IsNewBar || canvasIsNewTime || (change != 0))
|
||||
|
||||
@@ -6,62 +6,92 @@
|
||||
|
||||
#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()
|
||||
#ifdef MQL5_MARKET_DEMO
|
||||
int barSizeInTicks = 180; // Range bar size (in points)
|
||||
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
|
||||
ENUM_BOOL useRealVolume = false; // Use real volume ( false for FX )
|
||||
ENUM_TICK_PRICE_TYPE plotPrice = tickBid; // Build chart using
|
||||
int showNumberOfDays = 7; // Show history for number of days
|
||||
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||
|
||||
#ifdef USE_CUSTOM_SYMBOL
|
||||
string customChartName = ""; // Override default custom chart name with
|
||||
string applyTemplate = "default"; // Apply template to custom chart
|
||||
#endif
|
||||
#else
|
||||
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
|
||||
|
||||
#ifdef USE_CUSTOM_SYMBOL
|
||||
input string customChartName = ""; // Override default custom chart name with
|
||||
input string applyTemplate = "default"; // Apply template to custom chart
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USE_CUSTOM_SYMBOL
|
||||
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 = clrNONE; // Current bar's open time info color
|
||||
|
||||
input ENUM_BOOL NewBarAlert = false; // Alert on new a bar
|
||||
input ENUM_BOOL ReversalBarAlert = false; // Alert on reversal bar
|
||||
input ENUM_BOOL MaCrossAlert = false; // Alert on MA crossover
|
||||
input ENUM_BOOL UseAlertWindow = false; // Display alert in Alert Window
|
||||
input ENUM_BOOL UseSound = false; // Play sound on alert
|
||||
input ENUM_BOOL UsePushNotifications = false; // Send alert via push notification to a 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 ShiftObj = false; // Shift objects with chart
|
||||
input ENUM_BOOL UsedInEA = false; // Indicator used in EA via iCustom()
|
||||
#endif
|
||||
#else
|
||||
|
||||
//
|
||||
@@ -82,13 +112,18 @@ input ENUM_BOOL UsedInEA = false; // Indic
|
||||
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;
|
||||
|
||||
ENUM_BOOL NewBarAlert = false;
|
||||
ENUM_BOOL ReversalBarAlert = false;
|
||||
ENUM_BOOL MaCrossAlert = false;
|
||||
ENUM_BOOL UseAlertWindow = false;
|
||||
ENUM_BOOL UseSound = false;
|
||||
ENUM_BOOL UsePushNotifications = false;
|
||||
|
||||
string SoundFileBull = "";
|
||||
string SoundFileBear = "";
|
||||
ENUM_BOOL DisplayAsBarChart = true;
|
||||
ENUM_BOOL ShiftObj = false;
|
||||
ENUM_BOOL UsedInEA = true; // This should always be set to TRUE for EAs & Indicators
|
||||
|
||||
//
|
||||
@@ -172,10 +207,11 @@ void RangeBarSettings::Save(void)
|
||||
//
|
||||
// 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)
|
||||
@@ -261,7 +297,8 @@ void RangeBarSettings::Set(void)
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef USE_CUSTOM_SYMBOL
|
||||
chartIndicatorSettings.MA1on = MA1on;
|
||||
chartIndicatorSettings.MA1period = MA1period;
|
||||
chartIndicatorSettings.MA1method = MA1method;
|
||||
@@ -290,6 +327,7 @@ void RangeBarSettings::Set(void)
|
||||
chartIndicatorSettings.BollingerBandsDeviations = BollingerBandsDeviations;
|
||||
chartIndicatorSettings.SuperTrendPeriod = SuperTrendPeriod;
|
||||
chartIndicatorSettings.SuperTrendMultiplier = SuperTrendMultiplier;
|
||||
chartIndicatorSettings.ShiftObj = ShiftObj;
|
||||
chartIndicatorSettings.UsedInEA = UsedInEA;
|
||||
|
||||
//
|
||||
@@ -310,14 +348,18 @@ void RangeBarSettings::Set(void)
|
||||
alertInfoSettings.LowThresholdIndicatorColor = LowThresholdIndicatorColor;
|
||||
alertInfoSettings.showCurrentBarOpenTime = showCurrentBarOpenTime;
|
||||
alertInfoSettings.InfoTextColor = InfoTextColor;
|
||||
alertInfoSettings.UseSoundSignalOnNewBar = UseSoundSignalOnNewBar;
|
||||
alertInfoSettings.OnlySignalReversalBars = OnlySignalReversalBars;
|
||||
alertInfoSettings.UseAlertWindow = UseAlertWindow;
|
||||
alertInfoSettings.SendPushNotifications = SendPushNotifications;
|
||||
|
||||
alertInfoSettings.NewBarAlert = NewBarAlert;
|
||||
alertInfoSettings.ReversalBarAlert = ReversalBarAlert;
|
||||
alertInfoSettings.MaCrossAlert = MaCrossAlert ;
|
||||
alertInfoSettings.UseAlertWindow = UseAlertWindow;
|
||||
alertInfoSettings.UseSound = UseSound;
|
||||
alertInfoSettings.UsePushNotifications = UsePushNotifications;
|
||||
|
||||
alertInfoSettings.SoundFileBull = SoundFileBull;
|
||||
alertInfoSettings.SoundFileBear = SoundFileBear;
|
||||
alertInfoSettings.DisplayAsBarChart = DisplayAsBarChart;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#property copyright "Copyright 2017, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
|
||||
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
||||
//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay203"
|
||||
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay213"
|
||||
//#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
||||
|
||||
#define RANGEBAR_OPEN 00
|
||||
#define RANGEBAR_HIGH 01
|
||||
@@ -41,10 +41,12 @@ class RangeBars
|
||||
|
||||
int rangeBarsHandle;
|
||||
string rangeBarsSymbol;
|
||||
bool usedByIndicatorOnRangeBarChart;
|
||||
|
||||
public:
|
||||
|
||||
RangeBars();
|
||||
RangeBars(bool isUsedByIndicatorOnRangeBarChart);
|
||||
RangeBars(string symbol);
|
||||
~RangeBars(void);
|
||||
|
||||
@@ -67,7 +69,7 @@ class RangeBars
|
||||
private:
|
||||
|
||||
bool GetChannel(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count);
|
||||
|
||||
int GetIndicatorHandle(void);
|
||||
};
|
||||
|
||||
RangeBars::RangeBars(void)
|
||||
@@ -76,6 +78,15 @@ RangeBars::RangeBars(void)
|
||||
rangeBarSettings = new RangeBarSettings();
|
||||
rangeBarsHandle = INVALID_HANDLE;
|
||||
rangeBarsSymbol = _Symbol;
|
||||
usedByIndicatorOnRangeBarChart = false;
|
||||
}
|
||||
|
||||
RangeBars::RangeBars(bool isUsedByIndicatorOnRangeBarChart)
|
||||
{
|
||||
rangeBarSettings = new RangeBarSettings();
|
||||
rangeBarsHandle = INVALID_HANDLE;
|
||||
rangeBarsSymbol = _Symbol;
|
||||
usedByIndicatorOnRangeBarChart = isUsedByIndicatorOnRangeBarChart;
|
||||
}
|
||||
|
||||
RangeBars::RangeBars(string symbol)
|
||||
@@ -84,6 +95,7 @@ RangeBars::RangeBars(string symbol)
|
||||
rangeBarSettings = new RangeBarSettings();
|
||||
rangeBarsHandle = INVALID_HANDLE;
|
||||
rangeBarsSymbol = symbol;
|
||||
usedByIndicatorOnRangeBarChart = false;
|
||||
}
|
||||
|
||||
RangeBars::~RangeBars(void)
|
||||
@@ -100,6 +112,15 @@ int RangeBars::Init()
|
||||
{
|
||||
if(!MQLInfoInteger((int)MQL5_TESTING))
|
||||
{
|
||||
if(usedByIndicatorOnRangeBarChart)
|
||||
{
|
||||
//
|
||||
// Indicator on RangeBar chart uses the values of the RangeBar chart for calculations
|
||||
//
|
||||
rangeBarsHandle = GetIndicatorHandle();
|
||||
return rangeBarsHandle;
|
||||
}
|
||||
|
||||
if(!rangeBarSettings.Load())
|
||||
{
|
||||
if(rangeBarsHandle != INVALID_HANDLE)
|
||||
@@ -121,17 +142,28 @@ 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();
|
||||
#else
|
||||
//
|
||||
// Save indicator inputs for use by EA attached to same chart.
|
||||
//
|
||||
rangeBarSettings.Save();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
RANGEBAR_SETTINGS s = rangeBarSettings.GetRangeBarSettings();
|
||||
@@ -161,10 +193,12 @@ int RangeBars::Init()
|
||||
LowThresholdIndicatorColor,
|
||||
showCurrentBarOpenTime,
|
||||
InfoTextColor,
|
||||
UseSoundSignalOnNewBar,
|
||||
OnlySignalReversalBars,
|
||||
NewBarAlert,
|
||||
ReversalBarAlert,
|
||||
MaCrossAlert,
|
||||
UseAlertWindow,
|
||||
SendPushNotifications,
|
||||
UseSound,
|
||||
UsePushNotifications,
|
||||
SoundFileBull,
|
||||
SoundFileBear,
|
||||
cis.MA1on,
|
||||
@@ -192,6 +226,7 @@ int RangeBars::Init()
|
||||
cis.SuperTrendMultiplier,
|
||||
"",
|
||||
DisplayAsBarChart,
|
||||
ShiftObj,
|
||||
UsedInEA);
|
||||
|
||||
|
||||
@@ -233,10 +268,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 handle released");
|
||||
else
|
||||
Print("Failed to release RangeBar indicator handle");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -535,3 +573,23 @@ bool RangeBars::GetChannel(double &HighArray[], double &MidArray[], double &LowA
|
||||
#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)
|
||||
{
|
||||
Print("Using handle of "+iName);
|
||||
return ChartIndicatorGet(0,0,iName);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
Print("Failed getting handle of "+CUSTOM_CHART_NAME);
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -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 ¶ms);
|
||||
~CMarketOrder(void);
|
||||
|
||||
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0);
|
||||
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0);
|
||||
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0);
|
||||
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0);
|
||||
bool Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0);
|
||||
bool Initialize(CMarketOrderParameters ¶ms);
|
||||
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 ¶ms)
|
||||
{
|
||||
ctrade = new CTrade();
|
||||
Initialize(params);
|
||||
}
|
||||
|
||||
bool CMarketOrder::Initialize(CMarketOrderParameters ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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"
|
||||
//--- 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 rangeBarsIndicator;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
//
|
||||
// Process data through MedianRenko indicator
|
||||
//
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
//
|
||||
// Make the following modifications in the code below:
|
||||
//
|
||||
// rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||
//
|
||||
// rangeBarsIndicator.Open[] should be used instead of open[]
|
||||
// rangeBarsIndicator.Low[] should be used instead of low[]
|
||||
// rangeBarsIndicator.High[] should be used instead of high[]
|
||||
// rangeBarsIndicator.Close[] should be used instead of close[]
|
||||
//
|
||||
// rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||
//
|
||||
// rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||
// (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||
// rangeBarsIndicator.Real_volume[] should be used instead of Volume[]
|
||||
// (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||
//
|
||||
// rangeBarsIndicator.Price[] should be used instead of Price[]
|
||||
// (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used
|
||||
//
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int i,limit;
|
||||
//--- 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(rangeBarsIndicator.High[i],rangeBarsIndicator.Close[i-1])-MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.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(rangeBarsIndicator.High[i],rangeBarsIndicator.Close[i-1])-MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,145 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[];
|
||||
//--- handles for MAs
|
||||
int ExtFastSMAHandle;
|
||||
int ExtSlowSMAHandle;
|
||||
//--- bars minimum for calculation
|
||||
#define DATA_LIMIT 33
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||
RangeBarIndicator rangeBarsIndicator;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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);
|
||||
// renko mod
|
||||
// ExtFastSMAHandle=iCustom(Symbol(),_Period,"RangeBars\\Indicators\\RangeBars_MA",5,0,MODE_SMA,PRICE_MEDIAN,true);
|
||||
// ExtSlowSMAHandle=iCustom(Symbol(),_Period,"RangeBars\\Indicators\\RangeBars_MA",34,0,MODE_SMA,PRICE_MEDIAN,true);
|
||||
ExtFastSMAHandle=iCustom(Symbol(),_Period,"RangeBars\\RangeBars_MA",5,0,MODE_SMA,PRICE_MEDIAN,true);
|
||||
ExtSlowSMAHandle=iCustom(Symbol(),_Period,"RangeBars\\RangeBars_MA",34,0,MODE_SMA,PRICE_MEDIAN,true);
|
||||
//---- 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
|
||||
|
||||
//--- not all data may be calculated
|
||||
int calculated=BarsCalculated(ExtFastSMAHandle);
|
||||
if(calculated<rates_total)
|
||||
{
|
||||
Print("Not all data of ExtFastSMAHandle is calculated (",calculated,"bars ). Error",GetLastError());
|
||||
return(0);
|
||||
}
|
||||
calculated=BarsCalculated(ExtSlowSMAHandle);
|
||||
if(calculated<rates_total)
|
||||
{
|
||||
Print("Not all data of ExtSlowSMAHandle is calculated (",calculated,"bars ). Error",GetLastError());
|
||||
return(0);
|
||||
}
|
||||
//--- renko mod
|
||||
|
||||
if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time))
|
||||
return(0);
|
||||
|
||||
int _prev_calculated = rangeBarsIndicator.GetPrevCalculated();
|
||||
|
||||
//--- 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 FastSMA buffer
|
||||
if(IsStopped()) return(0); //Checking for stop flag
|
||||
if(CopyBuffer(ExtFastSMAHandle,0,0,to_copy,ExtFastBuffer)<=0)
|
||||
{
|
||||
Print("Getting fast SMA is failed! Error",GetLastError());
|
||||
return(0);
|
||||
}
|
||||
//--- get SlowSMA buffer
|
||||
if(IsStopped()) return(0); //Checking for stop flag
|
||||
if(CopyBuffer(ExtSlowSMAHandle,0,0,to_copy,ExtSlowBuffer)<=0)
|
||||
{
|
||||
Print("Getting slow SMA is failed! Error",GetLastError());
|
||||
return(0);
|
||||
}
|
||||
//--- 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.
@@ -0,0 +1,134 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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"
|
||||
#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))
|
||||
return(0);
|
||||
|
||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//--- check for data
|
||||
if(rates_total<InpSignalSMA)
|
||||
return(0);
|
||||
//--- we can copy not all data
|
||||
int to_copy;
|
||||
if(_prev_calculated>rates_total || _prev_calculated<0) to_copy=rates_total;
|
||||
else
|
||||
{
|
||||
to_copy=rates_total-_prev_calculated;
|
||||
if(_prev_calculated>0) to_copy++;
|
||||
}
|
||||
//--- get Fast EMA buffer
|
||||
if(IsStopped()) return(0); //Checking for stop flag
|
||||
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
||||
//--- get SlowSMA buffer
|
||||
if(IsStopped()) return(0); //Checking for stop flag
|
||||
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpSlowEMA,customChartIndicator.Close,ExtSlowMaBuffer);
|
||||
//---
|
||||
int limit;
|
||||
if(_prev_calculated==0)
|
||||
limit=0;
|
||||
else limit=_prev_calculated-1;
|
||||
//--- calculate MACD
|
||||
for(int i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||
/*
|
||||
if(ExtMacdBuffer[i] > 0)
|
||||
{
|
||||
ExtMacdBufferUp[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||
ExtMacdBufferDn[i] = 0;
|
||||
}
|
||||
else if(ExtMacdBuffer[i] < 0)
|
||||
{
|
||||
ExtMacdBufferDn[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||
ExtMacdBufferUp[i] = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
//--- calculate Signal
|
||||
SimpleMAOnBuffer(rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
||||
//--- OnCalculate done. Return new _prev_calculated.
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,188 @@
|
||||
#property copyright "Copyright 2018, AZ-iNVEST"
|
||||
#property link "http://www.az-invest.eu"
|
||||
#property version "1.01"
|
||||
#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 = clrWhiteSmoke; // Font color
|
||||
input int InpFontSize = 9; // Font size
|
||||
input int InpSpacing = 8; // Date/Time spacing
|
||||
input ENUM_DISPLAY_FORMAT InpDispFormat = DisplayFormat1; // Display format
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,"\n");
|
||||
IndicatorSetDouble(INDICATOR_MINIMUM,0);
|
||||
IndicatorSetDouble(INDICATOR_MAXIMUM,9);
|
||||
IndicatorSetInteger(INDICATOR_HEIGHT,28);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||
//---
|
||||
|
||||
customChartIndicator.SetGetTimeFlag();
|
||||
|
||||
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))
|
||||
return(0);
|
||||
|
||||
int start = customChartIndicator.GetPrevCalculated() - 1;
|
||||
//--- correct position
|
||||
if(start<0)
|
||||
start=0;
|
||||
|
||||
if((start == 0) || customChartIndicator.IsNewBar)
|
||||
{
|
||||
ObjectsDeleteAll(__chartId,PREFIX_SEED);
|
||||
DrawTimeLine(0,rates_total,time);
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
void DrawTimeLine(const int nPosition, const int nRatesCount, const datetime &canvasTime[])
|
||||
{
|
||||
datetime curBarTime = 0;
|
||||
bool _start = false;
|
||||
int c = 0;
|
||||
|
||||
for(int i=nPosition;i<nRatesCount;i++)
|
||||
{
|
||||
curBarTime = (datetime)customChartIndicator.Time[i];
|
||||
if(curBarTime == 0)
|
||||
continue;
|
||||
else
|
||||
_start = true;
|
||||
|
||||
if(c%InpSpacing == 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(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 );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user