I am coding an EA for trading SAR. My bear positions, based on the SAR, never action. All bull positions work fine. Using counters for each function I have confirmed that every function works as required.
values. in the below code simply refers to a pre-made structure.
Removing all components of CTrade and just using counters each function operates perfectly. Add the CTrade functions and the OpenSell() function never actions although the counter still does. So why do the counters tell me each function is called correctly yet the OpenSell() function is NEVER called?
//+------------------------------------------------------------------+ //| Open Sell Position | //+------------------------------------------------------------------+ void OpenSellTrade() { // Returned preamble data PreambleValues values = GetValues(); if(PositionsTotal() < 1) { trade.Sell(values.lotSize, cPair, values.bid, 0, (values.bid + (20 * _Point)), "SELL OPENED"); openSellCounter++; } }
shouldnt the sell tp, be a minus? And I also recommend that you Normalise tps on both buys and sells to avoid any errors caused by excess digits.
This code can help to fix the problem and will tell you the error code
#include <Trade\SymbolInfo.mqh> // Code to add before OnInit() CSymbolInfo m_symbol; // Code to add before OnInit() if(!m_symbol.Name(Symbol())) // This code for OnInit() return(INIT_FAILED); //+------------------------------------------------------------------+ //| Open Buy Position | //+------------------------------------------------------------------+ void OpenBuyTrade() { // Returned preamble data PreambleValues values = GetValues(); if(PositionsTotal() < 1) { ResetLastError(); bool res = trade.Buy(values.lotSize, cPair, SymbolInfoDouble(cPair,SYMBOL_ASK), 0, m_symbol.NormalizePrice((SymbolInfoDouble(cPair,SYMBOL_ASK) + (20 * Point()))), "BUY OPENED"); if(res == false) Print("trade for Buy error: ", GetLastError()); openBuyCounter++; } } //+------------------------------------------------------------------+ //| Open Sell Position | //+------------------------------------------------------------------+ void OpenSellTrade() { // Returned preamble data PreambleValues values = GetValues(); if(PositionsTotal() < 1) { ResetLastError(); bool res = trade.Sell(values.lotSize, cPair, SymbolInfoDouble(cPair,SYMBOL_BID), 0, m_symbol.NormalizePrice(((SymbolInfoDouble(cPair,SYMBOL_BID) - (20 * Point()))), "SELL OPENED"); if(res == false) Print("trade for Sell error: ", GetLastError()); openSellCounter++; } } //+------------------------------------------------------------------+
+ A function to check stop/freeze levels should also be added
SymbolInfoInteger(Symbol(), SYMBOL_TRADE_FREEZE_LEVEL)
SymbolInfoInteger(Symbol(), SYMBOL_TRADE_STOPS_LEVEL)
Here sample:
//+------------------------------------------------------------------+ //| Refreshes the symbol quotes data | //+------------------------------------------------------------------+ bool RefreshRates(void) { //--- refresh rates if(!m_symbol.RefreshRates()) { Print("RefreshRates error"); return(false); } //--- protection against the return value of "zero" if(m_symbol.Ask()==0 || m_symbol.Bid()==0) return(false); //--- return(true); }
//+------------------------------------------------------------------+ //| Check Freeze and Stops levels | //+------------------------------------------------------------------+ bool FreezeStopsLevels(double &level) { //--- check Freeze and Stops levels /* Type of order/position | Activation price | Check ------------------------|--------------------|-------------------------------------------- Buy Limit order | Ask | Ask-OpenPrice >= SYMBOL_TRADE_FREEZE_LEVEL Buy Stop order | Ask | OpenPrice-Ask >= SYMBOL_TRADE_FREEZE_LEVEL Sell Limit order | Bid | OpenPrice-Bid >= SYMBOL_TRADE_FREEZE_LEVEL Sell Stop order | Bid | Bid-OpenPrice >= SYMBOL_TRADE_FREEZE_LEVEL Buy position | Bid | TakeProfit-Bid >= SYMBOL_TRADE_FREEZE_LEVEL | | Bid-StopLoss >= SYMBOL_TRADE_FREEZE_LEVEL Sell position | Ask | Ask-TakeProfit >= SYMBOL_TRADE_FREEZE_LEVEL | | StopLoss-Ask >= SYMBOL_TRADE_FREEZE_LEVEL Buying is done at the Ask price | Selling is done at the Bid price ------------------------------------------------|---------------------------------- TakeProfit >= Bid | TakeProfit <= Ask StopLoss <= Bid | StopLoss >= Ask TakeProfit - Bid >= SYMBOL_TRADE_STOPS_LEVEL | Ask - TakeProfit >= SYMBOL_TRADE_STOPS_LEVEL Bid - StopLoss >= SYMBOL_TRADE_STOPS_LEVEL | StopLoss - Ask >= SYMBOL_TRADE_STOPS_LEVEL */ if(!RefreshRates() || !m_symbol.Refresh()) return(false); //--- FreezeLevel -> for pending order and modification double freeze_level=m_symbol.FreezeLevel()*m_symbol.Point(); if(freeze_level==0.0) freeze_level=(m_symbol.Ask()-m_symbol.Bid())*3.0; freeze_level*=1.1; //--- StopsLevel -> for TakeProfit and StopLoss double stop_level=m_symbol.StopsLevel()*m_symbol.Point(); if(stop_level==0.0) stop_level=(m_symbol.Ask()-m_symbol.Bid())*3.0; stop_level*=1.1; if(freeze_level<=0.0 || stop_level<=0.0) return(false); level=(freeze_level>stop_level)?freeze_level:stop_level; //--- return(true); }
Sometimes it is necessary to add a volume check
Sample function:
//+------------------------------------------------------------------+ //| Check the correctness of the position volume | //+------------------------------------------------------------------+ bool CheckVolumeValue(double volume,string &error_description) { //--- minimal allowed volume for trade operations double min_volume=m_symbol.LotsMin(); if(volume<min_volume) { if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian") error_description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume); else error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume); return(false); } //--- maximal allowed volume of trade operations double max_volume=m_symbol.LotsMax(); if(volume>max_volume) { if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian") error_description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume); else error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume); return(false); } //--- get minimal step of volume changing double volume_step=m_symbol.LotsStep(); int ratio=(int)MathRound(volume/volume_step); if(MathAbs(ratio*volume_step-volume)>0.0000001) { if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian") error_description=StringFormat("Объем не кратен минимальному шагу SYMBOL_VOLUME_STEP=%.2f, ближайший правильный объем %.2f", volume_step,ratio*volume_step); else error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f", volume_step,ratio*volume_step); return(false); } error_description="Correct volume value"; return(true); }
This code can help to fix the problem and will tell you the error code
+ A function to check stop/freeze levels should also be added
Here sample:
Sometimes it is necessary to add a volume check
Sample function:
Thanks Igor, a lot of information to go through there but looks good to me.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am coding an EA for trading SAR. My bear positions, based on the SAR, never action. All bull positions work fine. Using counters for each function I have confirmed that every function works as required.
values. in the below code simply refers to a pre-made structure.
Removing all components of CTrade and just using counters each function operates perfectly. Add the CTrade functions and the OpenSell() function never actions although the counter still does. So why do the counters tell me each function is called correctly yet the OpenSell() function is NEVER called?