Как правильно оформить новую структура запроса?
Страница 1 из 3 1 2 3 ПоследняяПоследняя
Показано с 1 по 10 из 25

Тема: Как правильно оформить новую структура запроса?

  1. #1
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126

    Как правильно оформить новую структура запроса?

    Здравствуйте.
    Есть такой код (Часть более объемного кода.)

    Код:
    bool SendOrder(double price, double volume)
    {
       counter++;
       MqlTradeRequest request = {0};
       MqlTradeResult  result  = {0};
      
    //---заполняем поля торгового запроса
       request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request.price        = price;                   // Цена  
       request.type         = ORDER_TYPE_BUY;          // Тип ордера
       request.tp           = price + 950*_Point;     // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_GTC;
       
       // Подсчитываем средства на нашем счете
          double AccountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
          
       // Подсчитываем баланс аккаунта  
          double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
          
       // Разница между балансом и средствами на счете
          double balanceMinusEquity = accountBalance - AccountEquity;
       
       //--- Проверяем состояние баланса счета при вхождении в позицию.
       if(AccountEquity < accountBalance)
       {
       MqlTradeRequest request_2 = {0};
       MqlTradeResult  result_2  = {0};
       request_2.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
       request_2.symbol       = _Symbol;                 // Имя торгового инструмента
       request_2.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request_2.price        = price;                   // Цена  
       request_2.type         = ORDER_TYPE_SELL;          // Тип ордера
       request_2.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
       request_2.type_time    = ORDER_TIME_GTC;
       
       Print("Условия на счете не соответствуют параметрам для входа в позицию");
       Print("Разница между балансом и средствами на счете: ", DoubleToString(balanceMinusEquity, 2), "$");
       Print("Количество открытых позиций: ", PositionsTotal());
       return (false);
       };
    }//-------------------------------------------------------------------------------------------------+
    Задача стоит - в случае определённого условия(связанного с балансом на аккаунте) прекратить доливать позиции и всё что есть(по данному инструменту) продать.
    (На данный момент в принтах(в журнале) у меня выводится, что позиция по прежнему сохраняется в наличии.)
    Вопрос:
    Как это правильно оформить?)
    (в инете и документации не удается найти ни одного примера.)
    Так же хотелось бы понять как покупать и продавать позицию по лимитному ордеру.
    Пробовал пере прописывать значение: request.action = TRADE_ACTION_PENDING;
    request.type = ORDER_TYPE_BUY_LIMIT;

    Но доливаться позиция начала вообще непонятно каким образом.
    На какие критерии необходимо обращать внимание, при оформлении(в таких случаях) структуры MqlTradeRequest request ?
    (Иными словами, почему у меня это все работает не корректно и как все это правильно организовать.)

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 04.08.2014 в 22:19.

  2. #2
    Программист
    Регистрация
    16.08.2012
    Адрес
    Челябинск
    Сообщений
    1,244
    Promo (¢)
    26,380
    Благодарности
    Получено: 424
    Отправлено: 42
    Цитата Сообщение от Mike_Kharkov Посмотреть сообщение
    в инете и документации не удается найти ни одного примера.
    Это читали - "Как использовать торговые классы Стандартной библиотеки при написании советника", см.: _http://www.mql5.com/ru/articles/138 , "Быстрый старт или краткий курс для начинающих" - _http://www.mql5.com/ru/articles/496 .
    Цитата Сообщение от Mike_Kharkov Посмотреть сообщение
    Задача стоит - в случае определённого условия(связанного с балансом на аккаунте) прекратить доливать позиции и всё что есть(по данному инструменту) продать.
    Итак
    1. есть условие доливки - там доливается
    2. есть условие закрытия позиции.

    необходимо написать таким образом условия 1 и 2, чтобы выполнялось строго либо 1, либо 2.
    Вопросы?

    Вы не можете благодарить!

  3. #3
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от wayfarer Посмотреть сообщение
    Итак
    1. есть условие доливки - там доливается
    2. есть условие закрытия позиции.

    необходимо написать таким образом условия 1 и 2, чтобы выполнялось строго либо 1, либо 2.
    Вопросы?
    Попробовал ещё вот такой вариант:

    Код:
    MqlTradeRequest request = {0};
       MqlTradeResult  result  = {0};
       
       // Подсчитываем средства на нашем счете
          double AccountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
          
       // Подсчитываем баланс аккаунта  
          double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
          
       // Разница между балансом и средствами на счете
          double balanceMinusEquity = accountBalance - AccountEquity;
       
       //--- Проверяем состояние баланса счета при вхождении в позицию.
       if(AccountEquity < accountBalance/2)
       {
       request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request.price        = price;                   // Цена  
       request.type         = ORDER_TYPE_SELL;         // Тип ордера
       request.tp           = price;                   // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_GTC;
       
       Print("Условия на счете не соответствуют параметрам для входа в позицию");
       Print("Разница между балансом и средствами на счете: ", DoubleToString(balanceMinusEquity, 2), "$");
       Print("Количество открытых позиций: ", PositionsTotal());
       return (false);
       }
       
       else{
       //---заполняем поля торгового запроса
       request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request.price        = price;                   // Цена  
       request.type         = ORDER_TYPE_BUY;          // Тип ордера
       request.tp           = price + 950*_Point;      // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_GTC;
       };
    Мне необходимо что бы при первом условии исключалась работа второго условия и продавала именно то, что осталось не закрытым(позицию, которая была куплена после второго условия.)

    + хочу понять как выходить из сделки не по тейк профитам а именно лимитными ордерами..
    (и как правильно делать вход позиции по лимитному ордеру. У меня почему то постоянные проблемы с этим.)

    p.s. ещё такой момент хотел выяснить:
    если я покупаю по лимитному ордеру позицию - то тейк профит работает как лимитный ордер или как рыночный?


    Если прописать вот это:

    Код:
    else{
       //---заполняем поля торгового запроса
       request.action       = TRADE_ACTION_PENDING;       // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request.price        = price;                   // Цена  
       request.type         = ORDER_TYPE_BUY_LIMIT;          // Тип ордера
       request.tp           = price + 950*_Point;      // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_GTC;
       };
    То вход в сделку вообще даже и не начинается.

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 04.08.2014 в 23:20.

  4. #4
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Так. Вроде разобрался с условиями и продажей рыночными ордерами.
    (проблема не срабатывания была в том, что из за высокой скорости движения котировки ордер рыночный почему то отказывается выполнять поставленную задачу.
    Хотя для меня лично не понятно почему. request.type_time = ORDER_TIME_GTC; означает что он ордер должен быть в заявке - пока не будет исполнен.
    ulong devitation = 1000000000; даже поставил специально.
    Иными словами у меня рыночный ордер висит днями(при тестировании на истории) и всё это время не срабатывает получается.
    Но на малых скачках выйти рыночным ордером из позиции все же удается.
    Никто не в курсе - почему так происходит?)
    P.S. C Тем как работают лимитные ордера я так пока что и не разобрался..
    (то докупается все это дело как попало из за них. То вообще не хочет ничего покупать с самого начала.)

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 05.08.2014 в 05:30.

  5. #5
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    По поводу попытки отправлять лимитные ордера - у меня в журнале выдает следующее:

    13.jpg

    Пробовал прописывать разные значения для тейк профитов и стоп лосов - но не помагает.

    Вы не можете благодарить!

  6. #6
    Программист
    Регистрация
    16.08.2012
    Адрес
    Челябинск
    Сообщений
    1,244
    Promo (¢)
    26,380
    Благодарности
    Получено: 424
    Отправлено: 42
    Цитата Сообщение от Mike_Kharkov Посмотреть сообщение
    Пробовал прописывать разные значения для тейк профитов и стоп лосов - но не помагает.
    Код в студию. Используйте при ответе расширенный режим и кнопку "вставить BB код". Туда и поместите кусок своей программ.

    Вы не можете благодарить!

  7. #7
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от wayfarer Посмотреть сообщение
    Код в студию. Используйте при ответе расширенный режим и кнопку "вставить BB код". Туда и поместите кусок своей программ.
    Код:
    //+------------------------------------------------------------------+
    //|                                                  My_Practics.mq5 |
    //+------------------------------------------------------------------+
    #property copyright "Mike_Kharkov"
    #property link      "https://www.fl.ru/users/Yamaradg/"
    #property version   "1.00"
    double COEF  = 1.0;                                              // коэффициент кратности увеличения лота
    int    DELTA = 1120;                                               // количество пунктов прохода цены для уведичения позиции
    int    counter = 0;                                              // счетчит вызовов функции
    ulong  magic_number = 87654321;                                  // магический ордер
    //+------------------------------------------------------------------+
    //| Expert initialization function                                   |
    //+------------------------------------------------------------------+
    //+------------------------------------------------------------------+
    //| Expert Get history price function                                |
    //+------------------------------------------------------------------+
    double GetHistoryPrice( const string aSymbol )
    {
      double price_in = 0;
      double volume_in = 0;
      
      if ( PositionSelect( aSymbol ) )
      {
        long pos_id = long( PositionGetInteger( POSITION_IDENTIFIER ) );
        
        if ( pos_id > 0 )
        {
          if ( HistorySelectByPosition( ulong( pos_id ) ) )
          {
            int deals = HistoryDealsTotal();
          
            for( int i = 0; i < deals; i++ )
            {
              ulong deal_ticket = HistoryDealGetTicket( i );
              ulong order_ticket = ulong( HistoryDealGetInteger( deal_ticket, DEAL_ORDER ) );
            
              if ( order_ticket > 0 )
              {
                long deal_entry = long( HistoryDealGetInteger( deal_ticket, DEAL_ENTRY ) );
                  
                if ( deal_entry == DEAL_ENTRY_IN )
                {
                  double price = HistoryDealGetDouble( deal_ticket, DEAL_PRICE );
                  double volume = HistoryDealGetDouble( deal_ticket, DEAL_VOLUME );
                                    
                  price_in = price_in + price * volume;
                  volume_in = volume_in + volume;  
                }
              }
            }
            if ( volume_in > 0 ) return( NormalizeDouble( price_in / volume_in, _Digits ) );
          }
          else
          {
            Print( "Не возможно получить историю позиции по символу ", aSymbol );
          }
        }
        else
        {
          Print( "Не возможно определить идентификатор позиции по символу ", aSymbol );
        }
      }
      return( 0 );
    }
    //+------------------------------------------------------------------+
    //| Expert initialization function                                   |
    //+------------------------------------------------------------------+
    
    
    int OnInit()
    {
    
    //---
       
    //---
       return(INIT_SUCCEEDED);
    }//---------------------------------------------------------------------------+
    
    
    
    //+------------------------------------------------------------------+
    //| Expert deinitialization function                                 |
    //+------------------------------------------------------------------+
    
    
    void OnDeinit(const int reason)
    {
    //---
    }//---------------------------------------------------------------------------+
    
    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    
    
    void OnTick()
    { 
       // вызываем функцию вычисления последнего ордера и преобразовываем результат в 5-ти значное число.
        //  double last_order = FindLastPrice(ORDER_TYPE_BUY);
        double hist_price = GetHistoryPrice(_Symbol);
        
        if(!PositionSelect(_Symbol))
        {
          double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
          counter = 0;
    
          // вызываем функцию, подсчитывающую кол-во лотов для стартовой сделки
          double trade_lot = function_trade_lot(AccountInfoDouble(ACCOUNT_BALANCE));
          
          if(SendOrder(prc, trade_lot))
           {
             // первоначальная позиция открыта..
             Print("         Первоначальное открытие               ");
           }
         
          }
          else
          {
            // доливка существующей позиции.  
            
          double prc = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
          
          double posVolume = PositionGetDouble(POSITION_VOLUME);
          
          //увеличим размер позиции на коэффициент
          double lot = posVolume * COEF;
          
          double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
          
          if(ask <= hist_price - DELTA * _Point)
          {
          
          // -------+ вызов функции формирования торгового запроса +--------- 
          if(SendOrder(prc, lot))
            {
              Print("Позиция добавлена");
            }
           
           }
          }
    }
    
    //функция формирующая торговый запрос на открытие позиции  -------------------+
    //и проверки результата открытия
    bool SendOrder(double price, double volume)
    {
       if(volume >= 100000){
       return(false);
       Print("ОШИБКА! Обьем Ордера привысил размер 100-ни лотов и сейчас ровняется", volume,"-м");
       };
       
       counter++;
       MqlTradeRequest request = {0};
       MqlTradeResult  result  = {0};
       //---заполняем поля торгового запроса
       request.action       = TRADE_ACTION_PENDING;    // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.magic        = magic_number;
       request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
       request.price        = price;                   // Цена  
       request.type         = ORDER_TYPE_BUY_LIMIT;    // Тип ордера
       request.tp           = price + 1110*_Point;      // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = price - 1275*_Point;      // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.deviation    = 100000000;               // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах
       request.type_filling = ORDER_FILLING_IOC;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_GTC;
       
       
    //---проверим хватает ли средств для открытия позиции
       double margin = 0.0;
       
       if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
          return(false);
       
       if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
          return(false);
    
       
    //---отправка запроса на сервер и проверка результата отправки
       if (OrderSend(request,result))
          {
            if ( result.retcode == TRADE_RETCODE_DONE)
            {
              return (true);
            }
          }
                                        
       return(false);
    }//-------------------------------------------------------------------------------------------------+
    
    
    
    
    // возвращает цену открытия последнего ордера, где nMode - ORDER_TYPE_BUY/ORDER_TYPE_SELL ----------+
    // для позиции с идентификатором PositionID
    double FindLastPrice(int nMode)
      {
        int  CntPos;               // количество ордеров в истории
        ulong nTicket;             // тикет выбранного ордера из истории
        ulong OldTicket = 0;       // тикет ордера найденного ранее
        long PosID, PosiID;        // идентификатор позиции, к которой относится выбранный ордер
        //long Magic;              // магический номер
        long Type;                 // тип найденного ордера (Buy или Sell)
        double OrderPrice = 0;     // найденная цена
        // идентификатор позиции
        if((PosiID = PositionGetInteger(POSITION_IDENTIFIER))==0) return(0.0);
        
        // создадим список ордеров и сделок, находящихся в истории
        HistorySelect(0, TimeCurrent());
        
        CntPos = HistoryOrdersTotal(); // количество ордеров в истории
        
        // переберем все ордеры истории и отберем те, что относятся к нашей открытой позиции
        for (int i = 0; i < CntPos; i++)
          {
            nTicket = HistoryOrderGetTicket(i);  // получим тикет очередного ордера
            PosID  = HistoryOrderGetInteger(nTicket, ORDER_POSITION_ID);  // позиция ордера
            Type   = HistoryOrderGetInteger(nTicket, ORDER_TYPE);         // тип ордера
            
            if ((PosID == PosiID) && (Type == nMode)) 
              {
                if (nTicket > OldTicket)  // этот ордер был открыт позже найденного ранее
                  {
                    OrderPrice = HistoryOrderGetDouble(nTicket, ORDER_PRICE_OPEN); // цена открытия ордера
                    OldTicket = nTicket; // запомним тикет
                  };
              };
          };
          
        return(OrderPrice);
      };//---------------------------------------------------------------------------+
    
      
    // ---- функция подсчета значения стартового лота. ------------------------------+
    
           double function_trade_lot(double account_balance ){
           
              double lot = 0.01;
              
              //lot = NormalizeDouble(0.01+MathMax(MathFloor((account_balance-100000)/50000),0)*0.01,2);
              
              //lot = MathMin(lot, SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX));
              
              
        return(lot);
      
      };//---------------------------------------------------------------------------+

    Вы не можете благодарить!

  8. #8
    Программист
    Регистрация
    16.08.2012
    Адрес
    Челябинск
    Сообщений
    1,244
    Promo (¢)
    26,380
    Благодарности
    Получено: 424
    Отправлено: 42
    Цитата Сообщение от Mike_Kharkov Посмотреть сообщение
    // доливка существующей позиции.
    double prc = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    Читаем help терминала:
    "Buy Limit — торговый приказ на покупку по цене "Ask" равной или меньшей, чем указанная в ордере. При этом текущий уровень цен больше значения установленного в ордере. Обычно ордера этого типа выставляются в расчете на то, что цена инструмента, опустившись до определенного уровня, начнет расти;"
    вопрос а какую цену вы подсунули в запрос? Ответ - Текущую. Отсюда и проблемы.

    Вы не можете благодарить!

  9. #9
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от wayfarer Посмотреть сообщение
    Читаем help терминала:
    "Buy Limit — торговый приказ на покупку по цене "Ask" равной или меньшей, чем указанная в ордере. При этом текущий уровень цен больше значения установленного в ордере. Обычно ордера этого типа выставляются в расчете на то, что цена инструмента, опустившись до определенного уровня, начнет расти;"
    вопрос а какую цену вы подсунули в запрос? Ответ - Текущую. Отсюда и проблемы.
    И что тогда можно придумать(с точки зрения идеи написания кода), если необходимо докупиться против себя лимитным ордером?

    Цитата Сообщение от wayfarer Посмотреть сообщение
    При этом текущий уровень цен больше значения установленного в ордере.
    То есть я могу послать данный ордер только тогда, когда моя цена(buy limit) находится выше той, которая у меня на ASK-е находиться в текущий момент?

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 06.08.2014 в 21:50.

  10. #10
    Программист
    Регистрация
    16.08.2012
    Адрес
    Челябинск
    Сообщений
    1,244
    Promo (¢)
    26,380
    Благодарности
    Получено: 424
    Отправлено: 42
    Цитата Сообщение от Mike_Kharkov Посмотреть сообщение
    То есть докупаться на форексе нельзя лимитными ордерами получается??
    Можно, только для Buy limit цена должна быть ниже текущей. Для Sell limit больше текущей. У каждого брокера своя величина допустимой разницы между текущей ценой рынка и ценой limit ордера. Исправьте цену, как правило разница не меньше спреда по паре, иначе брокер ничего не заработает!
    double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    например, на:
    double prc = NormalizeDouble((SymbolInfoDouble(Symbol(), SYMBOL_ASK)-5*_Point, _Digits);

    Вы не можете благодарить!

Страница 1 из 3 1 2 3 ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •