Лучше один раз увидеть: яркие отличия MQL5 от MQL4 - страница 3

 
artemiusgreat:

Честно говоря, сложно представить, зачем там ООП :)

Но, если сильно надо, то вроде бы работу на этом поле МК уже провели ... или это неправильное ООП и оно дает неправильный мед?

https://www.mql5.com/ru/docs/standardlibrary/tradeclasses/ctrade


Вы, похоже, не поняли проблемы. Очень часто сам ошибаюсь и не боюсь в этом признаться. В данном случае своей ошибки до сих пор не вижу. ООП в обоих MQL идентичное и очень нравится.

А теперь по задаче:

hrenfx:

Выставляю два (однонаправленных, никаких локов) лимитника со своими тэйкпрофитами и стоплоссами. В четверке с этим вообще никаких проблем. Здесь же неприятный облом

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

1.

Засада #1. Некоторые наивно ожидают, что один советник должен работать и под МТ4 и под МТ5, а если это не так, то ты хреновый программист, поскольку не можешь обеспечить переемственность версий. Очень редко но бывает.

Засада #2. Формулировка - "просто перепишите мне советника с МТ4 в МТ5". При обсуждения выясняется, что заказчик не знаком с отличиями МТ5 от МТ4. Тратится часа 2-3 на объяснения, после понимания различий советник под МТ5 ему оказывается ненужным. Бывает постоянно.

Как это не парадоксально, но фрилансер - это род деятельности, где почти половина времени и сил уходит на общение с людьми, а не на написание кода. Общение с людьми - тяжкий труд. Разработчики могли бы его облегчить, если бы доходчиво и в видном месте написали один раз, что MT5 по своим возможностям не является преемником MT4. Ведь знают же люди, что arm и x86 - это разное. Хоть и запускаются на обеих платформах angrybirds.


2.

По своему опыту. Хорошую универсальную библиотеку или шаблон удается создать только после того, как раз 10-20 (с заходом с разных сторон) решал однотипную задачу.

Да, надо обладать очень сильным чувством предвидения всех возможных задач, и исходя из этого писать библиотеку. А это почти невозможно сразу сделать даже если библиотеку писать лишь для себя, без замахивания на фрилансерство. Придумать сразу универсальную красивую и гибкую архитектуру библиотеку - огромный труд!

3. От перезапуска терминала все сломается. Может, как вариант выхода из кризиса. В конце описания мелкими буквами о том, что перезапускать терминал нельзя.

Если бы советник или индикатор мог перехватывать событие попытки закрыть приложение и соответственно реагировать на это...
 
hrenfx: Вы, похоже, не поняли проблемы. Очень часто сам ошибаюсь и не боюсь в этом признаться. В данном случае своей ошибки до сих пор не вижу. ООП в обоих MQL идентичное и очень нравится.

Возможно действительно не понял ... тогда надо больше условий к задаче :)

А вообще делаю так, получается лихо ...

if (OrdersTotal() == 0)
{
    double SL = 100 * _Point; // 100 pips on 5 digits
    double TP = 100 * _Point;

    PositionOpenRelative(_Symbol,  1, InpVolume); // Buy Market
    PositionOpenRelative(_Symbol, -1, InpVolume); // Sell Market
    
    PositionOpenRelative(_Symbol,  2, InpVolume, SL, TP,   100 * _Point); // Buy Stop
    PositionOpenRelative(_Symbol, -2, InpVolume, SL, TP, - 100 * _Point); // Sell Stop

    PositionOpenRelative(_Symbol,  3, InpVolume, SL, TP, - 200 * _Point); // Buy Limits
    PositionOpenRelative(_Symbol,  3, InpVolume, SL, TP, - 400 * _Point);
    PositionOpenRelative(_Symbol,  3, InpVolume, SL, TP, - 600 * _Point);
    
    PositionOpenRelative(_Symbol, -3, InpVolume, SL, TP, 200 * _Point); // Sell Limits
    PositionOpenRelative(_Symbol, -3, InpVolume, SL, TP, 400 * _Point);
    PositionOpenRelative(_Symbol, -3, InpVolume, SL, TP, 600 * _Point);

    for (int k = 1; k <= 5; k++)
    {
        PositionOpenRelative(_Symbol,  3, InpVolume, SL, TP, - k * 100 * _Point);
        PositionOpenRelative(_Symbol, -3, InpVolume, SL, TP, k * 100 * _Point);
    }
 }

Код для PositionOpenRelative :

double PositionOpenRelative(
    const string symbol, 
    const int order, 
    const double volume, 
    const double SL = 0, 
    const double TP = 0,
    const double PL = 0,
    const int ID = 0)
{
    double SLPrice = 0;
    double TPPrice = 0;
    double PLPrice = 0;
    double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
    double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
    
    if (MathAbs(order) == 1)
    {
        SLPrice = SL != 0 ? (order > 0 ? bid - SL : ask + SL) : 0;
        TPPrice = TP != 0 ? (order > 0 ? ask + TP : bid - TP) : 0;
    }
    else
    {
        PLPrice = PL != 0 ? (PL > 0 ? ask + MathAbs(PL) : bid - MathAbs(PL)) : 0;
        SLPrice = SL != 0 ? (order > 0 ? PLPrice - SL : PLPrice + SL) : 0;
        TPPrice = TP != 0 ? (order > 0 ? PLPrice + TP : PLPrice - TP) : 0;
    }
    
    return(PositionOpen(symbol, order, volume, SLPrice, TPPrice, PLPrice, ID));
}

double PositionOpen(
    const string symbol, 
    const int order, 
    const double volume, 
    const double SL = 0, 
    const double TP = 0,
    const double PL = 0,
    const int ID = 0)
{
    int digits = int(SymbolInfoInteger(symbol, SYMBOL_DIGITS));
    double price = PL ? PL : SymbolInfoDouble(symbol, order > 0 ? SYMBOL_ASK : SYMBOL_BID);

    MqlTradeResult R = {0};
    MqlTradeRequest Q = {0};

    Q.magic = ID;
    Q.symbol = symbol;
    Q.type_time = ORDER_TIME_GTC;
    Q.type_filling = ORDER_FILLING_FOK;
    Q.tp = NormalizeDouble(TP, digits);
    Q.sl = NormalizeDouble(SL, digits);
    Q.price = NormalizeDouble(price, digits);
    Q.volume = NormalizeDouble(volume, LotDigits());
    
    switch (order)
    {
        case  1 : Q.action = TRADE_ACTION_DEAL; Q.type = ORDER_TYPE_BUY; break;
        case -1 : Q.action = TRADE_ACTION_DEAL; Q.type = ORDER_TYPE_SELL; break;
        case  2 : Q.action = TRADE_ACTION_PENDING; Q.type = ORDER_TYPE_BUY_STOP; break;
        case -2 : Q.action = TRADE_ACTION_PENDING; Q.type = ORDER_TYPE_SELL_STOP; break;
        case  3 : Q.action = TRADE_ACTION_PENDING; Q.type = ORDER_TYPE_BUY_LIMIT; break;
        case -3 : Q.action = TRADE_ACTION_PENDING; Q.type = ORDER_TYPE_SELL_LIMIT; break;
    }

    if (OrderSend(Q, R) == false)
    {
        R.retcode = TRADE_RETCODE_REJECT;
    }
    
    return(R.retcode);
}
 

МТ4, на мой взгляд, это идеальный (на данный момент) компромисс между чисто трейдинговыми и чисто программерскими задачами. Это Т-34 среди танков или АК среди автоматов. Он достаточно прост, надежен и нагляден - что, с одной стороны, важно для первоначального освоения трейдинга, а с другой позволяет проводить на нем достаточно сложные исследовательские работы без излишних заморочек . Да он не без недостатков, но, по совокупности характеристик, плюсов у него больше чем минусов. Мне кажется, разработчики не оценили талантов своего детища и, одно время, даже пытались его усиленно похоронить.

Раздельные ордера, чисто в математическом плане, не дают прибыли как, аналогично, и единая совокупная позиция - тоже. Т.е. в этом плане они равны и, чисто технически, можно преобразовать одно в другое (по сути написав свой МТ4 в МТ5 или МТ5 в МТ4). А вот в плане исследовательского инструмента - МТ4 на голову бьет МТ5, даже несмотря на его новый мультивалютный тестер. По тестерам МТ4 и МТ5, на данный момент, тоже равны т.к. и там и там тиковая история генерируются - весьма неточно, как я неоднократно убеждался, и строить серьезные системы на сгенерированных последовательностях тиков - это, безусловно, мартышкин труд. Но МТ4 позволяет выкрутиться из этой ситуации - можно своей историей, а можно запустив несколько параллельных экспертов с разными настройками и/или алгоритмами торговли. Это конечно тоже эрзац полноценного тестера, т.к. требует своих заморочек, но в МТ4 этих заморочек меньше чем в МТ5. На данный момент у меня параллельно запущено ~200 советников, каждый со своим блоком статистики по торговым операциям. С каждым из этих советников я могу безболезненно для остальных проводить манипуляции. + очень наглядно видно на экране - кто открылся, как сопровождал, где закрылся и т.д. А для МТ5 для аналогичных действий я должен, насколько я понимаю, на порядок больше потанцевать с бубном.

В МТ4 мне не хватает:

1) полноценного тестера с нормальными тиками и временем их прихода (желательно и мультивалютного, конечно));

2) ускорения торговых операций увеличением количества торговых потоков и асинхронными командами;

Для МТ5, насколько я понял, часть этих пунктов уже реализована и будет совершенствоваться. Но хотелось бы, чтобы и про МТ4 не забывали, чтобы он не был в роли падчерицы.

На мой взгляд, не надо МТ4 и МТ5 противопоставлять, лучше развивать их параллельно. В свое время, с выходом МТ4, вы породили немало сторонников раздельной позиции и у этого решения тоже есть очевидные плюсы. Для меня, например,  раздельный учет позиции удобен как исследовательскими возможностями, так и для работы (можно "на лету" корректировать стратегию) + к этому, Форекс по определению децентрализован, а с развитием агрегаторов ЕСН и для них это более удобный инструмент ведения позиции - один ордер запулил одному поставщику, другой другому и т.д. 

 
zenz: Но МТ4 позволяет выкрутиться из этой ситуации - можно своей историей
https://www.mql5.com/ru/forum/43553
 
 Насколько я понял, пока это не реализовано, так что мои слова до сих пор актуальны. А так, за реальную историю я двумя руками - ЗА. Я же и пишу, что хочется полноценный тестер и для МТ4 и МТ5.
 
artemiusgreat:

Возможно действительно не понял ... тогда надо больше условий к задаче :)

Выставить не проблема, конечно. А вот что дальше будет с ними происходить - в этом и сложность в казалось бы элементарщине.
 
zenz:В МТ4 мне не хватает:

2) ускорения торговых операций увеличением количества торговых потоков и асинхронными командами

Делал искусственную асинхронность в MT4:

  1. Сколько нужно торговых потоков, столько и запускается "советников"-отправщиков торговых приказов.
  2. Каждый боевой советник отправляет виртуальный торговый приказ.
  3. Свободный "советник"-отправщик перехватывает виртуальный приказ и шлет соответствующий реальный торговый запрос.
  4. С обратной связью сильно не заморачивался.

Полезно было при торговле синтетиками, когда нужно открыться одновременно по нескольким символам.

 
максимально 8 торговых потоков, и работает просто отлично кстати
 
hrenfx:

Делал искусственную асинхронность в MT4:

  1. Сколько нужно торговых потоков, столько и запускается "советников"-отправщиков торговых приказов.
  2. Каждый боевой советник отправляет виртуальный торговый приказ.
  3. Свободный "советник"-отправщик перехватывает виртуальный приказ и шлет соответствующий реальный торговый запрос.
  4. С обратной связью сильно не заморачивался.

Полезно было при торговле синтетиками, когда нужно открыться одновременно по нескольким символам.

FAQ:
максимально 8 торговых потоков, и работает просто отлично кстати
 Так я эти параллельные восемь потоков тоже вовсю использую! Но скорости много не бывает! - надо больше. Разработчики тратят много времени на оптимизацию компилятора и соревнования в микросекундах с языком С++ (тоже нужная работа, конечно), но, при этом, терминал теряет времени в тысячи раз больше на отправку и получение торговых приказов. Где логика? Ведь сама по себе быстрая работа программы это только пол дела, - ее еще надо реализовать с помощью максимально быстрой подачи команд с терминала на торговый сервер. Надо убрать это "бутылочное горлышко" максимально расширив канал передачи. Это можно рассматривать и как маркетинговую фишку (самый быстрый терминал в мире) и реально полезно для трейдеров.