Структура торгового запроса (MqlTradeRequest)

Взаимодействие клиентского терминала и торгового сервера для проведения операций постановки ордеров производится посредством торговых запросов. Запрос представлен специальной предопределенной структурой MqlTradeRequest, которая содержит все поля, необходимые для заключения торговых сделок. Результат обработки запроса представлен структурой MqlTradeResult.

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Тип выполняемого действия
   ulong                         magic;            // Штамп эксперта (идентификатор magic number)
   ulong                         order;            // Тикет ордера
   string                        symbol;           // Имя торгового инструмента
   double                        volume;           // Запрашиваемый объем сделки в лотах
   double                        price;            // Цена 
   double                        stoplimit;        // Уровень StopLimit ордера
   double                        sl;               // Уровень Stop Loss ордера
   double                        tp;               // Уровень Take Profit ордера
   ulong                         deviation;        // Максимально приемлемое отклонение от запрашиваемой цены
   ENUM_ORDER_TYPE               type;             // Тип ордера
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Тип ордера по исполнению
   ENUM_ORDER_TYPE_TIME          type_time;        // Тип ордера по времени действия
   datetime                      expiration;       // Срок истечения ордера (для ордеров типа ORDER_TIME_SPECIFIED)
   string                        comment;          // Комментарий к ордеру
   ulong                         position;         // Тикет позиции
   ulong                         position_by;      // Тикет встречной позиции
  };

Описание полей

Поле

Описание

action

Тип торговой операции. Значение может быть одним из значений перечисления ENUM_TRADE_REQUEST_ACTIONS

magic

Идентификатор эксперта. Позволяет организовать аналитическую обработку торговых ордеров. Каждый эксперт может выставлять свой собственный уникальный идентификатор при отправке торгового запроса

order

Тикет ордера. Требуется для модификации отложенных ордеров

symbol

Имя торгового инструмента, по которому выставляется ордер. Не требуется при операциях модификации ордеров и закрытии позиций

volume

Запрашиваемый объем сделки в лотах. Реальное значение объема при открытии сделки будет зависеть от типа ордера по исполнению.

price

Цена, при достижении которой ордер должен быть исполнен. Для рыночных ордеров по инструментам с типом исполнения "Market Execution" (SYMBOL_TRADE_EXECUTION_MARKET), имеющих тип TRADE_ACTION_DEAL, указание цены не требуется

stoplimit

Цена, по которой будет выставлен отложенный Limit ордер, при достижении ценой значения price (это условие является обязательным). До этого момента отложенный ордер в торговую систему не выводится

sl

Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении

tp

Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении

deviation

Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах

type

Тип ордера. Значение может быть одним из значений перечисления ENUM_ORDER_TYPE

type_filling

Тип ордера по исполнению. Значение может быть одним из значений ENUM_ORDER_TYPE_FILLING

type_time

Тип ордера по по истечению. Значение может быть одним из значений ENUM_ORDER_TYPE_TIME

expiration

Срок истечения отложенного ордера (для ордеров типа ORDER_TIME_SPECIFIED)

comment

Комментарий к ордеру

position

Тикет позиции. Следует заполнять при изменении и закрытии позиции для ее однозначной идентификации. Как правило, соответствует тикету ордера, в результате которого позиция была открыта.

position_by

Тикет встречной позиции. Используется при закрытии позиции встречной — открытой по тому же инструменту, но в противоположном направлении.

При модификации или закрытии позиции в системе хеджинга обязательно указывайте ее тикет (MqlTradeRequest::position). В системе неттинга тикет также можно указывать, однако идентификации позиции осуществляется по имени символа.

Для отправки приказов на совершение торговых операций  необходимо использовать функцию OrderSend(). Для каждой торговой операции необходимо указывать обязательные поля и можно заполнять опциональные поля. Всего предусмотрено семь вариантов отправки торгового запроса:

Request Execution

Торговый ордер на открытие позиции в режиме Request Execution (режим торговли по запросу текущих цен). Требуется указание 9 полей:

  • action
  • symbol
  • volume
  • price
  • sl
  • tp
  • deviation
  • type
  • type_filling

Можно также задать значения полей magic и comment.

Instant Execution

Торговый ордер на открытие позиции в режиме Instant Execution (режим торговли по потоковым ценам). Требуется указание 9 полей:

  • action
  • symbol
  • volume
  • price
  • sl
  • tp
  • deviation
  • type
  • type_filling

Можно также задать значения полей magic и comment.

Market Execution

Торговый ордер на открытие позиции в режиме Market Execution (режим исполнения торговых приказов по рынку). Требуется указание 5 полей:

  • action
  • symbol
  • volume
  • type
  • type_filling

Можно также задать значения полей magic и comment.

Exchange Execution

Торговый ордер на открытие позиции в режиме Exchange Execution (биржевой режим исполнения торговых приказов). Требуется указание 5 полей:

  • action
  • symbol
  • volume
  • type
  • type_filling

Можно также задать значения полей magic и comment.

Пример торговой операции TRADE_ACTION_DEAL для открытия позиции Buy:

#define EXPERT_MAGIC 123456   // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Открытие позиции Buy                                             |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =0.1;                                   // объем в 0.1 лот
   request.type     =ORDER_TYPE_BUY;                        // тип ордера
   request.price    =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // цена для открытия
   request.deviation=5;                                     // допустимое отклонение от цены
   request.magic    =EXPERT_MAGIC;                          // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }

 

Пример торговой операции TRADE_ACTION_DEAL для открытия позиции Sell:

#define EXPERT_MAGIC 123456   // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Открытие позиции Sell                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =0.2;                                   // объем в 0.2 лот
   request.type     =ORDER_TYPE_SELL;                       // тип ордера
   request.price    =SymbolInfoDouble(Symbol(),SYMBOL_BID); // цена для открытия
   request.deviation=5;                                     // допустимое отклонение от цены
   request.magic    =EXPERT_MAGIC;                          // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }

 
Пример торговой операции TRADE_ACTION_DEAL для закрытия позиций:

#define EXPERT_MAGIC 123456   // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Закрытие всех позиций                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- объявление запроса и результата
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // количество открытых позиций   
//--- перебор всех открытых позиций
   for(int i=total-1; i>=0; i--)
     {
      //--- параметры ордера
      ulong  position_ticket=PositionGetTicket(i);                                      // тикет позиции
      string position_symbol=PositionGetString(POSITION_SYMBOL);                        // символ 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);              // количество знаков после запятой
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                  // MagicNumber позиции
      double volume=PositionGetDouble(POSITION_VOLUME);                                 // объем позиции
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);    // тип позиции
      //--- вывод информации о позиции
      PrintFormat("#%I64u %s  %s  %.2f  %s [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  magic);
      //--- если MagicNumber совпадает
      if(magic==EXPERT_MAGIC)
        {
         //--- обнуление значений запроса и результата
         ZeroMemory(request);
         ZeroMemory(result);
         //--- установка параметров операции
         request.action   =TRADE_ACTION_DEAL;        // тип торговой операции
         request.position =position_ticket;          // тикет позиции
         request.symbol   =position_symbol;          // символ 
         request.volume   =volume;                   // объем позиции
         request.deviation=5;                        // допустимое отклонение от цены
         request.magic    =EXPERT_MAGIC;             // MagicNumber позиции
         //--- установка цены и типа ордера в зависимости от типа позиции
         if(type==POSITION_TYPE_BUY)
           {
            request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
            request.type =ORDER_TYPE_SELL;
           }
         else
           {
            request.price=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
            request.type =ORDER_TYPE_BUY;
           }
         //--- вывод информации о закрытии
         PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- отправка запроса
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // если отправить запрос не удалось, вывести код ошибки
         //--- информация об операции   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //---
        }
     }
  }

 

SL & TP Modification

Торговый приказ на модификацию уровней StopLoss и/или TakeProfit. Требуется указание 4 полей:

  • action
  • symbol
  • sl
  • tp
  • position

 

Пример торговой операции TRADE_ACTION_SLTP для изменения значений Stop Loss и Take Profit у открытой позиции:

#define EXPERT_MAGIC 123456  // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Модификация Stop Loss и Take Profit позиции                      |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- объявление запроса и результата
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // количество открытых позиций   
//--- перебор всех открытых позиций
   for(int i=0; i<total; i++)
     {
      //--- параметры ордера
      ulong  position_ticket=PositionGetTicket(i);// тикет позиции
      string position_symbol=PositionGetString(POSITION_SYMBOL); // символ 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // количество знаков после запятой
      ulong  magic=PositionGetInteger(POSITION_MAGIC); // MagicNumber позиции
      double volume=PositionGetDouble(POSITION_VOLUME);    // объем позиции
      double sl=PositionGetDouble(POSITION_SL);  // Stop Loss позиции
      double tp=PositionGetDouble(POSITION_TP);  // Take Profit позиции
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);  // тип позиции
      //--- вывод информации о позиции
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- если MagicNumber совпадает, Stop Loss и Take Profit не заданы
      if(magic==EXPERT_MAGIC && sl==0 && tp==0)
        {
         //--- вычисление текущих ценовых уровней
         double price=PositionGetDouble(POSITION_PRICE_OPEN);
         double bid=SymbolInfoDouble(position_symbol,SYMBOL_BID);
         double ask=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
         int    stop_level=(int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL);
         double price_level;
         //--- если уровень минимально допустимого отступа в пунктах от текущей цены закрытия не задан
         if(stop_level<=0)
            stop_level=150; // зададим отступ в 150 пунктов от текущей цены закрытия
         else
            stop_level+=50; // уровень отступа возьмем равным (SYMBOL_TRADE_STOPS_LEVEL + 50) пунктов для надежности
 
         //--- вычисление и округление значений Stop Loss и Take Profit
         price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
         if(type==POSITION_TYPE_BUY)
           {
            sl=NormalizeDouble(bid-price_level,digits);
            tp=NormalizeDouble(bid+price_level,digits);
           }
         else
           {
            sl=NormalizeDouble(ask+price_level,digits);
            tp=NormalizeDouble(ask-price_level,digits);
           }
         //--- обнуление значений запроса и результата
         ZeroMemory(request);
         ZeroMemory(result);
         //--- установка параметров операции
         request.action  =TRADE_ACTION_SLTP// тип торговой операции
         request.position=position_ticket;   // тикет позиции
         request.symbol=position_symbol;     // символ 
         request.sl      =sl;                // Stop Loss позиции
         request.tp      =tp;                // Take Profit позиции
         request.magic=EXPERT_MAGIC;         // MagicNumber позиции
         //--- вывод информации о модификации
         PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- отправка запроса
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // если отправить запрос не удалось, вывести код ошибки
         //--- информация об операции   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }
  }

 
Pending Order

Торговый приказ на установку отложенного ордера. Требуется указание 11 полей:

  • action
  • symbol
  • volume
  • price
  • stoplimit
  • sl
  • tp
  • type
  • type_filling
  • type_time
  • expiration

Можно также задать значения полей magic и comment.
 
Пример торговой операции TRADE_ACTION_PENDING для установки отложенного ордера:

#property description "Пример установки отложенных ордеров"
#property script_show_inputs
#define EXPERT_MAGIC 123456                             // MagicNumber эксперта
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT;   // тип ордера
//+------------------------------------------------------------------+
//| Установка отложенных ордеров                                     |
//+------------------------------------------------------------------+
void OnStart()
  {
//-- объявление и инициализация запроса и результата
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- параметры для установки отложенного ордера
   request.action   =TRADE_ACTION_PENDING;                             // тип торговой операции
   request.symbol   =Symbol();                                         // символ
   request.volume   =0.1;                                              // объем в 0.1 лот
   request.deviation=2;                                                // допустимое отклонение от цены
   request.magic    =EXPERT_MAGIC;                                     // MagicNumber ордера
   int offset = 50;                                                    // отступ от текущей цены для установки ордера, в пунктах
   double price;                                                       // цена срабатывания ордера
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);                // размер пункта
   int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);                // кол-во знаков после запятой (точность)
   //--- проверка типа операции
   if(orderType==ORDER_TYPE_BUY_LIMIT)
     {
      request.type     =ORDER_TYPE_BUY_LIMIT;                          // тип ордера
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;        // цена для открытия 
      request.price    =NormalizeDouble(price,digits);                 // нормализованная цена открытия 
     }
   else if(orderType==ORDER_TYPE_SELL_LIMIT)
     {
      request.type     =ORDER_TYPE_SELL_LIMIT;                          // тип ордера
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point;         // цена для открытия 
      request.price    =NormalizeDouble(price,digits);                  // нормализованная цена открытия 
     }
   else if(orderType==ORDER_TYPE_BUY_STOP)
     {
      request.type =ORDER_TYPE_BUY_STOP;                                // тип ордера
      price        =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // цена для открытия 
      request.price=NormalizeDouble(price,digits);                      // нормализованная цена открытия 
     }
   else if(orderType==ORDER_TYPE_SELL_STOP)
     {
      request.type     =ORDER_TYPE_SELL_STOP;                           // тип ордера
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID)-offset*point;         // цена для открытия 
      request.price    =NormalizeDouble(price,digits);                  // нормализованная цена открытия 
     }
   else Alert("Этот пример только для установки отложенных ордеров");   // если выбран не отложенный ордер
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());                 // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }
//+------------------------------------------------------------------+

 
Modify Pending Order

Торговый приказ на модификацию уровней цен отложенного ордера. Требуется указание 7 полей:

  • action
  • order
  • price
  • sl
  • tp
  • type_time
  • expiration

 

Пример торговой операции TRADE_ACTION_MODIFY для модификации уровней цен отложенного ордера:

#define EXPERT_MAGIC 123456  // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Модификация отложенных ордеров                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//-- объявление и инициализация запроса и результата
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   int total=OrdersTotal(); // количество установленных отложенных ордеров
//--- перебор всех установленных отложенных ордеров
   for(int i=0; i<total; i++)
     {
      //--- параметры ордера
      ulong  order_ticket=OrderGetTicket(i);                             // тикет ордера
      string order_symbol=Symbol();                                      // символ
      int    digits=(int)SymbolInfoInteger(order_symbol,SYMBOL_DIGITS);  // количество знаков после запятой
      ulong  magic=OrderGetInteger(ORDER_MAGIC);                         // MagicNumber ордера
      double volume=OrderGetDouble(ORDER_VOLUME_CURRENT);                // текущий объем ордера
      double sl=OrderGetDouble(ORDER_SL);                                // текущий Stop Loss ордера
      double tp=OrderGetDouble(ORDER_TP);                                // текущий Take Profit ордера
      ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); // тип ордера
      int offset = 50;                                                   // отступ от текущей цены для установки ордера, в пунктах
      double price;                                                      // цена срабатывания ордера
      double point=SymbolInfoDouble(order_symbol,SYMBOL_POINT);          // размер пункта
      //--- вывод информации об ордере
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  order_ticket,
                  order_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- если MagicNumber совпадает, Stop Loss и Take Profit не заданы
      if(magic==EXPERT_MAGIC && sl==0 && tp==0)
        {
         request.action=TRADE_ACTION_MODIFY;                           // тип торговой операции
         request.order = OrderGetTicket(i);                            // тикет ордера
         request.symbol   =Symbol();                                   // символ
         request.deviation=5;                                          // допустимое отклонение от цены
        //--- установка уровня цены, тейк-профит и стоп-лосс ордера в зависимости от его типа
         if(type==ORDER_TYPE_BUY_LIMIT)
           {
            price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; 
            request.tp = NormalizeDouble(price+offset*point,digits);
            request.sl = NormalizeDouble(price-offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                // нормализованная цена открытия
           }
         else if(type==ORDER_TYPE_SELL_LIMIT)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point; 
            request.tp = NormalizeDouble(price-offset*point,digits);
            request.sl = NormalizeDouble(price+offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // нормализованная цена открытия
           }
         else if(type==ORDER_TYPE_BUY_STOP)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; 
            request.tp = NormalizeDouble(price+offset*point,digits);
            request.sl = NormalizeDouble(price-offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // нормализованная цена открытия
           }
         else if(type==ORDER_TYPE_SELL_STOP)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_BID)-offset*point; 
            request.tp = NormalizeDouble(price-offset*point,digits);
            request.sl = NormalizeDouble(price+offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // нормализованная цена открытия
           }
         //--- отправка запроса
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // если отправить запрос не удалось, вывести код ошибки
         //--- информация об операции   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //--- обнуление значений запроса и результата
         ZeroMemory(request);
         ZeroMemory(result);
        }
     }
  }
//+------------------------------------------------------------------+

 
Delete Pending Order

Торговый приказ на удаление отложенного ордера. Требуется указание 2 полей:

  • action
  • order

 

Пример торговой операции TRADE_ACTION_REMOVE для удаления отложенных ордеров:

#define EXPERT_MAGIC 123456  // MagicNumber эксперта
//+------------------------------------------------------------------+
//| Удаление отложенных ордеров                                      |
//+------------------------------------------------------------------+
void OnStart()
  {
//-- объявление и инициализация запроса и результата
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   int total=OrdersTotal(); // количество установленных отложенных ордеров
//--- перебор всех установленных отложенных ордеров
   for(int i=total-1; i>=0; i--)
     {
      ulong  order_ticket=OrderGetTicket(i);                   // тикет ордера
      ulong  magic=OrderGetInteger(ORDER_MAGIC);               // MagicNumber ордера
      //--- если MagicNumber совпадает
      if(magic==EXPERT_MAGIC)
        {
         //--- обнуление значений запроса и результата
         ZeroMemory(request);
         ZeroMemory(result);
         //--- установка параметров операции     
         request.action=TRADE_ACTION_REMOVE;                   // тип торговой операции
         request.order = order_ticket;                         // тикет ордера
         //--- отправка запроса
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // если отправить запрос не удалось, вывести код ошибки
         //--- информация об операции   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }
  }
//+------------------------------------------------------------------+

 

Смотри также

Структуры и классы, Торговые функции, Свойства ордеров