Updated for ver.3.16

This commit is contained in:
Artur
2021-05-10 18:11:10 +02:00
parent 380071b195
commit 419ea51fca
71 changed files with 510 additions and 121 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,38 +12,32 @@
#ifdef SHOW_INDICATOR_INPUTS
#ifdef MQL5_MARKET_DEMO // hardcoded values
int barSizeInTicks = 180; // Range bar size (in ticks)
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
int atrPeriod = 14; // ATR period
int atrPercentage = 10; // Use percentage of ATR
int showNumberOfDays = 7; // Show history for number of days
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
double InpBarSize = 180; // Range bar size
ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS; // Bar size calculation
int InpShowNumberOfDays = 7; // Show history for number of days
ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
int InpAtrPeriod = 14; // ATR period setting
ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
#else // user defined settings
input int barSizeInTicks = 100; // Range bar size (in ticks)
input int showNumberOfDays = 5; // Show history for number of days
input group "### ATR based bar size calculation"
input ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
input ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
input int atrPeriod = 14; // ATR period
input int atrPercentage = 10; // Use percentage of ATR
input group "### Chart synchronization"
input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
input double InpBarSize = 100; // Range bar size
input ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS;// Bar size calculation
input int InpShowNumberOfDays = 5; // Show history for number of days
input group "### ATR bar size calculation settings"
input ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
input int InpAtrPeriod = 14; // ATR period setting
input group "### Chart synchronization"
input ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
#endif
#else // don't SHOW_INDICATOR_INPUTS
int barSizeInTicks = 180; // Range bar size (in ticks)
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
int atrPeriod = 14; // ATR period
int atrPercentage = 10; // Use percentage of ATR
int showNumberOfDays = 7; // Show history for number of days
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
double InpBarSize = 180; // Range bar size
ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS;// Bar size calculation
int InpShowNumberOfDays = 7; // Show history for number of days
ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
int InpAtrPeriod = 14; // ATR period setting
ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
#endif
//
@@ -52,15 +46,18 @@
//
#include <az-invest/sdk/CustomChartSettingsBase.mqh>
#define SETNAME_BAR_SIZE_CALC_MODE "barSizeCalcMode"
#define SETNAME_ATR_TIMEFRAME "atrTimeFrame"
#define SETNAME_ATR_PERIOD "atrPeriod"
struct RANGEBAR_SETTINGS
{
int barSizeInTicks;
ENUM_BOOL atrEnabled;
ENUM_TIMEFRAMES atrTimeFrame;
int atrPeriod;
int atrPercentage;
int showNumberOfDays;
ENUM_BOOL resetOpenOnNewTradingDay;
double barSize;
ENUM_BAR_SIZE_CALC_MODE barSizeCalcMode;
ENUM_TIMEFRAMES atrTimeFrame;
int atrPeriod;
int showNumberOfDays;
ENUM_BOOL resetOpenOnNewTradingDay;
};
@@ -109,12 +106,10 @@ uint CRangeBarCustomChartSettigns::CustomChartSettingsFromFile(int file_handle)
void CRangeBarCustomChartSettigns::SetCustomChartSettings()
{
settings.barSizeInTicks = barSizeInTicks;
settings.atrEnabled = atrEnabled;
settings.atrTimeFrame = atrTimeFrame;
settings.atrPeriod = atrPeriod;
settings.atrPercentage = atrPercentage;
settings.showNumberOfDays = showNumberOfDays;
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
settings.barSize = InpBarSize;
settings.barSizeCalcMode = InpBarSizeCalcMode;
settings.showNumberOfDays = InpShowNumberOfDays;
settings.atrTimeFrame = InpAtrTimeFrame;
settings.atrPeriod = InpAtrPeriod;
settings.resetOpenOnNewTradingDay = InpResetOpenOnNewTradingDay;
}
+9 -9
View File
@@ -1,8 +1,8 @@
#property copyright "Copyright 2018-2020, Level Up Software"
#property copyright "Copyright 2018-2021, Level Up Software"
#property link "http://www.az-invest.eu"
#ifdef DEVELOPER_VERSION
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay300"
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay316"
#else
#ifdef RANGEBAR_LICENSE
#ifdef MQL5_MARKET_VERSION
@@ -193,23 +193,23 @@ int RangeBars::Init()
RANGEBAR_SETTINGS s = rangeBarSettings.GetCustomChartSettings();
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
ALERT_INFO_SETTINGS als = rangeBarSettings.GetAlertInfoSettings();
rangeBarsHandle = iCustom(this.rangeBarsSymbol, _Period, RANGEBAR_INDICATOR_NAME,
s.barSizeInTicks,
s.barSize,
s.barSizeCalcMode,
s.showNumberOfDays,
"=",
s.atrEnabled,
s.atrTimeFrame,
s.atrPeriod,
s.atrPercentage,
"=",
s.resetOpenOnNewTradingDay,
"=",
showPivots,
pivotPointCalculationType,
als.showPivots,
als.pivotPointCalculationType,
"=",
AlertMeWhen,
AlertNotificationType,
InpAlertMeWhen,
InpAlertNotificationType,
"=",
cis.MA1lineType,
cis.MA1period,
+20 -4
View File
@@ -1,5 +1,5 @@
//
// Copyright 2017-2018, Artur Zas
// Copyright 2017-2021, Artur Zas
// https://www.az-invest.eu
// https://www.mql5.com/en/users/arturz
//
@@ -732,8 +732,26 @@ bool CMarketOrder::ClosePartial(ulong ticket, double lots)
while(!IsStopped() && !result)
{
result = ctrade.PositionClosePartial(ticket, NormalizeLots(symbol,lots));
if(_IsNettingAccount()) // Netting account type
{
// open opposite position with volume = "lots" to do a parial close
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
result = this.Short(symbol,lots,0,0);
}
else if(type == POSITION_TYPE_SELL)
{
result = this.Long(symbol,lots,0,0);
}
}
else // Hedging account type
{
result = ctrade.PositionClosePartial(ticket, lots);
}
if(result)
{
Sleep(500);
@@ -1072,5 +1090,3 @@ void CMarketOrder::SetTradeId(ulong tradeId)
ctrade.SetExpertMagicNumber(tradeId);
}
+266
View File
@@ -0,0 +1,266 @@
//
// Copyright 2018-2021, Artur Zas
// https://www.az-invest.eu
// https://www.mql5.com/en/users/arturz
//
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
class CTradeManagerState
{
public:
void Clear() { DoneBreakEven = false; TrailStarted = false; DonePartialClose = false; };
// Break Even
bool DoneBreakEven;
// Trailing Stop
bool TrailStarted;
// Partial Close
bool DonePartialClose;
};
struct CTradeManagerParameters
{
// Break Even
int BEPoints;
// Trailing Stop
int TrailByPoints;
int TrailStartPoints;
// Partial Close
int PartialCloseAtProfitPoints;
int PartialClosePercentage;
};
class CTradeManager
{
private:
bool initialized;
CMarketOrder *orderHandler;
CTradeManagerParameters inputs;
ENUM_ORDER_TYPE __type;
double __open;
double __lots;
string __symbol;
double __tp;
double __sl;
double __bid;
double __ask;
public:
CTradeManager();
CTradeManager(CTradeManagerParameters &params, CMarketOrder *orderHalder);
~CTradeManager();
bool IsInitialized() { return this.initialized; };
bool Initialize(CTradeManagerParameters &params, CMarketOrder *orderHalder);
bool Manage(ulong ticket, CTradeManagerState &_state);
string ToString();
private:
bool GetTradeInfo(ulong ticket);
bool BreakEven(ulong ticket);
bool OkToTrailTheStop(ulong ticket);
bool TrailTheStop(ulong ticket);
bool PartialClose(ulong ticket, double lots);
double GetPartialCloseLotSize();
bool IsDistanceFromOpenReached(double distancePriceDiff);
ENUM_ORDER_TYPE GetType(ulong ticket);
};
CTradeManager::CTradeManager(void)
{
this.orderHandler = NULL;
this.initialized = false;
}
CTradeManager::CTradeManager(CTradeManagerParameters &params,CMarketOrder *_orderHandler)
{
this.orderHandler = NULL;
this.initialized = false;
Initialize(params, _orderHandler);
}
CTradeManager::~CTradeManager(void)
{
}
bool CTradeManager::GetTradeInfo(ulong ticket)
{
__type = GetType(ticket);
__open = PositionGetDouble(POSITION_PRICE_OPEN);
if(__open == 0)
return false;
__lots = PositionGetDouble(POSITION_VOLUME);
__symbol = PositionGetString(POSITION_SYMBOL);
__tp = PositionGetDouble(POSITION_TP);
__sl = PositionGetDouble(POSITION_SL);
__bid = SymbolInfoDouble(__symbol,SYMBOL_BID);
__ask = SymbolInfoDouble(__symbol,SYMBOL_ASK);
return true;
}
bool CTradeManager::Initialize(CTradeManagerParameters &params, CMarketOrder *_orderHandler)
{
// Dependency injection
this.orderHandler = _orderHandler;
if(this.orderHandler == NULL)
{
Print(__FUNCTION__," failed on orderHandler == NULL");
return false;
}
//
this.inputs = params;
// normalize inputs
this.inputs.PartialClosePercentage = MathMin(MathAbs(this.inputs.PartialClosePercentage), 100);
//
this.initialized = true;
return initialized;
}
bool CTradeManager::Manage(ulong ticket, CTradeManagerState &_state)
{
if(!GetTradeInfo(ticket))
return false; // trade info not available
if(!_state.DonePartialClose)
{
_state.DonePartialClose = PartialClose(ticket, GetPartialCloseLotSize());
}
if(!_state.DoneBreakEven)
{
if(BreakEven(ticket))
_state.DoneBreakEven = true;
}
if(!_state.TrailStarted)
{
_state.TrailStarted = OkToTrailTheStop(ticket);
}
if(_state.TrailStarted)
{
TrailTheStop(ticket);
}
return true;
}
bool CTradeManager::PartialClose(ulong ticket, double lots)
{
if(this.inputs.PartialCloseAtProfitPoints == 0 || lots == 0)
return false; // nothing to do
double _partialCloseDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.PartialCloseAtProfitPoints;
if(!IsDistanceFromOpenReached(_partialCloseDistance))
return false;
return orderHandler.ClosePartial(ticket, lots);
}
bool CTradeManager::BreakEven(ulong ticket)
{
if(this.inputs.BEPoints == 0)
return false; // nothing to do
double _beDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.BEPoints;
if(!IsDistanceFromOpenReached(_beDistance))
return false;
return orderHandler.Modify(ticket,__open,__tp);
}
bool CTradeManager::OkToTrailTheStop(ulong ticket)
{
if(this.inputs.TrailByPoints == 0)
return false; // nothing to do
double _startDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.TrailStartPoints;
if(!IsDistanceFromOpenReached(_startDistance))
return false;
return true;
}
bool CTradeManager::TrailTheStop(ulong ticket)
{
if(this.inputs.TrailByPoints == 0)
return false; // nothing to do
double _trailDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.TrailByPoints;
double _sl = __sl;
bool okToModify = false;
if(__type == ORDER_TYPE_BUY)
{
_sl = (__bid - _trailDistance);
if(_sl > __sl)
okToModify = true;
}
else if(__type == ORDER_TYPE_SELL)
{
_sl = (__ask + _trailDistance);
if(_sl < __sl)
okToModify = true;
}
if(okToModify)
return orderHandler.Modify(ticket,_sl,__tp);
return false;
}
ENUM_ORDER_TYPE CTradeManager::GetType(ulong ticket)
{
ENUM_POSITION_TYPE _pType;
orderHandler.GetPositionType(ticket,_pType);
return orderHandler.TradeBias((ENUM_ORDER_TYPE)_pType);
}
double CTradeManager::GetPartialCloseLotSize()
{
double lotsToClose = (__lots * inputs.PartialClosePercentage) / 100;
return NormalizeLots(__symbol, lotsToClose);
}
bool CTradeManager::IsDistanceFromOpenReached(double distancePriceDiff)
{
if(__type == ORDER_TYPE_BUY)
{
if((__bid - distancePriceDiff) >= __open)
return true;
}
else if(__type == ORDER_TYPE_SELL)
{
if((__ask + distancePriceDiff) <= __open)
return true;
}
return false;
}
string CTradeManager::ToString()
{
string _be = (inputs.BEPoints > 0) ? "[BE ON] " : "[BE off] ";
string _trail = (inputs.TrailByPoints > 0) ? "[Trail ON] ": "[Trail off] ";
string _partial = (inputs.PartialCloseAtProfitPoints > 0) ? "[Partial "+(string)inputs.PartialClosePercentage+"%] ": "[Partial off] ";
return _be+_trail+_partial;
}