- www.mql5.com
Are you verifying that the prices are aligned to the tick size? I don't see that in your code.
Are you verifying the Stops Level and Freeze Levels? I also don't see that in your code.
The checks a trading robot must pass before publication in the Market
MetaQuotes, 2016.08.01 09:30
Before any product is published in the Market, it must undergo compulsory preliminary checks in order to ensure a uniform quality standard. This article considers the most frequent errors made by developers in their technical indicators and trading robots. An also shows how to self-test a product before sending it to the Market.
Forum on trading, automated trading systems and testing trading strategies
Tick size vs Point(), can be a little tricky in Multicurrency EA
Fernando Carreiro, 2022.03.09 12:11
Tick Size and Point Size can be very different especially on stocks and other symbols besides forex.
Always use Tick Size to adjust and align your prices, not the point size. In essence, make sure that your price quotes, are properly aligned to the Tick size (see following examples).
... double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE ); ... double normalised_price = round( price / tick_size ) * tick_size; ... // Or use a function double Round2Ticksize( double price ) { double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE ); return( round( price / tick_size ) * tick_size ); };
Should I utilize tick size during trailing stop losses? Freeze Levels, Stop Levels are returning zero for now but thanks for pointing out as it'll be needed when placing orders and trailing stop losses as they change from broker to broker.
I've added in the necessary code snippet and added in a variable called tick_size which updates for every symbol, calculating and storing it under normalised_sl and just assigning that as my stop-loss send request, should I use it anywhere else for comparing?
def trail_sl(symbol, order_ticket, timeframe, stop_loss_dict): while True: bars = mt5.copy_rates_from_pos(symbol, timeframe, 0, 4) bars_df = pd.DataFrame(bars) bar1_high = bars_df['high'].iloc[0] bar2_high = bars_df['high'].iloc[1] bar3_high = bars_df['high'].iloc[2] bar1_low = bars_df['low'].iloc[0] bar2_low = bars_df['low'].iloc[1] bar3_low = bars_df['low'].iloc[2] if mt5.positions_get(ticket=order_ticket): position_type = mt5.positions_get(ticket=order_ticket)[0].type if position_type == mt5.ORDER_TYPE_SELL: stop_loss_value = max( bar1_high, bar2_high, bar3_high) # Sell order S/L else: stop_loss_value = min(bar1_low, bar2_low, bar3_low) # Buy order S/L tick_size = mt5.symbol_info(symbol).trade_tick_size normalised_sl = round(stop_loss_value / tick_size) * tick_size if normalised_sl != stop_loss_dict[symbol]: current_sl = mt5.positions_get(ticket=order_ticket)[0].sl if normalised_sl != current_sl: request = { "action": mt5.TRADE_ACTION_SLTP, "position": order_ticket, "symbol": symbol, "magic": 24001, "sl": normalised_sl } result = mt5.order_send(request) if result.retcode == mt5.TRADE_RETCODE_DONE: print( f"[{datetime.now()}] Trailing Stop Loss for Order {order_ticket} updated. New S/L: {normalised_sl}") print() stop_loss_dict[symbol] = normalised_sl elif result.retcode == 10025: # Ignore error code 10025 pass else: print( f"[{datetime.now()}] Failed to update Trailing Stop Loss for Order {order_ticket}: {result.comment}") print(f"Error code: {result.retcode}") print() time.sleep(1) # Wait for 1 second before checking again
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
For reference here is one of the many log messages I receive in the MetaTrader 5's Journal
2023.06.02 00:23:36.885 Trades '5013799956': failed modify #50475513619 sell 0.01 AUDUSD sl: 0.65727, tp: 0.00000 -> sl: 0.65722, tp: 0.00000 [Invalid stops]
This seems to be an issue with the trail_sl function which handles the trailing of stop losses... but not exactly sure where to pin-point it...
I am using MetaQuotes-Demo server for testing out and ruling off what could be causing the issue for invalid stops... Perhaps the stop-loss is too small of a change for it to even send?