Помогите модернизировать ! Не работает Trailing stop , и нужно добавить Способ определения размера лота

 

Сам код:

//+------------------------------------------------------------------+
//|                                        Adjustable Moving Average |
//|                             Copyright © 2009-2014, EarnForex.com |
//|                                        http://www.earnforex.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009-2014, EarnForex"
#property link      "http://www.earnforex.com"
#property version   "1.04"

#property description "Adjustable MA EA - expert advisor for customizable MA trading."
#property description "Modify StopLoss, TakeProfit, TrailingStop, MA Period, MA Type"
#property description "and minimum difference between MAs to count as cross."

#include <Trade/Trade.mqh>

input double Lots      = 0.1;
input int StopLoss     = 100;
input int TakeProfit   = 70;
input int TrailingStop = 0;
input int Slippage     = 3;

input int Period_1     = 20;
input int Period_2     = 17;

//0 - SMA, 1 - EMA, 2 - SMMA, 3 - LWMA
input ENUM_MA_METHOD MA_Method = MODE_EMA;
//The minimum difference between MAs for Cross to count
input int MinDiff = 3;

// Money management
input bool UseMM = false;
// Amount of lots per every 10,000 of free margin
input double LotsPer10000 = 1;

input bool ECN_Mode = false; // ECN_Mode: Set to true if stop-loss should be added only after Position Open

// Main trading object
CTrade *Trade;

//Depend on broker's quotes
double Poin;
ulong Deviation;

int LastBars = 0;

//0 - undefined, 1 - bullish cross (fast MA above slow MA), -1 - bearish cross (fast MA below slow MA)
int PrevCross = 0;

int SlowMA;
int FastMA;

int myMA1, myMA2;

//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
void OnInit()
{
   FastMA = MathMin(Period_1, Period_2);
   SlowMA = MathMax(Period_1, Period_2);

   if (FastMA == SlowMA)
   {
      Print("MA periods should differ.");
      return;
   }

Poin = _Point;
Deviation = Slippage;
//Checking for unconvetional Point digits number
   if ((_Point == 0.00001) || (_Point == 0.001))
   {
      Poin *= 10;
      Deviation *= 10;
   }
   
        Trade = new CTrade;
Trade.SetDeviationInPoints(Deviation);

   myMA1 = iMA(NULL, 0, FastMA, 0, MA_Method, PRICE_CLOSE);
   myMA2 = iMA(NULL, 0, SlowMA, 0, MA_Method, PRICE_CLOSE);
}

//+------------------------------------------------------------------+
//| Expert Deinitialization Function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
delete Trade;
}

//+------------------------------------------------------------------+
//| Each Tick                                                        |
//+------------------------------------------------------------------+
void OnTick()
{
   if (ECN_Mode) DoSLTP();
   if (TrailingStop > 0) DoTrailing();

   //Wait for the new Bar in a chart.
if (LastBars == Bars(_Symbol, _Period)) return;
else LastBars = Bars(_Symbol, _Period);

   if ((Bars(_Symbol, _Period) < SlowMA) || (MQL5InfoInteger(MQL5_TRADE_ALLOWED) == false)) return;
   
   CheckCross();
}

//+------------------------------------------------------------------+
//| Check for cross and open/close the positions respectively        |
//+------------------------------------------------------------------+
void CheckCross()
{
double FMABuffer[], SMABuffer[];
   
   CopyBuffer(myMA1, 0, 1, 1, FMABuffer);
   //ArraySetAsSeries(FMABuffer, true);

   CopyBuffer(myMA2, 0, 1, 1, SMABuffer);
   //ArraySetAsSeries(SMABuffer, true);

   double FMA_Current = FMABuffer[0];
   double SMA_Current = SMABuffer[0];

   if (PrevCross == 0) //Was undefined
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) PrevCross = 1; //Bullish state
      else if ((SMA_Current - FMA_Current) >= MinDiff * Poin) PrevCross = -1; //Bearish state
      return;
   }
   else if (PrevCross == 1) //Was bullish
   {
      if ((SMA_Current - FMA_Current) >= MinDiff * Poin) //Became bearish
      {
         ClosePrev();
         fSell();
         PrevCross = -1;
      }
   }
   else if (PrevCross == -1) //Was bearish
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) //Became bullish
      {
         ClosePrev();
         fBuy();
         PrevCross = 1;
      }
   }
}

//+------------------------------------------------------------------+
//| Close previous position                                          |
//+------------------------------------------------------------------+
void ClosePrev()
{
   //Closing position if necessary
   if (PositionsTotal() > 0)
   {
      if (PositionSelect(_Symbol))
      {
         //If the open position is Long we have to send a Sell order to close it
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            fSell();
         }
         //If not then it's a Short position and we need to send Buy order
         else fBuy();
      }
   }
}

//+------------------------------------------------------------------+
//| Sell                                                             |
//+------------------------------------------------------------------+
void fSell()
{
double SL, TP;
if (StopLoss > 0) SL = SymbolInfoDouble(Symbol(), SYMBOL_BID) + StopLoss * Poin;
else SL = 0;
   if (TakeProfit > 0) TP = SymbolInfoDouble(Symbol(), SYMBOL_BID) - TakeProfit * Poin;
else TP = 0;

MqlTradeRequest Request;
ZeroMemory(Request);
Request.action = TRADE_ACTION_DEAL;
Request.symbol = _Symbol;
Request.volume = LotsOptimized();
Request.price = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), _Digits);
Request.type = ORDER_TYPE_SELL; 
if (!ECN_Mode)
{
  Request.sl = NormalizeDouble(SL, _Digits);
  Request.tp = NormalizeDouble(TP, _Digits);
}
else
{
  Request.sl = 0;
  Request.tp = 0;
}
   Request.type_filling = ORDER_FILLING_FOK;
   Request.deviation = Deviation;
   Request.comment = "Adjustable MA";
   
   MqlTradeResult Result;
   ZeroMemory(Result);
   
bool result = OrderSend(Request, Result); 
if (result == false)    Print("Incorrect Request/Result Structure when Buying.");
else Print("Result Code: ", Result.retcode, ", ", "Deal: ", Result.deal, ", ", "Volume: ", Result.volume, ", ", "Price: ", Result.price, ", ", "Requote Bid: ", Result.bid, ", ", "Requote Ask: ", Result.ask);
}

//+------------------------------------------------------------------+
//| Buy                                                              |
//+------------------------------------------------------------------+
void fBuy()
{
double SL, TP;
if (StopLoss > 0) SL = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - StopLoss * Poin;
else SL = 0;
   if (TakeProfit > 0) TP = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + TakeProfit * Poin;
else TP = 0;

MqlTradeRequest Request;
ZeroMemory(Request);
Request.action = TRADE_ACTION_DEAL;
Request.symbol = _Symbol;
Request.volume = LotsOptimized();
Request.price = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), _Digits);
Request.type = ORDER_TYPE_BUY; 
if (!ECN_Mode)
{
  Request.sl = NormalizeDouble(SL, _Digits);
  Request.tp = NormalizeDouble(TP, _Digits);
}
else
{
  Request.sl = 0;
  Request.tp = 0;
}
   Request.type_filling = ORDER_FILLING_FOK;
   Request.deviation = Deviation;
   Request.comment = "Adjustable MA";
   
   MqlTradeResult Result;
   ZeroMemory(Result);
   
bool result = OrderSend(Request, Result); 
if (result == false)    Print("Incorrect Request/Result Structure when Selling.");
else Print("Result Code: ", Result.retcode, ", ", "Deal: ", Result.deal, ", ", "Volume: ", Result.volume, ", ", "Price: ", Result.price, ", ", "Requote Bid: ", Result.bid, ", ", "Requote Ask: ", Result.ask);
}

void DoTrailing()
{
   //Modifying SL if necessary
   if (PositionsTotal() > 0)
   {
      if (PositionSelect(_Symbol))
      {
         //If the open position is Long
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            if (SymbolInfoDouble(Symbol(), SYMBOL_BID) - PositionGetDouble(POSITION_PRICE_OPEN) >= TrailingStop * Poin) //If profit is greater or equal to the desired Trailing Stop value
            {
             if (PositionGetDouble(POSITION_SL) < (SymbolInfoDouble(Symbol(), SYMBOL_BID) - TrailingStop * Poin))
             {
               MqlTradeRequest Request;
            Request.action = TRADE_ACTION_SLTP;
            Request.symbol = _Symbol;
            Request.sl = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID) - TrailingStop * Poin, _Digits);
            Request.tp = PositionGetDouble(POSITION_TP);
               Request.deviation = Deviation;
               
               MqlTradeResult Result;
               
            bool result = OrderSend(Request, Result); 
            if (result == false)        Print("Incorrect Request/Result Structure when Selling.");
            else Print("Result Code: ", Result.retcode, ", ", "Deal: ", Result.deal, ", ", "Volume: ", Result.volume, ", ", "Price: ", Result.price, ", ", "Requote Bid: ", Result.bid, ", ", "Requote Ask: ", Result.ask);
             }
            }
         }
         //If it's Short
         else
         {
            if (PositionGetDouble(POSITION_PRICE_OPEN) - SymbolInfoDouble(Symbol(), SYMBOL_ASK) >= TrailingStop * Poin) //If profit is greater or equal to the desired Trailing Stop value
            {
             if (PositionGetDouble(POSITION_SL) > (SymbolInfoDouble(Symbol(), SYMBOL_ASK) + TrailingStop * Poin))
             {
               MqlTradeRequest Request;
            Request.action = TRADE_ACTION_SLTP;
            Request.symbol = _Symbol;
            Request.sl = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK) + TrailingStop * Poin, _Digits);
            Request.tp = PositionGetDouble(POSITION_TP);
               Request.deviation = Deviation;
               
               MqlTradeResult Result;
               
            bool result = OrderSend(Request, Result); 
            if (result == false)        Print("Incorrect Request/Result Structure when Selling.");
            else Print("Result Code: ", Result.retcode, ", ", "Deal: ", Result.deal, ", ", "Volume: ", Result.volume, ", ", "Price: ", Result.price, ", ", "Requote Bid: ", Result.bid, ", ", "Requote Ask: ", Result.ask);
             }
            }
         
         }
      }
   }
}

double LotsOptimized()
{
   if (!UseMM) return(Lots);
   double vol = NormalizeDouble((AccountInfoDouble(ACCOUNT_FREEMARGIN) / 10000) * LotsPer10000, 1);
   if (vol <= 0) return(0.1);
   return(vol);
}

//+------------------------------------------------------------------+
//| Applies SL and TP to open positions if ECN mode is on.           |
//+------------------------------------------------------------------+
void DoSLTP()
{
   if (!PositionSelect(_Symbol)) return;
   
   double SL = 0, TP = 0;
   
   if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
   {
      if (StopLoss > 0) SL = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) - StopLoss * Poin, _Digits);
      if (TakeProfit > 0) TP = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) + TakeProfit * Poin, _Digits);
   }
   if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
   {
      if (StopLoss > 0) SL = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) + StopLoss * Poin, _Digits);
      if (TakeProfit > 0) TP = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) - TakeProfit * Poin, _Digits);
   }

   if (((PositionGetDouble(POSITION_SL) != SL) || (PositionGetDouble(POSITION_TP) != TP)) && (PositionGetDouble(POSITION_SL) == 0) && (PositionGetDouble(POSITION_TP) == 0))
   {
      Trade.PositionModify(_Symbol, SL, TP);
   }
}
//+------------------------------------------------------------------+
Файлы:
 

Структуру MqlTradeRequest при создании нужно обнулять:

MqlTradeRequest Request={0};

Пример есть тут: OrderSend 

 

Добавлено позже:

обнуление требуется для того, чтобы убрать "мусор" из неиспользуемых полей. Этот "мусор" изначально содержится в полях структуры при её создании (как, впрочем и в любом массиве при его объявлении). 

 

Добавлено позже:

при вставке кода в сообщение, пожалуйста, правильно оформляйте код - Правильно вставляем код на форуме