Skip to content

Instantly share code, notes, and snippets.

@calvez
Created May 23, 2020 04:55
Show Gist options
  • Save calvez/9fae08213f4c2871ca9bf4f31d2d38f6 to your computer and use it in GitHub Desktop.
Save calvez/9fae08213f4c2871ca9bf4f31d2d38f6 to your computer and use it in GitHub Desktop.
// Base EA template
// More templates and snippets on https://github.com/sibvic/mq4-templates
// You need:
// 1. To implement LongCondition, ShortCondition, ExitLongCondition and ExitShortCondition
// 2. To replace all includes with code from the snippets folder. You can use https://github.com/sibvic/MQ4Inject for that.
#property version "1.0"
#property description "Developed by Victor Tereschenko: sibvic@gmail.com"
#property strict
#define ACT_ON_SWITCH_CONDITION
#define SHOW_ACCOUNT_STAT
#define REVERSABLE_LOGIC_FEATURE
#define STOP_LOSS_FEATURE
#define NET_STOP_LOSS_FEATURE
#define USE_NET_BREAKEVEN
#define TAKE_PROFIT_FEATURE
#define NET_TAKE_PROFIT_FEATURE
#define MARTINGALE_FEATURE
#define USE_MARKET_ORDERS
#define WEEKLY_TRADING_TIME_FEATURE
#define TRADING_TIME_FEATURE
#define POSITION_CAP_FEATURE
#define WITH_EXIT_LOGIC
#ifdef SHOW_ACCOUNT_STAT
string EA_NAME = "[sibvic EA Base ]";
#endif
enum TradingMode
{
TradingModeLive, // Live
TradingModeOnBarClose // On bar close
};
input string GeneralSection = ""; // == General ==
input string GeneralSectionDesc = "https://github.com/sibvic/mq4-templates/wiki/EA_Base-template-parameters"; // Description of parameters could be found at
input ENUM_TIMEFRAMES trading_timeframe = PERIOD_CURRENT; // Trading timeframe
input bool ecn_broker = false; // ECN Broker?
input TradingMode entry_logic = TradingModeLive; // Entry logic
#ifdef WITH_EXIT_LOGIC
input TradingMode exit_logic = TradingModeLive; // Exit logic
#endif
#include <Enums/PositionSizeType.mq4>
enum LogicDirection
{
DirectLogic, // Direct
ReversalLogic // Reversal
};
enum TradingSide
{
LongSideOnly, // Long
ShortSideOnly, // Short
BothSides // Both
};
input double lots_value = 0.1; // Position size
input PositionSizeType lots_type = PositionSizeContract; // Position size type
input int slippage_points = 3; // Slippage, points
input TradingSide trading_side = BothSides; // What trades should be taken
#ifdef REVERSABLE_LOGIC_FEATURE
input LogicDirection logic_direction = DirectLogic; // Logic type
#else
LogicDirection logic_direction = DirectLogic;
#endif
#ifdef USE_MARKET_ORDERS
input bool close_on_opposite = true; // Close on opposite signal
#else
bool close_on_opposite = false;
#endif
#ifdef POSITION_CAP_FEATURE
input string CapSection = ""; // == Position cap ==
input bool position_cap = false; // Position Cap
input int no_of_positions = 1; // Max # of buy+sell positions
input int no_of_buy_position = 1; // Max # of buy positions
input int no_of_sell_position = 1; // Max # of sell positions
#endif
enum MartingaleType
{
MartingaleDoNotUse, // Do not use
MartingaleOnLoss // Open another position on loss
};
enum MartingaleLotSizingType
{
MartingaleLotSizingNo, // No lot sizing
MartingaleLotSizingMultiplicator, // Using miltiplicator
MartingaleLotSizingAdd // Addition
};
enum MartingaleStepSizeType
{
MartingaleStepSizePips, // Pips
MartingaleStepSizePercent, // %
};
#ifdef MARTINGALE_FEATURE
input string MartingaleSection = ""; // == Martingale type ==
input MartingaleType martingale_type = MartingaleDoNotUse; // Martingale type
input MartingaleLotSizingType martingale_lot_sizing_type = MartingaleLotSizingNo; // Martingale lot sizing type
input double martingale_lot_value = 1.5; // Matringale lot sizing value
input MartingaleStepSizeType martingale_step_type = MartingaleStepSizePercent; // Step unit
input double martingale_step = 5; // Open matringale position step
#endif
enum TrailingType
{
TrailingDontUse, // No trailing
TrailingPips // Use trailing in pips
};
#include <Enums/StopLossType.mq4>
#include <Enums/StopLimitType.mq4>
#ifdef STOP_LOSS_FEATURE
string StopLossSection = ""; // == Stop loss ==
input StopLossType stop_loss_type = SLDoNotUse; // Stop loss type
input double stop_loss_value = 10; // Stop loss value
input TrailingType trailing_type = TrailingDontUse; // Trailing type
input double trailing_step = 10; // Trailing step
input double trailing_start = 0; // Min distance to order to activate the trailing
#else
StopLossType stop_loss_type = SLDoNotUse; // Stop loss type
double stop_loss_value = 10;
#endif
input StopLimitType breakeven_type = StopLimitDoNotUse; // Trigger type for the breakeven
input double breakeven_value = 10; // Trigger for the breakeven
input double breakeven_level = 0; // Breakeven target
#ifdef NET_STOP_LOSS_FEATURE
input StopLimitType net_stop_loss_type = StopLimitDoNotUse; // Net stop loss type
input double net_stop_loss_value = 10; // Net stop loss value
#endif
enum TakeProfitType
{
TPDoNotUse, // Do not use
TPPercent, // Set in %
TPPips, // Set in Pips
TPDollar, // Set in $,
TPRiskReward, // Set in % of stop loss
TPAbsolute, // Set in absolite value (rate),
TPAtr // Set in ATR(value) * mult
};
#ifdef TAKE_PROFIT_FEATURE
input string TakeProfitSection = ""; // == Take Profit ==
input TakeProfitType take_profit_type = TPDoNotUse; // Take profit type
input double take_profit_value = 10; // Take profit value
input double take_profit_atr_multiplicator = 1; // Take profit multiplicator (for ATR TP)
#else
TakeProfitType take_profit_type = TPDoNotUse;
double take_profit_value = 10;
#endif
#ifdef NET_TAKE_PROFIT_FEATURE
input StopLimitType net_take_profit_type = StopLimitDoNotUse; // Net take profit type
input double net_take_profit_value = 10; // Net take profit value
#endif
#include <enums/DayOfWeek.mq4>
input string OtherSection = ""; // == Other ==
input int magic_number = 42; // Magic number
#ifdef TRADING_TIME_FEATURE
input string start_time = "000000"; // Start time in hhmmss format
input string stop_time = "000000"; // Stop time in hhmmss format
input bool mandatory_closing = false; // Mandatory closing for non-trading time
#endif
#ifdef WEEKLY_TRADING_TIME_FEATURE
input bool use_weekly_timing = false; // Weekly time
input DayOfWeek week_start_day = DayOfWeekSunday; // Start day
input string week_start_time = "000000"; // Start time in hhmmss format
input DayOfWeek week_stop_day = DayOfWeekSaturday; // Stop day
input string week_stop_time = "235959"; // Stop time in hhmmss format
#else
bool use_weekly_timing = false; // Weekly time
DayOfWeek week_start_day = DayOfWeekSunday; // Start day
string week_start_time = "000000"; // Start time in hhmmss format
DayOfWeek week_stop_day = DayOfWeekSaturday; // Stop day
string week_stop_time = "235959"; // Stop time in hhmmss format
#endif
input bool print_log = false; // Print decisions into the log
input string log_file = "log.csv"; // Log file name
#include <Signaler.mq4>
#include <InstrumentInfo.mq4>
#include <conditions/ActOnSwitchCondition.mq4>
#include <conditions/DisabledCondition.mq4>
#include <Streams/AStream.mq4>
#ifndef USE_MARKET_ORDERS
class LongEntryStream : public AStream
{
public:
LongEntryStream(const string symbol, const ENUM_TIMEFRAMES timeframe)
:AStream(symbol, timeframe)
{
}
bool GetValue(const int period, double &val)
{
val = iHigh(_symbol, _timeframe, period);
return true;
}
};
class ShortEntryStream : public AStream
{
public:
ShortEntryStream(const string symbol, const ENUM_TIMEFRAMES timeframe)
:AStream(symbol, timeframe)
{
}
bool GetValue(const int period, double &val)
{
val = iHigh(_symbol, _timeframe, period);
return true;
}
};
#endif
#include <OrdersIterator.mq4>
#include <TradingCalculator.mq4>
#include <Order.mq4>
#include <Actions/AAction.mq4>
#include <Logic/ActionOnConditionController.mq4>
#include <Logic/ActionOnConditionLogic.mq4>
#include <Conditions/HitProfitCondition.mq4>
#include <Actions/MoveNetStopLossAction.mq4>
#include <Actions/MoveNetTakeProfitAction.mq4>
#include <MoneyManagement/ILotsProvider.mq4>
#include <MoneyManagement/IStopLossStrategy.mq4>
#include <MoneyManagement/DollarStopLossStrategy.mq4>
#include <MoneyManagement/RiskLotsProvider.mq4>
#include <MoneyManagement/HighLowStopLossStrategy.mq4>
#include <MoneyManagement/DefaultStopLossStrategy.mq4>
#include <MoneyManagement/DefaultLotsProvider.mq4>
#include <MoneyManagement/MoneyManagementStrategy.mq4>
#include <MoneyManagement/RiskToRewardTakeProfitStrategy.mq4>
#include <MoneyManagement/DefaultTakeProfitStrategy.mq4>
#include <MoneyManagement/ATRTakeProfitStrategy.mq4>
#include <MartingaleStrategy.mq4>
#include <TradingCommands.mq4>
#include <CloseOnOpposite.mq4>
#include <PositionCap.mq4>
#include <OrderBuilder.mq4>
#include <MarketOrderBuilder.mq4>
#include <EntryStrategy.mq4>
#include <Actions/MoveStopLossOnProfitOrderAction.mq4>
#include <TradingController.mq4>
#include <Conditions/NoCondition.mq4>
#include <AccountStatistics.mq4>
TradingController *controllers[];
#ifdef SHOW_ACCOUNT_STAT
AccountStatistics *stats;
#endif
#include <actions/CreateTrailingAction.mq4>
#include <actions/CloseAllAction.mq4>
#include <conditions/ACondition.mq4>
#include <conditions/TradingTimeCondition.mq4>
#include <conditions/AndCondition.mq4>
#include <conditions/OrCondition.mq4>
#include <conditions/NotCondition.mq4>
#include <conditions/PriceMovedFromTradeOpenCondition.mq4>
class LongCondition : public ACondition
{
public:
LongCondition(const string symbol, ENUM_TIMEFRAMES timeframe)
:ACondition(symbol, timeframe)
{
}
bool IsPass(const int period, const datetime date)
{
//TODO: implement
return false;
}
};
class ShortCondition : public ACondition
{
public:
ShortCondition(const string symbol, ENUM_TIMEFRAMES timeframe)
:ACondition(symbol, timeframe)
{
}
bool IsPass(const int period, const datetime date)
{
//TODO: implement
return false;
}
};
class ExitLongCondition : public ACondition
{
public:
ExitLongCondition(const string symbol, ENUM_TIMEFRAMES timeframe)
:ACondition(symbol, timeframe)
{
}
bool IsPass(const int period, const datetime date)
{
//TODO: implement
return false;
}
};
class ExitShortCondition : public ACondition
{
public:
ExitShortCondition(const string symbol, ENUM_TIMEFRAMES timeframe)
:ACondition(symbol, timeframe)
{
}
bool IsPass(const int period, const datetime date)
{
//TODO: implement
return false;
}
};
ICondition* CreateLongCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
if (trading_side == ShortSideOnly)
{
return (ICondition *)new DisabledCondition();
}
AndCondition* condition = new AndCondition();
condition.Add(new LongCondition(symbol, timeframe), false);
#ifdef ACT_ON_SWITCH_CONDITION
ActOnSwitchCondition* switchCondition = new ActOnSwitchCondition(symbol, timeframe, (ICondition*) condition);
condition.Release();
return switchCondition;
#else
return (ICondition*) condition;
#endif
}
ICondition* CreateLongFilterCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
if (trading_side == ShortSideOnly)
{
return (ICondition *)new DisabledCondition();
}
AndCondition* condition = new AndCondition();
condition.Add(new NoCondition(), false);
return condition;
}
ICondition* CreateShortCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
if (trading_side == LongSideOnly)
{
return (ICondition *)new DisabledCondition();
}
AndCondition* condition = new AndCondition();
condition.Add(new ShortCondition(symbol, timeframe), false);
#ifdef ACT_ON_SWITCH_CONDITION
ActOnSwitchCondition* switchCondition = new ActOnSwitchCondition(symbol, timeframe, (ICondition*) condition);
condition.Release();
return switchCondition;
#else
return (ICondition*) condition;
#endif
}
ICondition* CreateShortFilterCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
if (trading_side == LongSideOnly)
{
return (ICondition *)new DisabledCondition();
}
AndCondition* condition = new AndCondition();
condition.Add(new NoCondition(), false);
return condition;
}
ICondition* CreateExitLongCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
AndCondition* condition = new AndCondition();
condition.Add(new ExitLongCondition(symbol, timeframe), false);
#ifdef ACT_ON_SWITCH_CONDITION
ActOnSwitchCondition* switchCondition = new ActOnSwitchCondition(symbol, timeframe, (ICondition*) condition);
condition.Release();
return switchCondition;
#else
return (ICondition *)condition;
#endif
}
ICondition* CreateExitShortCondition(string symbol, ENUM_TIMEFRAMES timeframe)
{
AndCondition* condition = new AndCondition();
condition.Add(new ExitShortCondition(symbol, timeframe), false);
#ifdef ACT_ON_SWITCH_CONDITION
ActOnSwitchCondition* switchCondition = new ActOnSwitchCondition(symbol, timeframe, (ICondition*) condition);
condition.Release();
return switchCondition;
#else
return (ICondition *)condition;
#endif
}
IStopLossStrategy* CreateStopLossStrategy(TradingCalculator* tradingCalculator, string symbol,
ENUM_TIMEFRAMES timeframe, bool isBuy)
{
switch (stop_loss_type)
{
case SLDoNotUse:
return new DefaultStopLossStrategy(tradingCalculator, StopLimitDoNotUse, stop_loss_value, isBuy);
case SLPercent:
return new DefaultStopLossStrategy(tradingCalculator, StopLimitPercent, stop_loss_value, isBuy);
case SLPips:
return new DefaultStopLossStrategy(tradingCalculator, StopLimitPips, stop_loss_value, isBuy);
case SLAbsolute:
return new DefaultStopLossStrategy(tradingCalculator, StopLimitAbsolute, stop_loss_value, isBuy);
case SLHighLow:
return new HighLowStopLossStrategy((int)stop_loss_value, isBuy, symbol, timeframe);
case SLAtr:
return NULL; // Not supported yet
case SLDollar:
return NULL; // Not supported at all
}
return NULL;
}
MoneyManagementStrategy* CreateMoneyManagementStrategy(TradingCalculator* tradingCalculator, string symbol,
ENUM_TIMEFRAMES timeframe, bool isBuy)
{
ILotsProvider* lots = NULL;
IStopLossStrategy* stopLoss = NULL;
switch (lots_type)
{
case PositionSizeRisk:
stopLoss = CreateStopLossStrategy(tradingCalculator, symbol, timeframe, isBuy);
lots = new RiskLotsProvider(tradingCalculator, lots_type, lots_value, stopLoss);
break;
default:
lots = new DefaultLotsProvider(tradingCalculator, lots_type, lots_value);
switch (stop_loss_type)
{
case SLDollar:
stopLoss = new DollarStopLossStrategy(tradingCalculator, StopLimitDollar, stop_loss_value, isBuy, lots);
break;
default:
stopLoss = CreateStopLossStrategy(tradingCalculator, symbol, timeframe, isBuy);
break;
}
break;
}
ITakeProfitStrategy* tp = NULL;
switch (take_profit_type)
{
case TPDoNotUse:
tp = new DefaultTakeProfitStrategy(tradingCalculator, StopLimitDoNotUse, take_profit_value, isBuy);
break;
#ifdef TAKE_PROFIT_FEATURE
case TPPercent:
tp = new DefaultTakeProfitStrategy(tradingCalculator, StopLimitPercent, take_profit_value, isBuy);
break;
case TPPips:
tp = new DefaultTakeProfitStrategy(tradingCalculator, StopLimitPips, take_profit_value, isBuy);
break;
case TPDollar:
tp = new DefaultTakeProfitStrategy(tradingCalculator, StopLimitDollar, take_profit_value, isBuy);
break;
case TPRiskReward:
tp = new RiskToRewardTakeProfitStrategy(take_profit_value, isBuy);
break;
case TPAbsolute:
tp = new DefaultTakeProfitStrategy(tradingCalculator, StopLimitAbsolute, take_profit_value, isBuy);
break;
case TPAtr:
tp = new ATRTakeProfitStrategy(symbol, timeframe, (int)take_profit_value, take_profit_atr_multiplicator, isBuy);
break;
#endif
}
return new MoneyManagementStrategy(lots, stopLoss, tp);
}
TradingController *CreateController(const string symbol, const ENUM_TIMEFRAMES timeframe, string &error)
{
#ifdef TRADING_TIME_FEATURE
ICondition* tradingTimeCondition = CreateTradingTimeCondition(start_time, stop_time, use_weekly_timing,
week_start_day, week_start_time, week_stop_day,
week_stop_time, error);
if (tradingTimeCondition == NULL)
return NULL;
#endif
TradingCalculator* tradingCalculator = TradingCalculator::Create(symbol);
if (!tradingCalculator.IsLotsValid(lots_value, lots_type, error))
{
tradingTimeCondition.Release();
delete tradingCalculator;
return NULL;
}
Signaler* signaler = new Signaler(symbol, timeframe);
signaler.SetMessagePrefix(symbol + "/" + signaler.GetTimeframeStr() + ": ");
TradingController* controller = new TradingController(tradingCalculator, timeframe, timeframe, signaler);
ActionOnConditionLogic* actions = new ActionOnConditionLogic();
controller.SetActions(actions);
controller.SetECNBroker(ecn_broker);
if (breakeven_type != StopLimitDoNotUse)
{
#ifndef USE_NET_BREAKEVEN
MoveStopLossOnProfitOrderAction* orderAction = new MoveStopLossOnProfitOrderAction(breakeven_type, breakeven_value, breakeven_level, signaler, actions);
controller.AddOrderAction(orderAction);
orderAction.Release();
#endif
}
#ifdef STOP_LOSS_FEATURE
switch (trailing_type)
{
case TrailingDontUse:
break;
#ifdef INDICATOR_BASED_TRAILING
case TrailingIndicator:
break;
#endif
case TrailingPips:
{
CreateTrailingAction* trailingAction = new CreateTrailingAction(trailing_start, trailing_step, actions);
controller.AddOrderAction(trailingAction);
trailingAction.Release();
}
break;
}
#endif
#ifdef MARTINGALE_FEATURE
switch (martingale_type)
{
case MartingaleDoNotUse:
controller.SetShortMartingaleStrategy(new NoMartingaleStrategy());
controller.SetLongMartingaleStrategy(new NoMartingaleStrategy());
break;
case MartingaleOnLoss:
{
PriceMovedFromTradeOpenCondition* condition = new PriceMovedFromTradeOpenCondition(symbol, timeframe, martingale_step_type, martingale_step);
controller.SetShortMartingaleStrategy(new ActiveMartingaleStrategy(tradingCalculator, martingale_lot_sizing_type, martingale_lot_value, condition));
controller.SetLongMartingaleStrategy(new ActiveMartingaleStrategy(tradingCalculator, martingale_lot_sizing_type, martingale_lot_value, condition));
condition.Release();
}
break;
}
#endif
AndCondition* longCondition = new AndCondition();
longCondition.Add(CreateLongCondition(symbol, timeframe), false);
AndCondition* shortCondition = new AndCondition();
shortCondition.Add(CreateShortCondition(symbol, timeframe), false);
#ifdef TRADING_TIME_FEATURE
longCondition.Add(tradingTimeCondition, true);
shortCondition.Add(tradingTimeCondition, true);
#endif
tradingTimeCondition.Release();
ICondition* longFilterCondition = CreateLongFilterCondition(symbol, timeframe);
ICondition* shortFilterCondition = CreateShortFilterCondition(symbol, timeframe);
#ifdef WITH_EXIT_LOGIC
controller.SetExitLogic(exit_logic);
ICondition* exitLongCondition = CreateExitLongCondition(symbol, timeframe);
ICondition* exitShortCondition = CreateExitShortCondition(symbol, timeframe);
#else
ICondition* exitLongCondition = new DisabledCondition();
ICondition* exitShortCondition = new DisabledCondition();
#endif
switch (logic_direction)
{
case DirectLogic:
controller.SetLongCondition(longCondition);
controller.SetLongFilterCondition(longFilterCondition);
controller.SetShortCondition(shortCondition);
controller.SetShortFilterCondition(shortFilterCondition);
controller.SetExitLongCondition(exitLongCondition);
controller.SetExitShortCondition(exitShortCondition);
break;
case ReversalLogic:
controller.SetLongCondition(shortCondition);
controller.SetLongFilterCondition(shortFilterCondition);
controller.SetShortCondition(longCondition);
controller.SetShortFilterCondition(longFilterCondition);
controller.SetExitLongCondition(exitShortCondition);
controller.SetExitShortCondition(exitLongCondition);
break;
}
if (mandatory_closing)
{
NotCondition* condition = new NotCondition(tradingTimeCondition);
IAction* action = new CloseAllAction(magic_number, slippage_points);
actions.AddActionOnCondition(action, condition);
action.Release();
condition.Release();
}
IMoneyManagementStrategy* longMoneyManagement = CreateMoneyManagementStrategy(tradingCalculator, symbol, timeframe, true);
IMoneyManagementStrategy* shortMoneyManagement = CreateMoneyManagementStrategy(tradingCalculator, symbol, timeframe, false);
controller.AddLongMoneyManagement(longMoneyManagement);
controller.AddShortMoneyManagement(shortMoneyManagement);
#ifdef NET_STOP_LOSS_FEATURE
if (net_stop_loss_type != StopLimitDoNotUse)
{
MoveNetStopLossAction* action = new MoveNetStopLossAction(tradingCalculator, net_stop_loss_type, net_stop_loss_value, magic_number);
#ifdef USE_NET_BREAKEVEN
if (breakeven_type != StopLimitDoNotUse)
{
//TODO: use breakeven_type as well
action.SetBreakeven(breakeven_value, breakeven_level);
}
#endif
NoCondition* condition = new NoCondition();
actions.AddActionOnCondition(action, condition);
action.Release();
condition.Release();
}
#endif
#ifdef NET_TAKE_PROFIT_FEATURE
if (net_take_profit_type != StopLimitDoNotUse)
{
IAction* action = new MoveNetTakeProfitAction(tradingCalculator, net_take_profit_type, net_take_profit_value, magic_number);
NoCondition* condition = new NoCondition();
actions.AddActionOnCondition(action, condition);
action.Release();
condition.Release();
}
#endif
if (close_on_opposite)
controller.SetCloseOnOpposite(new DoCloseOnOppositeStrategy(slippage_points, magic_number));
else
controller.SetCloseOnOpposite(new DontCloseOnOppositeStrategy());
#ifdef POSITION_CAP_FEATURE
if (position_cap)
{
controller.SetLongPositionCap(new PositionCapStrategy(BuySide, magic_number, no_of_buy_position, no_of_positions, symbol));
controller.SetShortPositionCap(new PositionCapStrategy(SellSide, magic_number, no_of_sell_position, no_of_positions, symbol));
}
else
{
controller.SetLongPositionCap(new NoPositionCapStrategy());
controller.SetShortPositionCap(new NoPositionCapStrategy());
}
#endif
controller.SetEntryLogic(entry_logic);
#ifdef USE_MARKET_ORDERS
controller.SetEntryStrategy(new MarketEntryStrategy(symbol, magic_number, slippage_points, actions));
#else
AStream *longPrice = new LongEntryStream(symbol, timeframe);
AStream *shortPrice = new ShortEntryStream(symbol, timeframe);
controller.SetEntryStrategy(new PendingEntryStrategy(symbol, magic_number, slippage_points, longPrice, shortPrice, actions));
#endif
if (print_log)
{
controller.SetPrintLog(log_file);
}
return controller;
}
int OnInit()
{
#ifdef SHOW_ACCOUNT_STAT
stats = NULL;
#endif
if (!IsDllsAllowed() && advanced_alert)
{
Print("Error: Dll calls must be allowed!");
return INIT_FAILED;
}
#ifdef MARTINGALE_FEATURE
if (lots_type == PositionSizeRisk && martingale_type == MartingaleOnLoss)
{
Print("Error: martingale_type couldn't be used with this lot type!");
return INIT_FAILED;
}
#endif
string error;
TradingController *controller = CreateController(_Symbol, trading_timeframe, error);
if (controller == NULL)
{
Print(error);
return INIT_FAILED;
}
int controllersCount = 0;
ArrayResize(controllers, controllersCount + 1);
controllers[controllersCount++] = controller;
#ifdef SHOW_ACCOUNT_STAT
stats = new AccountStatistics(EA_NAME);
#endif
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
#ifdef SHOW_ACCOUNT_STAT
delete stats;
#endif
int i_count = ArraySize(controllers);
for (int i = 0; i < i_count; ++i)
{
delete controllers[i];
}
}
void OnTick()
{
int i_count = ArraySize(controllers);
for (int i = 0; i < i_count; ++i)
{
controllers[i].DoTrading();
}
#ifdef SHOW_ACCOUNT_STAT
stats.Update();
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment