Советники: eaBreakeven

 

eaBreakeven:

eaBreakeven - советник, который переносит стоп лосс позиции в безубыток и при этом воспроизводит звуковой файл. Советник управляет позициями только для символа валюты графика, т.е. если вы присоедините этот советник к графику GBPUSD, он будет управлять позициями GBPUSD.


Параметры советника

  • Breakeven in points - значение прибыли позиции, когда эксперт перемещает стоп лосс в безубыток;
  • Breakeven distance in points - значение прибыли в пунктах, где установлен стоп лосс. Т.е. если цена открытия короткой позиции 1.9873 и этот параметр 5 пунктов, то eaBreakeven перенесет стоп лосс на 1.9868;
  • Magic Number - идентификационный номер управляемых позиций. Если 0, то EA будет управлять всеми позициями для текущего символа;
  • Enable/disable playing sound when breakeven set - включить/отключить воспроизведение звукового файла при срабатывании безубытка;
  • Sound file name - имя звуковой файла из каталога \Sound.

Автор: Alexey Lopatin

 

Ошибки:

  1. Цикл должен быть обратным.
  2. PositionSelect нужно выкинуть из кода.

 
fxsaber:

Ошибки:

  1. Цикл должен быть обратным.
  2. PositionSelect нужно выкинуть из кода.


Аргументы в студию.

 
Alexey Lopatin:

Аргументы в студию.

По поводу цикла - долго объяснять. А PositionSelect после PositionGetSymbol лишняя, т.к. выбор уже произведен, если LastError в порядке. Ну а на хедж-счете PositionSelect еще и зло.

Лучший вариант - всегда использовать вместо вышеупомянутых такое

if (PositionGetTicket(i))


Так же latest_price для любого направления позиции можно было бы брать через POSITION_PRICE_CURRENT.


И это условие

if(latest_price.bid-price_open>=Breakeven*point && new_stoploss>stoploss && latest_price.bid-new_stoploss>stop_level)

может срабатывать даже в случаях (из-за double-особенностей), когда модифицировать ничего не нужно.


В общем, можно переписать несколько компактнее и без ошибок. Я бы делал в MT4-style.

#include <MT4Orders.mqh>     // https://www.mql5.com/ru/code/16006
#include <Price_Compare.mqh> // https://www.mql5.com/ru/code/16169

input int    Breakeven           = 15;           //Breakeven in points
input int    Distance            = 5;            //Breakeven distance in points from open price of position
input int    MagicNumber         = 16112017;     //Magic number
input bool   EnableSound         = true;         //Enable/disable playing sound when breakeven set
input string SoundFile           = "alert1.wav"; //Sound file name

void OnTick()
{
  DoBreakeven();
}

double GetNewStopLoss()
{
  const double point = SymbolInfoDouble(OrderSymbol(), SYMBOL_POINT);  
  const double stop_level = SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_STOPS_LEVEL) * point;
  
  const double price_open = OrderOpenPrice();
  const double latest_price = OrderClosePrice();  
  const double stoploss = OrderStopLoss();

  double new_stoploss = 0;
  
  //--- Move stop-loss at breakven price + Distance, if position profit greater than Breakeven points  
  return(((OrderType() == OP_BUY)  && (CP(latest_price - price_open, point) >= Breakeven * point) &&
                                      (CP(new_stoploss = price_open + Distance * point, point) > stoploss) &&
                                      (CP(latest_price - new_stoploss, point) > stop_level)) ||
         ((OrderType() == OP_SELL) && (CP(price_open - latest_price, point) >= Breakeven * point) &&
                                      ((CP(new_stoploss = price_open - Distance * point, point) < stoploss) || !stoploss) &&
                                      (CP(new_stoploss - latest_price, point) > stop_level))
         ? NormalizeDouble(new_stoploss, (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS)) : 0);
}

void DoBreakeven()
{
//If Breakeven is negative, then disable breakeven function
  if (Breakeven >= 0)      
  //Loop for positions
    for (int i = OrdersTotal() - 1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (!MagicNumber || (OrderMagicNumber() == MagicNumber)))
      {
        const double new_stoploss = GetNewStopLoss();
        
        if (new_stoploss)      
        {
          if (!OrderModify(OrderTicket(), OrderOpenPrice(), new_stoploss, OrderTakeProfit(), OrderExpiration()))
            Print(GetLastError());
          else if(EnableSound)
            PlaySound(SoundFile);
        }
      }
}
 

Спасибо за ответ с примером. Всегда рад узнать что-то новое для себя.

Но вот интересно было бы узнать почему  PositionSelect на хэдж-счете зло?

 
Alexey Lopatin:

Но вот интересно было бы узнать почему  PositionSelect на хэдж-счете зло?

Потому что символ не определяет однозначно позицию.

 
caolyhuynh:
 
5000000
 
caolyhuynh: