
MQL5 Cookbook: 포지션 속성 가져오기
소개
"MQL5 Cookbook: 다른 프린트 모드 사용"이라는 이전 글에서는 세 가지 다른 모드를 사용하여 스크립트를 빠르게 작성하고 필요한 정보를 프린트하는 방법을 보여주었습니다. 이제 모든 포지션 속성을 가져와 사용자에게 표시하는 스크립트를 만들어 보겠습니다.
다음과 같이 사용자가 스크립트의 외부 매개변수에서 적절한 옵션을 선택할 수 있도록 하는 방식으로 구현해야 합니다. 하나의 (현재) 기호에서만 포지션 속성을 얻거나 열려 있는 모든 포지션에서 실행 (있는 경우) 모든 기호에 하나씩. 이번에는 매우 편리한 대화 상자에서 바로 필요한 정보를 볼 것이며 이 방법이 더 유용할 수도 있습니다.
스크립트 작성
프로그램의 시작은 이전 글에서와 거의 동일합니다(아래 코드 참조). 프로그램 속성부터 시작합니다. 그 다음에 #define 지시어가 있는 행을 지정한 다음 MQL5_PROGRAM_NAME 상수와 MQLInfoString() 함수를 사용하여 SCRIPT_NAME 변수에 프로그램 이름을 할당합니다. MQLInfoString() 함수의 가능한 모든 값에 대한 자세한 정보는 MQL5 참조에서 찾을 수 있습니다.
계속해서 모드를 열거합니다. 모든 식별자에 대한 주석을 작성하면 해당 주석의 텍스트가 외부 매개변수의 드롭다운 목록에 표시됩니다. 우리는 두 가지 옵션을 구현할 것입니다:
- 현재 기호 - 현재 기호에만 포지션 속성을 표시합니다.
- 모든 기호 - 모든 기호의 포지션 속성을 표시합니다.
적절한 모드를 선택하는 데 사용할 외부 매개변수(mode)는 하나만 있을 것입니다. 외부 매개변수 다음에 오는 주석도 외부 매개변수 창에 표시됩니다. 이를 통해 보다 의미 있는 매개변수 이름을 만들 수 있습니다. 동시에 변수의 이름이 짧을수록 코드 측면에서 더 편리합니다.
#property copyright "Copyright 2012, http://tol64.blogspot.com" #property link "http://tol64.blogspot.com" #property description "email: hello.tol64@gmail.com" #property version "1.0" #property script_show_inputs //--- #define SCRIPT_NAME MQLInfoString(MQL_PROGRAM_NAME) // Script name //--- // ENUMERATION OF MODES enum ENUM_SYMBOLS_MODE { CURRENT_SYMBOL =0, // Current symbol ALL_SYMBOLS =1 // All symbols }; //--- // INPUT PARAMETERS input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL; // Mode
코드는 전역 변수로 계속됩니다. 스크립트의 어느 부분에서나 전역 변수에 액세스하려면 함수 외부에 배치해야 합니다(일반적으로 프로그램의 맨 처음에).
// GLOBAL VARIABLES long pos_magic=0; // Magic number string pos_symbol=""; // Symbol string pos_comment=""; // Comment double pos_swap=0.0; // Swap double pos_commission=0.0; // Commission double pos_price=0.0; // Current price of the position double pos_cprice=0.0; // Current price of the position double pos_profit=0.0; // Profit/Loss of the position double pos_volume=0.0; // Position volume double pos_sl=0.0; // Stop Loss of the position double pos_tp=0.0; // Take Profit of the position datetime pos_time=NULL; // Position opening time long pos_id=0; // Position identifier ENUM_POSITION_TYPE pos_type=NULL; // Position type //---
기본 프로그램 함수에서 필요한 모든 작업을 수행하는 PrintPositionProperties()라는 하나의 사용자 정의 함수만 호출합니다.
//+------------------------------------------------------------------+ //| MAIN FUNCTION | //+------------------------------------------------------------------+ void OnStart() { PrintPositionProperties(); }
이제 사용자 정의 PrintPositionProperties() 함수의 구조를 단계별로 살펴보겠습니다. 우리는 먼저 추가 작업을 위한 기반을 형성할 것입니다. 매우 간단하며 구현하면 다음과 같습니다.
//+------------------------------------------------------------------+ //| OPENING A DIALOG BOX WITH SYMBOL DATA | //+------------------------------------------------------------------+ void PrintPositionProperties() { int err=0; // Variable for handling errors //--- // If you need to get position properties on the current symbol only if(mode==CURRENT_SYMBOL) { } //--- // If you need to get position properties on all symbols if(mode==ALL_SYMBOLS) { } }
두 개의 분기와 오류 처리를 담당하고 함수 시작 부분에 선언되는 지역 변수 err만 있습니다. 이제 각 옵션에 대한 사용 사례 시나리오를 작성해야 합니다. 첫 번째 것, 즉 "현재 기호에서만 포지션 속성을 가져와야 하는 경우"부터 시작하겠습니다.
그것은 매우 간단합니다. 먼저 현재 심볼에 포지션이 있는지 확인해야 합니다. 이는 심볼 이름을 유일한 매개변수로 사용하는 MQL5에서 사용 가능한 PositionSelect() 함수로 수행할 수 있습니다. 현재 기호 이름을 전달하려면 Symbol() 함수 또는 현재 기호 이름을 이미 포함하고 있는 미리 정의된 변수 _Symbol을 사용해야 합니다. PositionSelect() 함수는 해당 기호에 포지션이 있는 경우 긍정적인 결과를 반환하고 포지션이 없거나 오류가 발생한 경우 부정적인 결과를 반환합니다.
첫 번째 옵션에 대한 자세한 설명이 있는 코드는 다음과 같습니다.
//--- // If a position exists, then... if(PositionSelect(_Symbol)) { // ...get its properties GetPositionProperties(); //--- // Open a dialog box to display all the data we obtained MessageBox("Symbol : "+pos_symbol+"\n"+ "Comment : "+pos_comment+"\n"+ "Magic Number : "+IntegerToString(pos_magic)+"\n"+ "Price Open : "+DoubleToString(pos_price,_Digits)+"\n"+ "Current Price : "+DoubleToString(pos_cprice,_Digits)+"\n"+ "Stop Loss : "+DoubleToString(pos_sl,_Digits)+"\n"+ "Take Profit : "+DoubleToString(pos_tp,_Digits)+"\n"+ "Type : "+PositionTypeToString(pos_type)+"\n"+ "Volume : "+DoubleToString(pos_volume,2)+"\n"+ "Commission : "+DoubleToString(pos_commission,2)+"\n"+ "Swap : "+DoubleToString(pos_swap,2)+"\n"+ "Profit : "+DoubleToString(pos_profit,2)+"\n"+ "Time : "+TimeToString(pos_time)+"\n"+ "Identifier : "+IntegerToString(pos_id)+"", //--- "Message Box",MB_ICONASTERISK); //--- return; } // If there is no position or an error has occurred, report it else { err=GetLastError(); // Get the code of the last registered error //--- if(err>0) // If there is an error { // Print the relevant message MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+_Symbol+") !\n\n"+ "It is possible that there is no position on this symbol. If this is not the case, please try again.", "Error", MB_ICONWARNING); //--- return; // Exit the function } } //---
위의 코드에서 GetPositionProperties() 및 PositionTypeToString()의 두 가지 사용자 정의 함수를 더 볼 수 있습니다. 프로그램 전반에 걸쳐 다양한 지점에서 포지션 속성을 얻어야 하기 때문에 코드의 양을 줄여 가독성을 높이려면 별도의 함수를 만드는 것이 좋습니다. 아래는 이 함수의 코드입니다. GetPositionProperties()에 사용된 MQL5 함수 및 식별자에 대한 추가 정보는 MQL5 참조를 확인하세요.
//+------------------------------------------------------------------+ //| GETTING SYMBOL PROPERTIES | //+------------------------------------------------------------------+ void GetPositionProperties() { pos_symbol =PositionGetString(POSITION_SYMBOL); pos_comment =PositionGetString(POSITION_COMMENT); pos_magic =PositionGetInteger(POSITION_MAGIC); pos_price =PositionGetDouble(POSITION_PRICE_OPEN); pos_cprice =PositionGetDouble(POSITION_PRICE_CURRENT); pos_sl =PositionGetDouble(POSITION_SL); pos_tp =PositionGetDouble(POSITION_TP); pos_type =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); pos_volume =PositionGetDouble(POSITION_VOLUME); pos_commission =PositionGetDouble(POSITION_COMMISSION); pos_swap =PositionGetDouble(POSITION_SWAP); pos_profit =PositionGetDouble(POSITION_PROFIT); pos_time =(datetime)PositionGetInteger(POSITION_TIME); pos_id =PositionGetInteger(POSITION_IDENTIFIER); }
사용자 정의 PositionTypeToString() 함수는 아래 코드와 같이 정수로 반환된 포지션 유형을 읽을 형식으로 문자열로 변환합니다.
//+------------------------------------------------------------------+ //| CONVERTING POSITION TYPE TO A STRING | //+------------------------------------------------------------------+ string PositionTypeToString(int position_type) { string str=""; //--- if(position_type==0) { str="buy"; } if(position_type==1) { str="sell"; } //--- return(str); }
따라서 현재 기호에서만 포지션 속성을 볼 수 있는 첫 번째 옵션에 대한 코드가 준비되었습니다. 글에 설명된 모든 단계를 수행했다면 지금 바로 테스트할 수도 있습니다. 표준 도구를 사용하여 MetaTrader 5에서 포지션을 엽니다. 이를 위해 F9 키를 누르면 주문 창이 열리기 전에 포지션 속성을 설정하는 데 필요한 모든 옵션을 찾을 수 있습니다.
그림 1. MetaTrader 5 클라이언트 터미널의 주문 창.
모든 속성이 설정되면 Sell 또는 Buy를 선택하고 차트로 두 번 클릭하거나 드래그 해서 스크립트를 실행합니다. 스크립트 창이 열립니다. Mode 매개변수의 필수 값(현재 기호)은 기본적으로 이미 설정되어 있습니다. 확인 버튼을 클릭하면 현재 기호의 모든 포지션 속성을 표시하는 대화 상자가 열립니다.
그림 2. 현재 기호의 포지션 속성이 있는 대화 상자.
그렇지 않고 현재 기호에 포지션이 없으면 경고 상자가 나타납니다.
그림 3. 경고 상자.
모든 것이 계획대로 작동하고 코드에 구현된 것처럼 보입니다.
이제 모든 열린 포지션 속성을 보기로 선택한 경우 사용할 프로그램 코드를 검토해 보겠습니다. 자세한 주석이 있는 코드는 다음과 같습니다.
//--- int digits=0; // Number of decimal places int mb_res=-1; // Variable with the option selected in the dialog box int pos_total=PositionsTotal(); // Number of open positions in the terminal //--- // View properties of all positions in a loop one by one for(int i=0; i<pos_total; i++) { ResetLastError(); // Reset the last error //--- pos_symbol=PositionGetSymbol(i); // Get the symbol name digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS); // Get the number of digits in the price //--- // If a position on this symbol exists, then... if(PositionSelect(pos_symbol)) { // ...get its properties GetPositionProperties(); //--- // Open a dialog box to display all position properties obtained mb_res=MessageBox("Total Positions/Current: "+IntegerToString(pos_total)+"/"+IntegerToString(i+1)+"\n"+ "---------------------------------\n"+ "Symbol: " +pos_symbol+"\n"+ "Comment: " +pos_comment+"\n"+ "Magic Number: " +IntegerToString(pos_magic)+"\n"+ "Price Open: " +DoubleToString(pos_price,digits)+"\n"+ "Current Price: " +DoubleToString(pos_cprice,digits)+"\n"+ "Stop Loss: " +DoubleToString(pos_sl,digits)+"\n"+ "Take Profit: " +DoubleToString(pos_tp,digits)+"\n"+ "Type: " +PositionTypeToString(pos_type)+"\n"+ "Volume: " +DoubleToString(pos_volume,2)+"\n"+ "Commission: " +DoubleToString(pos_commission,2)+"\n"+ "Swap: " +DoubleToString(pos_swap,2)+"\n"+ "Profit: " +DoubleToString(pos_profit,2)+"\n"+ "Time: " +TimeToString(pos_time)+"\n"+ "Identifier: " +IntegerToString(pos_id)+"", //--- "Message Box",MB_CANCELTRYCONTINUE|MB_ICONASTERISK); //--- if(mb_res==IDCANCEL) // If you have clicked Cancel or Close { Print("The program ("+SCRIPT_NAME+") has been terminated by the user!"); return; } // Exit the function //--- // If you have clicked Retry if(mb_res==IDTRYAGAIN) { i--; } // Reset the counter to retry } else // If there is no position or an error has occurred, report it { err=GetLastError(); // Get the code of the last registered error //--- if(err>0) // If there is an error { // Print the relevant message MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+pos_symbol+") !\n\n"+ "It is possible that there is no position on this symbol. If this is not the case, please try again.", "Error", MB_ICONWARNING); } } } //---
이제 이 옵션을 테스트하기만 하면 됩니다. 예를 들어 두 기호(AUDUSD 및 EURUSD)에 대한 포지션을 열어 보겠습니다. 스크립트를 실행하고 외부 매개변수의 드롭다운 목록에서 모든 기호 모드를 선택하고 확인을 클릭하면 아래와 같은 대화 상자가 열립니다.
그림 4. 두 번째 옵션에 대한 포지션 속성이 있는 대화 상자.
결론
위 그림에서 볼 수 있듯이 대화 상자에는 세 개의 버튼이 있습니다. 재시도를 클릭하면 루프 카운터가 재설정되고 대화 상자에 현재 표시된 기호의 포지션 속성이 새로 고쳐집니다. 계속을 클릭하면 프로그램이 다음 기호로 진행합니다. 취소 버튼은 프로그램을 종료하는 역할을 합니다.
또한 포지션 속성 목록 위의 첫 번째 줄에는 열린 포지션의 총 수(총 포지션)와 포지션 카운터의 현재 숫자(현재).
그게 다입니다. MetaEditor에서 컴파일해야 하는 아래에 첨부된 소스 코드 파일을 자유롭게 다운로드하세요.
MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/639



