Initial commit: MQL Trading Bots

- MultiSignal Confluence EA v1.11 (stop loss bug fixed)
- Harmonic Pattern Finder v2 (optimized)
- Candlestick Pattern EA (fixed)
- Pivot Fade EA v4 (fixed)
- Bot series (10001, 10002, EnhancedEA)

Performance: ~19% return in 2 months on 00k account
This commit is contained in:
2026-03-21 18:39:48 -04:00
commit 74308b38e7
13 changed files with 4262 additions and 0 deletions

713
CandlestickPatternEA.mq5 Executable file
View File

@@ -0,0 +1,713 @@
//+------------------------------------------------------------------+
//| CandlestickPatternEA.mq5 |
//| Copyright 2025, ART inc. |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, ARTi"
#property link "https://www.abbeyroadtech.com"
#property version "1.00"
#property strict
// Include necessary libraries
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
// Input Parameters for Trading
input double InpLotSize = 0.01; // Lot size
input int InpStopLoss = 100; // Stop Loss in points
input int InpTakeProfit = 200; // Take Profit in points
input bool InpUseHammerSignals = true; // Trade Hammer signals
input bool InpUsePinBarSignals = true; // Trade Pin Bar signals
input bool InpUseWickRejection = true; // Trade Wick Rejection signals
input bool InpUseTweezerTop = true; // Trade Tweezer Top signals
input bool InpUseShootingStar = true; // Trade Shooting Star signals
input int InpMaxPositions = 5; // Maximum open positions
input bool InpCloseOnOppositeSignal = true; // Close position on opposite signal
// Trailing Stop Parameters
input bool InpUseTrailingStop = true; // Use trailing stop
input int InpTrailingStart = 50; // Points of profit before trailing begins
input int InpTrailingStep = 10; // Trailing step in points
input int InpTrailingStop = 30; // Trailing stop distance in points
// Input Parameters for Moving Average Filter
input int InpFastMA = 50; // Fast MA period
input int InpSlowMA = 200; // Slow MA period
input ENUM_MA_METHOD InpMAMethod = MODE_SMA; // MA method
input ENUM_APPLIED_PRICE InpMAPrice = PRICE_CLOSE; // Applied price
// Input Parameters for Indicator
input int InpCandlesToAnalyze = 300; // Number of candles to analyze
input double InpHammerRatio = 0.3; // Hammer body to wick ratio
input double InpPinBarRatio = 0.25; // Pin bar body to wick ratio
input double InpWickRejectionRatio = 0.4; // Wick rejection ratio
input double InpTweezerMaxDiff = 0.1; // Tweezer top max difference %
input double InpShootingStarRatio = 0.3; // Shooting star body to wick ratio
input int InpConfirmationCandles = 1; // Confirmation candles
// ATR Filter Parameters
input bool InpUseATRFilter = true; // Use ATR filter
input int InpATRPeriod = 14; // ATR period
input group "ATR Filter Mode"
input bool InpUseFixedATRValue = true; // Use fixed ATR value (vs percentage of peak)
input double InpMinATRValue = 0.0010; // Fixed: Minimum ATR value to trade (adjust for your pair)
input int InpATRLookbackPeriod = 50; // Period to find peak ATR value
input double InpATRPercentage = 30.0; // Percentage of peak ATR (30% = 0.3 * max ATR)
// Bollinger Band Width Filter Parameters
input bool InpUseBBWFilter = true; // Use Bollinger Band Width filter
input int InpBBPeriod = 20; // Bollinger Bands period
input double InpBBDeviation = 2.0; // Bollinger Bands deviation
input double InpMinBBWidth = 0.0020; // Minimum BB width to trade (as ratio)
// Global Variables
CTrade Trade; // Trading object
CSymbolInfo SymbolInfo; // Symbol info object
int FastMAHandle; // Fast MA indicator handle
int SlowMAHandle; // Slow MA indicator handle
int ATRHandle; // ATR indicator handle
int BBHandle; // Bollinger Bands indicator handle
int PatternIndicatorHandle; // Candlestick pattern indicator handle
bool isTradingAllowed = true; // Flag to control trading
datetime lastBarTime = 0; // Last processed bar time
// Order tracking
int totalBuyPositions = 0; // Track current buy positions
int totalSellPositions = 0; // Track current sell positions
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize symbol info
if(!SymbolInfo.Name(_Symbol))
{
Print("Failed to initialize symbol info");
return INIT_FAILED;
}
// Initialize trade object
Trade.SetExpertMagicNumber(123456); // Set a magic number for this EA
// Initialize indicator handles
FastMAHandle = iMA(_Symbol, _Period, InpFastMA, 0, InpMAMethod, InpMAPrice);
SlowMAHandle = iMA(_Symbol, _Period, InpSlowMA, 0, InpMAMethod, InpMAPrice);
// Initialize volatility filter indicators
if(InpUseATRFilter)
ATRHandle = iATR(_Symbol, _Period, InpATRPeriod);
if(InpUseBBWFilter)
BBHandle = iBands(_Symbol, _Period, InpBBPeriod, InpBBDeviation, 0, PRICE_CLOSE);
// Initialize the custom candlestick pattern indicator
PatternIndicatorHandle = iCustom(_Symbol, _Period, "CandlePatternConfirmation",
InpCandlesToAnalyze, InpHammerRatio, InpPinBarRatio,
InpWickRejectionRatio, InpTweezerMaxDiff, InpShootingStarRatio, InpConfirmationCandles);
// Check if indicators were created successfully
if(FastMAHandle == INVALID_HANDLE || SlowMAHandle == INVALID_HANDLE || PatternIndicatorHandle == INVALID_HANDLE)
{
Print("Failed to create primary indicators: Error ", GetLastError());
return INIT_FAILED;
}
if((InpUseATRFilter && ATRHandle == INVALID_HANDLE) || (InpUseBBWFilter && BBHandle == INVALID_HANDLE))
{
Print("Failed to create volatility filter indicators: Error ", GetLastError());
return INIT_FAILED;
}
// Set lastBarTime to avoid immediate trading on EA start
lastBarTime = iTime(_Symbol, _Period, 0);
// Count currently open positions
CountOpenPositions();
// Log initialization info
string atrModeDesc = InpUseFixedATRValue ? "Fixed value: " + DoubleToString(InpMinATRValue, 5) :
"Dynamic: " + DoubleToString(InpATRPercentage, 1) + "% of peak over " +
IntegerToString(InpATRLookbackPeriod) + " bars";
Print("EA initialized with volatility filters: ATR = ", (InpUseATRFilter ? "ON (" + atrModeDesc + ")" : "OFF"),
", BBW = ", (InpUseBBWFilter ? "ON" : "OFF"));
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles
if(FastMAHandle != INVALID_HANDLE) IndicatorRelease(FastMAHandle);
if(SlowMAHandle != INVALID_HANDLE) IndicatorRelease(SlowMAHandle);
if(PatternIndicatorHandle != INVALID_HANDLE) IndicatorRelease(PatternIndicatorHandle);
if(InpUseATRFilter && ATRHandle != INVALID_HANDLE) IndicatorRelease(ATRHandle);
if(InpUseBBWFilter && BBHandle != INVALID_HANDLE) IndicatorRelease(BBHandle);
Print("Expert removed. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if there's a new bar
datetime currentBarTime = iTime(_Symbol, _Period, 0);
bool isNewBar = (currentBarTime != lastBarTime);
// Process trailing stops on every tick (not just new bars)
if(InpUseTrailingStop)
{
ManageTrailingStops();
}
// Only process signals on new bar
if(!isNewBar) return;
// Update lastBarTime
lastBarTime = currentBarTime;
// Check if trading is allowed
if(!isTradingAllowed) return;
// Count currently open positions
CountOpenPositions();
// Check if maximum positions reached
if(totalBuyPositions + totalSellPositions >= InpMaxPositions) return;
// Check volatility filters first
if(!CheckVolatilityFilters())
{
Print("Trade skipped due to low volatility or market indecision");
return;
}
// Check for MA filter
bool fastAboveSlow = false;
bool fastBelowSlow = false;
CheckMAFilter(fastAboveSlow, fastBelowSlow);
// Get candlestick pattern signals
bool hammerSignal = false;
bool pinBarSignal = false;
bool wickRejectionBullSignal = false;
bool wickRejectionBearSignal = false;
bool tweezerTopSignal = false;
bool shootingStarSignal = false;
CheckCandlestickPatterns(hammerSignal, pinBarSignal, wickRejectionBullSignal,
wickRejectionBearSignal, tweezerTopSignal, shootingStarSignal);
// Define candlestick pattern signals (without MA filter)
bool buyPatternSignal = (InpUseHammerSignals && hammerSignal) ||
(InpUseWickRejection && wickRejectionBullSignal);
bool sellPatternSignal = (InpUsePinBarSignals && pinBarSignal) ||
(InpUseWickRejection && wickRejectionBearSignal) ||
(InpUseTweezerTop && tweezerTopSignal) ||
(InpUseShootingStar && shootingStarSignal);
// Check for opposite candlestick pattern signals and close positions if needed
// This happens regardless of MA filter - based ONLY on candlestick patterns
if(sellPatternSignal && InpCloseOnOppositeSignal)
{
// Close buy positions on a sell pattern signal
CloseBuyPositions();
}
if(buyPatternSignal && InpCloseOnOppositeSignal)
{
// Close sell positions on a buy pattern signal
CloseSellPositions();
}
// For opening new positions, use both candlestick pattern AND MA filter
bool validBuySignal = buyPatternSignal && fastAboveSlow;
bool validSellSignal = sellPatternSignal && fastBelowSlow;
// Process buy signals
if(validBuySignal && (totalBuyPositions < InpMaxPositions))
{
// Open buy positions based on specific signals
if(InpUseHammerSignals && hammerSignal)
{
OpenBuyPosition("Hammer");
}
else if(InpUseWickRejection && wickRejectionBullSignal)
{
OpenBuyPosition("Wick Rejection Bullish");
}
}
// Process sell signals
if(validSellSignal && (totalSellPositions < InpMaxPositions))
{
// Open sell positions based on specific signals
if(InpUsePinBarSignals && pinBarSignal)
{
OpenSellPosition("Pin Bar");
}
else if(InpUseWickRejection && wickRejectionBearSignal)
{
OpenSellPosition("Wick Rejection Bearish");
}
else if(InpUseTweezerTop && tweezerTopSignal)
{
OpenSellPosition("Tweezer Top");
}
else if(InpUseShootingStar && shootingStarSignal)
{
OpenSellPosition("Shooting Star");
}
}
}
//+------------------------------------------------------------------+
//| Check volatility filters to avoid trades during indecision |
//+------------------------------------------------------------------+
bool CheckVolatilityFilters()
{
// Check ATR Filter
if(InpUseATRFilter)
{
double atrValues[];
double minRequiredATR = 0;
// Get current ATR value
if(CopyBuffer(ATRHandle, 0, 0, 1, atrValues) <= 0)
{
Print("Failed to copy current ATR value: Error ", GetLastError());
return false;
}
double currentATR = atrValues[0];
// Determine which ATR threshold to use
if(InpUseFixedATRValue)
{
// Use the fixed value directly
minRequiredATR = InpMinATRValue;
}
else
{
// Get historical ATR values for the lookback period
if(CopyBuffer(ATRHandle, 0, 0, InpATRLookbackPeriod, atrValues) <= 0)
{
Print("Failed to copy historical ATR values: Error ", GetLastError());
return false;
}
// Find the peak ATR value in the lookback period
double peakATR = 0;
for(int i = 0; i < InpATRLookbackPeriod; i++)
{
if(atrValues[i] > peakATR)
peakATR = atrValues[i];
}
// Calculate minimum required ATR as percentage of peak
minRequiredATR = peakATR * (InpATRPercentage / 100.0);
Print("Dynamic ATR Threshold: Peak ATR = ", DoubleToString(peakATR, 5),
", Required ", DoubleToString(InpATRPercentage, 1), "% = ",
DoubleToString(minRequiredATR, 5));
}
// If current ATR is below threshold, market volatility is too low
if(currentATR < minRequiredATR)
{
Print("ATR Filter: Current ATR (", DoubleToString(currentATR, 5),
") is below minimum threshold (", DoubleToString(minRequiredATR, 5), ")");
return false;
}
else
{
Print("ATR Filter PASSED: Current ATR (", DoubleToString(currentATR, 5),
") exceeds minimum threshold (", DoubleToString(minRequiredATR, 5), ")");
}
}
// Check Bollinger Band Width Filter
if(InpUseBBWFilter)
{
double upperBand[1], lowerBand[1], middleBand[1];
if(CopyBuffer(BBHandle, 1, 0, 1, upperBand) <= 0 ||
CopyBuffer(BBHandle, 2, 0, 1, lowerBand) <= 0 ||
CopyBuffer(BBHandle, 0, 0, 1, middleBand) <= 0)
{
Print("Failed to copy Bollinger Bands values: Error ", GetLastError());
return false;
}
// Calculate width as a ratio rather than raw points
double bbWidth = (upperBand[0] - lowerBand[0]) / middleBand[0];
// If BB width is below minimum threshold, market is in consolidation
if(bbWidth < InpMinBBWidth)
{
Print("BB Width Filter: Current BB width (", DoubleToString(bbWidth, 5),
") is below minimum threshold (", DoubleToString(InpMinBBWidth, 5), ")");
return false;
}
else
{
Print("BB Width Filter PASSED: Current width (", DoubleToString(bbWidth, 5),
") exceeds minimum threshold (", DoubleToString(InpMinBBWidth, 5), ")");
}
}
// All filters passed or are disabled
return true;
}
//+------------------------------------------------------------------+
//| Check Moving Average Filter |
//+------------------------------------------------------------------+
void CheckMAFilter(bool &fastAboveSlow, bool &fastBelowSlow)
{
// Get MA values
double fastMAValue[1] = {0};
double slowMAValue[1] = {0};
// Copy MA values
if(CopyBuffer(FastMAHandle, 0, 0, 1, fastMAValue) <= 0 ||
CopyBuffer(SlowMAHandle, 0, 0, 1, slowMAValue) <= 0)
{
Print("Failed to copy MA values: Error ", GetLastError());
return;
}
// Set filter flags
fastAboveSlow = (fastMAValue[0] > slowMAValue[0]);
fastBelowSlow = (fastMAValue[0] < slowMAValue[0]);
}
//+------------------------------------------------------------------+
//| Check Candlestick Patterns |
//+------------------------------------------------------------------+
void CheckCandlestickPatterns(bool &hammerSignal, bool &pinBarSignal,
bool &wickRejectionBullSignal, bool &wickRejectionBearSignal,
bool &tweezerTopSignal, bool &shootingStarSignal)
{
// Arrays to store indicator values for each pattern
double hammerValues[1] = {0};
double pinBarValues[1] = {0};
double wickRejectionValues[1] = {0};
double tweezerTopValues[1] = {0};
double shootingStarValues[1] = {0};
// Get values from the pattern indicator
if(CopyBuffer(PatternIndicatorHandle, 0, 1, 1, hammerValues) <= 0 ||
CopyBuffer(PatternIndicatorHandle, 1, 1, 1, pinBarValues) <= 0 ||
CopyBuffer(PatternIndicatorHandle, 2, 1, 1, wickRejectionValues) <= 0 ||
CopyBuffer(PatternIndicatorHandle, 3, 1, 1, tweezerTopValues) <= 0 ||
CopyBuffer(PatternIndicatorHandle, 4, 1, 1, shootingStarValues) <= 0)
{
Print("Failed to copy pattern values: Error ", GetLastError());
return;
}
// Set signal flags
hammerSignal = (hammerValues[0] != EMPTY_VALUE);
pinBarSignal = (pinBarValues[0] != EMPTY_VALUE);
// For wick rejection, we need to determine if it's bullish or bearish
if(wickRejectionValues[0] != EMPTY_VALUE)
{
// Determine if bullish or bearish based on the position relative to the candle
double candleHigh = iHigh(_Symbol, _Period, 1);
wickRejectionBullSignal = (wickRejectionValues[0] < candleHigh);
wickRejectionBearSignal = (wickRejectionValues[0] > candleHigh);
}
else
{
wickRejectionBullSignal = false;
wickRejectionBearSignal = false;
}
tweezerTopSignal = (tweezerTopValues[0] != EMPTY_VALUE);
shootingStarSignal = (shootingStarValues[0] != EMPTY_VALUE);
}
//+------------------------------------------------------------------+
//| Open a Buy position |
//+------------------------------------------------------------------+
void OpenBuyPosition(string signalType)
{
// Update symbol info
SymbolInfo.Refresh();
SymbolInfo.RefreshRates();
// Calculate position size
double lotSize = InpLotSize;
// Calculate stop loss and take profit levels
double stopLoss = SymbolInfo.Ask() - InpStopLoss * SymbolInfo.Point();
double takeProfit = SymbolInfo.Ask() + InpTakeProfit * SymbolInfo.Point();
// Execute buy order
if(!Trade.Buy(lotSize, _Symbol, SymbolInfo.Ask(), stopLoss, takeProfit, signalType))
{
Print("Buy order failed: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
else
{
Print("Buy order placed successfully: Signal = ", signalType);
totalBuyPositions++;
}
}
//+------------------------------------------------------------------+
//| Open a Sell position |
//+------------------------------------------------------------------+
void OpenSellPosition(string signalType)
{
// Update symbol info
SymbolInfo.Refresh();
SymbolInfo.RefreshRates();
// Calculate position size
double lotSize = InpLotSize;
// Calculate stop loss and take profit levels
double stopLoss = SymbolInfo.Bid() + InpStopLoss * SymbolInfo.Point();
double takeProfit = SymbolInfo.Bid() - InpTakeProfit * SymbolInfo.Point();
// Execute sell order
if(!Trade.Sell(lotSize, _Symbol, SymbolInfo.Bid(), stopLoss, takeProfit, signalType))
{
Print("Sell order failed: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
else
{
Print("Sell order placed successfully: Signal = ", signalType);
totalSellPositions++;
}
}
//+------------------------------------------------------------------+
//| Close all Buy positions |
//+------------------------------------------------------------------+
void CloseBuyPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionSelectByTicket(PositionGetTicket(i)))
{
// Check if it's our EA's position
if(PositionGetInteger(POSITION_MAGIC) == Trade.RequestMagic())
{
// Check if it's a buy position
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
// Close the position
if(!Trade.PositionClose(PositionGetTicket(i)))
{
Print("Failed to close buy position: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
else
{
Print("Buy position closed on opposite signal");
}
}
}
}
}
// Reset counter
totalBuyPositions = 0;
}
//+------------------------------------------------------------------+
//| Close all Sell positions |
//+------------------------------------------------------------------+
void CloseSellPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionSelectByTicket(PositionGetTicket(i)))
{
// Check if it's our EA's position
if(PositionGetInteger(POSITION_MAGIC) == Trade.RequestMagic())
{
// Check if it's a sell position
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{
// Close the position
if(!Trade.PositionClose(PositionGetTicket(i)))
{
Print("Failed to close sell position: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
else
{
Print("Sell position closed on opposite signal");
}
}
}
}
}
// Reset counter
totalSellPositions = 0;
}
//+------------------------------------------------------------------+
//| Close only losing positions by type |
//+------------------------------------------------------------------+
void CloseLosingPositions(ENUM_POSITION_TYPE posType)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionSelectByTicket(PositionGetTicket(i)))
{
// Check if it's our EA's position and the correct type
if(PositionGetInteger(POSITION_MAGIC) == Trade.RequestMagic() &&
PositionGetInteger(POSITION_TYPE) == posType)
{
// Check if the position is losing
double posProfit = PositionGetDouble(POSITION_PROFIT);
if(posProfit < 0) // Only close if it's losing money
{
// Close the position
if(!Trade.PositionClose(PositionGetTicket(i)))
{
Print("Failed to close losing position: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
else
{
string posTypeStr = (posType == POSITION_TYPE_BUY) ? "Buy" : "Sell";
Print("Losing ", posTypeStr, " position closed on opposite signal. Profit: ", posProfit);
}
}
}
}
}
// Reset counters after closing positions
CountOpenPositions();
}
//+------------------------------------------------------------------+
//| Count open positions |
//+------------------------------------------------------------------+
void CountOpenPositions()
{
totalBuyPositions = 0;
totalSellPositions = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByTicket(PositionGetTicket(i)))
{
// Check if it's our EA's position
if(PositionGetInteger(POSITION_MAGIC) == Trade.RequestMagic())
{
// Count by position type
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
totalBuyPositions++;
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
totalSellPositions++;
}
}
}
}
//+------------------------------------------------------------------+
//| Manage trailing stops for all open positions |
//+------------------------------------------------------------------+
void ManageTrailingStops()
{
// Update symbol info
SymbolInfo.Refresh();
SymbolInfo.RefreshRates();
double ask = SymbolInfo.Ask();
double bid = SymbolInfo.Bid();
double point = SymbolInfo.Point();
// Process all open positions
for(int i = 0; i < PositionsTotal(); i++)
{
// Select position by ticket
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket))
continue;
// Check if it's our EA's position
if(PositionGetInteger(POSITION_MAGIC) != Trade.RequestMagic())
continue;
// Get position details
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// Trailing logic for BUY positions
if(posType == POSITION_TYPE_BUY)
{
// Calculate profit in points
double profitPoints = (bid - openPrice) / point;
// Only trail if minimum profit is reached
if(profitPoints >= InpTrailingStart)
{
// Calculate new stop loss level
double newSL = bid - InpTrailingStop * point;
// Only modify if new SL is higher (better) than current one
// and at least one trailing step away from current SL
if(newSL > currentSL + InpTrailingStep * point)
{
if(Trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP)))
{
Print("Trailing stop adjusted for BUY position #", ticket,
" New stop loss: ", newSL,
" Previous stop loss: ", currentSL);
}
else
{
Print("Failed to adjust trailing stop: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
}
}
}
// Trailing logic for SELL positions
else if(posType == POSITION_TYPE_SELL)
{
// Calculate profit in points
double profitPoints = (openPrice - ask) / point;
// Only trail if minimum profit is reached
if(profitPoints >= InpTrailingStart)
{
// Calculate new stop loss level
double newSL = ask + InpTrailingStop * point;
// Only modify if new SL is lower (better) than current one
// and at least one trailing step away from current SL
if(currentSL == 0 || newSL < currentSL - InpTrailingStep * point)
{
if(Trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP)))
{
Print("Trailing stop adjusted for SELL position #", ticket,
" New stop loss: ", newSL,
" Previous stop loss: ", currentSL);
}
else
{
Print("Failed to adjust trailing stop: Error ", Trade.ResultRetcode(), ", ", Trade.ResultRetcodeDescription());
}
}
}
}
}
}