English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5로 하는 트레이드 오퍼레이션 - 어렵지 않아요!

MQL5로 하는 트레이드 오퍼레이션 - 어렵지 않아요!

MetaTrader 5 | 5 7월 2021, 11:40
364 39
MetaQuotes
MetaQuotes

대부분의 투자자들이 수익 창출을 목적으로 하지만 투자 과정 자체를 즐기는 투자자들도 있습니다. 하지만 반드시 수동 매매여야만 그 과정이 즐거울 수 있는 건 아니예요. 자동 거래 시스템 개발 또한 꽤 흥미진진하답니다. 트레이딩 로봇 개발은 좋은 추리 소설을 읽는 것 만큼이나 재밌을 수 있어요.

알고리즘을 설계할 때 꽤 많은 테크니컬 이슈를 고려해야 하는데요. 그 중에서도 가장 중요한 몇몇은 다음과 같습니다:

  1. 무엇을 거래할 것인가?
  2. 언제 거래할 것인가?
  3. 어떻게 거래할 것인가?

자신에게 가장 적합한 심볼을 고르려면 첫 번째 질문에 대한 답을 생각해 보아야 합니다. 이 경우 자동 매매 시스템 구축 가능 여부를 포함한 여러 요인에 선택이 좌우됩니다. 두 번째 질문은 거래의 방향성, 진입 및 청산 조건을 명확하게 규정하는 정교한 거래 규칙을 세우는 것과 관련이 있습니다. 세 번째 질문은 조금 더 간단해 보이죠: 어떻게 하면 프로그래밍 언어를 이용하여 매매 거래를 할 수 있을까요?

이번 글에서는 MQL5를 이용한 거래 알고리즘을 어떻게 실제로 실행할 수 있는지에 대해 알아볼게요.


알고리즘 트레이딩을 위한 MQL5 기능

MQL5는 주문, 포지션 및 거래 요청 관련 업무에 필요한 다양한 거래 함수를 갖춘 거래 전략 프로그래밍 언어입니다. 그렇기 때문에 MQL5를 이용하는 것이 개발자에게 가장 손이 덜 가는 트레이딩 로봇 개발 방법이 되죠.

MQL5를 이용하면 거래 요청OrderSend() 함수 또는 OrderSendAsync() 함수를 통해 서버로 보내고, 처리 결과를 받아 보고, 거래 기록을 확인하고, 원하는 심볼의 계약 명세를 살펴보고, 이벤트를 핸들링하고, 그 밖의 필요한 데이터 또한 요청할 수 있습니다.

그 밖에도 기술적 지표를 커스텀하거나, 이미 완성된 지표를 적용하고, 차트에 원하는 마크 또는 객체를 추가하고, 커스텀 UI를 구축하는 등 다양하게 활용할 수 있습니다. 다양한 구현 예제는 관련 문서에서 찾아 보세요.


트레이드 오퍼레이션: 알파벳 배우기만큼 쉬워요!

다음은 트레이딩 로봇에 필요한 기본적인 트레이드 오퍼레이션의 예시입니다:

  1. 현재가로 매수/매도 거래하기,
  2. 정해진 조건에 따른 매수/매도 대기 주문 입력하기,
  3. 대기 주문 정정/취소하기,
  4. 포지션 청산/확대/축소/전환하기.

위의 모든 오퍼레이션은 OrderSend() 함수를 통해 실행 가능합니다. 비동기적으로 처리되는 OrderSendAsync() 함수도 있죠. 모든 트레이드 오퍼레이션은 MqlTradeRequest 구조로 작성되어 있습니다. 따라서, 어려운 일이 있다면 MqlTradeRequest 구조를 올바르게 채우는 것과 요청 실행 결과를 핸들링하는 것 정도가 되겠네요.

매매 프로그램을 이용하면 시장가로 매도 및 매수 주문을 체결할 수 있으며(BUY 또는 SELL), 현재 시장가와는 거리가 다소 떨어져 있는 가격으로 매도 및 매수 대기 주문을 넣을 수 있습니다:

  • BUY STOP, SELL STOP - 지정가 돌파 시 매수 또는 매도(현재가보다 하락한 가격으로 거래);
  • BUY LIMIT, SELL LIMIT - 지정가 도달 시 매수 또는 매도(현재가보다 상승한 가격으로 거래);
  • BUY STOP LIMIT, SELL STOP LIMIT - 지정가 도달 시 스탑-리밋 매수 또는 스탑-리밋 매도

이 같은 기본 주문 유형은 열거형인 ENUM_ORDER_TYPE에 해당합니다. 



대기 주문을 정정하거나 취소해야 하는 경우도 있습니다. 그럴 때는 OrderSend() 또는 OrderSendAsync() 함수를 사용하면 되는데요. 오픈 포지션의 변경 또한 동일한 트레이드 오퍼레이션을 통해 이루어지므로 꽤 쉬운 편입니다.

트레이드 오퍼레이션이 복잡하고 까다롭다고만 생각하셨다면 이제 생각을 바꿀 때입니다. MQL5를 이용한 매매거래 코딩 방법뿐 아니라 거래 계좌 및 심볼 속성의 활용법에 대해서도 알려 드릴게요. 트레이드 클래스도 도움이 될 거예요.


CAccountInfo로 거래 계좌 확인하기

트레이딩 로봇을 개발할 때 가장 처음 생각해야 할 것은 사용하게 될 거래 계좌입니다. 학습 코드를 제작 중인 만큼 한번 엑스퍼트 어드바이저가 실제 계좌에서 열리면 어떤지 확인해 보도록 하죠.

CAccountInfo 클래스는 계좌 관련 작업에 사용됩니다. AccountInfo.mqh 파일을 실행하고 클래스 변수를 account라고 선언하겠습니다:

#include <Trade\AccountInfo.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- object for working with the account
   CAccountInfo account;
//--- receiving the account number, the Expert Advisor is launched at
   long login=account.Login();
   Print("Login=",login);
//--- clarifying account type
   ENUM_ACCOUNT_TRADE_MODE account_type=account.TradeMode();
//--- if the account is real, the Expert Advisor is stopped immediately!
   if(account_type==ACCOUNT_TRADE_MODE_REAL)
     {
      MessageBox("Trading on a real account is forbidden, disabling","The Expert Advisor has been launched on a real account!");
      return(-1);
     }
//--- displaying the account type    
   Print("Account type: ",EnumToString(account_type));
//--- clarifying if we can trade on this account
   if(account.TradeAllowed())
      Print("Trading on this account is allowed");
   else
      Print("Trading on this account is forbidden: you may have entered using the Investor password");
//--- clarifying if we can use an Expert Advisor on this account
   if(account.TradeExpert())
      Print("Automated trading on this account is allowed");
   else
      Print("Automated trading using Expert Advisors and scripts on this account is forbidden");
//--- clarifying if the permissible number of orders has been set
   int orders_limit=account.LimitOrders();
   if(orders_limit!=0)Print("Maximum permissible amount of active pending orders: ",orders_limit);
//--- displaying company and server names
   Print(account.Company(),": server ",account.Server());
//--- displaying balance and current profit on the account in the end
   Print("Balance=",account.Balance(),"  Profit=",account.Profit(),"   Equity=",account.Equity());
   Print(__FUNCTION__,"  completed"); //---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }

위의 코드를 통해 확인 가능하듯, OnInit() 함수에서 account 변수를 활용하면 다양하고 유용한 정보를 수신할 수 있어요. 해당 코드를 엑스퍼트 어드바이저에 추가하면 명령어 분석을 통해 로그를 검토할 수 있습니다.

다음은 2012 자동 거래 챔피언십 계좌에 열린 엑스퍼트 에드바이저의 모습입니다.



CSymbolInfo로 심볼 설정 불러오기

이제 계좌에 대한 정보는 있으니, 필요한 트레이드 오퍼레이션을 실행하기 전에 대상 심볼의 속성을 알아봐야 겠죠. CSymbolInfo 클래스는 이럴 때 사용할 수 있는 다양한 메소드를 제공합니다. 아래 예시에서는 아주 일부만 살펴볼 거예요.

#include<Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- object for receiving symbol settings
   CSymbolInfo symbol_info;
//--- set the name for the appropriate symbol
   symbol_info.Name(_Symbol);
//--- receive current rates and display
   symbol_info.RefreshRates();
   Print(symbol_info.Name()," (",symbol_info.Description(),")",
         "  Bid=",symbol_info.Bid(),"   Ask=",symbol_info.Ask());
//--- receive minimum freeze levels for trade operations
   Print("StopsLevel=",symbol_info.StopsLevel()," pips, FreezeLevel=",
         symbol_info.FreezeLevel()," pips");
//--- receive the number of decimal places and point size
   Print("Digits=",symbol_info.Digits(),
         ", Point=",DoubleToString(symbol_info.Point(),symbol_info.Digits()));
//--- spread info
   Print("SpreadFloat=",symbol_info.SpreadFloat(),", Spread(current)=",
         symbol_info.Spread()," pips");
//--- request order execution type for limitations
   Print("Limitations for trade operations: ",EnumToString(symbol_info.TradeMode()),
         " (",symbol_info.TradeModeDescription(),")");
//--- clarifying trades execution mode
   Print("Trades execution mode: ",EnumToString(symbol_info.TradeExecution()),
         " (",symbol_info.TradeExecutionDescription(),")");
//--- clarifying contracts price calculation method
   Print("Contract price calculation: ",EnumToString(symbol_info.TradeCalcMode()),
         " (",symbol_info.TradeCalcModeDescription(),")");
//--- sizes of contracts
   Print("Standard contract size: ",symbol_info.ContractSize(),
         " (",symbol_info.CurrencyBase(),")");
//--- minimum and maximum volumes in trade operations
   Print("Volume info: LotsMin=",symbol_info.LotsMin(),"  LotsMax=",symbol_info.LotsMax(),
         "  LotsStep=",symbol_info.LotsStep());
//--- 
   Print(__FUNCTION__,"  completed");
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }

아래는 자동 거래 챔피언십의 EUR/USD 통화쌍 속성입니다. 이제 트레이드 오퍼레이션을 실행할 준비가 됐습니다.



CTrade - 트레이드 오퍼레이션을 위한 편리한 클래스

MQL5에서는 OrderSend()와 OrderSendAsync() 함수 두 가지만 알면 거래가 가능합니다. 사실 두 가지 함수라기 구현 방법이 두 가지인 한 가지 함수이죠. OrderSend() 함수는 거래 요청을 보내고 실행 결과를 기다립니다. 비동기적으로 처리되는 OrderSendAsync() 함수는 요청에 대한 트레이딩 서버의 응답을 기다리지 않고 다음 작업을 수행해 나가죠. 하나의 함수만으로 모든 트레이드 오퍼레이션이 가능한 거나 마찬가지니까 MQL5로 거래하는 건 정말 쉽습니다.

그래도 어려운 것도 있겠죠? 두 함수 모두 12개가 넘는 필드를 첫 번째 매개 변수로 갖는 MqlTradeRequest 구조를 수신합니다. 모든 필드를 채울 필요는 없습니다. 필요한 필드 세트는 트레이드 연산 형식에 따라 달라지죠. 필요한 값을 잘못 입력하거나 빈 값으로 두는 경우 오류가 발생하여 서버로 요청이 전달되지 않습니다. 이 가운데 5가지 필드는 미리 정의된 열거형에 포함된 올바른 값을 필요로 하죠.

하나의 거래 요청에 대한 수많은 주문 속성을 규정하기 위해 이렇게 많은 필드가 필요한 건데요. 주문은 실행 정책, 유효 기간 및 기타 매개 변수에 따라 변합니다. 하지만 이 모든 구성 요소를 외울 필요는 없죠. CTrade 클래스를 이용하면 됩니다. 이런 식으로 저희가 제공하는 클래스를 이용해서 트레이딩 로봇을 만들 수 있어요.

#include<Trade\Trade.mqh>
//--- object for performing trade operations
CTrade  trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set MagicNumber for your orders identification
   int MagicNumber=123456;
   trade.SetExpertMagicNumber(MagicNumber);
//--- set available slippage in points when buying/selling
   int deviation=10;
   trade.SetDeviationInPoints(deviation);
//--- order filling mode, the mode allowed by the server should be used
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
//--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own
   trade.LogLevel(1); 
//--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()
   trade.SetAsyncMode(true);
//---
   return(0);
  }

그럼 CTrade가 트레이드 오퍼레이션에 어떤 도움이 되는지 보도록 할게요.

현재가로 매수/매도 거래하기

매매 전략은 지금 당장 현재가로 매수 또는 매도할 수 있게 해주죠. CTrade를 사용할 경우 거래량만 정하면 됩니다. 나머지 매개 변수(시가 및 심볼, 손절매 및 이익실현 가격, 주석)는 선택적입니다.

//--- 1. example of buying at the current symbol
   if(!trade.Buy(0.1))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

CTrade는 심볼이 규정되지 않은 경우 자동으로 차트에 있는 심볼을 사용합니다. 간단한 전략을 만들 때 편리하죠. 다중 통화 매매 전략인 경우 트레이드 오퍼레이션 대상 심볼은 항상 명확하게 규정해야 합니다.

//--- 2. example of buying at the specified symbol
   if(!trade.Buy(0.1,"GBPUSD"))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

손절매 및 이익실현 가격, 시가 및 주석 등의 모든 매개 변수도 규정할 수 있죠.

//--- 3. example of buying at the specified symbol with specified SL and TP
   double volume=0.1;         // specify a trade operation volume
   string symbol="GBPUSD";    //specify the symbol, for which the operation is performed
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); // number of decimal places
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);         // point
   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);             // current price for closing LONG
   double SL=bid-1000*point;                                   // unnormalized SL value
   SL=NormalizeDouble(SL,digits);                              // normalizing Stop Loss
   double TP=bid+1000*point;                                   // unnormalized TP value
   TP=NormalizeDouble(TP,digits);                              // normalizing Take Profit
//--- receive the current open price for LONG positions
   double open_price=SymbolInfoDouble(symbol,SYMBOL_ASK);
   string comment=StringFormat("Buy %s %G lots at %s, SL=%s TP=%s",
                               symbol,volume,
                               DoubleToString(open_price,digits),
                               DoubleToString(SL,digits),
                               DoubleToString(TP,digits));
   if(!trade.Buy(volume,symbol,open_price,SL,TP,comment))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

이미 언급한 바와 같이 매직 넘버와 허용되는 슬리피지는 Ctrade를 초기화할 때 설정되었고요. 따라서 필수는 아닙니다. 하지만 필요한 경우 오퍼레이션 실행 전에 설정할 수 있습니다.

리미트오더 설정하기

리미트오더 송신에는 BuyLimit() 또는 SellLimit() 클래스 메소드가 사용됩니다. 대부분의 경우 축약된 버전(시가 및 거래량만 지정)이면 충분해요. 지정가 매수 시가는 현재가보다 낮고, 지정가 매도 시에는 현재가보다 높아야 겠죠. 이러한 주문의 경우 가장 유리한 가격으로 시장에 진입하는 것이 목적이며 가격이 지지선에서 반등할 것으로 예상되는 경우에 사용하는 것이 적합합니다. 엑스퍼트 어드바이저의 심볼은 이럴 때 사용됩니다.

//--- 1. example of placing a Buy Limit pending order
   string symbol="GBPUSD";    // specify the symbol, at which the order is placed
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); // number of decimal places
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);         // point
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);             // current buy price
   double price=1000*point;                                   // unnormalized open price
   price=NormalizeDouble(price,digits);                       // normalizing open price
//--- everything is ready, sending a Buy Limit pending order to the server
   if(!trade.BuyLimit(0.1,price))
     {
      //--- failure message
      Print("BuyLimit() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("BuyLimit() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

손절매 및 이익실현 가격, 유효 기간, 심볼 및 주석 등 모든 매개 변수를 설정하는, 보다 상세한 버전의 주문도 가능한데요.

//--- 2. example of placing a Buy Limit pending order with all parameters
   double volume=0.1;
   string symbol="GBPUSD";    // specify the symbol, at which the order is placed
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); // number of decimal places
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);         // point
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);             // current buy price
   double price=1000*point;                                 // unnormalized open price
   price=NormalizeDouble(price,digits);                      // normalizing open price
   int SL_pips=300;                                         // Stop Loss in points
   int TP_pips=500;                                         // Take Profit in points
   double SL=price-SL_pips*point;                           // unnormalized SL value
   SL=NormalizeDouble(SL,digits);                            // normalizing Stop Loss
   double TP=price+TP_pips*point;                           // unnormalized TP value
   TP=NormalizeDouble(TP,digits);                            // normalizing Take Profit
   datetime expiration=TimeTradeServer()+PeriodSeconds(PERIOD_D1);
   string comment=StringFormat("Buy Limit %s %G lots at %s, SL=%s TP=%s",
                               symbol,volume,
                               DoubleToString(price,digits),
                               DoubleToString(SL,digits),
                               DoubleToString(TP,digits));
//--- everything is ready, sending a Buy Limit pending order to the server
   if(!trade.BuyLimit(volume,price,symbol,SL,TP,ORDER_TIME_GTC,expiration,comment))
     {
      //--- failure message
      Print("BuyLimit() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("BuyLimit() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

두 번째 버전으로 주문을 넣는 경우 손절매 및 이익실현 가격을 정확하게 입력하는 것이 중요합니다. 매수 시 이익실현 가격은 시가보다 높아야 하고, 손절매 가격은 시가보다 낮아야 하겠죠. 지정가 매도 시에는 이와 반대로 하면 됩니다. 엑스퍼트 어드바이저에서 과거 데이터로 테스팅을 해보면 쉽게 이해가 될 거예요. 이 경우 CTrade 클래스는 자동으로 메시지를 표시하게 됩니다. LogLevel 함수를 요청한 것이 아니라면요.

스탑오더 설정하기

이와 유사한 방법으로 BuyStop()SellStop() 메소드가 스탑오더 전송에 사용됩니다. 지정가 매수 시 시가는 현재가보다 높고 지정가 매도 시에는 현재가보다 낮아야겠죠. 지정가 주문은 저항선 돌파 시에 시장에 진입하거나 손해를 감수해야 하는 경우에 사용됩니다. 축약된 버전:

//--- 1. example of placing a Buy Stop pending order
   string symbol="USDJPY";    // specify the symbol, at which the order is placed
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); // number of decimal places
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);         // point
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);             // current buy price
   double price=1000*point;                                    // unnormalized open price
   price=NormalizeDouble(price,digits);                        // normalizing open price
//--- everything is ready, sending a Buy Stop pending order to the server 
   if(!trade.BuyStop(0.1,price))
     {
      //--- failure message
      Print("BuyStop() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("BuyStop() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

좀 더 상세한 버전에서는 지정가 대기 주문에 대한 최대 매개 변수가 모두 설정됩니다.

//--- 2. example of placing a Buy Stop pending order with all parameters
   double volume=0.1;
   string symbol="USDJPY";    // specify the symbol, at which the order is placed
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); // number of decimal places
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);         // point
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);             // current buy price
   double price=1000*point;                                   // unnormalized open price
   price=NormalizeDouble(price,digits);                       // normalizing open price
   int SL_pips=300;                                          // Stop Loss in points
   int TP_pips=500;                                          // Take Profit in points
   double SL=price-SL_pips*point;                            // unnormalized SL value
   SL=NormalizeDouble(SL,digits);                             // normalizing Stop Loss
   double TP=price+TP_pips*point;                            // unnormalized TP value
   TP=NormalizeDouble(TP,digits);                             // normalizing Take Profit
   datetime expiration=TimeTradeServer()+PeriodSeconds(PERIOD_D1);
   string comment=StringFormat("Buy Stop %s %G lots at %s, SL=%s TP=%s",
                               symbol,volume,
                               DoubleToString(price,digits),
                               DoubleToString(SL,digits),
                               DoubleToString(TP,digits));
//--- everything is ready, sending a Buy Stop pending order to the server 
   if(!trade.BuyStop(volume,price,symbol,SL,TP,ORDER_TIME_GTC,expiration,comment))
     {
      //--- failure message
      Print("BuyStop() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("BuyStop() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

적합한 CTrade 클래스 메소드가 지정가 매매 주문에 사용될 수 있죠. 이번에는 가격을 정확하게 입력하는 것이 매우 중요합니다.

포지션 함수

Buy() 또는 Sell() 메소드 대신 포지션 오픈 메소드를 사용할 수도 있지만 더 많은 세부 사항을 입력해야 합니다.

//--- number of decimal places
   int    digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
//--- point value
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
//--- receiving a buy price
   double price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
//--- calculate and normalize SL and TP levels
   double SL=NormalizeDouble(price-1000*point,digits);
   double TP=NormalizeDouble(price+1000*point,digits);
//--- filling comments
   string comment="Buy "+_Symbol+" 0.1 at "+DoubleToString(price,digits);
//--- everything is ready, trying to open a buy position
   if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.1,price,SL,TP,comment))
     {
      //--- failure message
      Print("PositionOpen() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("PositionOpen() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

CTrade 클래스를 사용할 경우에는 심볼만 입력하면 나머지가 자동으로 입력되죠.

//--- closing a position at the current symbol
   if(!trade.PositionClose(_Symbol))
     {
      //--- failure message
      Print("PositionClose() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("PositionClose() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

오픈된 포지션은 손절매 및 이익실현 가격만 수정이 가능한데요. 이는 PositionModify() 메소드를 이용해 진행됩니다.

//--- number of decimal places
   int    digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
//--- point value
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
//--- receiving the current Bid price
   double price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
//--- calculate and normalize SL and TP levels
   double SL=NormalizeDouble(price-1000*point,digits);
   double TP=NormalizeDouble(price+1000*point,digits);
//--- everything is ready, trying to modify the buy position
   if(!trade.PositionModify(_Symbol,SL,TP))
     {
      //--- failure message
      Print("Метод PositionModify() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("PositionModify() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

주문 정정 및취소하기

CTrade 클래스의 OrderModify() 메소드는 대기 주문의 매개 변수 수정을 위해 구현되었습니다. 모든 필요 매개 변수는 이 메소드로 제출되어야 하죠.

//--- this is a sample order ticket, it should be received
   ulong ticket=1234556;
//--- this is a sample symbol, it should be received
   string symbol="EURUSD";
//--- number of decimal places
   int    digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
//--- point value
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
//--- receiving a buy price
   double price=SymbolInfoDouble(symbol,SYMBOL_ASK);
//--- calculate and normalize SL and TP levels
//--- they should be calculated based on the order type
   double SL=NormalizeDouble(price-1000*point,digits);
   double TP=NormalizeDouble(price+1000*point,digits);
   //--- setting one day as a lifetime
   datetime expiration=TimeTradeServer()+PeriodSeconds(PERIOD_D1);   
//--- everything is ready, trying to modify the order 
   if(!trade.OrderModify(ticket,price,SL,TP,ORDER_TIME_GTC,expiration))
     {
      //--- failure message
      Print("OrderModify() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("OrderModify() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

수정된 주문에 대한 티켓이 발행될 겁니다. 주문 형식에 따라 정확한 손절매 또는 이익실현 가격이 설정되어야 합니다. 새로운 시장가 또한 현재가를 기준으로 적절하게 설정해야 하죠.

주문을 취소하기 위해서는 해당 주문의 티켓을 알고 있어야 합니다.

//--- this is a sample order ticket, it should be received
   ulong ticket=1234556;
//--- everyrging is ready, trying to modify a buy position
   if(!trade.OrderDelete(ticket))
     {
      //--- failure message
      Print("OrderDelete() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("OrderDelete() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

CTrade 클래스의 OrderOpen() 다목적 메소드를 사용하면 어떤 형태의 대기 주문이라도 설정할 수 있게 됩니다. 특수하게 고안된 BuyLimit, BuyStop, SellLimit 그리고 SellStop 메소드와는 달리, 더 많은 매개 변수를 명시해야 하는데요. 어쩌면 그게 더 편하실 수도 있어요.


마지막으로 고려할 테크니컬 이슈는 뭘까요?

세 가지 중 두 가지 테크니컬 이슈에 대해 알아봤네요. 여러분의 전략에 맞는 심볼을 정했고 트레이딩 로봇을 이용한 대기 주문 설정 방법 및 매매 주문 설정 방법도 알려 드렸죠. 트레이드 클래스 섹션에서 MQL5 개발자를 위한 유용한 도구를 더 찾으실 수 있을 거예요.

이 클래스들을 활용하면 전략의 테크니컬 이슈는 최소화하면서 거래 자체에 집중할 수 있죠. 또한, CTrade 클래스는 거래 요청 확인에 사용될 수도 있습니다. 약간의 연습을 거치면 클래스를 사용해서 거래 요청 실행 결과 핸들링에 필요한 로직을 갖춘 커스텀 클래스를 제작하실 수 있을 거예요.

마지막 문제는 어떻게 거래 시그널을 받고 또 어떻게 그 시그널을 MQL5로 작성하냐는 것인데요. 알고리즘 트레이딩을 처음 시작하시는 분들은 보통 이동평균 교차를 기반으로 하는 표준 트레이딩 시스템부터 공부를 하시는데요. 표준 시스템 공부를 하려면 먼저 트레이딩 로봇에서 테크니컬 인디케이터를 생성하고 사용할 줄 알아야 합니다.

인디케이터예제->인디케이터 섹션을 처음부터 읽어 보세요. 아주 기초적인 내용부터 아주 복잡한 내용까지 찬찬히 배울 수 있을 거예요. 인디케이터 활용법을 빠르게 한번 훑어보고 싶다면 뉴비들을 위한 MQL5: 엑스퍼트 어드바이저 테크니컬 인디케이터 사용 가이드를 참조하세요.


MQL5로 하는 트레이드 오퍼레이션

복잡한 작업 쉽게 해결하기

어떤 일이라도 처음 마주하게 되는 어려움은 알고 보면 가장 간단하게 해결 가능한 일이기 마련입니다. 숙련된 개발자분들에게 도움이 되는 부분이 있을 수도 있지만 여기에 언급된 트레이딩 알고리즘 개발 방법은 대부분 초보자를 대상으로 작성되었습니다.

MQL5는 알고리즘 트레이딩의 무한한 가능성을 열어줄 뿐 아니라 모두에게 가장 빠르고 쉬운 알고리즘 구현 방법을 제공합니다. 스탠다드 라이브러리의 트레이드 클래스를 이용해 '추세란 무엇이며 실시간 추세는 어떻게 찾나'와 같이 모든 거래자들이 궁금해 하는 내용을 읽으며 더 많은 정보를 더 빠르게 배워 보세요.

조만간 추세를 쫓거나 외국어를 배우는 것보다 MQL5로 트레이딩 로봇을 개발하는 게 훨씬 쉽다는 걸 알게 되실 겁니다!


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/481

최근 코멘트 | 토론으로 가기 (39)
MrBrooklin
MrBrooklin | 16 9월 2020 에서 11:42

모두 좋은 하루 되세요!

저는 MQL5 프로그래밍 언어를 계속 공부하고 있습니다. 저에게 유용한 정보를 찾기 위해 거의 모든 사이트를 검색했습니다. 사이트에있는 대부분의 정보는 이미 프로그래밍에 대한 기본적인 이해가있는 사람들을위한 것입니다.

그리고 여기! 많은 것을 이해하고 EA를 개선하는 데 도움이 된 훌륭한 기사를 하나 더 발견했습니다! 저자가이 일련의 기사를 계속 쓰지 않고 2012 년으로 만 제한 한 것은 유감입니다. 그러나 모두 똑같이, 나는이 사람에게 큰 존경을 표하고 모든 초보자를 대신하여 그에게 감사를 표합니다!

존경심을 담아, 블라디미르.

Keith Watford
Keith Watford | 22 1월 2021 에서 13:20
이 주제와 관련이 없는 댓글은 '주제에서 벗어난 게시물'로 이동되었습니다.
Huong Huong
Huong Huong | 15 2월 2021 에서 20:24
pdev:

안녕하세요, 매우 유용한 게시물에 감사드리며 이 문제를 해결하도록 도와주세요. MT5를 처음 사용하며 EA를 만드는 방법을 배우고 있어서 샘플 코드를 복사하여 Ctrade.Buy를 실행했지만 백테스트가 실패했습니다. 자세한 내용은 다음과 같습니다:


1) 계좌: 기본 통화가 NZD인 실거래 계좌

2) 백테스트를 위한 메타에디터 설정:


3) 코드: https://www.mql5.com/ko/articles/481 에서 복사:


//+------------------------------------------------------------------+

//|                                                         demo.mq5 |

//|                        Copyright 2017, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2017, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"

#property version   "1.00"

#include<Trade\Trade.mqh>


//--- object for performing trade operations

CTrade  trade;

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

   //--- set MagicNumber for your orders identification

   int MagicNumber=123456;

   trade.SetExpertMagicNumber(MagicNumber);

   //--- set available slippage in points when buying/selling

   int deviation=10;

   trade.SetDeviationInPoints(deviation);

   //--- order execution mode

   trade.SetTypeFilling(ORDER_FILLING_RETURN);

   //--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own

   trade.LogLevel(1);

   //--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()

   trade.SetAsyncMode(true);

   //---

   return(0);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

   

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   BuySample1();

  }


//--- Buy sample  

//+------------------------------------------------------------------+

//|  Buying a specified volume at the current symbol                 |

//+------------------------------------------------------------------+

void BuySample1()

  {

//--- 1. example of buying at the current symbol

   if(!trade.Buy(0.1))

     {

      //--- failure message

      Print("Buy() method failed. Return code=",trade.ResultRetcode(),

            ". Code description: ",trade.ResultRetcodeDescription());

     }

   else

     {

      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),

            " (",trade.ResultRetcodeDescription(),")");

     }

//---

  }

4) 오류 로그(EUR/USD로만 테스트 중임을 참고하세요):

GJ 0 19:36:44.410 127.0.0.1 로그인 (빌드 1730)

HH 0 19:36:44.420 네트워크 38520바이트의 계정 정보 로드됨

JO 0 19:36:44.420 네트워크 1482바이트의 테스터 매개변수 로드됨

QE 0 19:36:44.420 네트워크 188바이트의 입력 매개변수 로드됨

FR 0 19:36:44.421 네트워크 443바이트의 심볼 목록 로드됨

IF 0 19:36:44.421 테스터 전문가 파일 추가됨: Experts\demo.ex5. 46684 바이트 로드됨

QH 0 19:36:44.433 테스터 초기 예탁금 10000.00 NZD, 레버리지 1:100

JN 0 19:36:44.437 테스터 초기화 성공

ES 0 19:36:44.437 네트워크 총 초기화 데이터 수신 46Kb

PP 0 19:36:44.437 테스터 인텔 코어 i7-4510U @ 2.00GHz, 8103MB

RJ 0 19:36:44.799 심볼 EURUSD: 동기화할 심볼

HR 0 19:36:44.800 기호 EURUSD: 기호 동기화됨, 3624바이트의 기호 정보 수신됨

NJ 0 19:36:44.800 내역 EURUSD: 내역 동기화 시작됨

GO 0 19:36:44.856 내역 EURUSD: 0:00:00.000에 동기화할 27바이트의 내역 데이터를 로드합니다.

RQ 0 19:36:44.856 내역 EURUSD: 2012.01.01부터 2017.11.15까지 동기화된 내역

EF 0 19:36:44.993 히스토리 EURUSD,Daily: 1010 바에 할당된 히스토리 캐시, 2014.01.01 00:00 ~ 2014.12.31 00:00의 312 바 포함

ND 0 19:36:44.993 내역 EURUSD,일간: 2014.01.01 00:00부터 내역 시작

OL 0 19:36:44.996 테스터 EURUSD,일일 (핼리팩스플러스-라이브): 모든 틱 발생

GN 0 19:36:44.996 Tester EURUSD,Daily: 2015.01.01 00:00부터 2017.11.15 00:00까지 Experts\demo.ex5 테스트 시작

CK 0 19:36:56.288 심볼 NZDUSD: 동기화할 심볼

IS 0 19:36:56.288 기호 NZDUSD: 기호 동기화됨, 3624바이트의 기호 정보 수신됨

JL 0 19:36:56.288 내역 NZDUSD: 내역 동기화 시작됨

HJ 0 19:36:56.575 내역 NZDUSD: 0:00:00.078에 동기화할 14Kb의 내역 데이터 로드 중

LS 0 19:36:56.575 내역 NZDUSD: 2013.01.01부터 2017.11.15까지 동기화된 내역

CO 0 19:36:56.579 심볼 EURNZD: 동기화할 심볼

OJ 0 19:36:56.580 심볼 EURNZD: 심볼 동기화됨, 3624바이트의 심볼 정보 수신됨

DL 0 19:36:56.580 히스토리 EURNZD: 히스토리 동기화 시작됨

MK 0 19:36:56.656 히스토리 EURNZD: 0:00:00.000에 동기화할 27바이트의 히스토리 데이터 로드 중

OD 0 19:36:56.656 히스토리 EURNZD: 2013.01.01부터 2017.11.15까지 동기화된 히스토리

IN 0 19:36:56.665 거래 2015.01.02 03:00:00 시장가 매수 0.10 EURUSD (1.20538 / 1.20549 / 1.20538)

PE 0 19:36:56.665 거래 2015.01.02 03:00:00 거래 #2 1.20549에 0.10 EURUSD 매수 완료(주문 #2기준)

FH 0 19:36:56.666 2015.01.02 03:00:00 거래 체결 [#2 매수 0.10 EURUSD at 1.20549] 완료

OG 0 19:36:56.666 거래 2015.01.02 03:00:00 주문 수행 1.20549에 0.10 매수 [#2 매수 0.10 EURUSD at 1.20549]

FO 0 19:36:56.670 데모 (EURUSD,D1) 2015.01.02 03:00:00 매수() 메서드가 성공적으로 실행되었습니다. 반환 코드=10009 (1.20549에서 완료)

NM 2 19:37:15.823 내역 NZDUSD 2016.09.21 23:01:00: 손상된 내역 감지됨 (s:-73370, o:73433, h:+48, l:-123, c:-117 -- tv:63, rv:11250111)

JF 2 19:37:15.823 내역 NZDUSD 2016.09.21, 불량 컨테이너 발견, 재동기화해야 함

LQ 2 19:37:16.106 정의되지 않은 기능에서 테스터 이력 오류 9 발생

OH 2 19:37:16.106 테스터가 테스트 간격 0%에서 '20 NZDUSD' 오류로 중지됨


무엇이 잘못되었고 어떻게 해결해야 하나요?

[삭제] | 6 5월 2021 에서 10:24
pdev:

안녕하세요, 매우 유용한 게시물에 감사드리며 이 문제를 해결하도록 도와주세요. MT5를 처음 사용하며 EA를 만드는 방법을 배우고 있어서 샘플 코드를 복사하여 Ctrade.Buy를 실행했지만 백테스트가 실패했습니다. 자세한 내용은 다음과 같습니다:


1) 계좌: 기본 통화가 NZD인 실거래 계좌

2) 백테스트를 위한 메타에디터 설정:


3) 코드: https://www.mql5.com/ko/articles/481 에서 복사:


//+------------------------------------------------------------------+

//|                                                         demo.mq5 |

//|                        Copyright 2017, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2017, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"

#property version   "1.00"

#include<Trade\Trade.mqh>


//--- object for performing trade operations

CTrade  trade;

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

   //--- set MagicNumber for your orders identification

   int MagicNumber=123456;

   trade.SetExpertMagicNumber(MagicNumber);

   //--- set available slippage in points when buying/selling

   int deviation=10;

   trade.SetDeviationInPoints(deviation);

   //--- order execution mode

   trade.SetTypeFilling(ORDER_FILLING_RETURN);

   //--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own

   trade.LogLevel(1);

   //--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()

   trade.SetAsyncMode(true);

   //---

   return(0);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

   

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   BuySample1();

  }


//--- Buy sample  

//+------------------------------------------------------------------+

//|  Buying a specified volume at the current symbol                 |

//+------------------------------------------------------------------+

void BuySample1()

  {

//--- 1. example of buying at the current symbol

   if(!trade.Buy(0.1))

     {

      //--- failure message

      Print("Buy() method failed. Return code=",trade.ResultRetcode(),

            ". Code description: ",trade.ResultRetcodeDescription());

     }

   else

     {

      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),

            " (",trade.ResultRetcodeDescription(),")");

     }

//---

  }

4) 오류 로그(EUR/USD로만 테스트 중임을 참고하세요):

GJ 0 19:36:44.410 127.0.0.1 로그인 (빌드 1730)

HH 0 19:36:44.420 네트워크 38520바이트의 계정 정보 로드됨

JO 0 19:36:44.420 네트워크 1482바이트의 테스터 매개변수 로드됨

QE 0 19:36:44.420 네트워크 188바이트의 입력 매개변수 로드됨

FR 0 19:36:44.421 네트워크 443바이트의 심볼 목록 로드됨

IF 0 19:36:44.421 테스터 전문가 파일 추가됨: Experts\demo.ex5. 46684 바이트 로드됨

QH 0 19:36:44.433 테스터 초기 예탁금 10000.00 NZD, 레버리지 1:100

JN 0 19:36:44.437 테스터 초기화 성공

ES 0 19:36:44.437 네트워크 총 초기화 데이터 수신 46Kb

PP 0 19:36:44.437 테스터 인텔 코어 i7-4510U @ 2.00GHz, 8103MB

RJ 0 19:36:44.799 심볼 EURUSD: 동기화할 심볼

HR 0 19:36:44.800 심볼 EURUSD: 심볼 동기화됨, 3624바이트의 심볼 정보 수신됨

NJ 0 19:36:44.800 내역 EURUSD: 내역 동기화 시작됨

GO 0 19:36:44.856 내역 EURUSD: 0:00:00.000에 동기화할 27바이트의 내역 데이터를 로드합니다.

RQ 0 19:36:44.856 내역 EURUSD: 2012.01.01부터 2017.11.15까지 동기화된 내역

EF 0 19:36:44.993 히스토리 EURUSD,Daily: 1010 바에 할당된 히스토리 캐시, 2014.01.01 00:00 ~ 2014.12.31 00:00의 312 바 포함

ND 0 19:36:44.993 내역 EURUSD,일간: 2014.01.01 00:00부터 내역 시작

OL 0 19:36:44.996 테스터 EURUSD,일일 (핼리팩스플러스-라이브): 모든 틱 발생

GN 0 19:36:44.996 Tester EURUSD,Daily: 2015.01.01 00:00부터 2017.11.15 00:00까지 Experts\demo.ex5 테스트 시작

CK 0 19:36:56.288 심볼 NZDUSD: 동기화할 심볼

IS 0 19:36:56.288 기호 NZDUSD: 기호 동기화됨, 3624바이트의 기호 정보 수신됨

JL 0 19:36:56.288 내역 NZDUSD: 내역 동기화 시작됨

HJ 0 19:36:56.575 내역 NZDUSD: 0:00:00.078에 동기화할 14Kb의 내역 데이터 로드 중

LS 0 19:36:56.575 내역 NZDUSD: 2013.01.01부터 2017.11.15까지 동기화된 내역

CO 0 19:36:56.579 심볼 EURNZD: 동기화할 심볼

OJ 0 19:36:56.580 심볼 EURNZD: 심볼 동기화됨, 3624바이트의 심볼 정보 수신됨

DL 0 19:36:56.580 히스토리 EURNZD: 히스토리 동기화 시작됨

MK 0 19:36:56.656 히스토리 EURNZD: 0:00:00.000에 동기화할 27바이트의 히스토리 데이터 로드 중

OD 0 19:36:56.656 히스토리 EURNZD: 2013.01.01부터 2017.11.15까지 동기화된 히스토리

IN 0 19:36:56.665 거래 2015.01.02 03:00:00 시장가 매수 0.10 EURUSD (1.20538 / 1.20549 / 1.20538)

PE 0 19:36:56.665 거래 2015.01.02 03:00:00 거래 #2 1.20549에 0.10 EURUSD 매수 완료(주문 #2기준)

FH 0 19:36:56.666 2015.01.02 03:00:00 거래 체결 [#2 매수 0.10 EURUSD at 1.20549] 완료

OG 0 19:36:56.666 거래 2015.01.02 03:00:00 주문 수행 1.20549에 0.10 매수 [#2 매수 0.10 EURUSD at 1.20549]

FO 0 19:36:56.670 데모 (EURUSD,D1) 2015.01.02 03:00:00 매수() 메서드가 성공적으로 실행되었습니다. 반환 코드=10009 (1.20549에서 완료)

NM 2 19:37:15.823 내역 NZDUSD 2016.09.21 23:01:00: 손상된 내역 감지됨 (s:-73370, o:73433, h:+48, l:-123, c:-117 -- tv:63, rv:11250111)

JF 2 19:37:15.823 내역 NZDUSD 2016.09.21, 불량 컨테이너 발견, 재동기화해야 함

LQ 2 19:37:16.106 정의되지 않은 기능에서 테스터 이력 오류 9 발생

OH 2 19:37:16.106 테스터가 테스트 간격 0%에서 '20 NZDUSD' 오류로 중지됨


무엇이 잘못되었고 어떻게 해결해야 하나요?

Dmitrii Troshin
Dmitrii Troshin | 29 6월 2021 에서 06:21

모든 곳에서 제한 및 중지 주문을 열 때 기사에서

double price=1000*point;

그 기사를 쓰는 사람들이 기사에서 코드를 삽입하는 데 도움이되었는지 궁금합니다.

매매 전략 다목적 엑스퍼트 어드바이저 매매 전략 다목적 엑스퍼트 어드바이저
이 글은 대기 주문을 활용하는 전략 및 해당 전략 개발에 사용되는 Metalanguage, 그리고 그 Metalanguage를 기반으로 작동하는 다목적 엑스퍼트 어드바이저에 대한 설명입니다.
MQL5 간단하게 알아보기 MQL5 간단하게 알아보기
매매 전략 프로그래밍 언어인 MQL5를 배우기로 결심은 했는데 아무 것도 모르겠다고요? 초보 투자자의 입장에서 MQL5와 MetaTrader5를 이용해 보고 간단한 소개글을 남깁니다. 이 글은 MQL5를 이용해 할 수 있는 것들에 대한 설명 그리고 MetaEditor5와 MetaTrader5를 사용하는 데에 유용한 팁들을 포함하고 있습니다.
초보자를 위한 간편 스타트 가이드 초보자를 위한 간편 스타트 가이드
여러분, 안녕하세요! 엑스퍼트 어드바이저 생성 방식이나 인디케이터 활용법을 쉽고 빠르게 이해할 수 있도록 돕고자 이번 글을 씁니다. 이 글은 초보자를 대상으로 하며 복잡하거나 난해한 예제는 포함하지 않습니다.
손쉽게 트레이딩 로봇 만들기 손쉽게 트레이딩 로봇 만들기
시장 거래에는 많은 위험이 따릅니다. 그 중에서도 가장 큰 위험은 잘못된 결정을 내리는 것이죠. 투자자라면 누구나 언제든지 작동 가능하고 두려움, 탐욕, 조바심 같은 우리 인간의 약점을 갖지 않는 자신만의 트레이딩 로봇을 꿈꿉니다.