# EA wont take trades - unsure where i have gone wrong exactly

i tried to combine 2 tutorials...

an RSI where the EA will take a sell if price is above 65 and buy if price is below 35

max 2 trades at 1 time... and using calcLots to work out 1% of the account balance...

it wont take any trades when prices moves into those levels

i see i have declared calcLots = twice but im also not sure where else to go from here

Additionally i would like to add a Breakeven once price moved to 100 points

but i figured i needed to get it to take trades before i follow another tutorial and try to add the break even in

thanks

```#include <Trade\Trade.mqh>

int OnInit(){

//calcLots(0.5,sl); // i get error about sl undeclared if i uncomment this

return(INIT_SUCCEEDED);
}

void OnTick() {

if(PositionsTotal() <= 2){

double sell = SymbolInfoDouble(_Symbol,SYMBOL_BID);
sell = NormalizeDouble(sell,_Digits);

double sl = 200 * _Point;
sl = NormalizeDouble(sl,_Digits);

double tp = 200 * _Point;
tp = NormalizeDouble(tp, _Digits);

//Define the properties for the RSI
int myRSIDefinition = iRSI (_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE);

double lots = calcLots(0.5, sl); //call this function - 1%, and sl

//Create a string for the signal
string signal="";

//Create an array for the price data
double myRSIArray[];

//sort the array from the current candle downwards
ArraySetAsSeries(myRSIArray,true);

//Define EA, from current candle, for 3 candles, save in array
CopyBuffer(myRSIDefinition,0,0,
3 ,myRSIArray);

//Calculate the current RSI value
double myRSIValue=NormalizeDouble(myRSIArray[0],2);

if (myRSIValue>65)
signal="sell";

if (myRSIValue<35)

//rsi at 75 or above and positions total is 1 or less, then sell
if(signal =="sell" && PositionsTotal()<=1)

//rsi below or at 25 and positions total is 1 or less, the buy

}
}

//custom function to calculate lotsize based on percentage of account
double calcLots(double riskPercent, double slDistance) {
double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); //from this function we want the tick size to be returned and stored in variable called ticksize
double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); // find the value of 0.00001 (ticksize) and invested with 1 lot, this will make a difference of \$1
double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); //smallest change in lot size = 0.01 for EURUSD

if(ticksize == 0 || tickvalue == 0 || lotstep == 0){ // in this case something failed - not go on with calculations
Print(__FUNCTION__," > Lotsize cannot be calculated...");
return 0;
}

double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100; // calculates 1% of account balance
double moneyLotStep = (slDistance / ticksize) * tickvalue * lotstep;    //distance between entry and Stop Loss in Points - 2.5pips if trading using 0.1 lots

if(moneyLotStep == 0) {
return 0;
}
double lots = MathFloor(riskMoney / moneyLotStep) * lotstep;

return lots;
}
```
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
• www.mql5.com
Symbol Properties - Environment State - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5

1. Indicator handlers need to be assigned into OnInit
2. Never use PositionsTotal but always count trades specific for that EA (with a function that count trades based on Magic number)

Point 2 is not mandatory for testing an EA into the tester but surely mandatory for running an EA on a live account.

Fabio Cavalloni #:
1. Indicator handlers need to be assigned into OnInit
2. Never use PositionsTotal but always count trades specific for that EA (with a function that count trades based on Magic number)

Point 2 is not mandatory for testing an EA into the tester but surely mandatory for running an EA on a live account.

OK so for point 1... i have made these changes.

Is this correct?

```#include <Trade\Trade.mqh>

int rsiHandle;

int OnInit(){

//Define the properties for the RSI
rsiHandle = iRSI (_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE);

return 0;
}

void OnDeinit(const int reason){

}

void OnTick() {

double rsi[];
CopyBuffer(rsiHandle,0,1,1,rsi);
```

Also these are the errors i'm getting

Indicators calls are correct now.

About the errror: read logs carefully. You are trying to open trades with SL = TP. This it's impossible to do an broker server reply with "Invalid stops".

You need also to normalize prices to tick size, to avoid using not normalized prices into SL and TP that can generate errors too...

Fabio Cavalloni #:

Indicators calls are correct now.

About the errror: read logs carefully. You are trying to open trades with SL = TP. This it's impossible to do an broker server reply with "Invalid stops".

You need also to normalize prices to tick size, to avoid using not normalized prices into SL and TP that can generate errors too...

Do you meant here?

```if(PositionsTotal() <= 2){

double sell = SymbolInfoDouble(_Symbol,SYMBOL_BID);
sell = NormalizeDouble(sell,_Digits);

double sl = 200 * _Point;
sl = NormalizeDouble(sl,_Digits);

double tp = 200 * _Point;
tp = NormalizeDouble(tp, _Digits);```

or for the actual buys and sells?

for the sells i have SL is +200 points and TP is -200 points

and for buys i have SL is -200points and TP is +200 points

``` //Calculate the current RSI value
double myRSIValue=NormalizeDouble(myRSIArray[0],2);

if (myRSIValue>65)
signal="sell";

if (myRSIValue<35)

//rsi at 65 or above and positions total is 1 or less, then sell
if(signal =="sell" && PositionsTotal()<=1)

//rsi below or at 35 and positions total is 1 or less, the buy

```

I tried changing all the code to...

```#include <Trade\Trade.mqh>

int calcLots;
int rsiHandle;
int myRSIValue;
int sl;
int tp;
ulong posTicket;
string signal;

int OnInit(){

//Define the properties for the RSI
rsiHandle = iRSI (_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE);

return 0;
}

void OnDeinit(const int reason){

}

void OnTick() {

double lots = calcLots(1, sl); //call this function - 1%, and 2.5pips

double rsi[];
CopyBuffer(rsiHandle,0,1,1,rsi);

if (myRSIValue>65)
signal="sell";

if (myRSIValue<35)

//rsi at 35 or below and positions total is 1 or less, then buy
if(posTicket > 0 && PositionSelectByTicket(posTicket)) {
int posType = (int)PositionGetInteger(POSITION_TYPE);
posTicket = 0;
}

}

if(posTicket <= 0) {
}

//rsi at 65 or above and positions total is 1 or less, then sell
}else if(signal =="sell" && PositionsTotal()<=0) {
if(posTicket > 0 && PositionSelectByTicket(posTicket)) {
int posType = (int)PositionGetInteger(POSITION_TYPE);
if(posType == POSITION_TYPE_SELL){
posTicket = 0;
}

}

if(posTicket <= 0) {

}

}

if(PositionSelectByTicket(posTicket)){
double posPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double posSl = PositionGetDouble(POSITION_SL);
double posTp = PositionGetDouble(POSITION_TP);
int posType = (int)PositionGetInteger(POSITION_TYPE);

if(posSl == 0){
double sl = posPrice - 0.00200;
double tp = posPrice + 0.00200;

}
}else if(posType == POSITION_TYPE_SELL){
if(posSl == 0){
double sl = posPrice + 0.00200;
double tp = posPrice - 0.00200;
}

}

}else{
posTicket = 0;

}

//Create a string for the signal
string signal="";

//Create an array for the price data
double myRSIArray[];

//sort the array from the current candle downwards
ArraySetAsSeries(myRSIArray,true);

//Define EA, from current candle, for 3 candles, save in array
CopyBuffer(rsiHandle,0,0,
3 ,myRSIArray);

//Calculate the current RSI value
double myRSIValue=NormalizeDouble(myRSIArray[0],2);

}

//custom function to calculate lotsize based on percentage of account
double calcLots(double riskPercent, double slDistance) {
double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); //from this function we want the tick size to be returned and stored in variable called ticksize
double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); // find the value of 0.00001 (ticksize) and invested with 1 lot, this will make a difference of \$1
double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); //smallest change in lot size = 0.01 for EURUSD

if(ticksize == 0 || tickvalue == 0 || lotstep == 0){ // in this case something failed - not go on with calculations
Print(__FUNCTION__," > Lotsize cannot be calculated...");
return 0;
}

double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100; // calcualtes 1% of account balance
double moneyLotStep = (slDistance / ticksize) * tickvalue * lotstep;    //distance between entry and Stop Loss in Points - 2.5pips if trading using 0.1 lots

if(moneyLotStep == 0) {
return 0;
}
double lots = MathFloor(riskMoney / moneyLotStep) * lotstep;

return lots;
}
```

but now it doesnt even attempt to take any trades

You are using some global declared variables that you don't initialize or clear after usage, so, avoid use most of them, because they are basically useless.

```if( myRSIArray[0]>65 )
if( myRSIArray[0]<35 )

```

Fabio Cavalloni #:

You are using some global declared variables that you don't initialize or clear after usage, so, avoid use most of them, because they are basically useless.

ok now i have this....

but im getting this error

but i cant work out where it needs to go...

sorry im just learning all of this...
it seems this simple task is not simple at all

when following the tutorials, i was able to get things working seperately.. but just not together

```#include <Trade\Trade.mqh>

int rsiHandle;

int OnInit(){

//Define the properties for the RSI
rsiHandle = iRSI (_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE);

return 0;
}

void OnDeinit(const int reason){

}

void OnTick() {

double lots = calcLots(1, sl);

double rsi[];
CopyBuffer(rsiHandle,0,1,1,rsi);

if (myRSIValue>65)
signal="sell";

if (myRSIValue<35)

//Create a string for the signal
string signal="";

//Create an array for the price data
double myRSIArray[];

//sort the array from the current candle downwards
ArraySetAsSeries(myRSIArray,true);

//Define EA, from current candle, for 3 candles, save in array
CopyBuffer(rsiHandle,0,0,3,myRSIArray);

//Calculate the current RSI value
double myRSIValue=NormalizeDouble(myRSIArray[0],2);

if(PositionsTotal() <= 0){

double sell = SymbolInfoDouble(_Symbol,SYMBOL_BID);
sell = NormalizeDouble(sell,_Digits);

double sl = 0.00030 * _Point;
sl = NormalizeDouble(sl,_Digits);

double tp = 0.00063 * _Point;
tp = NormalizeDouble(tp, _Digits);

if(myRSIArray[0]>65)
trade.Sell(lots, _Symbol,sell,(sell+sl * _Point), (sell-tp * _Point),NULL);
if(myRSIArray[0]<35)

}

//custom function to calculate lotsize based on percentage of account
double calcLots(double riskPercent, double slDistance) {
double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); //from this function we want the tick size to be returned and stored in variable called ticksize
double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); // find the value of 0.00001 (ticksize) and invested with 1 lot, this will make a difference of \$1
double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); //smallest change in lot size = 0.01 for EURUSD

if(ticksize == 0 || tickvalue == 0 || lotstep == 0){ // in this case something failed - not go on with calculations
Print(__FUNCTION__," > Lotsize cannot be calculated...");
return 0;
}

double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100; // calcualtes 1% of account balance
double moneyLotStep = (slDistance / ticksize) * tickvalue * lotstep;    //distance between entry and Stop Loss in Points - 2.5pips if trading using 0.1 lots

if(moneyLotStep == 0) {
return 0;
}
double lots = MathFloor(riskMoney / moneyLotStep) * lotstep;

return lots;
}
```

This is what I meant for: you are complicating an easy thing :D

Less rows than yours, but with inputs and better understanding code. I hope you appreciate the effort.

```#include <Trade\Trade.mqh>          CTrade            trade;

input int      iMagicNumber   = 100;   // Magic number
input double   iRisk          = 1.0;   // Risk in %
input int      iSL            = 300;   // Stop loss points
input int      iTP            = 300;   // Take profit points

int      Handle_RSI;

;

int OnInit(){
if( (Handle_RSI= iRSI(_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE)) == INVALID_HANDLE ) return INIT_FAILED;
return INIT_SUCCEEDED;
}

void OnDeinit(const int reason){
}

void OnTick() {
RefreshGlobals();
if( buys==0 && RSI(1)<35 ) {
double sl = ask - iSL*_Point;
double tp = ask + iTP*_Point;
}
if( sells==0 && RSI(1)>65 ) {
double sl = bid + iSL*_Point;
double tp = bid - iTP*_Point;
double slpp = sl-bid;
}
}

void RefreshGlobals() {
bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
sells = 0;
for( int i=PositionsTotal()-1; i>=0; i-- ) {
if( !m_position.SelectByIndex(i) || m_position.Magic()!=iMagicNumber || m_position.Symbol()!=_Symbol ) continue;
if( m_position.PositionType()==POSITION_TYPE_SELL ) sells ++;
}
}

double RSI(int shift) { double value[1]; return CopyBuffer(Handle_RSI,0,shift,1,value)>0 ? value[0] : WRONG_VALUE; }

double calcLots(double slDistance) {
double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);

if(ticksize == 0 || tickvalue == 0 || lotstep == 0){
Print(__FUNCTION__," > Lotsize cannot be calculated...");
return 0;
}

double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * iRisk / 100;
double moneyLotStep = (slDistance / ticksize) * tickvalue * lotstep;

if(moneyLotStep == 0) return 0;
double lot = MathFloor(riskMoney / moneyLotStep) * lotstep;

return lot;
}```

Fabio Cavalloni #:

This is what I meant for: you are complicating an easy thing :D

Thankyou so much... I was over complicating it completely! Sorry i didn't get what you meant...
Hopefully with ALOT of practice.. i will one day be able to help people like you have helped me today

Thankyou again

pebs85 #:

Thankyou so much... I was over complicating it completely! Sorry i didn't get what you meant...
Hopefully with ALOT of practice.. i will one day be able to help people like you have helped me today

Thankyou again

It was a pleasure to help! I always found a lot of helps and good codes on the web, so it's correct to give contribute to who is in need!

Fabio Cavalloni #:

It was a pleasure to help! I always found a lot of helps and good codes on the web, so it's correct to give contribute to who is in need!

Hey Fabio,

Could i check something?

If i am wanting to add Breakeven and a Trailing Stop.. does this look correct?

Also... how do i make sure it only takes 1 trade when it crosses the overbought or oversold levels?
I dont mind if it takes a trade when price crosses the level, then if it crosses back and then crosses again it takes another...

i just dont want it taking 1 million trades cause price stays above or below the level for a while, etc

Theres always the chance i overcomplicated that as well lol

```#include <Trade\Trade.mqh>          CTrade            trade;

input int      iMagicNumber   = 100;   // Magic number
input double   iRisk          = 1.0;   // Risk in %
input int      iSL            = 200;   // Stop loss points
input int      iTP            = 200;   // Take profit points
input int      TrailingStop   = 25; // Trailing Stop points

int      Handle_RSI;

int OnInit(){

if( (Handle_RSI= iRSI(_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE)) == INVALID_HANDLE ) return INIT_FAILED;
return INIT_SUCCEEDED;
}

void OnDeinit(const int reason){
}

void OnTick() {
bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);

RefreshGlobals();
if( buys==0 && RSI(1)<25 ) {
double sl = bid + iSL*_Point;
double tp = bid - iTP*_Point;
}
if( sells==0 && RSI(1)>75 ) {
double sl = bid + iSL*_Point;
double tp = bid - iTP*_Point;
double slpp = sl-bid;
}

}

void RefreshGlobals() {
sells = 0;
for( int i=PositionsTotal()-1; i>=0; i-- ) {
if( !m_position.SelectByIndex(i) || m_position.Magic()!=iMagicNumber || m_position.Symbol()!=_Symbol) continue;
if( m_position.PositionType()==POSITION_TYPE_SELL ) sells ++;
}
}

double RSI(int shift) { double value[1]; return CopyBuffer(Handle_RSI,0,shift,1,value)>0 ? value[0] : WRONG_VALUE; }

double calcLots(double slDistance) {
double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);

if(ticksize == 0 || tickvalue == 0 || lotstep == 0)
{
Print(__FUNCTION__," > Lotsize cannot be calculated...");
return 0;
}

double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * iRisk / 100;
double moneyLotStep = (slDistance / ticksize) * tickvalue * lotstep;

if(moneyLotStep == 0) return 0;
double lot = MathFloor(riskMoney / moneyLotStep) * lotstep;

return lot;
}

//Go through all positions
for(int i=PositionsTotal()-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i); // get position symbol

if (_Symbol==symbol) // if chart symbol equals position symbol
{

//get the ticket number
ulong PositionTicket=PositionGetInteger(POSITION_TICKET);

//calculate the current open price / buy price

//calculate the current open price / sell price
double PositionSellPrice=PositionGetDouble(POSITION_PRICE_OPEN);

//if current price is 30 points above buy price
if (ask > (PositionSellPrice - 50* _Point)){
//Modify the stop loss to 10 points above entry, dont change Take Profit
}

//if current price is 50 points above buy price
else if (bid < (PositionBuyPrice + 50* _Point))

{
//Modify the stop loss to 10 points below entry, dont change Take Profit
}
}   // if loop closed
} // End for loop
}  // End breakeven stop function

void checkTrailingStop (double ask, double bid){

double TrailingStop = (50*_Point);

//Go through all positions
for(int i=PositionsTotal()-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i); // get position symbol

if (_Symbol==symbol) // if chart symbol equals position symbol
{

//get the ticket number
ulong PositionTicket=PositionGetInteger(POSITION_TICKET);

//calculate the current stop loss
double CurrentStopLoss=PositionGetDouble(POSITION_SL);

//if current SL is 50 points from current SL and position type is buy
{
//Modify the stop loss up by 100 points

//if current price is 30 points above buy price
}else if (CurrentStopLoss>iSL && m_position.PositionType()==POSITION_TYPE_SELL){
//Modify the stop loss down by 100 points