Looking for some help with my EA

 

I am new to coding so please bear with me if I ask a lot of questions.

Okay so the idea behind the EA is that

Long Entry Short Entry

PSAR < Price PSAR > Price

MACD > 0 MACD < 0

The expert will close out a trade when it has reached a user defined amount of pips OR the PSAR reverses to the opposite side. However, when it comes to opening trades, I am trying to get the system to ONLY open a buy/sell on the third SAR dot in the trend, and not any other dots. I can't seem to get it to do this. I have gotten it to wait until the third dot but it will open a trade on the 4th dot, 5th dot, etc. I am also looking for a way to get the Expert to trade only once per bar (within the other parameters obviously).

I just am looking for some direction. If anyone can help point me the right way I would be very appreciative. Thank you.

#include <stderror.mqh>
#include <stdlib.mqh>
#define MAGIC 48759100
#define STUP   1    // PSAR > Price
#define STDOWN 2    // PSAR < Price

string  EA_Version = "Kyle_v100";

//---- input parameters

extern double   Lot_Size                      = 0.1;
extern double   Take_Profit                   = 200;
extern int      Dot_Count                     = 3;


int slippage = 100;

// globals:
double macd;
int psar_status;

double spread;

// broker specific variables:

double lot_min;
double lot_max;
double lot_step;
double pip_size;
double min_stop;

// --------------------------------------------------
// --------------------------------------------------

int init()  {

  lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
  lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
  lot_step = MarketInfo(Symbol(), MODE_LOTSTEP);
  pip_size = MarketInfo(Symbol(), MODE_TICKVALUE);
  min_stop = MarketInfo(Symbol(), MODE_STOPLEVEL);

  return(0);
}

int deinit()  {
  return(0);
}

int start()  {

  if(Bars < 100 || IsTradeAllowed()==false) {
    return(0);
  }

  GetValues();
  CheckForEnter();
  CheckForClose();

  return(0);
}

// --------------------------------------------------
// --------------------------------------------------

void GetValues() {
  double psar;
  double price;
  int up = 0;
  int down = 0;

  macd = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);

  psar_status = 0;

  for(int i = 0; i < Dot_Count; i++) {
    psar = iSAR(NULL, 0, 0.02, 0.2, i);
    price = iClose(NULL, 0, i);
    if(psar > price) {
      up++;
    } else {
      down++;
    }
  }
  if(up == Dot_Count) {
    psar_status = STUP;
  }
  if(down == Dot_Count) {
    psar_status = STDOWN;
  }

  return;
}

//-------------------------------------------------------------------------------

void CheckForEnter() {

  if(TradeExists() == true) return;

  // for long:
  if(psar_status == STDOWN && macd > 0) {
    OpenLong();
  }

  // for short:
  if(psar_status == STUP && macd < 0) {
    OpenShort();
  }

  return;
}


void CheckForClose() {
  double psar, price;

  for(int i=0; i < OrdersTotal(); i++) {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) {
      break;
    }
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC && OrderCloseTime() == 0) {
      psar = iSAR(NULL, 0, 0.02, 0.2, 1);
      price = iClose(NULL, 0, 1);
      if(OrderType() == OP_BUY && psar > price) {
        OrderClose(OrderTicket(), OrderLots(), Ask, slippage, Red);
      }
      if(OrderType() == OP_SELL && psar < price) {
        OrderClose(OrderTicket(), OrderLots(), Bid, slippage, Red);
      }
    }
  }
  return;
}


void OpenLong() {
  double tp_level;

  RefreshRates();
  WaitIfBusy();

  tp_level = Ask + (Take_Profit / MathPow(10, Digits));

  int res = OrderSend(Symbol(), OP_BUY, N(Lot_Size), Ask, slippage, 0, N(tp_level), EA_Version, MAGIC, 0, Green);
  if(res < 0) {
    PrintError();
  }

  return;
}


void OpenShort() {
  double tp_level;

  RefreshRates();
  WaitIfBusy();

  tp_level = Bid - (Take_Profit / MathPow(10, Digits));

  int res = OrderSend(Symbol(), OP_SELL, N(Lot_Size), Ask, slippage, 0, N(tp_level), EA_Version, MAGIC, 0, Green);
  if(res < 0) {
    PrintError();
  }

  return;

}


bool TradeExists() {
  for(int i=0; i < OrdersTotal(); i++) {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) {
      break;
    }
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC && OrderCloseTime() == 0) {
      return(true);
    }
  }
  return(false);
}


void PrintError() {
  int err = GetLastError();
  Print("error(", err, "): ", ErrorDescription(err));
  return(0);
}



void WaitIfBusy() {
   if (IsConnected() && IsTradeAllowed()) while (IsTradeContextBusy()) Sleep(75);
}

double N(double d) {
  return(NormalizeDouble(d, Digits));
}
 

On a failed OrderSelect you quit the entire function. You probably should use a continue rather than a break so you check the rest of the open orders

void CheckForClose() {
  double psar, price;

  for(int i=0; i < OrdersTotal(); i++) {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) {
      // TODO use a continue here rather than a break or you will just quit the function
      break;
    }
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC && OrderCloseTime() == 0) {
      psar = iSAR(NULL, 0, 0.02, 0.2, 1);
      price = iClose(NULL, 0, 1);
      if(OrderType() == OP_BUY && psar > price) {
        OrderClose(OrderTicket(), OrderLots(), Ask, slippage, Red);
      }
      if(OrderType() == OP_SELL && psar < price) {
        OrderClose(OrderTicket(), OrderLots(), Bid, slippage, Red);
      }
    }
  }
  return;
}

same thing in the TradeExists function

 

This construction is unpleasant

tp_level = Ask + (Take_Profit / MathPow(10, Digits))

People usually multiply TakeProfit by Point (often with pip to point factors to allow for 4 or 5 digit brokers.)

 
noozak:

I am new to coding so please bear with me if I ask a lot of questions.

...

I am also looking for a way to get the Expert to trade only once per bar (within the other parameters obviously).

For somebody "new to coding" your code is looking remarkably good :-)

The once per bar thing is easy. Use a static or global datetime variable and compare it Time[0]. If not equal it is a new bar. On the new bar set the datetime variable to equal Time[0]. This forum is flooded with this code.

 
Well I spent two years as an Information Technology major at college so I have a little bit of knowledge, but struggled and changed majors so I don't feel really comfortable with this haha. I appreciate you looking over the code and offering some suggestions for me. I actually was just searching around the forum for the code related to a once per bar function. I feel like I can get that taken care of. I just cant find out how to get it to only open a trade on the 3rd PSAR dot.
 
noozak:
I just cant find out how to get it to only open a trade on the 3rd PSAR dot.

So you want the case when the current Psar dot is below the price, and the previous one, and the previous one, but not the one previous to that.

Something like ...

if( psar(1)<Low[1] && psar(2)<Low[2] && psar(3)<Low[3] && psar(4)>High[4] ){
   // do stuff
}
 

I guess to better explain what I mean by only opening a trade on the 3rd psar dot Ill show you the picture I made to illustrate what I wanted to do when I started coding this.

(I apologize if your previous answer just explained exactly what I just showed you)

 
noozak:

(I apologize if your previous answer just explained exactly what I just showed you)

Well my answer was supposed to address just the 3rd psar dot issue. When I wrote psar(1) for example I was just saying "the value of the psar indicator for bar 1". Perhaps I should have written it out more fully as

psar1 = iSAR(NULL, 0, 0.02, 0.2, 1);
psar2 = iSAR(NULL, 0, 0.02, 0.2, 2);
psar3 = iSAR(NULL, 0, 0.02, 0.2, 3);
psar4 = iSAR(NULL, 0, 0.02, 0.2, 4);

if( psar1<Low[1] && psar2<Low[2] && psar3<Low[3] && psar4>High[4] ){
   // do stuff
}
 
dabbler:

Well my answer was supposed to address just the 3rd psar dot issue. When I wrote psar(1) for example I was just saying "the value of the psar indicator for bar 1". Perhaps I should have written it out more fully as

hello everybody

 i wonder if anybody could help me modify the above strategy a bit.

 i would really appreciate your help.

 
motarek:

hello everybody

 i wonder if anybody could help me modify the above strategy a bit.

 i would really appreciate your help.

  

https://www.mql5.com/en/job
 
motarek:

hello everybody

 i wonder if anybody could help me modify the above strategy a bit.

 i would really appreciate your help.

Send a PM to noozak instead of dredging up a year old thread.
Reason: