wonder833 Posted August 10, 2010 Report Share Posted August 10, 2010 Hi, I'm very new and I have never done coding before, was playing around with moving average strategy. The strategy is simple, buy position is triggered when one MA is above another, and same thing to sell position. The thing is I only want one trade to be triggered for one position. For example, if now buy position is triggered and then position is closed due to strategy condition is fulfilled. I do not want another buy position to trigger if the condition is fulfilled again. I want the EA to wait for sell signal, and open one sell position only. Then wait for buy position again. How can I do it? thx :) Quote Link to comment Share on other sites More sharing options...
chrisbenjy Posted August 10, 2010 Report Share Posted August 10, 2010 (edited) Here hope this helps: Paste this somewhere outside of any other methods/functions [size="1"]int LastTradeOP() //Function that finds the order type of the last trade { if(OrderSelect(0,SELECT_BY_POS,MODE_HISTORY)==true) //Selects the last trade from Account History { if(OrderType()==OP_BUY) { return(1); //LastTradeOP()==1 if it was a long trade } if(OrderType()==OP_SELL) { return(2); //LastTradeOP()==2 if it was a short trade } } return(0); //LastTradeOP()==0 if there are no trades }[/size] Add this to the long conditions [size="1"]&& (LastTradeOP()==2 || 0)) // One of the long conditions is that the last trade was a short or there was no trade[/size] Add this to the short conditions [size="1"]&& (LastTradeOP()==1 || 0)) // One of the short conditions is that the last trade was a long or there was no trade[/size] Read the comments in the code to understand what it does. (Sorry it is so small; it's so that the code does not getting broken up into several lines. Chris Edited August 10, 2010 by chrisbenjy wonder833 1 Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 10, 2010 Author Report Share Posted August 10, 2010 thx Chris! :) I try to understand how to plug this in. Quote Link to comment Share on other sites More sharing options...
chrisbenjy Posted August 10, 2010 Report Share Posted August 10, 2010 Ok, if you need help pm me. Chris Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 10, 2010 Author Report Share Posted August 10, 2010 (edited) Chris or anyone, please kindly help. Really have no clue what's the problem. The strategy is simply for experimental purpose. It can't trigger a trade. I try to separate the code for (LastTradeOP()==2 || 0)), it manage to trigger 1 position, the rest is still error. Thx in advanced! I put the definition at the front part //+------------------------------------------------------------------+ //| This MQL is generated by Expert Advisor Builder | //| http://sufx.core.t3-ism.net/ExpertAdvisorBuilder/ | //| | //| In no event will author be liable for any damages whatsoever. | //| Use at your own risk. | //| | //+------------------- DO NOT REMOVE THIS HEADER --------------------+ #define SIGNAL_NONE 0 #define SIGNAL_BUY 1 #define SIGNAL_SELL 2 #define SIGNAL_CLOSEBUY 3 #define SIGNAL_CLOSESELL 4 #property copyright "Expert Advisor Builder" #property link "http://sufx.core.t3-ism.net/ExpertAdvisorBuilder/" extern int MagicNumber = 0; extern bool SignalMail = False; extern bool EachTickMode = True; extern double Lots = 1.0; extern int Slippage = 3; extern bool UseStopLoss = False; extern int StopLoss = 30; extern bool UseTakeProfit = False; extern int TakeProfit = 60; extern bool UseTrailingStop = False; extern int TrailingStop = 30; int BarCount; int Current; bool TickCheck = False; int LastTradeOP() //Function that finds the order type of the last trade { if(OrderSelect(0,SELECT_BY_POS,MODE_HISTORY)==true) //Selects the last trade from Account History { if(OrderType()==OP_BUY) { return(1); //LastTradeOP()==1 if it was a long trade } if(OrderType()==OP_SELL) { return(2); //LastTradeOP()==2 if it was a short trade } } return(0); //LastTradeOP()==0 if there are no trades } //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { BarCount = Bars; if (EachTickMode) Current = 0; else Current = 1; return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { int Order = SIGNAL_NONE; int Total, Ticket; double StopLossLevel, TakeProfitLevel; if (EachTickMode && Bars != BarCount) TickCheck = False; Total = OrdersTotal(); Order = SIGNAL_NONE; //+------------------------------------------------------------------+ //| Variable Begin | //+------------------------------------------------------------------+ double Buy1_1 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Buy1_2 = iMA(NULL, 0, 336, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Buy2_1 = iMA(NULL, 0, 7, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Buy2_2 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Buy3_1 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Buy3_2 = iMA(NULL, 0, 84, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell1_1 = iMA(NULL, 0, 336, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell1_2 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell2_1 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell2_2 = iMA(NULL, 0, 7, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell3_1 = iMA(NULL, 0, 84, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double Sell3_2 = iMA(NULL, 0, 21, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double CloseBuy1_1 = iMA(NULL, 0, 7, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double CloseBuy1_2 = iMA(NULL, 0, 84, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double CloseSell1_1 = iMA(NULL, 0, 7, 0, MODE_EMA, PRICE_CLOSE, Current + 0); double CloseSell1_2 = iMA(NULL, 0, 84, 0, MODE_EMA, PRICE_CLOSE, Current + 0); //+------------------------------------------------------------------+ //| Variable End | //+------------------------------------------------------------------+ //Check position bool IsTrade = False; for (int i = 0; i < Total; i ++) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); if(OrderType() <= OP_SELL && OrderSymbol() == Symbol()) { IsTrade = True; if(OrderType() == OP_BUY) { //Close //+------------------------------------------------------------------+ //| Signal Begin(Exit Buy) | //+------------------------------------------------------------------+ if (CloseBuy1_1 < CloseBuy1_2) Order = SIGNAL_CLOSEBUY; //+------------------------------------------------------------------+ //| Signal End(Exit Buy) | //+------------------------------------------------------------------+ if (Order == SIGNAL_CLOSEBUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) { OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, MediumSeaGreen); if (SignalMail) SendMail("[signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Close Buy"); if (!EachTickMode) BarCount = Bars; IsTrade = False; continue; } //Trailing stop if(UseTrailingStop && TrailingStop > 0) { if(Bid - OrderOpenPrice() > Point * TrailingStop) { if(OrderStopLoss() < Bid - Point * TrailingStop) { OrderModify(OrderTicket(), OrderOpenPrice(), Bid - Point * TrailingStop, OrderTakeProfit(), 0, MediumSeaGreen); if (!EachTickMode) BarCount = Bars; continue; } } } } else { //Close //+------------------------------------------------------------------+ //| Signal Begin(Exit Sell) | //+------------------------------------------------------------------+ if (CloseSell1_1 > CloseSell1_2) Order = SIGNAL_CLOSESELL; //+------------------------------------------------------------------+ //| Signal End(Exit Sell) | //+------------------------------------------------------------------+ if (Order == SIGNAL_CLOSESELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount)))) { OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, DarkOrange); if (SignalMail) SendMail("[signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Close Sell"); if (!EachTickMode) BarCount = Bars; IsTrade = False; continue; } //Trailing stop if(UseTrailingStop && TrailingStop > 0) { if((OrderOpenPrice() - Ask) > (Point * TrailingStop)) { if((OrderStopLoss() > (Ask + Point * TrailingStop)) || (OrderStopLoss() == 0)) { OrderModify(OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderTakeProfit(), 0, DarkOrange); if (!EachTickMode) BarCount = Bars; continue; } } } } } } //+------------------------------------------------------------------+ //| Signal Begin(Entry) | //+------------------------------------------------------------------+ if (Buy1_1 > Buy1_2 && Buy2_1 > Buy2_2 && Buy3_1 > Buy3_2) Order = SIGNAL_BUY; if (Sell1_1 > Sell1_2 && Sell2_1 > Sell2_2 && Sell3_1 > Sell3_2) Order = SIGNAL_SELL; Edited August 10, 2010 by wonder833 Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 10, 2010 Author Report Share Posted August 10, 2010 Continue with 2nd part. Where I put the code under the long condition and short condition. //+------------------------------------------------------------------+ //| Signal End | //+------------------------------------------------------------------+ //Buy if (Order == SIGNAL_BUY && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount))) && (LastTradeOP()==2 || 0)) { if(!IsTrade) { //Check free margin if (AccountFreeMargin() < (1000 * Lots)) { Print("We have no money. Free Margin = ", AccountFreeMargin()); return(0); } if (UseStopLoss) StopLossLevel = Ask - StopLoss * Point; else StopLossLevel = 0.0; if (UseTakeProfit) TakeProfitLevel = Ask + TakeProfit * Point; else TakeProfitLevel = 0.0; Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, StopLossLevel, TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, 0, DodgerBlue); if(Ticket > 0) { if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("BUY order opened : ", OrderOpenPrice()); if (SignalMail) SendMail("[signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Ask, Digits) + " Open Buy"); } else { Print("Error opening BUY order : ", GetLastError()); } } if (EachTickMode) TickCheck = True; if (!EachTickMode) BarCount = Bars; return(0); } } //Sell if (Order == SIGNAL_SELL && ((EachTickMode && !TickCheck) || (!EachTickMode && (Bars != BarCount))) && (LastTradeOP()==1 || 0)) { if(!IsTrade) { //Check free margin if (AccountFreeMargin() < (1000 * Lots)) { Print("We have no money. Free Margin = ", AccountFreeMargin()); return(0); } if (UseStopLoss) StopLossLevel = Bid + StopLoss * Point; else StopLossLevel = 0.0; if (UseTakeProfit) TakeProfitLevel = Bid - TakeProfit * Point; else TakeProfitLevel = 0.0; Ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, StopLossLevel, TakeProfitLevel, "Sell(#" + MagicNumber + ")", MagicNumber, 0, DeepPink); if(Ticket > 0) { if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("SELL order opened : ", OrderOpenPrice()); if (SignalMail) SendMail("[signal Alert]", "[" + Symbol() + "] " + DoubleToStr(Bid, Digits) + " Open Sell"); } else { Print("Error opening SELL order : ", GetLastError()); } } if (EachTickMode) TickCheck = True; if (!EachTickMode) BarCount = Bars; return(0); } } if (!EachTickMode) BarCount = Bars; return(0); } //+------------------------------------------------------------------+ Quote Link to comment Share on other sites More sharing options...
chrisbenjy Posted August 10, 2010 Report Share Posted August 10, 2010 Hey wonder833, Do you have a function that checks the open trades and checks that only one trade is opened per signal? Chris Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 10, 2010 Author Report Share Posted August 10, 2010 hmm..i was thinking if the 'lasttrade OP' function can do the job? as it has to open opposite position, then should be one trade per signal? correct me if i'm wrong. :) Quote Link to comment Share on other sites More sharing options...
chrisbenjy Posted August 10, 2010 Report Share Posted August 10, 2010 The last trade op function just checks order history (closed orders and not open open orders). Is it right though that you wanted it to buy and sell in order, i.e buy, then sell, then buy, then sell, etc? To make it trade only once per signal you can use this: [size="1"]int CheckTrades() //Function that finds the order type of the open trades { for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true) //Selects a trade from the currently open trades { if(OrderType()==OP_BUY) { return(1); //if CurrentTrades()==1 There is an open long } if(OrderType()==OP_SELL) { return(2); //if CurrentTrades()==2 There is an open short } } } return(0); //CurrentTrades()==0 if there are no open trades }[/size] Same as before add this to the trade conditions. Long: [size="1"]&& (CheckTrades()==2 || CheckTrades()==0))[/size] Short: [size="1"]&& (CheckTrades()==2 || CheckTrades()==0))[/size] This should fix it. Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 10, 2010 Author Report Share Posted August 10, 2010 Thanks again Chris! you are very responsive! :) I will try this. Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 11, 2010 Author Report Share Posted August 11, 2010 I have tried again in backtest. Still can't solve the problem. It is not the open orders problem, as the EA only open one trade at a time. But, It can't recognize the order type of last closed order in the backtest. Hence, it turns out buy, sell, sell, sell, buy, buy, etc. I wonder if it got something to do with backtest, probably it can't find the last order in backtest history? Quote Link to comment Share on other sites More sharing options...
wonder833 Posted August 11, 2010 Author Report Share Posted August 11, 2010 Hi guys, I have found out how to solve the problem. Here's the code. Thanks to Chris for starting to help. [size="1"]int LastTradeOP() //Function that finds the order type of the last trade {for(int i=OrdersHistoryTotal()-1;i>=0;i--){ if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==true) //Selects the last trade from Account History { if(OrderType()==OP_BUY) { return(1); //LastTradeOP()==1 if it was a long trade } if(OrderType()==OP_SELL) { return(2); //LastTradeOP()==2 if it was a short trade } } } return(0); //LastTradeOP()==0 if there are no trades }[/size] And this is to add to long condition && (LastTradeOP()==2 || LastTradeOP()==0)) Add this to short condition && (LastTradeOP()==1 || LastTradeOP()==0)) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.