Forum on trading, automated trading systems and testing trading strategies
Hello,
Please EDIT your post and use the SRC button when you post code.
- Use SRC
- Use the debugger, or print out your variables, and find out why.

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
int LotDigits; //initialized in OnInit
int MagicNumber = 937422;
double TradeSize = 0.1;
int MaxSlippage = 3; //adjusted in OnInit
int MaxSlippage_;
bool crossed[2]; //initialized to true, used in function Cross
int MaxOpenTrades = 1000;
int MaxLongTrades = 1000;
int MaxShortTrades = 1000;
int MaxPendingOrders = 1000;
bool Hedging = true;
int OrderRetry = 5; //# of retries if sending order returns error
int OrderWait = 5; //# of seconds to wait if sending order returns error
double myPoint; //initialized in OnInit
int DEMA_handle;
double DEMA[];
int DEMA_handle2;
double DEMA2[];
bool Cross(int i, bool condition) //returns true if "condition" is true and was false in the previous call
{
bool ret = condition && !crossed[i];
crossed[i] = condition;
return(ret);
}
void myAlert(string type, string message)
{
if(type == "print")
Print(message);
else if(type == "error")
{
Print(type+" | MT5 EMA 12, 26 @ "+Symbol()+","+Period()+" | "+message);
}
else if(type == "order")
{
}
else if(type == "modify")
{
}
}
int TradesCount(ENUM_ORDER_TYPE type) //returns # of open trades for order type, current symbol and magic number
{
if(type <= 1)
{
if (PositionSelect(Symbol()) && PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetInteger(POSITION_TYPE) == type)
return(1);
else
return(0);
}
else
{
int result = 0;
int total = OrdersTotal();
for(int i = 0; i < total; i++)
{
if(OrderGetTicket(i) <= 0) continue;
if(OrderGetInteger(ORDER_MAGIC) != MagicNumber || OrderGetString(ORDER_SYMBOL) != Symbol() || OrderGetInteger(ORDER_TYPE) != type) continue;
result++;
}
return(result);
}
}
ulong myOrderSend(ENUM_ORDER_TYPE type, double price, double volume, string ordername) //send order, return ticket ("price" is irrelevant for market orders)
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(0);
int retries = 0;
int long_trades = TradesCount(ORDER_TYPE_BUY);
int short_trades = TradesCount(ORDER_TYPE_SELL);
int long_pending = TradesCount(ORDER_TYPE_BUY_LIMIT) + TradesCount(ORDER_TYPE_BUY_STOP) + TradesCount(ORDER_TYPE_BUY_STOP_LIMIT);
int short_pending = TradesCount(ORDER_TYPE_SELL_LIMIT) + TradesCount(ORDER_TYPE_SELL_STOP) + TradesCount(ORDER_TYPE_SELL_STOP_LIMIT);
string ordername_ = ordername;
if(ordername != "")
ordername_ = "("+ordername+")";
//test Hedging
if(!Hedging && ((type % 2 == 0 && short_trades + short_pending > 0) || (type % 2 == 1 && long_trades + long_pending > 0)))
{
myAlert("print", "Order"+ordername_+" not sent, hedging not allowed");
return(0);
}
//test maximum trades
if((type % 2 == 0 && long_trades >= MaxLongTrades)
|| (type % 2 == 1 && short_trades >= MaxShortTrades)
|| (long_trades + short_trades >= MaxOpenTrades)
|| (type > 1 && long_pending + short_pending >= MaxPendingOrders))
{
myAlert("print", "Order"+ordername_+" not sent, maximum reached");
return(0);
}
//prepare to send order
MqlTradeRequest request={0};
request.action = (type <= 1) ? TRADE_ACTION_DEAL : TRADE_ACTION_PENDING;
//set allowed filling type
int filling = (int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
if(request.action == TRADE_ACTION_DEAL && (filling & 1) != 1)
request.type_filling = ORDER_FILLING_IOC;
request.magic = MagicNumber;
request.symbol = Symbol();
request.volume = NormalizeDouble(volume, LotDigits);
request.sl = 0;
request.tp = 0;
request.deviation = MaxSlippage_;
request.type = type;
request.comment = ordername;
int expiration=(int)SymbolInfoInteger(Symbol(), SYMBOL_EXPIRATION_MODE);
if((expiration & SYMBOL_EXPIRATION_GTC) != SYMBOL_EXPIRATION_GTC)
{
request.type_time = ORDER_TIME_DAY;
request.type_filling = ORDER_FILLING_RETURN;
}
MqlTradeResult result={0};
while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
{
//refresh price before sending order
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
if(type == ORDER_TYPE_BUY)
price = last_tick.ask;
else if(type == ORDER_TYPE_SELL)
price = last_tick.bid;
else if(price < 0) //invalid price for pending order
{
myAlert("order", "Order"+ordername_+" not sent, invalid price for pending order");
return(0);
}
request.price = NormalizeDouble(price, Digits());
OrderSend(request, result);
if(!OrderSuccess(result.retcode))
{
myAlert("print", "OrderSend"+ordername_+" error: "+result.comment);
Sleep(OrderWait*1000);
}
retries++;
}
if(!OrderSuccess(result.retcode))
{
myAlert("error", "OrderSend"+ordername_+" failed "+(OrderRetry+1)+" times; error: "+result.comment);
return(0);
}
string typestr[8] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop", "Buy Stop Limit", "Sell Stop Limit"};
myAlert("order", "Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+MagicNumber);
return((type <= 1) ? result.deal : result.order);
}
void myOrderClose(ENUM_ORDER_TYPE type, int volumepercent, string ordername) //close open orders for current symbol, magic number and "type" (ORDER_TYPE_BUY or ORDER_TYPE_SELL)
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
if (type > 1)
{
myAlert("error", "Invalid type in myOrderClose");
return;
}
bool success = false;
string ordername_ = ordername;
if(ordername != "")
ordername_ = "("+ordername+")";
if (!PositionSelect(Symbol())) return;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber || PositionGetInteger(POSITION_TYPE) != type)
return;
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
double price = (type == ORDER_TYPE_SELL) ? last_tick.ask : last_tick.bid;
MqlTradeRequest request={0};
request.action = TRADE_ACTION_DEAL;
//set allowed filling type
int filling = (int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
if(request.action == TRADE_ACTION_DEAL && (filling & 1) != 1)
request.type_filling = ORDER_FILLING_IOC;
request.magic = MagicNumber;
request.symbol = Symbol();
request.volume = NormalizeDouble(PositionGetDouble(POSITION_VOLUME)*volumepercent * 1.0 / 100, LotDigits);
if (NormalizeDouble(request.volume, LotDigits) == 0) return;
request.price = NormalizeDouble(price, Digits());
request.sl = 0;
request.tp = 0;
request.deviation = MaxSlippage_;
request.type = 1-type; //opposite type
request.comment = ordername;
MqlTradeResult result={0};
OrderSend(request, result);
success = OrderSuccess(result.retcode);
if(!success)
{
myAlert("error", "OrderClose"+ordername_+" failed; error: "+result.comment);
}
string typestr[8] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop", "Buy Stop Limit", "Sell Stop Limit"};
if(success) myAlert("order", "Orders closed"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+MagicNumber);
}
bool OrderSuccess(uint retcode)
{
return(retcode == TRADE_RETCODE_PLACED || retcode == TRADE_RETCODE_DONE
|| retcode == TRADE_RETCODE_DONE_PARTIAL || retcode == TRADE_RETCODE_NO_CHANGES);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
MaxSlippage_ = MaxSlippage;
//initialize myPoint
myPoint = Point();
if(Digits() == 5 || Digits() == 3)
{
myPoint *= 10;
MaxSlippage_ *= 10;
}
//initialize LotDigits
double LotStep = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
if(LotStep >= 1) LotDigits = 0;
else if(LotStep >= 0.1) LotDigits = 1;
else if(LotStep >= 0.01) LotDigits = 2;
else LotDigits = 3;
int i;
//initialize crossed
for (i = 0; i < ArraySize(crossed); i++)
crossed[i] = true;
DEMA_handle = iDEMA(NULL, PERIOD_CURRENT, 12, 0, PRICE_CLOSE);
if(DEMA_handle < 0)
{
Print("The creation of iDEMA has failed: DEMA_handle=", INVALID_HANDLE);
Print("Runtime error = ", GetLastError());
return(INIT_FAILED);
}
DEMA_handle2 = iDEMA(NULL, PERIOD_CURRENT, 26, 0, PRICE_CLOSE);
if(DEMA_handle2 < 0)
{
Print("The creation of iDEMA has failed: DEMA_handle2=", INVALID_HANDLE);
Print("Runtime error = ", GetLastError());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
ulong ticket = 0;
double price;
if(CopyBuffer(DEMA_handle, 0, 0, 200, DEMA) <= 0) return;
ArraySetAsSeries(DEMA, true);
if(CopyBuffer(DEMA_handle2, 0, 0, 200, DEMA2) <= 0) return;
ArraySetAsSeries(DEMA2, true);
//Close Long Positions, instant signal is tested first
if(Cross(0, DEMA[0] < DEMA2[0]) //Double Exponential Moving Average crosses below Double Exponential Moving Average
)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
myOrderClose(ORDER_TYPE_BUY, 100, "");
else //not autotrading => only send alert
myAlert("order", "");
}
//Open Buy Order, instant signal is tested first
if(Cross(1, DEMA[0] > DEMA2[0]) //Double Exponential Moving Average crosses above Double Exponential Moving Average
)
{
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
price = last_tick.ask;
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
{
ticket = myOrderSend(ORDER_TYPE_BUY, price, TradeSize, "");
if(ticket == 0) return;
}
else //not autotrading => only send alert
myAlert("order", "");
}
}
//+------------------------------------------------------------------+[/code]