Тейк-профит и виртуальный стоп-лосс

 

Привет,

Я пытаюсь сделать простой код для проверки идеи Take Profit и виртуального Stop Loss.


Мне удалось попасть сюда, в голове все нормально, но операции не отменяются при достижении тейк-профита или стоп-лосса.


Не могли бы вы помочь мне проанализировать это?

//+------------------------------------------------------------------+
//|                                                VirtualPrices.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

CTrade trade;
CSymbolInfo _symb;

MqlTick tick;

input double            lot             = 1;              //LotSize/Contract
input double            takeprofit      = 5;             //TakeProfit
input double            stoploss        = 5;             //StopLoss
input ulong             MagicNumber     = 12345;          //MagicNumber

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   double Take = 0;
   double Stop = 0;

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

   if(PositionsTotal()<2 && OrdersTotal()<2)
     {

      bool ok =trade.Buy(lot,_Symbol,Ask,0,0,"Buy");

      if(ok)
        {
         Take = Ask + takeprofit*_Point;
         Stop = Bid - stoploss*_Point;
         Print("Buy Price: ",Ask," Take Price: ",Take," Stop Price: ", Stop);
        }
     }

   VirtualTakeStop(Take,Stop);

  }
//+------------------------------------------------------------------+
void VirtualTakeStop(double take, double stop)
  {

   if(PositionSelect(_Symbol)==true)
     {

      for(int i=PositionsTotal()-1; i>=0; i--)
        {

         ulong  PositionTicket    = PositionGetTicket(i);
         string PositionSymbol    = PositionGetString(POSITION_SYMBOL);
         ulong  PositionMagicNum  = PositionGetInteger(POSITION_MAGIC);
         double PositionPriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
         double PositionProfit    = PositionGetDouble(POSITION_PROFIT);
         double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
         double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

         if(PositionSymbol==_Symbol && PositionMagicNum == MagicNumber)
           {
            if(Bid>=take)
              {
               Print("TakeProfit reached at transaction ticket: ",PositionTicket, "result: ",PositionProfit);
               CloseOrders();
               ClosePositions();
              }
            else
               if(Ask<=stop)
                 {
                  Print("StopLoss reached at transaction ticket: ",PositionTicket, "result: ",PositionProfit);
                  CloseOrders();
                  ClosePositions();
                 }
           }
        }

     }

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ClosePositions()
  {
   int n_positions = PositionsTotal();

   for(int i = n_positions - 1; i >= 0; i--)
     {

      string mySymbol = PositionGetSymbol(i);
      ulong  myMagicNum = PositionGetInteger(POSITION_MAGIC);

      if(mySymbol == _Symbol && myMagicNum == MagicNumber)
        {
         trade.PositionClose(mySymbol);
        }
     }
  }
//+------------------------------------------------------------------+
void CloseOrders()
  {

   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      ulong  ticket  = OrderGetTicket(i);
      string mySymbol = OrderGetString(ORDER_SYMBOL);
      ulong  myMagicNum = OrderGetInteger(ORDER_MAGIC);

      if(mySymbol == _Symbol && myMagicNum == MagicNumber)
        {
         trade.OrderDelete(ticket);
        }
     }
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
 

Привет!

Нужно переменные сделать глобальными, а то они на следующем тике обнуляются.

double Take = 0;
double Stop = 0;


void OnTick()
  {

 

Спасибо, я внес изменения, но это все еще не сработало.


//+------------------------------------------------------------------+
//|                                                VirtualPrices.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

CTrade trade;
CSymbolInfo _symb;

MqlTick tick;

input double            lot             = 1;              //LotSize/Contract
input double            takeprofit      = 5;             //TakeProfit
input double            stoploss        = 5;             //StopLoss
input ulong             MagicNumber     = 12345;          //MagicNumber

double Take = 0;
double Stop = 0;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

   if(PositionsTotal()<2 && OrdersTotal()<2)
     {

      bool ok =trade.Buy(lot,_Symbol,Ask,0,0,"Buy");

      if(ok)
        {
         Take = Ask + takeprofit*_Point;
         Stop = Bid - stoploss*_Point;
         Print("Buy Price: ",Ask," Take Price: ",Take," Stop Price: ", Stop);
        }
     }

   VirtualTakeStop(Take,Stop);

  }
//+------------------------------------------------------------------+
void VirtualTakeStop(double take, double stop)
  {

   if(PositionSelect(_Symbol)==true)
     {

      for(int i=PositionsTotal()-1; i>=0; i--)
        {

         ulong  PositionTicket    = PositionGetTicket(i);
         string PositionSymbol    = PositionGetString(POSITION_SYMBOL);
         ulong  PositionMagicNum  = PositionGetInteger(POSITION_MAGIC);
         double PositionPriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
         double PositionProfit    = PositionGetDouble(POSITION_PROFIT);
         double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
         double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

         if(PositionSymbol==_Symbol && PositionMagicNum == MagicNumber)
           {
  
            if(Ask>=take)
              {
               Print("TakeProfit reached at transaction ticket: ",PositionTicket, "result: ",PositionProfit);
               CloseOrders();
               ClosePositions();

              }
            else
               if(Bid<=stop)
                 {
                  Print("StopLoss reached at transaction ticket: ",PositionTicket, "result: ",PositionProfit);
                  CloseOrders();
                  ClosePositions();
                 }
           }
        }

     }

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ClosePositions()
  {
   int n_positions = PositionsTotal();

   for(int i = n_positions - 1; i >= 0; i--)
     {

      string mySymbol = PositionGetSymbol(i);
      ulong  myMagicNum = PositionGetInteger(POSITION_MAGIC);

      if(mySymbol == _Symbol && myMagicNum == MagicNumber)
        {
         trade.PositionClose(mySymbol);
        }
     }
  }
//+------------------------------------------------------------------+
void CloseOrders()
  {

   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      ulong  ticket  = OrderGetTicket(i);
      string mySymbol = OrderGetString(ORDER_SYMBOL);
      ulong  myMagicNum = OrderGetInteger(ORDER_MAGIC);

      if(mySymbol == _Symbol && myMagicNum == MagicNumber)
        {
         trade.OrderDelete(ticket);
        }
     }
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
 

Я попытался начать с нуля, просмотрев несколько уроков.

Но это тоже не сработало.


//+------------------------------------------------------------------+
//|                                                 VirtualPrice.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CPositionInfo  m_position;                 // trade position object
CTrade         m_trade;                    // trading object
CSymbolInfo    m_symbol;                   // symbol info object

input double   Lot               = 1;      // Lots
input ushort   TakeProfit        = 5;      // Virtual Take Profit (in pips)
input ushort   StopLoss          = 5;      // Virtual Take Profit (in pips)
input ulong    m_magic           = 111;    // magic number

double Take = 0;
double Stop = 0;

double         ExtTakeProfit=0.0;
double         ExtStopLoss=0.0;

double         m_adjusted_point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   m_trade.SetExpertMagicNumber(m_magic);
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;

   ExtTakeProfit  = TakeProfit* m_adjusted_point;
   ExtStopLoss    = StopLoss* m_adjusted_point;

//---

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   m_symbol.RefreshRates();

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

   if(PositionsTotal()<1 && OrdersTotal()<1)
     {

      bool ok = m_trade.Buy(Lot,_Symbol,Ask,0,0,"Buy");

      if(ok)
        {
         Take = Ask + TakeProfit*_Point;
         Stop = Bid - StopLoss*_Point;
         Print("Buy Price: ",Ask," TakeProfit: ",Take," StopLoss: ", Stop);
        }
     }

//--- virtual take profit

   bool close=false;
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {

               if(m_position.PriceCurrent()-m_position.PriceOpen()>=ExtTakeProfit)
                 {

                  Print(m_position.PriceCurrent()," - ",m_position.PriceOpen()," - ",m_position.PriceCurrent()-m_position.PriceOpen()," - ",ExtTakeProfit);
                  m_trade.PositionClose(m_position.Ticket());
                  Print("Buy TakeProfit Reached Result: ", m_position.Profit());
                  close=true;

                 }


               if(m_position.PriceOpen()-m_position.PriceCurrent()>=ExtStopLoss)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Buy StopLoss Reached, Result: ", m_position.Profit());
                  close=true;

                 }
              }


            if(m_position.PositionType()==POSITION_TYPE_SELL)
              {

               if(m_position.PriceOpen()-m_position.PriceCurrent()>=ExtTakeProfit)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Sell TakeProfit Reached Result: ", m_position.Profit());
                  close=true;

                 }

               if(m_position.PriceCurrent()-m_position.PriceOpen()>=ExtStopLoss)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Sell StopLoss Reached, Result: ", m_position.Profit());
                  close=true;

                 }
              }


           }
   if(close)
      return;


  }
//+------------------------------------------------------------------+
 

Теперь все в порядке! Вы можете использовать это!


//+------------------------------------------------------------------+
//|                                                 VirtualPrice.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CPositionInfo  m_position;                 // trade position object
CTrade         m_trade;                    // trading object
CSymbolInfo    m_symbol;                   // symbol info object

input double   Lot               = 1;      // Lots
input ushort   TakeProfit        = 5;      // Virtual Take Profit (in pips)
input ushort   StopLoss          = 5;      // Virtual Take Profit (in pips)
input ulong    m_magic           = 111;    // magic number

double Take = 0;
double Stop = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   m_trade.SetExpertMagicNumber(m_magic);


   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   m_symbol.RefreshRates();

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   double PriceOpen = NormalizeDouble(m_position.PriceOpen(),_Digits);
   double PriceCurrent = NormalizeDouble(m_position.PriceCurrent(),_Digits);

   if(PositionsTotal()<1 && OrdersTotal()<1)
     {

      bool ok = m_trade.Buy(Lot,_Symbol,Ask,0,0,"Buy");

      if(ok)
        {
         Take = Ask + TakeProfit*_Point;
         Stop = Bid - StopLoss*_Point;
         Print("Buy Price: ",Ask," TakeProfit: ",Take," StopLoss: ", Stop);
        }
     }


   bool close=false;  
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==_Symbol && m_position.Magic()==m_magic)
           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {

               if(PriceCurrent>=PriceOpen+TakeProfit*_Point)
                 {


                  m_trade.PositionClose(m_position.Ticket());
                  Print("Buy TakeProfit Reached Result: ", m_position.Profit());
                  close=true;

                 }


               if(PriceCurrent<=PriceOpen-StopLoss*_Point)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Buy StopLoss Reached, Result: ", m_position.Profit());
                  close=true;

                 }
              }


            if(m_position.PositionType()==POSITION_TYPE_SELL)
              {

               if(PriceCurrent<=PriceOpen-TakeProfit*_Point)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Sell TakeProfit Reached Result: ", m_position.Profit());
                  close=true;

                 }

               if(PriceCurrent>=PriceOpen+StopLoss*_Point)
                 {

                  m_trade.PositionClose(m_position.Ticket());
                  Print("Sell StopLoss Reached, Result: ", m_position.Profit());
                  close=true;

                 }
              }


           }
   if(close)
      return;


  }
//+------------------------------------------------------------------+
 
Молодец!