- Indicator handlers need to be assigned into OnInit
- 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.
- Indicator handlers need to be assigned into OnInit
- 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> //Create an instance of CTrade CTrade trade; 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...
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 buy = SymbolInfoDouble(_Symbol,SYMBOL_ASK); buy = NormalizeDouble(buy,_Digits); 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) signal="buy"; //rsi at 65 or above and positions total is 1 or less, then sell if(signal =="sell" && PositionsTotal()<=1) trade.Sell(lots,_Symbol,sell,(sell+sl * _Point),(sell-tp * _Point),NULL); //rsi below or at 35 and positions total is 1 or less, the buy if(signal =="buy" && PositionsTotal()<1) trade.Buy(lots,_Symbol,buy,(buy-sl * _Point),(buy+tp * _Point),NULL);
I tried changing all the code to...
#include <Trade\Trade.mqh> //Create an instance of CTrade CTrade trade; 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) signal="buy"; //rsi at 35 or below and positions total is 1 or less, then buy if(signal =="buy" && PositionsTotal()<=0) { if(posTicket > 0 && PositionSelectByTicket(posTicket)) { int posType = (int)PositionGetInteger(POSITION_TYPE); if(posType == POSITION_TYPE_BUY){ trade.PositionClose(posTicket); posTicket = 0; } } if(posTicket <= 0) { trade.Sell(lots,_Symbol); posTicket = trade.ResultOrder(); } //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){ trade.PositionClose(posTicket); posTicket = 0; } } if(posTicket <= 0) { trade.Buy(lots,_Symbol); posTicket = trade.ResultOrder(); } } 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(posType == POSITION_TYPE_BUY){ if(posSl == 0){ double sl = posPrice - 0.00200; double tp = posPrice + 0.00200; trade.PositionModify(posTicket,sl,tp); } }else if(posType == POSITION_TYPE_SELL){ if(posSl == 0){ double sl = posPrice + 0.00200; double tp = posPrice - 0.00200; trade.PositionModify(posTicket,sl,tp); } } }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
Seems that you did some confusion about an easy task...
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 ) trade.Sell(lots,_Symbol,sell,(sell+sl * _Point),(sell-tp * _Point),NULL); if( myRSIArray[0]<35 ) trade.Buy(lots,_Symbol,buy,(buy-sl * _Point),(buy+tp * _Point),NULL);
Seems that you did some confusion about an easy task...
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.
Thankyou for your help Fabio
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> //Create an instance of CTrade CTrade trade; 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) signal="buy"; //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 buy = SymbolInfoDouble(_Symbol,SYMBOL_ASK); buy = NormalizeDouble(buy,_Digits); 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) trade.Buy(lots, _Symbol,buy,(sell-sl * _Point), (sell+tp * _Point),NULL); } //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; #include <Trade\PositionInfo.mqh> CPositionInfo m_position; 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 buys, sells; double ask, bid ; int OnInit(){ trade.SetExpertMagicNumber(iMagicNumber); trade.SetTypeFillingBySymbol(_Symbol); 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; double slpp = ask-sl; trade.Buy(calcLots(slpp), _Symbol,ask,sl,tp); } if( sells==0 && RSI(1)>65 ) { double sl = bid + iSL*_Point; double tp = bid - iTP*_Point; double slpp = sl-bid; trade.Sell(calcLots(slpp), _Symbol,bid,sl,tp); } } void RefreshGlobals() { ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); buys = 0; 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_BUY ) buys ++; 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 ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); 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; }
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
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!
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?
Currently, it looks like its going to take trade after trade after trade...
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; #include <Trade\PositionInfo.mqh> CPositionInfo m_position; 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 buys, sells; double ask, bid; int OnInit(){ trade.SetExpertMagicNumber(iMagicNumber); trade.SetTypeFillingBySymbol(_Symbol); 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() { ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); RefreshGlobals(); if( buys==0 && RSI(1)<25 ) { double sl = bid + iSL*_Point; double tp = bid - iTP*_Point; double slpp = ask-sl; trade.Buy(calcLots(slpp),_Symbol,ask,sl,tp); } if( sells==0 && RSI(1)>75 ) { double sl = bid + iSL*_Point; double tp = bid - iTP*_Point; double slpp = sl-bid; trade.Sell(calcLots(slpp),_Symbol,bid,sl,tp); } checkBreakEvenStop(ask,bid); checkTrailingStop(ask,bid); } void RefreshGlobals() { buys = 0; 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_BUY ) buys ++; 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 ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); 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; } void checkBreakEvenStop(double ask, double bid){ //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 double PositionBuyPrice=PositionGetDouble(POSITION_PRICE_OPEN); //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 trade.PositionModify(PositionTicket,PositionBuyPrice - 10* _Point,0); } //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 trade.PositionModify(PositionTicket,PositionSellPrice + 10* _Point,0); } } // 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 if(CurrentStopLoss<iSL && m_position.PositionType()==POSITION_TYPE_BUY) { //Modify the stop loss up by 100 points trade.PositionModify(PositionTicket,(CurrentStopLoss + 100* _Point),0); //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 trade.PositionModify(PositionTicket,(CurrentStopLoss - 100* _Point),0); } } // if loop closed } // End for loop } // End breakeven stop function

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Can you please help me identify where i went wrong?
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