Nur Nutzer, die das Produkt gekauft oder gemietet haben, können Kommentare hinterlassen
Jochen1965  
Hello, your strategy seems to be very interesting! Unfortunately i am not able to modify your code in mt5. Is it not possible, that you publish a working ea for direct use and backtesting your strategy? This would be very kind of you!
Alireza Kamrani  
Jochen1965 #:
Hello, your strategy seems to be very interesting! Unfortunately i am not able to modify your code in mt5. Is it not possible, that you publish a working ea for direct use and backtesting your strategy? This would be very kind of you!
here You Are:

//+------------------------------------------------------------------+
//|                                                    Modified_EA.mq5 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// Include Trade class for MQL5
#include <Trade\Trade.mqh>

// Create an instance of CTrade
CTrade Trade;

// Define inputs for the strategy
input int fastMAPeriod = 10;      // Fast MA period
input int slowMAPeriod = 20;      // Slow MA period
input ENUM_MA_METHOD maMethod = MODE_SMA;  // Moving average method
input double RiskPercent = 0.01;  // Risk percentage (1%)
input double R2R = 2;             // Risk to Reward ratio
input double StopLossPoints = 100; // Stop Loss in points
input double MinimumStopLossPoints = 25; // Minimum SL in points

// Global variables
double lotSize = 0.01;
int maShift_current = 0; 
int maShift_Previous = 1;
bool lastCandleTime = 0;
bool IsBuy = false;
bool TradeIsOk = false;
double StopLoss = 0;
double TakeProfit = 0;

//+------------------------------------------------------------------+
//| Custom function to calculate Moving Average                      |
//+------------------------------------------------------------------+
double MACalculator(string symbol, ENUM_TIMEFRAMES timeframe, int period, int shift, 
                    ENUM_MA_METHOD method, ENUM_APPLIED_PRICE applied_price)
{
   double MAArray[];
   ArraySetAsSeries(MAArray, true);
   
   int handle = iMA(symbol, timeframe, period, 0, method, applied_price);
   if(handle == INVALID_HANDLE)
   {
      Print("Error creating MA indicator");
      return 0.0;
   }
   
   int copied = CopyBuffer(handle, 0, shift, 1, MAArray);
   if(copied <= 0)
   {
      Print("Error copying MA data, code: ", GetLastError());
      return 0.0;
   }
   
   return MAArray[0];
}

//+------------------------------------------------------------------+
//| Check if it's a new candle                                       |
//+------------------------------------------------------------------+
bool IsNewCanddle(ENUM_TIMEFRAMES timeframe)
{
   static datetime lastTime = 0;
   datetime currentTime = iTime(_Symbol, timeframe, 0);
   
   if(lastTime != currentTime)
   {
      lastTime = currentTime;
      return true;
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| Check if there's enough money for the trade                      |
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symbol, double lot, ENUM_ORDER_TYPE type)
{
   double margin = 0.0;
   
   if(!OrderCalcMargin(type, symbol, lot, SymbolInfoDouble(symbol, SYMBOL_ASK), margin))
   {
      Print("Error in OrderCalcMargin: ", GetLastError());
      return false;
   }
   
   if(margin > AccountInfoDouble(ACCOUNT_MARGIN_FREE))
   {
      Print("Not enough money for ", EnumToString(type), " ", lot, " ", symbol);
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Check if the volume is valid                                     |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume, string &error_description)
{
   double min_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double max_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   
   if(volume < min_volume)
   {
      error_description = "Volume is less than minimum allowed";
      return false;
   }
   
   if(volume > max_volume)
   {
      error_description = "Volume is greater than maximum allowed";
      return false;
   }
   
   int steps = (int)MathRound((volume - min_volume) / volume_step);
   double correct_volume = min_volume + steps * volume_step;
   
   if(MathAbs(volume - correct_volume) > 0.0000001)
   {
      error_description = "Volume is not a multiple of minimum step";
      return false;
   }
   
   error_description = "";
   return true;
}

//+------------------------------------------------------------------+
//| Calculate optimum lot size based on risk                         |
//+------------------------------------------------------------------+
double OptimumLotSize(string symbol, double entry_price, double stop_loss, double risk_percent)
{
   double tick_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   double tick_value = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
   double lot_step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   double min_lot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   double max_lot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
   
   double risk_money = AccountInfoDouble(ACCOUNT_BALANCE) * risk_percent;
   double price_distance = MathAbs(entry_price - stop_loss);
   double num_ticks = price_distance / tick_size;
   double tick_value_converted = tick_value;
   
   // Adjust for account currency (if necessary)
   string account_currency = AccountInfoString(ACCOUNT_CURRENCY);
   string base_currency = SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE);
   
   double lot_size = risk_money / (num_ticks * tick_value_converted);
   lot_size = MathFloor(lot_size / lot_step) * lot_step;
   
   if(lot_size < min_lot) lot_size = min_lot;
   if(lot_size > max_lot) lot_size = max_lot;
   
   return lot_size;
}

//+------------------------------------------------------------------+
//| Count open orders for symbol                                     |
//+------------------------------------------------------------------+
int SymbolOpenOrders(string symbol)
{
   int count = 0;
   
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      ulong ticket = PositionGetTicket(i);
      if(ticket <= 0) continue;
      
      if(!PositionSelectByTicket(ticket)) continue;
      
      string pos_symbol = PositionGetString(POSITION_SYMBOL);
      if(pos_symbol == symbol) count++;
   }
   
   return count;
}

//+------------------------------------------------------------------+
//| Close all open positions                                         |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      ulong ticket = PositionGetTicket(i);
      if(ticket <= 0) continue;
      
      if(!PositionSelectByTicket(ticket)) continue;
      
      Trade.PositionClose(ticket);
   }
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set up the Trade object
   Trade.SetExpertMagicNumber(123456);  // Set a unique magic number
   Trade.SetMarginMode();
   Trade.SetTypeFillingBySymbol(_Symbol);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Cleanup code here
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Apply MA to Close prices
   ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE;

   // Get the values of the current and previous moving averages   
   double fastMA_Current = MACalculator(_Symbol, PERIOD_CURRENT, fastMAPeriod, maShift_current, maMethod, appliedPrice);
   double slowMA_Current = MACalculator(_Symbol, PERIOD_CURRENT, slowMAPeriod, maShift_current, maMethod, appliedPrice);
   double fastMA_Previous = MACalculator(_Symbol, PERIOD_CURRENT, fastMAPeriod, maShift_Previous, maMethod, appliedPrice);
   double slowMA_Previous = MACalculator(_Symbol, PERIOD_CURRENT, slowMAPeriod, maShift_Previous, maMethod, appliedPrice);
   double Reference_MA = MACalculator(_Symbol, PERIOD_CURRENT, 100, maShift_Previous, maMethod, appliedPrice);
   
   // Close all positions if profit exceeds 100 (commented out in original code)
   // if(AccountInfoDouble(ACCOUNT_PROFIT) > 100) CloseAllPositions();
   
   // Get current prices
   double ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   double bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
   string error_message = "";

   // Check for new H1 candle
   if(IsNewCanddle(PERIOD_H1))
   {
      TradeIsOk = true;
   }

   // Check for sell signal
   if(fastMA_Previous < slowMA_Previous && fastMA_Current > slowMA_Current && 
      SymbolOpenOrders(_Symbol) == 0 && bid < Reference_MA)
   {
      // Calculate lot size or use default
      // lotSize = OptimumLotSize(_Symbol, bid, bid + StopLossPoints * _Point, RiskPercent);
      lotSize = 0.01;  // Default as in original code
      
      // Check if we have enough money and valid volume
      bool enough_money = CheckMoneyForTrade(_Symbol, lotSize, ORDER_TYPE_SELL);
      bool enough_volume = CheckVolumeValue(lotSize, error_message);
      
      // Calculate SL and TP
      StopLoss = bid + StopLossPoints * _Point;
      TakeProfit = bid - R2R * StopLossPoints * _Point;
      
      // Execute sell order if conditions are met
      if(enough_money && enough_volume)
      {
         Trade.Sell(lotSize, _Symbol, 0, StopLoss, TakeProfit, "Logic Order");
         IsBuy = false;
      }
   }

   // Check for buy signal
   if(fastMA_Previous > slowMA_Previous && fastMA_Current < slowMA_Current && 
      SymbolOpenOrders(_Symbol) == 0 && ask > Reference_MA)
   {
      // Calculate lot size or use default
      // lotSize = OptimumLotSize(_Symbol, ask, ask - StopLossPoints * _Point, RiskPercent);
      lotSize = 0.01;  // Default as in original code
      
      // Check if we have enough money and valid volume
      bool enough_money = CheckMoneyForTrade(_Symbol, lotSize, ORDER_TYPE_BUY);
      bool enough_volume = CheckVolumeValue(lotSize, error_message);
      
      // Calculate SL and TP
      StopLoss = ask - StopLossPoints * _Point;
      TakeProfit = ask + R2R * StopLossPoints * _Point;
      
      // Execute buy order if conditions are met
      if(enough_money && enough_volume)
      {
         Trade.Buy(lotSize, _Symbol, 0, StopLoss, TakeProfit, "Logic Order");
         IsBuy = true;
      }
   }
   
   // The cascade trading part is commented out since the ST_StopLoss_TakeProfit structure
   // isn't defined in the provided code and would require implementation
   /*
   if(TradeIsOk && SymbolOpenOrders(_Symbol) >= 1)
   {   
      // Implement your cascade trading logic here if needed
   }
   */
}