mql5/Experts/testRefactor2/TrailingStop.mqh

72 Zeilen
2,7 KiB
MQL5

2026-02-01 21:39:33 +01:00
//+------------------------------------------------------------------+
//| 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 <Trade/Trade.mqh>
//+------------------------------------------------------------------+
//| 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