Jump to content

Code 'maximum trade per direction'


wonder833

Recommended Posts

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 :)
Link to comment
Share on other sites

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 by chrisbenjy
Link to comment
Share on other sites

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 by wonder833
Link to comment
Share on other sites

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);
}

//+------------------------------------------------------------------+

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?
Link to comment
Share on other sites

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))
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...