Советник MQL4 ничего не делает - PullRequest
0 голосов
/ 01 июля 2018

Предполагается, что этот бот покупается на основе уровней поддержки и сопротивления, а стоп-лосс - на уровне сопротивления скользящих средних. Когда я проверю это, он не будет ничего пытаться. Как мне отладить это, чтобы сделать то, что я хочу?

После просмотра кода у вас есть какие-либо пожелания или замечания? Я попытался прокомментировать код как можно лучше.

#property strict
string BotName = "SRMATrader";

/********** SETTINGS *************/
extern int Magic = 8008;
string CandleColor;
int MaxCloseSpreadPips = 600;
int MaxTrades = 1; // was 10
int AcceptableSpread = 2;
double LotsToTrade = .2;     // 0.1
double StopLoss = -3700;   // 3800
double ProfitTarget = 20.00;  // $280 at 2.0 trade size


int MaxOpenOrderDurationSeconds = (5 * 24 * 60 * 60); // 5 days was profitable 
int TradeDelayTimeSeconds = 30; //(10 * 24 * 60 * 60); // 10 Days
int PendingOrderExpirationSeconds = (4 * 24 * 60 * 60); // 4 Days
datetime LastTradePlacedTimestamp = 0;


int OnInit()
{
   return(INIT_SUCCEEDED);
}


void OnDeinit(const int reason)
{

}

// MAIN LOOP
void OnTick()
{  


  double CurrentPrice = MarketInfo(Symbol(), MODE_BID);

  double CandleResistance = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_HIGH, 0);

  double CandleSupport = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_LOW, 0);

   // Should we place a trade?
   if (GetTotalOpenTrades() < MaxTrades)
   {
      if ( (TimeCurrent() - LastTradePlacedTimestamp) > TradeDelayTimeSeconds ) 
      {

         // long
         if ( CurrentPrice <= CandleSupport )
         {

            if (CandleColor == "Green") 
            {
               PlacePendingOrder("Green", LotsToTrade, CandleSupport, PendingOrderExpirationSeconds);
               LastTradePlacedTimestamp = TimeCurrent();
            }
         }

         // short
         if ( CurrentPrice >= CandleResistance) 
         {
            if (CheckForTradeSetup() == "Red" )
            {
               PlacePendingOrder("Red", LotsToTrade, CandleResistance, PendingOrderExpirationSeconds);
               LastTradePlacedTimestamp = TimeCurrent();
            }

         }

      } 

   }

   if (GetTotalOpenTrades() > 0) 
   {
      CloseTradeAfterAge(MaxOpenOrderDurationSeconds);
      CheckForOrderClose(ProfitTarget, StopLoss);
   }

} // end OnTick()


string CheckForTradeSetup()
{
  double CurrentPrice = MarketInfo(Symbol(), MODE_BID);

  double CandleSupport = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_LOW, 0); 
  double CandleResistance = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_HIGH, 0);


    if ( CurrentPrice <= CandleSupport )
   {
      CandleColor = "Green";
   }
   if ( CurrentPrice >= CandleResistance )
   {
      CandleColor = "Red";
   }

   return "no-setup";

}


void PlacePendingOrder(string Trade_Type, double Lots, double At_Price, int Expiration_Seconds)
{
   int TicketResult = 0;
   datetime Expiration_Time = (TimeCurrent() + Expiration_Seconds);
   double Price = NormalizeDouble(At_Price, Digits);

   if (Trade_Type == "Green")
   {   
      if (Ask < At_Price) return;
      double StopPrice = CalculateStopLossPrice(Price, Lots, StopLoss, Trade_Type);
      TicketResult = OrderSend(Symbol(), OP_BUYLIMIT, Lots, Price, 10, StopPrice, 0, " Buy", Magic, Expiration_Time, clrGreen); 
   }
   if (Trade_Type == "Red")
   {
      if (Bid > At_Price) return;
      double StopPrice = CalculateStopLossPrice(Price, Lots, StopLoss, Trade_Type);
      TicketResult = OrderSend(Symbol(),OP_SELLLIMIT, Lots, NormalizeDouble(At_Price, Digits), 10, StopPrice, 0, " Sell", Magic, Expiration_Time, clrRed);
   }


   if(TicketResult < 0)
   {
      Print("OrderSend failed with error #",GetLastError());
   }
   else
   {
      Print("OrderSend placed successfully");
   }
}


double CalculateStopLossPrice(double OrderPrice, double TradeSize, double StopLossDollars, string PositionType)
{  
   // Convert stop loss dollars to positive number
   double CurrentSpread = MarketInfo(Symbol(), MODE_SPREAD);
   Print("*** CurrentSpread: ", CurrentSpread);


   double PipValue = (TradeSize * 10);
   double StopLossPips = (StopLossDollars / PipValue);
   double CandleSupport = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_LOW, 0); 
   double CandleResistance = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_HIGH, 0);


   if (PositionType == "Green")
   {
      double StopLossPrice = CandleResistance;
   }
   if (PositionType == "Red") 
   {
      double StopLossPrice = CandleSupport;
   }

   return 0.0;
}


void CloseAllTrades()
{
   int CloseResult = 0;

   for(int t=0; t<OrdersTotal(); t++)
   {
      if(OrderSelect(t, SELECT_BY_POS,MODE_TRADES))
      {
         if(OrderMagicNumber() != Magic) continue;
         if(OrderSymbol() != Symbol()) continue;

         if(OrderType() == OP_BUY)  CloseResult = OrderClose(OrderTicket(), OrderLots(), Bid, MaxCloseSpreadPips, clrRed);
         if(OrderType() == OP_SELL) CloseResult = OrderClose(OrderTicket(), OrderLots(), Ask, MaxCloseSpreadPips, clrGreen);

         t--;       
      }
   }

   if(CloseResult < 0)
   {
      Print("OrderSend failed with error #", GetLastError());
   }
   else
   {
      Print("OrderSend placed successfully");
   }

   return;
}


int GetTotalOpenTrades()
{
   int TotalTrades = 0;
   for (int t=0; t<OrdersTotal(); t++)
   {
      if(OrderSelect(t, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() != Symbol()) continue;
         if(OrderMagicNumber() != Magic) continue;
         if(OrderCloseTime() != 0) continue;

         TotalTrades = (TotalTrades + 1);
      }
   }
   return TotalTrades;
}


double GetTotalProfits()
{
   double TotalProfits = 0.0;

   for (int t=0; t<OrdersTotal(); t++)
   {
      if(OrderSelect(t, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() != Symbol()) continue;
         if(OrderMagicNumber() != Magic) continue;
         if(OrderCloseTime() != 0) continue;

         TotalProfits = (TotalProfits + OrderProfit());
      }
   }

   return TotalProfits;
}


// Close all trades if we are at profit or loss
void CheckForOrderClose(double Target, double Stop)
{
   // check for profit or loss
   if (GetTotalProfits() > Target)
   {
      CloseAllTrades();
   }
}


// Close if trade is more than (n) seconds old
string CloseTradeAfterAge(int MaxOpenTradeAgeSeconds)
{
   for(int t=0; t < OrdersTotal(); t++)
   {
      if(OrderSelect(t, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() != Symbol()) return "wrong symbol";
         if(OrderMagicNumber() != Magic) return "magic number does not match";
         if(OrderCloseTime() != 0) return "order already closed";      

         datetime OrderOpenTime = OrderOpenTime();

         string Now = (TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS));
         datetime NowTimeStamp = (StrToTime(Now));

         if ((NowTimeStamp - OrderOpenTime) > MaxOpenTradeAgeSeconds) // 1 * 24 * 60 * 60
         {
            if ((OrderType() == 0) || (OrderType() == 1)) // Only close orders that are live (not limit ordes)
            {
               CloseAllTrades();
               return "all trades closed";
            }
         }

      }
   }
   return "trades not closed"; 
}

1 Ответ

0 голосов
/ 01 июля 2018

проверяйте и просматривайте этот кусок кода, пока не убедитесь, что понимаете логику и заставляете ее работать

     //...
     if (CandleColor == "Green") //this one is NULL
        {
           PlacePendingOrder("Green", LotsToTrade, CandleSupport, PendingOrderExpirationSeconds);
           LastTradePlacedTimestamp = TimeCurrent();
        }
     }

     // short
     if ( CurrentPrice >= CandleResistance) 
     {
        if (CheckForTradeSetup() == "Red" )//this fn() returns "no-setup"
     //....

поэтому отредактируйте функцию CheckForTradeSetup () и вызовите ее перед проверкой цветов, а также сравнением двух строк - очень плохая идея, потому что она слишком медленная. + 1/0 / -1 или перечисления или даже цвета (== int) предпочтительнее

...