Updated for ver.3.16
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ¶ms, CMarketOrder *orderHalder);
|
||||
~CTradeManager();
|
||||
|
||||
bool IsInitialized() { return this.initialized; };
|
||||
bool Initialize(CTradeManagerParameters ¶ms, 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 ¶ms,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 ¶ms, 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;
|
||||
}
|
||||
Reference in New Issue
Block a user