거래 작업 유형

거래는 OrderSend() 기능을 사용하여 열린 포지션으로 주문을 보내고 보류중인 주문을 작성, 수정 또는 삭제하는 방식으로 이루어집니다. 각 거래 주문은 요청된 작업의 유형을 나타냅니다. 거래 작업은 ENUM_TRADE_REQUEST_ACTIONS 열거에 설명되어 있습니다.

ENUM_TRADE_REQUEST_ACTIONS

식별자

설명

TRADE_ACTION_DEAL

지정된 매개변수를 사용하여 즉시 실행할 거래 주문 작성(시장 주문)

TRADE_ACTION_PENDING

지정된 조건에서 실행에 대한 거래 주문 작성(보류 중인 주문)

TRADE_ACTION_SLTP

열린 포지션의 Stop Loss 및 Take Profit 값

TRADE_ACTION_MODIFY

이전에 발주된 주문의 매개변수 수정

TRADE_ACTION_REMOVE

이전에 발주된 보류 중인 주문을 삭제

TRADE_ACTION_CLOSE_BY

반대 포지션으로 포지션 닫기

 
매입 포지션을 열기 위한 TRADE_ACTION_DEAL 거래 작업의 예:

#define EXPERT_MAGIC 123456   // MagicNumber of the expert
//+------------------------------------------------------------------+
//| 매입 위치 열기                                                     |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 거래 요청과 거래 요청 결과를 선언하고 초기화
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- 요청의 매개변수
   request.action   =TRADE_ACTION_DEAL;                     // 거래 작업 유형
   request.symbol   =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());     // if unable to send the request, output the error code
//--- 작업에 대한 정보
   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={0};
   MqlTradeResult  result={0};
//--- 요청의 매개변수
   request.action   =TRADE_ACTION_DEAL;                     // 거래 작업 유형
   request.symbol   =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 of the order
//--- 요청 전송
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // if unable to send the request, output the error code
//--- 작업에 대한 정보
   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)
        {
         //--- 요청 및 결과 값 0 설정
         ZeroMemory(request);
         ZeroMemory(result);
         //--- 작업 매개변수 설정
         request.action   =TRADE_ACTION_DEAL;        // 거래 작업의 유형
         request.position =position_ticket;          // t포지션의 티켓
         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);
         //---
        }
     }
  }
//+------------------------------------------------------------------+

 
보류 중인 주문을 발주하기 위한 TRADE_ACTION_PENDING 거래 작업의 예:

#property description "Example of placing pending orders"
#property script_show_inputs
#define EXPERT_MAGIC 123456                             // MagicNumber of the expert
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT;   // order type
//+------------------------------------------------------------------+
//| Placing pending orders                                           |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declare and initialize the trade request and result of trade request
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- parameters to place a pending order
   request.action   =TRADE_ACTION_PENDING;                             // type of trade operation
   request.symbol   =Symbol();                                         // symbol
   request.volume   =0.1;                                              // volume of 0.1 lot
   request.deviation=2;                                                // allowed deviation from the price
   request.magic    =EXPERT_MAGIC;                                     // MagicNumber of the order
   int offset = 50;                                                    // offset from the current price to place the order, in points
   double price;                                                       // order triggering price
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);                // value of point
   int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);                // number of decimal places (precision)
   //--- checking the type of operation
   if(orderType==ORDER_TYPE_BUY_LIMIT)
     {
      request.type     =ORDER_TYPE_BUY_LIMIT;                          // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;        // price for opening 
      request.price    =NormalizeDouble(price,digits);                 // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_SELL_LIMIT)
     {
      request.type     =ORDER_TYPE_SELL_LIMIT;                          // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point;         // price for opening 
      request.price    =NormalizeDouble(price,digits);                  // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_BUY_STOP)
     {
      request.type =ORDER_TYPE_BUY_STOP;                                // order type
      price        =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // price for opening 
      request.price=NormalizeDouble(price,digits);                      // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_SELL_STOP)
     {
      request.type     =ORDER_TYPE_SELL_STOP;                           // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;         // price for opening 
      request.price    =NormalizeDouble(price,digits);                  // normalized opening price 
     }
   else Alert("This example is only for placing pending orders");   // if not pending order is selected
//--- send the request
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());                 // if unable to send the request, output the error code
//--- information about the operation
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }
//+------------------------------------------------------------------+

 
열린 포지션의 솔실 중지 및 이익 취하기 값을 수정하기 위한 TRADE_ACTION_SLTP 거래 작업의 예:

#define EXPERT_MAGIC 123456  // 엑스퍼트의 MagicNumber
//+------------------------------------------------------------------+
//| 손실 정지 수정 및 포지션 이익 취득            |
//+------------------------------------------------------------------+
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);  // 포지션의 손실 중지
      double tp=PositionGetDouble(POSITION_TP);  // 포지션의 이익 가져가기
      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가 일치하는 경우 손실 중지 및 이익 취득이 정의되지 않습니다
      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; // set the offset distance to (SYMBOL_TRADE_STOPS_LEVEL + 50) points for reliability
 
         //--- 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(ask+price_level,digits);
           }
         else
           {
            sl=NormalizeDouble(ask+price_level,digits);
            tp=NormalizeDouble(bid-price_level,digits);
           }
         //--- 요청 및 결과 값 0 설정
         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;         // 포지션의 매직넘버
         //--- 수정에 대한 정보 출력
         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);
        }
     }
  }
//+------------------------------------------------------------------+

 
보류 중인 주문의 가격 수준을 수정하기 위한 TRADE_ACTION_MODIFY 거래 작업의 예:

#define EXPERT_MAGIC 123456  // MagicNumber of the expert
//+------------------------------------------------------------------+
//| 보류 중인 주문 수정                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 거래 요청과 거래 요청의 결과를 선언하고 초기화
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   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);                         // 주문의 매직넘버
      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);
      //--- 매직넘버가 일치하는 경우 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;                                          // 가격 허용 편차
        //--- 주문의 유형에 따라 Take Profit 및 Stop Loss, 가격 수준 설정
         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_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_SELL_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);                 // 정규 시가
           }
         //--- 요청 전송
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // 요청 전송을 할 수 없는 경우 오류 코드 출력
         //--- 작업 정보   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //--- 요청 및 결과 값 0 설정
         ZeroMemory(request);
         ZeroMemory(result);
        }
     }
  }
//+------------------------------------------------------------------+

 
보류 중인 주문을 삭제하기 위한 TRADE_ACTION_REMOVE 거래 작업의 예:

#define EXPERT_MAGIC 123456  // 엑스퍼트의 MagicNumber
//+------------------------------------------------------------------+
//| 보류 중인 주문 삭제                                          |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 거래 요청과 거래 요청 결과를 선언하고 초기화
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   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)
        {
         //--- 요청 및 결과 값 0 설정
         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);
        }
     }
  }
//+------------------------------------------------------------------+

 
서로 반대되는 포지션에 의한 포지션 폐쇄의 TRADE_ACTION_CLOSE_BY 거래 작업 예:

#define EXPERT_MAGIC 123456  // MagicNumber of the expert
//+------------------------------------------------------------------+
//| 반대 포지션으로 모든 포지션 닫기                        |
//+------------------------------------------------------------------+
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);                                // 포지션의 매직넘버
      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);
      //--- 매직넘버가 일치하는 경우
      if(magic==EXPERT_MAGIC)
        {
         for(int j=0; j<i; j++)
           {
            string symbol=PositionGetSymbol(j); // 반대 포지션의 기호
            //--- 반대 포지션과 초기 포지션의 기호가 일치하는 경우
            if(symbol==position_symbol && PositionGetInteger(POSITION_MAGIC)==EXPERT_MAGIC)
              {
               //--- 반대 포지션 유형 설정
               ENUM_POSITION_TYPE type_by=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
               //--- 처음 포지션과 반대 포지션의 유형이 일치할 경우 떠나기
               if(type==type_by)
                  continue;
               //--- 요청 및 결과 값 0
               ZeroMemory(request);
               ZeroMemory(result);
               //--- 작업 매개변수 설정
               request.action=TRADE_ACTION_CLOSE_BY;                         // 거래 작업 유형
               request.position=position_ticket;                             // 포지션 티켓
               request.position_by=PositionGetInteger(POSITION_TICKET);      // 반대 포지션 티켓
               //request.symbol     =position_symbol;
               request.magic=EXPERT_MAGIC;                                   // MagicNumber of the position
               //--- 반대 포지션으로 폐쇄 정보를 출력
               PrintFormat("Close #%I64d %s %s by #%I64d",position_ticket,position_symbol,EnumToString(type),request.position_by);
               //--- 요청 전송
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError()); // 요청을 전송할 수 없는 경우 오류 코드 출력
 
               //--- 작업 정보   
               PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+