While I'm not entirely new to coding I'm no pro either. I'm trying to code an EA that trades based on a basic Donchian Channel strategy, where I place a buy order when the price closes above the upper band, and closes that order when it touches the middle band. The short will open when the price is below the lower band, and close when the price touches the middle band. And we don't open any new orders until the previously opened position is closed.
The EA currently only places 7 trades and then just stops. It closes them improperly and I don't believe its respecting the stop losses.
Here is my code. Any tips would be greatly appreciated!
//+------------------------------------------------------------------+//| Donchian-Trader.mq4 |//+------------------------------------------------------------------+#property version"1.00"#property strict// Declare external variables.externint MinPipLimit = 0;
externint TakeProfit = 40;
externint StopLoss = 40;
externdouble Lots = 1;
externint Magic = 1;
externbool ECNExecution = false;
externbool UseTrailingSL = false;
externint TrailValue = 40;
externbool AutoAdjustTo5Digits = false;
externint DonchianBarsToCount = 20;
externint Slippage;
double MyPoint;
double dUpper = iCustom(NULL, 0, "DonchianChannels", 20, 0, 0);
double dMiddle = iCustom(NULL, 0, "DonchianChannels", 20, 1, 0);
double dLower = iCustom(NULL, 0, "DonchianChannels", 20, 2, 0);
//On init, lets adjust to a 5 digit broker, if necessaryvoidOnInit()
{
SetMyPoint();
}
voidOnTick()
{
staticbool IsFirstTick = true;
staticbool ReadyForNewOrder = true;
staticint ticket = 0;
string comment;
//Order Execution
comment = GetDateAndTime();
//FindTicket makes sure that the EA will pick up its orders//even if it is relaunched
ticket = FindTicket(Magic);
bool res;
res = OrderSelect(ticket, SELECT_BY_TICKET);
//If an open position exists, lets see if we can close it.if (res == true)
{
if (OrderCloseTime() == 0)
{
//No new orders until the open position is closed
ReadyForNewOrder = false;
// Select the open orderint SelectedOrder = OrderSelect(ticket, SELECT_BY_TICKET);
//Lets get our long positions and do something.if (OrderType() == OP_BUY)
{
//Long order should close when the price is less than or equal to the middle Donchian band.if (Open[0] <= dMiddle)
{
//Lets close the order and store the result in a boolean.bool res2;
res2 = OrderClose(ticket, OrderLots(), OrderClosePrice(), 10);
if (res2)
{
ReadyForNewOrder = true;
}
}
}
//Lets get our short position and do something.elseif (OrderType() == OP_SELL)
{
//Short order should close when the price is greater than or equal to the middle Donchian bandif (Open[0] >= dMiddle)
{
//Lets close the order and store the result in a boolean.bool res2;
res2 = OrderClose(ticket, OrderLots(), OrderClosePrice(), 10);
if (res2)
{
ReadyForNewOrder = true;
}
}
}
}
}
//When all our open positions are closed, lets start a new order.if (ReadyForNewOrder == true)
{
//Open a long position when the price is greater than or equal to the upper band.if (Open[0] >= dUpper)
{
ticket = MarketOrderSend(Symbol(), OP_BUY, Lots, ND(Ask), 10 * int(MyPoint / Point()), ND(Bid - StopLoss * MyPoint), ND(Bid + TakeProfit * MyPoint), "Set by SimpleSystem", Magic);
//Check if the order was sent successfullyif (ticket < 0)
{
comment = comment + " " + "Error Sending BUY Order";
}
else
{
comment = comment + " " + "BUY Order Executed Succesfuly";
}
}
//Open a short position when the price is less than or equal to the lower band.elseif (Open[0] <= dLower)
{
ticket = MarketOrderSend(Symbol(), OP_SELL, Lots, ND(Ask), 10 * int(MyPoint / Point()), ND(Bid - StopLoss * MyPoint), ND(Bid + TakeProfit * MyPoint), "Set by SimpleSystem", Magic);
if (ticket < 0)
{
comment = comment + " " + "Error Sending SELL Order";
}
else
{
comment = comment + " " + "SELL Order Executed Succesfully";
}
}
}
//Print resultsComment(comment);
Print(comment);
//execute trailing stop - this has to be done on every tickif (UseTrailingSL == true)
{
//FindTicket makes sure that the EA will pick up its orders//even if it is relaunchedint ticket_trailing = FindTicket(Magic);
if (ticket_trailing > 0)
{
TrailingStop(ticket_trailing);
}
}
}
/*
-------------------------------
Auxiliary Functions
-------------------------------
*/int FindTicket(int M)
{
int ret = 0;
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
bool res;
res = OrderSelect(i, SELECT_BY_POS);
if (res == true)
{
if (OrderMagicNumber() == M)
{
ret = OrderTicket();
break;
}
}
}
return (ret);
}
string GetDateAndTime()
{
return (string(Year()) + "-" + StringFormat("%02d", Month()) + "-" + StringFormat("%02d", Day()) + " " + StringFormat("%02d", Hour()) + ":" + StringFormat("%02d", Minute()));
}
int MarketOrderSend(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic)
{
int ticket;
if (ECNExecution == false)
{
ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic);
if (ticket <= 0)
Alert("OrderSend Error: ", GetLastError());
return (ticket);
}
else
{
ticket = OrderSend(symbol, cmd, volume, price, slippage, 0, 0, comment, magic);
if (ticket <= 0)
Alert("OrderSend Error: ", GetLastError());
else
{
bool res = OrderModify(ticket, OrderOpenPrice(), stoploss, takeprofit, 0);
if (!res)
Alert("!!! ORDER #", ticket, " HAS NO STOPLOSS AND TAKEPROFIT --- ORDER MODIFY ERROR: ", GetLastError());
}
return (ticket);
}
}
void TrailingStop(int ticket)
{
bool res;
res = OrderSelect(ticket, SELECT_BY_TICKET);
if (res == true)
{
if (OrderType() == OP_BUY)
{
if (Bid - OrderStopLoss() > TrailValue * MyPoint) //adjust stop loss if it is too far
{
res = OrderModify(OrderTicket(), OrderOpenPrice(), ND(Bid - TrailValue * MyPoint), OrderTakeProfit(), 0);
if (!res)
{
Alert("TrailingStop OrderModify Error: ", GetLastError());
}
}
}
if (OrderType() == OP_SELL)
{
if (OrderStopLoss() - Ask > TrailValue * MyPoint) //adjust stop loss if it is too far
{
res = OrderModify(OrderTicket(), OrderOpenPrice(), ND(Ask + TrailValue * MyPoint), OrderTakeProfit(), 0);
if (!res)
{
Alert("TrailingStop OrderModify Error: ", GetLastError());
}
}
}
}
}
void SetMyPoint()
{
MyPoint = Point();
if (AutoAdjustTo5Digits == true && (Digits() == 3 || Digits() == 5))
{
Alert("Digits=", Digits(), " Broker quotes given in 5-digit mode. Old values of SL, TP and slippage will be multiplied by 10");
MyPoint = Point() * 10;
}
}
double ND(double val)
{
return (NormalizeDouble(val, Digits()));
}
Hi All,
While I'm not entirely new to coding I'm no pro either. I'm trying to code an EA that trades based on a basic Donchian Channel strategy, where I place a buy order when the price closes above the upper band, and closes that order when it touches the middle band. The short will open when the price is below the lower band, and close when the price touches the middle band. And we don't open any new orders until the previously opened position is closed.
The EA currently only places 7 trades and then just stops. It closes them improperly and I don't believe its respecting the stop losses.
Here is my code. Any tips would be greatly appreciated!