//+------------------------------------------------------------------+ //| TrailingStop.mqh – trailing stop pro režim jedné pozice | //+------------------------------------------------------------------+ #property copyright "TestRefactor" #property strict #ifndef __TRAILING_STOP_MQH__ #define __TRAILING_STOP_MQH__ #include "Context.mqh" #include "Positions.mqh" #include "Logger.mqh" #include //+------------------------------------------------------------------+ //| CTrailingStop – logika trailing stop uvnitř třídy | //+------------------------------------------------------------------+ class CTrailingStop { private: SContext m_ctx; CPositions *m_positions; CTrade *m_trade; string m_symbol; public: CTrailingStop() : m_positions(NULL), m_trade(NULL), m_symbol("") {} void SetContext(const SContext &ctx) { m_ctx = ctx; } void SetPositions(CPositions *pos) { m_positions = pos; } void SetTrade(CTrade *trade) { m_trade = trade; } void SetSymbol(string symbol) { m_symbol = symbol; } void Update() { if(m_ctx.tradeMode == TRADE_GRID || m_ctx.exitMode != EXIT_BY_SL_TRAIL) return; if(!m_trade || !m_positions) return; double tickValue = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_SIZE); if(tickValue <= 0 || tickSize <= 0) return; m_positions.Refresh(); ulong tickets[]; m_positions.GetTickets(tickets); int n = ArraySize(tickets); for(int i = 0; i < n; i++) { if(!PositionSelectByTicket(tickets[i])) continue; if(PositionGetString(POSITION_SYMBOL) != m_symbol) continue; double profit = PositionGetDouble(POSITION_PROFIT); if(profit < m_ctx.trailingTriggerUSD) continue; ulong ticket = tickets[i]; double sl = PositionGetDouble(POSITION_SL); double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double volume = PositionGetDouble(POSITION_VOLUME); double gapUSD = m_ctx.trailingTriggerUSD - m_ctx.trailingDistanceUSD; double targetProfitUSD = profit - gapUSD; double priceDelta = (targetProfitUSD * tickSize) / (tickValue * volume); double newSl = 0; if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { newSl = NormalizeDouble(openPrice + priceDelta, _Digits); if(newSl > sl) m_trade.PositionModify(ticket, newSl, 0); } else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { newSl = NormalizeDouble(openPrice - priceDelta, _Digits); if(newSl < sl || sl == 0) m_trade.PositionModify(ticket, newSl, 0); } } } }; #endif