Compare commits

..

15 Commits

Author SHA1 Message Date
unknown bd957ab1af updated Smoothalgorithms.mqh 2020-01-15 22:30:38 +01:00
unknown 0ba2c53a35 Merge branch 'master' of https://github.com/9nix6/Range-Bars-Charting 2019-09-30 13:03:01 +02:00
unknown dde1849bb0 added OBV indicator 2019-09-30 13:02:46 +02:00
9nix6 e4e0bb483a Fixed RageBar indicator path 2019-08-28 20:59:48 +02:00
unknown b784e9556d Merge branch 'master' of https://github.com/9nix6/Range-Bars-Charting 2019-08-25 22:22:29 +02:00
unknown 695a66b812 update for version 2.13 2019-08-25 22:20:16 +02:00
9nix6 bd3a18958e Fixed error on line 99 2019-07-12 22:43:13 +02:00
9nix6 dd2f769c89 Update for version 2.11 2019-05-14 17:22:40 +02:00
9nix6 38937ddce1 new version update 2018-12-13 00:19:34 +01:00
9nix6 75a0f76352 Added MACD Line indicator 2018-07-16 12:51:08 +02:00
9nix6 4f56445d60 Updated TimeLine indicator 2018-06-01 17:01:39 +02:00
9nix6 a23213f3e1 Added time line indicator 2018-05-28 19:38:04 +02:00
9nix6 91e99e93cc Update to version 2.04 2018-05-15 19:27:24 +02:00
9nix6 a19c291525 Added AwesomeOscillator 2018-03-14 13:17:04 +01:00
9nix6 60a4d0ad07 Added missing dependency: smoothalgorithms.mqh 2018-03-07 21:56:20 +01:00
16 changed files with 2476 additions and 181 deletions
+4 -4
View File
@@ -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
+3 -3
View File
@@ -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.
+52
View File
@@ -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);
}
+23 -9
View File
@@ -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))
+108 -66
View File
@@ -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
}
+77 -19
View File
@@ -6,8 +6,8 @@
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay213"
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay203"
#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;
}
+545 -80
View File
@@ -1,11 +1,13 @@
//+------------------------------------------------------------------+
//| TradeFunctions.mqh |
//| Copyright 2017, AZ-iNVEST |
//| http://www.az-invest.eu |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AZ-iNVEST"
#property link "http://www.az-invest.eu"
//
// Copyright 2017-2018, Artur Zas
// https://www.az-invest.eu
// https://www.mql5.com/en/users/arturz
//
#include <Trade\Trade.mqh>
#include <AZ-INVEST/SDK/Normailze.mqh>
#include <AZ-INVEST/SDK/TradingChecks.mqh>
CTradingChecks tradingChecks;
#define POSITION_TYPE_NONE -1
@@ -15,40 +17,58 @@
struct CMarketOrderParameters
{
bool m_async_mode; // trade mode
ulong m_magic; // expert magic number
ulong m_deviation; // deviation default
bool m_async_mode; // trade mode
ulong m_magic; // expert magic number
ulong m_deviation; // deviation default
ENUM_ORDER_TYPE_FILLING m_type_filling;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
};
class CMarketOrder
{
protected:
CTrade * ctrade;
CTrade *ctrade;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
bool initialized;
int numberOfRetries;
int busyTimeout_ms;
int requoteTimeout_ms;
public:
CMarketOrder(void);
CMarketOrder(CMarketOrderParameters &params);
~CMarketOrder(void);
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0);
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0);
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0);
bool Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0);
bool Initialize(CMarketOrderParameters &params);
bool IsInitialized() {return initialized;};
bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0,bool stopsInPips = true, string comment = "");
bool Long(string symbol,double lots, double priceSL=0,double priceTP=0, string comment = "");
bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0,bool stopsInPips = true, string comment = "");
bool Short(string symbol,double lots, double priceSL=0,double priceTP=0, string comment = "");
bool PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "");
bool PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "");
bool PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "");
bool PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "");
bool Modify(ulong ticket, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1);
bool Modify(ulong ticket, double priceSL=0,double priceTP=0);
bool ModifyPending(ulong ticket, double entry, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0);
bool ModifyPending(ulong ticket, double entry, double priceSL=0, double priceTP=0, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0);
bool Close(ulong ticket);
bool ClosePartial(ulong ticket, double lots);
bool CloseAll(string symbol = "");
bool Delete(ulong ticket);
bool Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0);
bool Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0);
bool IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0);
@@ -57,8 +77,13 @@ class CMarketOrder
bool IsOpen(ulong &ticket, string symbol, long magicNumber = 0);
bool IsOpen(ulong &ticket, ENUM_POSITION_TYPE &type, string symbol, long magicNumber = 0);
bool GetPositionType(ulong ticket, ENUM_POSITION_TYPE &_pType);
string PositionTypeToString(ENUM_POSITION_TYPE t);
string OrderTypeToString(ENUM_ORDER_TYPE t);
ENUM_ORDER_TYPE TradeBias(ENUM_ORDER_TYPE t);
bool RetryOrderRequest(int retryNumber);
void SetTradeId(ulong tradeId);
private:
@@ -68,19 +93,31 @@ class CMarketOrder
};
CMarketOrder::CMarketOrder(void)
{
ctrade = new CTrade();
this.initialized = false;
}
CMarketOrder::CMarketOrder(CMarketOrderParameters &params)
{
ctrade = new CTrade();
Initialize(params);
}
bool CMarketOrder::Initialize(CMarketOrderParameters &params)
{
ctrade.SetExpertMagicNumber(params.m_magic);
ctrade.SetDeviationInPoints(params.m_deviation);
ctrade.SetTypeFilling(params.m_type_filling);
ctrade.SetAsyncMode(params.m_async_mode);
this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries;
this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms;
this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms;
this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries;
this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms;
this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms;
this.initialized = true;
return this.initialized;
}
CMarketOrder::~CMarketOrder(void)
@@ -89,7 +126,7 @@ CMarketOrder::~CMarketOrder(void)
delete ctrade;
}
bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
int counter = 0;
@@ -97,14 +134,21 @@ bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprof
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : 0.0);
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_BUY,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -121,7 +165,7 @@ bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprof
return false;
}
bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0)
bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0, string comment = "")
{
bool result = false;
int counter = 0;
@@ -130,8 +174,15 @@ bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double price
{
double price = SymbolInfoDouble(symbol,SYMBOL_ASK);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_BUY,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -148,7 +199,7 @@ bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double price
return false;
}
bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0)
bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
int counter = 0;
@@ -156,14 +207,21 @@ bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takepro
while(!IsStopped() && !result)
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : 0.0);
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_SELL,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -180,7 +238,7 @@ bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takepro
return false;
}
bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0)
bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0, string comment = "")
{
bool result = false;
int counter = 0;
@@ -189,8 +247,15 @@ bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double pric
{
double price = SymbolInfoDouble(symbol,SYMBOL_BID);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,ORDER_TYPE_SELL,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP);
result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP, comment);
if(result)
{
@@ -207,24 +272,202 @@ bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double pric
return false;
}
bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0)
bool CMarketOrder::PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to place buy
if(orderType == ORDER_TYPE_BUY_LIMIT)
result = ctrade.BuyLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_BUY_STOP)
result = ctrade.BuyStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingLong(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to buy
if(orderType == ORDER_TYPE_BUY_LIMIT)
result = ctrade.BuyLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_BUY_STOP)
result = ctrade.BuyStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, uint stoploss=0,uint takeprofit=0,bool stopsInPips = true, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//calc SL + TP
double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*point) : 0.0);
double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*point) : 0.0);
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
if(orderType == ORDER_TYPE_SELL_LIMIT)
result = ctrade.SellLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_SELL_STOP)
result = ctrade.SellStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::PendingShort(ENUM_ORDER_TYPE orderType, string symbol, double lots, double price, double priceSL=0, double priceTP=0, string comment = "")
{
bool result = false;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToOpenPosition(symbol,orderType,lots,price,priceSL,priceTP))
{
Alert("Unable to place trade: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to sell
if(orderType == ORDER_TYPE_SELL_LIMIT)
result = ctrade.SellLimit(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
else if(orderType == ORDER_TYPE_SELL_STOP)
result = ctrade.SellStop(NormalizeLots(symbol,lots),price,symbol,priceSL,priceTP,ORDER_TIME_GTC,0,comment);
if(result)
{
Sleep(500);
return true;
}
else
{
string err = ctrade.ResultRetcodeDescription();
MessageBox(err,"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
return false;
}
bool CMarketOrder::Modify(ulong ticket, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1)
{
if(!PositionSelectByTicket(ticket))
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double priceSL;
double priceTP;
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP));
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
priceSL = (stoploss < 0)
? PositionGetDouble(POSITION_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,price - stoploss*point);
priceTP = (takeprofit < 0)
? PositionGetDouble(POSITION_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,price + takeprofit*point);
// priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL));
// priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP));
}
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL));
priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP));
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{
// priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL));
// priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP));
priceSL = (stoploss < 0)
? PositionGetDouble(POSITION_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,price + stoploss*point);
priceTP = (takeprofit < 0)
? PositionGetDouble(POSITION_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,price - takeprofit*point);
}
else
return false;
@@ -232,15 +475,25 @@ bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0)
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyPosition(symbol,ticket,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(_IsNettingAccount())
result = ctrade.PositionModify(symbol,priceSL,priceTP);
else
result = ctrade.PositionModify(ticket,priceSL,priceTP);
if(result)
{
@@ -263,21 +516,167 @@ bool CMarketOrder::Modify(ulong ticket, double priceSL=0,double priceTP=0)
return false;
string symbol = PositionGetString(POSITION_SYMBOL);
double price = PositionGetDouble(POSITION_PRICE_CURRENT);
double _point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
//double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
//there's no change in SL or TP - do nothing!
if (priceSL == PositionGetDouble(POSITION_SL)
&& priceTP == PositionGetDouble(POSITION_TP))
return true;
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyPosition(symbol,ticket,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.PositionModify(symbol,priceSL,priceTP);
if(_IsNettingAccount())
result = ctrade.PositionModify(symbol,priceSL,priceTP);
else
result = ctrade.PositionModify(ticket,priceSL,priceTP);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::ModifyPending(ulong ticket, double entry, bool stopsInPips = true, int stoploss = -1, int takeprofit = -1, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0)
{
if(!OrderSelect(ticket))
return false;
string symbol = OrderGetString(ORDER_SYMBOL);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
if(entry == 0)
entry = OrderGetDouble(ORDER_PRICE_OPEN);
double priceSL;
double priceTP;
if((OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP_LIMIT))
{
priceSL = (stoploss < 0)
? OrderGetDouble(ORDER_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,entry - stoploss*point);
priceTP = (takeprofit < 0)
? OrderGetDouble(ORDER_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,entry + takeprofit*point);
}
else if((OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP) ||
(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP_LIMIT))
{
priceSL = (stoploss < 0)
? OrderGetDouble(ORDER_SL)
: (stoploss == 0)
? 0
: NormalizePrice(symbol,entry + stoploss*point);
priceTP = (takeprofit < 0)
? OrderGetDouble(ORDER_TP)
: (takeprofit == 0)
? 0
: NormalizePrice(symbol,entry - takeprofit*point);
}
else
return false;
//there's no change in parameters - do nothing!
if (priceSL == OrderGetDouble(ORDER_SL)
&& priceTP == OrderGetDouble(ORDER_TP)
&& entry == OrderGetDouble(ORDER_PRICE_OPEN)
&& orderTypeTime == OrderGetInteger(ORDER_TYPE_TIME)
&& expires == OrderGetInteger(ORDER_TIME_EXPIRATION))
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyOrder(symbol,ticket,entry,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.OrderModify(ticket,entry,priceSL,priceTP,orderTypeTime,expires);
if(result)
{
Sleep(500);
return true;
}
else
{
if(!RetryOrderRequest(++counter))
return false;
}
}
return false;
}
bool CMarketOrder::ModifyPending(ulong ticket, double entry, double priceSL=0, double priceTP=0, ENUM_ORDER_TYPE_TIME orderTypeTime = ORDER_TIME_GTC, datetime expires = 0)
{
if(!OrderSelect(ticket))
return false;
string symbol = OrderGetString(ORDER_SYMBOL);
if(entry == 0)
entry = OrderGetDouble(ORDER_PRICE_OPEN);
//there's no change in parameters - do nothing!
if (priceSL == OrderGetDouble(ORDER_SL)
&& priceTP == OrderGetDouble(ORDER_TP)
&& entry == OrderGetDouble(ORDER_PRICE_OPEN)
&& orderTypeTime == OrderGetInteger(ORDER_TYPE_TIME)
&& expires == OrderGetInteger(ORDER_TIME_EXPIRATION))
return false;
bool result = false;
int counter = 0;
while(!IsStopped() && !result)
{
//do checks
if(!tradingChecks.OkToModifyOrder(symbol,ticket,entry,priceSL,priceTP))
{
Print("Unable to modify: "+tradingChecks.GetCheckErrorToString());
return false;
}
//attempt to modify position
result = ctrade.OrderModify(ticket,entry,priceSL,priceTP,orderTypeTime,expires);
if(result)
{
@@ -350,6 +749,11 @@ bool CMarketOrder::ClosePartial(ulong ticket, double lots)
return false;
}
bool CMarketOrder::Delete(ulong ticket)
{
return ctrade.OrderDelete(ticket);
}
bool CMarketOrder::Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0)
{
if(!PositionSelectByTicket(ticket))
@@ -420,6 +824,44 @@ bool CMarketOrder::IsOpen(ulong &ticket, string symbol, long magicNumber = 0)
return this._IsOpen(ticket,symbol,magicNumber);
}
bool CMarketOrder::CloseAll(string symbol = "")
{
int positions=PositionsTotal();
ulong ticketsToClose[];
int ticketsToCloseCounter = 0;
if(positions > 0)
ArrayResize(ticketsToClose,positions);
else
return false;
for(int i=0;i<positions;i++)
{
// ResetLastError();
ulong _ticket=PositionGetTicket(i);
if(_ticket!=0)
{
if(PositionSelectByTicket(_ticket))
{
if((PositionGetString(POSITION_SYMBOL) == symbol) || (symbol == ""))
{
ticketsToClose[ticketsToCloseCounter] = _ticket;
ticketsToCloseCounter++;
}
}
}
}
ArrayResize(ticketsToClose,ticketsToCloseCounter);
for(int i=0;i<ticketsToCloseCounter;i++)
{
this.Close(ticketsToClose[i]);
}
return true;
}
bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,long magicNumber=0)
{
int positions=PositionsTotal();
@@ -458,6 +900,15 @@ bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,l
}
bool CMarketOrder::GetPositionType(ulong ticket, ENUM_POSITION_TYPE &_pType)
{
if(!PositionSelectByTicket(ticket))
return false;
_pType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
return true;
}
bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber)
{
int positions=PositionsTotal();
@@ -546,8 +997,43 @@ string CMarketOrder::PositionTypeToString(ENUM_POSITION_TYPE t)
return "-";
}
string CMarketOrder::OrderTypeToString(ENUM_ORDER_TYPE t)
{
if(t == ORDER_TYPE_BUY)
return "Buy";
else if(t == ORDER_TYPE_BUY_LIMIT)
return "Buy Limit";
else if(t == ORDER_TYPE_BUY_STOP)
return "Buy Stop";
else if(t == ORDER_TYPE_BUY_STOP_LIMIT)
return "Buy Stop Limit";
else if(t == ORDER_TYPE_SELL)
return "Sell";
else if(t == ORDER_TYPE_SELL_LIMIT)
return "Sell Limit";
else if(t == ORDER_TYPE_SELL_STOP)
return "Sell Stop";
else if(t == ORDER_TYPE_SELL_STOP_LIMIT)
return "Sell Stop Limit";
else
return "-";
}
ENUM_ORDER_TYPE CMarketOrder::TradeBias(ENUM_ORDER_TYPE t)
{
if((t == ORDER_TYPE_BUY) ||
(t == ORDER_TYPE_BUY_LIMIT) ||
(t == ORDER_TYPE_BUY_STOP) ||
(t == ORDER_TYPE_BUY_STOP_LIMIT))
return ORDER_TYPE_BUY;
else
return ORDER_TYPE_SELL;
}
bool CMarketOrder::RetryOrderRequest(int retryNumber)
{
Print(ctrade.ResultRetcodeDescription());
if(retryNumber >= this.numberOfRetries)
{
PrintFormat("Giving up on maximum number of retries (%d)",this.numberOfRetries);
@@ -575,37 +1061,16 @@ bool CMarketOrder::RetryOrderRequest(int retryNumber)
break;
default:
MessageBox(ctrade.ResultRetcodeDescription(),"Operation failed",MB_ICONEXCLAMATION);
return false;
}
}
//+------------------------------------------------------------------+
//| Normalizing |
//+------------------------------------------------------------------+
double NormalizeLots(string symbol, double InputLots)
void CMarketOrder::SetTradeId(ulong tradeId)
{
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
if(InputLots < lotsMin)
InputLots = lotsMin;
if(InputLots > lotsMax)
InputLots = lotsMax;
return NormalizeDouble(InputLots, lotsDigits);
ctrade.SetExpertMagicNumber(tradeId);
}
double NormalizePrice(string symbol, double price, double tick = 0)
{
double _tick = tick ? tick : SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
int _digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
if (tick)
return NormalizeDouble(MathRound(price/_tick)*_tick,_digits);
else
return NormalizeDouble(price,_digits);
}
+932
View File
@@ -0,0 +1,932 @@
//
// Copyright 2018, Artur Zas
// https://www.az-invest.eu
// https://www.mql5.com/en/users/arturz
//
#ifdef __MQL5__
//--- class for performing trade operations
#include <Trade\Trade.mqh>
CTrade trade;
//--- class for working with orders
#include <Trade\OrderInfo.mqh>
COrderInfo orderinfo;
//--- class for working with positions
#include <Trade\PositionInfo.mqh>
CPositionInfo positioninfo;
//--- introduce the predefined variables from MQL4 for versatility of the code
#define Ask SymbolInfoDouble(_symbol,SYMBOL_ASK)
#define Bid SymbolInfoDouble(_symbol,SYMBOL_BID)
bool suppressLogOutput = false;
void SuppressGlobalLogOutput() { suppressLogOutput = true; };
#endif
#define _point SymbolInfoDouble(_symbol,SYMBOL_POINT)
//--- redefine the order types from MQL5 to MQL4 for use in common code
#ifdef __MQL4__
#define ORDER_TYPE_BUY OP_BUY
#define ORDER_TYPE_SELL OP_SELL
#define ORDER_TYPE_BUY_LIMIT OP_BUYLIMIT
#define ORDER_TYPE_SELL_LIMIT OP_SELLLIMIT
#define ORDER_TYPE_BUY_STOP OP_BUYSTOP
#define ORDER_TYPE_SELL_STOP OP_SELLSTOP
#endif
enum ENUM_TC_ERROR
{
tcErrorNONE = 0,
tcErrorNotEnoughMoney,
tcErrorInvalidStops,
tcErrorOrderLimitReached,
tcErrorFreezeLevel,
tcErrorNothingChanged,
tcErrorInvalidPrice,
};
class CTradingChecks
{
private:
ENUM_TC_ERROR _err;
bool _suppressLogOutput;
public:
CTradingChecks();
~CTradingChecks();
string GetCheckErrorToString();
void SuppressLogOutput() { _suppressLogOutput = true; };
bool OkToOpenOrder(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice, double sl, double tp);
bool OkToModifyOrder(string _symbol,ulong ticket,double price, double sl, double tp);
#ifdef __MQL5__
bool OkToOpenPosition(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice, double sl, double tp);
bool OkToModifyPosition(string _symbol,ulong ticket, double sl, double tp);
#endif
};
CTradingChecks::CTradingChecks(void)
{
suppressLogOutput = false;
}
CTradingChecks::~CTradingChecks(void)
{
}
string CTradingChecks::GetCheckErrorToString(void)
{
switch(_err)
{
case tcErrorNONE:
return "No Error";
case tcErrorNotEnoughMoney:
return "Not enough money (check previous message in Experts log)";
case tcErrorInvalidStops:
return "Invalid stops (check previous message in Experts log)";
case tcErrorOrderLimitReached:
return "Maximum order limit reached";
case tcErrorFreezeLevel:
return "Freeze level (check previous message in Experts log)";
case tcErrorNothingChanged:
return "Nothing to change";
case tcErrorInvalidPrice:
return "Invalid entry price for this order type";
default:
return "";
}
}
bool CTradingChecks::OkToOpenOrder(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice,double sl, double tp)
{
if(!IsNewPendingOrderAllowed())
{
_err = tcErrorOrderLimitReached;
return false;
}
if(!CheckStopLoss_Takeprofit(_symbol,type,entryPrice,sl,tp))
{
_err = tcErrorInvalidStops;
return false;
}
_err = tcErrorNONE;
return true;
}
#ifdef __MQL5__
bool CTradingChecks::OkToOpenPosition(string _symbol,ENUM_ORDER_TYPE type, double lots, double entryPrice,double sl, double tp)
{
#ifdef __MQL5__
if(!CheckMoneyForTrade(_symbol,lots,type))
{
_err = tcErrorNotEnoughMoney;
return false;
}
// if(NewOrderAllowedVolume(_symbol) < lots)
// return false;
#else
if(!CheckMoneyForTrade(_symbol,lots,(int)type))
{
_err = tcErrorNotEnoughMoney;
return false;
}
if(!IsNewPendingOrderAllowed())
{
_err = tcErrorOrderLimitReached;
return false;
}
#endif
if(!CheckStopLoss_Takeprofit(_symbol,type,entryPrice,sl,tp))
{
_err = tcErrorInvalidStops;
return false;
}
_err = tcErrorNONE;
return true;
}
#endif;
bool CTradingChecks::OkToModifyOrder(string _symbol, ulong ticket,double price, double sl, double tp)
{
#ifdef __MQL5__
if(!OrderModifyCheck(ticket,price,sl,tp))
{
_err = tcErrorNothingChanged;
return false;
}
if(!CheckOrderForFREEZE_LEVEL(_symbol,ticket))
{
_err = tcErrorFreezeLevel;
return false;
}
#else
if(!OrderModifyCheck((int)ticket,price,sl,tp))
{
_err = tcErrorNothingChanged;
return false;
}
if(!CheckOrderForFREEZE_LEVEL(_symbol,(int)ticket))
{
_err = tcErrorFreezeLevel;
return false;
}
#endif
if(!CheckPendingOrderEntryChange(_symbol,ticket,price))
{
_err = tcErrorInvalidPrice;
return false;
}
_err = tcErrorNONE;
return true;
}
#ifdef __MQL5__
bool CTradingChecks::OkToModifyPosition(string _symbol, ulong ticket,double sl,double tp)
{
if(!PositionModifyCheck(ticket,sl,tp))
{
_err = tcErrorNothingChanged;
return false;
}
if(!CheckPositionForFREEZE_LEVEL(_symbol,ticket))
{
_err = tcErrorFreezeLevel;
return false;
}
_err = tcErrorNONE;
return true;
}
#endif
//////////////////////////////////////////////////////////////////
//
// Helper functions from https://www.mql5.com/en/articles/2555
//
///////////////////////////////////////////////////////////////////
#ifdef __MQL5__
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
{
//--- Getting the opening price
MqlTick mqltick;
SymbolInfoTick(symb,mqltick);
double price=mqltick.ask;
if(type==ORDER_TYPE_SELL)
price=mqltick.bid;
//--- values of the required and free margin
double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
if(!OrderCalcMargin(type,symb,lots,price,margin))
{
//--- something went wrong, report and return false
if(suppressLogOutput == false)
{
Print("Error in ",__FUNCTION__," code=",GetLastError());
}
return(false);
}
//--- if there are insufficient funds to perform the operation
if(margin>free_margin)
{
//--- report the error and return false
if(suppressLogOutput == false)
{
Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
Print("Required margin:"+DoubleToString(margin,2)+"; free margin:"+DoubleToString(free_margin,2));
}
return(false);
}
//--- checking successful
return(true);
}
#else
bool CheckMoneyForTrade(string symb, double lots,int type)
{
double free_margin=AccountFreeMarginCheck(symb,type, lots);
//-- if there is not enough money
if(free_margin<0)
{
string oper=(type==OP_BUY)? "Buy":"Sell";
if(suppressLogOutput == false)
{
Print("Not enough money for ", oper," ",lots, " ", symb, " Error code=",GetLastError());
}
return(false);
}
//--- checking successful
return(true);
}
#endif
//+------------------------------------------------------------------+
//| Check if another order can be placed |
//+------------------------------------------------------------------+
bool IsNewPendingOrderAllowed()
{
//--- get the number of pending orders allowed on the account
int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
//--- if there is no limitation, return true; you can send an order
if(max_allowed_orders==0) return(true);
//--- if we passed to this line, then there is a limitation; find out how many orders are already placed
int orders=OrdersTotal();
//--- return the result of comparing
return(orders<max_allowed_orders);
}
#ifdef __MQL5__
//+------------------------------------------------------------------+
//| Return the size of position on the specified symbol |
//+------------------------------------------------------------------+
double PositionVolume(string symbol)
{
//--- try to select position by a symbol
bool selected=PositionSelect(symbol);
//--- there is a position
if(selected)
//--- return volume of the position
return(PositionGetDouble(POSITION_VOLUME));
else
{
//--- report a failure to select position
if(suppressLogOutput == false)
{
Print(__FUNCTION__," Failed to perform PositionSelect() for symbol ",
symbol," Error ",GetLastError());
}
return(-1);
}
}
//+------------------------------------------------------------------+
//| returns the volume of current pending order by a symbol |
//+------------------------------------------------------------------+
double PendingsVolume(string symbol)
{
double volume_on_symbol=0;
ulong ticket;
//--- get the number of all currently placed orders by all symbols
int all_orders=OrdersTotal();
//--- get over all orders in the loop
for(int i=0;i<all_orders;i++)
{
//--- get the ticket of an order by its position in the list
ticket = OrderGetTicket(i);
if((bool)ticket)
{
//--- if our symbol is specified in the order, add the volume of this order
if(symbol==OrderGetString(ORDER_SYMBOL))
volume_on_symbol+=OrderGetDouble(ORDER_VOLUME_INITIAL);
}
}
//--- return the total volume of currently placed pending orders for a specified symbol
return(volume_on_symbol);
}
//+------------------------------------------------------------------+
//| Return the maximum allowed volume for an order on the symbol |
//+------------------------------------------------------------------+
double NewOrderAllowedVolume(string symbol)
{
double allowed_volume=0;
//--- get the limitation on the maximal volume of an order
double symbol_max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
//--- get the limitation on the volume by a symbol
double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_LIMIT);
//--- get the volume of the open position by a symbol
double opened_volume=PositionVolume(symbol);
if(opened_volume>=0)
{
//--- if we have exhausted the volume
if(max_volume-opened_volume<=0)
return(0);
//--- volume of the open position doesn't exceed max_volume
double orders_volume_on_symbol=PendingsVolume(symbol);
allowed_volume=max_volume-opened_volume-orders_volume_on_symbol;
if(allowed_volume>symbol_max_volume) allowed_volume=symbol_max_volume;
}
return(allowed_volume);
}
#endif
//+------------------------------------------------------------------+
//| Check the correctness of StopLoss and TakeProfit |
//+------------------------------------------------------------------+
bool CheckStopLoss_Takeprofit(string _symbol, ENUM_ORDER_TYPE type,double price,double SL,double TP)
{
//--- get the SYMBOL_TRADE_STOPS_LEVEL level
int stops_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_STOPS_LEVEL);
if(stops_level!=0)
{
if(suppressLogOutput == false)
{
PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must"+
" not be nearer than %d points from the closing price",stops_level,stops_level);
}
}
//---
bool SL_check=false,TP_check=false;
//--- check the order type
switch(type)
{
//--- Buy operation
case ORDER_TYPE_BUY:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : (Bid-SL>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
" (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,Bid-stops_level*_point,Bid,stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : (TP-Bid>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
" (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,Bid+stops_level*_point,Bid,stops_level);
//--- return the result of checking
return(SL_check&&TP_check);
}
//--- Sell operation
case ORDER_TYPE_SELL:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : (SL-Ask>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
" (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,Ask+stops_level*_point,Ask,stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : (Ask-TP>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
" (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,Ask-stops_level*_point,Ask,stops_level);
//--- return the result of checking
return(TP_check&&SL_check);
}
break;
//--- BuyLimit pending order
case ORDER_TYPE_BUY_LIMIT:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : ((price-SL)>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,price-stops_level*_point,(int)((price-SL)/_point),stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : ((TP-price)>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,price+stops_level*_point,(int)((TP-price)/_point),stops_level);
//--- return the result of checking
return(SL_check&&TP_check);
}
//--- SellLimit pending order
case ORDER_TYPE_SELL_LIMIT:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : ((SL-price)>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,price+stops_level*_point,(int)((SL-price)/_point),stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : ((price-TP)>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,price-stops_level*_point,(int)((price-TP)/_point),stops_level);
//--- return the result of checking
return(TP_check&&SL_check);
}
break;
//--- BuyStop pending order
case ORDER_TYPE_BUY_STOP:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : ((price-SL)>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,price-stops_level*_point,(int)((price-SL)/_point),stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : ((TP-price)>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,price-stops_level*_point,(int)((TP-price)/_point),stops_level);
//--- return the result of checking
return(SL_check&&TP_check);
}
//--- SellStop pending order
case ORDER_TYPE_SELL_STOP:
{
//--- check the StopLoss
SL_check= (SL==0) ? true : ((SL-price)>stops_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+
" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),SL,price+stops_level*_point,(int)((SL-price)/_point),stops_level);
//--- check the TakeProfit
TP_check= (TP==0) ? true : ((price-TP)>stops_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+
" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
EnumToString(type),TP,price-stops_level*_point,(int)((price-TP)/_point),stops_level);
//--- return the result of checking
return(TP_check&&SL_check);
}
break;
}
//---
return false;
}
#ifdef __MQL5__
//+------------------------------------------------------------------+
//| Checking the new values of levels before order modification |
//+------------------------------------------------------------------+
bool OrderModifyCheck(ulong ticket,double price,double sl,double tp)
{
//--- select order by ticket
if(orderinfo.Select(ticket))
{
//--- point size and name of the symbol, for which a pending order was placed
string symbol=orderinfo.Symbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
//--- check if there are changes in the Open price
bool PriceOpenChanged=(MathAbs(orderinfo.PriceOpen()-price)>point);
//--- check if there are changes in the StopLoss level
bool StopLossChanged=(MathAbs(orderinfo.StopLoss()-sl)>point);
//--- check if there are changes in the Takeprofit level
bool TakeProfitChanged=(MathAbs(orderinfo.TakeProfit()-tp)>point);
//--- if there are any changes in levels
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
return(true); // order can be modified
//--- there are no changes in the Open, StopLoss and Takeprofit levels
else
{
//--- notify about the error
if(suppressLogOutput == false)
{
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
ticket,orderinfo.PriceOpen(),orderinfo.StopLoss(),orderinfo.TakeProfit());
}
}
}
//--- came to the end, no changes for the order
return(false); // no point in modifying
}
//+------------------------------------------------------------------+
//| Checking the new values of levels before order modification |
//+------------------------------------------------------------------+
bool PositionModifyCheck(ulong ticket,double sl,double tp)
{
//--- select order by ticket
if(positioninfo.SelectByTicket(ticket))
{
//--- point size and name of the symbol, for which a pending order was placed
string symbol=positioninfo.Symbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
//--- check if there are changes in the StopLoss level
bool StopLossChanged=(MathAbs(positioninfo.StopLoss()-sl)>point);
//--- check if there are changes in the Takeprofit level
bool TakeProfitChanged=(MathAbs(positioninfo.TakeProfit()-tp)>point);
//--- if there are any changes in levels
if(StopLossChanged || TakeProfitChanged)
return(true); // position can be modified
//--- there are no changes in the StopLoss and Takeprofit levels
else
{
//--- notify about the error
if(suppressLogOutput == false)
{
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
ticket,orderinfo.PriceOpen(),orderinfo.StopLoss(),orderinfo.TakeProfit());
}
}
}
//--- came to the end, no changes for the order
return(false); // no point in modifying
}
#else
//+------------------------------------------------------------------+
//| Checking the new values of levels before order modification |
//+------------------------------------------------------------------+
bool OrderModifyCheck(int ticket,double price,double sl,double tp)
{
//--- select order by ticket
if(OrderSelect(ticket,SELECT_BY_TICKET))
{
//--- point size and name of the symbol, for which a pending order was placed
string symbol=OrderSymbol();
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
//--- check if there are changes in the Open price
bool PriceOpenChanged=true;
int type=OrderType();
if(!(type==OP_BUY || type==OP_SELL))
{
PriceOpenChanged=(MathAbs(OrderOpenPrice()-price)>point);
}
//--- check if there are changes in the StopLoss level
bool StopLossChanged=(MathAbs(OrderStopLoss()-sl)>point);
//--- check if there are changes in the Takeprofit level
bool TakeProfitChanged=(MathAbs(OrderTakeProfit()-tp)>point);
//--- if there are any changes in levels
if(PriceOpenChanged || StopLossChanged || TakeProfitChanged)
return(true); // order can be modified
//--- there are no changes in the Open, StopLoss and Takeprofit levels
else
{
//--- notify about the error
if(suppressLogOutput == false)
{
PrintFormat("Order #%d already has levels of Open=%.5f SL=%.5f TP=%.5f",
ticket,OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
}
}
}
//--- came to the end, no changes for the order
return(false); // no point in modifying
}
#endif
#ifdef __MQL5__
//+------------------------------------------------------------------+
//| Check the distance from opening price to activation price |
//+------------------------------------------------------------------+
bool CheckOrderForFREEZE_LEVEL(string _symbol, ulong ticket)
{
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
if(freeze_level!=0)
{
if(suppressLogOutput == false)
{
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
" nearer than %d points from the activation price",freeze_level,freeze_level);
}
}
//--- select order for working
if(!OrderSelect(ticket))
{
//--- failed to select order
return(false);
}
//--- get the order data
double price=OrderGetDouble(ORDER_PRICE_OPEN);
double sl=OrderGetDouble(ORDER_SL);
double tp=OrderGetDouble(ORDER_TP);
ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
//--- result of checking
bool check=false;
//--- check the order type
switch(type)
{
//--- BuyLimit pending order
case ORDER_TYPE_BUY_LIMIT:
{
//--- check the distance from the opening price to the activation price
check=((Ask-price)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
EnumToString(type),ticket,(int)((Ask-price)/_point),freeze_level);
return(check);
}
//--- BuyLimit pending order
case ORDER_TYPE_SELL_LIMIT:
{
//--- check the distance from the opening price to the activation price
check=((price-Bid)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified: Open-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
EnumToString(type),ticket,(int)((price-Bid)/_point),freeze_level);
return(check);
}
break;
//--- BuyStop pending order
case ORDER_TYPE_BUY_STOP:
{
//--- check the distance from the opening price to the activation price
check=((price-Ask)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
EnumToString(type),ticket,(int)((price-Ask)/_point),freeze_level);
return(check);
}
//--- SellStop pending order
case ORDER_TYPE_SELL_STOP:
{
//--- check the distance from the opening price to the activation price
check=((Bid-price)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified: Bid-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
EnumToString(type),ticket,(int)((Bid-price)/_point),freeze_level);
return(check);
}
break;
}
//--- order did not pass the check
return (false);
}
//+------------------------------------------------------------------+
//| Check if the TP and SL are too close to activation price |
//+------------------------------------------------------------------+
bool CheckPositionForFREEZE_LEVEL(string _symbol, ulong ticket)
{
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
if(freeze_level!=0 && suppressLogOutput == false)
{
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
" nearer than %d points from the activation price",freeze_level,freeze_level);
}
//--- select position for working
if(!PositionSelectByTicket(ticket))
{
//--- failed to select position
return(false);
}
//--- get the order data
ENUM_POSITION_TYPE pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double sl=PositionGetDouble(POSITION_SL);
double tp=PositionGetDouble(POSITION_TP);
//--- result of checking StopLoss and TakeProfit
bool SL_check=false,TP_check=false;
//--- position type
switch(pos_type)
{
//--- buy
case POSITION_TYPE_BUY:
{
SL_check=(sl == 0) ? true: (Bid-sl>freeze_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("Position %s #%d cannot be modified: Bid-StopLoss=%d points"+
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
EnumToString(pos_type),ticket,(int)((Bid-sl)/_point),freeze_level);
TP_check=(tp == 0) ? true: (tp-Bid>freeze_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("Position %s #%d cannot be modified: TakeProfit-Bid=%d points"+
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
EnumToString(pos_type),ticket,(int)((tp-Bid)/_point),freeze_level);
//--- return the result of checking
return(SL_check&&TP_check);
}
break;
//--- sell
case POSITION_TYPE_SELL:
{
SL_check=(sl == 0) ? true: (sl-Ask>freeze_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("Position %s cannot be modified: StopLoss-Ask=%d points"+
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
EnumToString(pos_type),(int)((sl-Ask)/_point),freeze_level);
TP_check=(tp == 0) ? true: (Ask-tp>freeze_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("Position %s cannot be modified: Ask-TakeProfit=%d points"+
" < SYMBOL_TRADE_FREEZE_LEVEL=%d points)",
EnumToString(pos_type),(int)((Ask-tp)/_point),freeze_level);
//--- return the result of checking
return(SL_check&&TP_check);
}
break;
}
//--- position did not pass the check
return (false);
}
#else
bool CheckOrderForFREEZE_LEVEL(string _symbol,int ticket)
{
//--- get the SYMBOL_TRADE_FREEZE_LEVEL level
int freeze_level=(int)SymbolInfoInteger(_symbol,SYMBOL_TRADE_FREEZE_LEVEL);
if(freeze_level!=0 && suppressLogOutput == false)
{
PrintFormat("SYMBOL_TRADE_FREEZE_LEVEL=%d: Cannot modify order"+
" nearer than %d points from the activation price",freeze_level,freeze_level);
}
//--- select order for working
if(!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
//--- failed to select order
return (false);
}
//--- get the order data
double price=OrderOpenPrice();
double sl=OrderStopLoss();
double tp=OrderTakeProfit();
int type=OrderType();
//--- result of checking
bool check=false;
//--- check the order type
switch(type)
{
//--- BuyLimit pending order
case OP_BUYLIMIT:
{
//--- check the distance from the opening price to the activation price
check=((Ask-price)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order OP_BUYLIMIT #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((Ask-price)/_point),freeze_level);
return(check);
}
//--- BuyLimit pending order
case OP_SELLLIMIT:
{
//--- check the distance from the opening price to the activation price
check=((price-Bid)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order OP_SELLLIMIT #%d cannot be modified: Open-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((price-Bid)/_point),freeze_level);
return(check);
}
break;
//--- BuyStop pending order
case OP_BUYSTOP:
{
//--- check the distance from the opening price to the activation price
check=((price-Ask)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order OP_BUYSTOP #%d cannot be modified: Ask-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((price-Ask)/_point),freeze_level);
return(check);
}
//--- SellStop pending order
case OP_SELLSTOP:
{
//--- check the distance from the opening price to the activation price
check=((Bid-price)>freeze_level*_point);
if(!check && suppressLogOutput == false)
PrintFormat("Order OP_SELLSTOP #%d cannot be modified: Bid-Open=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((Bid-price)/_point),freeze_level);
return(check);
}
break;
//--- checking opened Buy order
case OP_BUY:
{
//--- check TakeProfit distance to the activation price
bool TP_check=(tp == 0) ? true: (tp-Bid>freeze_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((tp-Bid)/_point),freeze_level);
//--- check TakeProfit distance to the activation price
bool SL_check=(sl == 0) ? true: (Bid-sl>freeze_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((Bid-sl)/_point),freeze_level);
return(SL_check&&TP_check);
}
break;
//--- checking opened Sell order
case OP_SELL:
{
//--- check TakeProfit distance to the activation price
bool TP_check=(tp == 0) ? true: (Ask-tp>freeze_level*_point);
if(!TP_check && suppressLogOutput == false)
PrintFormat("Order OP_SELL %d cannot be modified: Ask-TakeProfit=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((Ask-tp)/_point),freeze_level);
//--- check TakeProfit distance to the activation price
bool SL_check=(sl == 0) ? true: (sl-Ask>freeze_level*_point);
if(!SL_check && suppressLogOutput == false)
PrintFormat("Order OP_BUY %d cannot be modified: TakeProfit-Bid=%d points < SYMBOL_TRADE_FREEZE_LEVEL=%d points",
ticket,(int)((sl-Ask)/_point),freeze_level);
return(SL_check&&TP_check);
}
break;
}
//--- order did not pass the check
return (false);
}
#endif
bool CheckPendingOrderEntryChange(string _symbol, ulong ticket, double newEntryPrice)
{
//--- select order for working
if(!OrderSelect(ticket))
{
//--- failed to select order
return(false);
}
//--- get the order data
ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
//--- result of checking
bool check=false;
//--- check the order type
switch(type)
{
//--- BuyLimit pending order
case ORDER_TYPE_BUY_LIMIT:
{
//--- check the distance from the opening price to the activation price
check= (newEntryPrice < Ask);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified",
EnumToString(type),ticket);
return(check);
}
//--- BuyLimit pending order
case ORDER_TYPE_SELL_LIMIT:
{
//--- check the distance from the opening price to the activation price
check=(newEntryPrice > Bid);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified",
EnumToString(type),ticket);
return(check);
}
break;
//--- BuyStop pending order
case ORDER_TYPE_BUY_STOP:
{
//--- check the distance from the opening price to the activation price
check=(newEntryPrice > Ask);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified",
EnumToString(type),ticket);
return(check);
}
//--- SellStop pending order
case ORDER_TYPE_SELL_STOP:
{
//--- check the distance from the opening price to the activation price
check=(newEntryPrice < Bid);
if(!check && suppressLogOutput == false)
PrintFormat("Order %s #%d cannot be modified",
EnumToString(type),ticket);
return(check);
}
break;
}
//--- order did not pass the check
return (false);
}
Binary file not shown.
+144
View File
@@ -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);
}
//+------------------------------------------------------------------+
+121
View File
@@ -0,0 +1,121 @@
//+------------------------------------------------------------------+
//| OBV.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property description "On Balance Volume"
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 DodgerBlue
#property indicator_label1 "OBV"
//--- input parametrs
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes
//---- indicator buffer
double ExtOBVBuffer[];
//
// Initialize RangeBar indicator for data processing
// according to settings of the RangeBar indicator already on chart
//
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
RangeBarIndicator customIndicator;
//
//
//
//+------------------------------------------------------------------+
//| On Balance Volume initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- define indicator buffer
SetIndexBuffer(0,ExtOBVBuffer);
//--- set indicator digits
IndicatorSetInteger(INDICATOR_DIGITS,0);
//---- OnInit done
customIndicator.SetGetVolumesFlag();
}
//+------------------------------------------------------------------+
//| On Balance Volume |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//
// Process data through RangeBar indicator
//
if(!customIndicator.OnCalculate(rates_total,prev_calculated,time))
return(0);
int _prev_calculated = customIndicator.GetPrevCalculated();
//
//
//
//--- variables
int pos;
//--- check for bars count
if(rates_total<2)
return(0);
//--- starting calculation
pos=_prev_calculated-1;
//--- correct position, when it's first iteration
if(pos<1)
{
pos=1;
if(InpVolumeType==VOLUME_TICK)
ExtOBVBuffer[0]=(double)customIndicator.Tick_volume[0];
else ExtOBVBuffer[0]=(double)customIndicator.Real_volume[0];
}
//--- main cycle
if(InpVolumeType==VOLUME_TICK)
CalculateOBV(pos,rates_total,customIndicator.Close,customIndicator.Tick_volume);
else
CalculateOBV(pos,rates_total,customIndicator.Close,customIndicator.Real_volume);
//---- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
//| Calculate OBV by volume argument |
//+------------------------------------------------------------------+
void CalculateOBV(int StartPosition,
int RatesCount,
const double &ClBuffer[],
const long &VolBuffer[])
{
for(int i=StartPosition;i<RatesCount && !IsStopped();i++)
{
//--- get some data
double Volume=(double)VolBuffer[i];
double PrevClose=ClBuffer[i-1];
double CurrClose=ClBuffer[i];
//--- fill ExtOBVBuffer
if(CurrClose<PrevClose) ExtOBVBuffer[i]=ExtOBVBuffer[i-1]-Volume;
else
{
if(CurrClose>PrevClose) ExtOBVBuffer[i]=ExtOBVBuffer[i-1]+Volume;
else ExtOBVBuffer[i]=ExtOBVBuffer[i-1];
}
}
}
//+------------------------------------------------------------------+
+188
View File
@@ -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);
}