English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5 Cookbook: 파일에 거래 내역 쓰기 및 Excel의 각 기호에 대한 대차 대조표 생성

MQL5 Cookbook: 파일에 거래 내역 쓰기 및 Excel의 각 기호에 대한 대차 대조표 생성

MetaTrader 5 | 2 9월 2021, 17:11
93 0
Anatoli Kazharski
Anatoli Kazharski

소개

다양한 포럼에서 커뮤니케이션할 때 Microsoft Excel 차트의 스크린샷으로 표시되는 테스트 결과의 예를 자주 사용했습니다. 그러한 차트를 만드는 방법을 설명하라는 요청을 여러 번 받았습니다. Excel은 차트를 만들기 위한 충분한 기능을 제공하며 해당 주제에 대한 많은 책이 있습니다. 책에서 필요한 정보를 찾으려면 모두 읽어야 할 수도 있습니다. 이제 마지막으로 이 글에서 모든 것을 설명할 시간이 있습니다.

이전 두 글 MQL5 Cookbook: Multi-Currency Expert Advisor - Simple, Neat and Quick ApproachMQL5 Cookbook: 무제한 매개변수로 Multi-Currency Expert Advisor 개발 MQL5에서 다중 통화 EA의 개발을 다루었습니다. MetaTrader 5의 테스트 결과가 일반 균형/자본 곡선으로 표시된다는 것을 알고 있습니다. 즉, 각 기호에 대한 결과를 개별적으로 확인해야 하는 경우 Expert Advisor의 외부 매개변수로 계속 이동하여 모든 기호를 비활성화해야 합니다. 결과가 필요한 사람을 제외하고 테스트를 다시 실행하세요. 이것은 불편합니다.

그래서 오늘은 클릭 몇 번으로 단일 Excel 다이어그램에서 다중 통화 Expert Advisor의 누적 결과와 함께 모든 기호에 대한 대차 대조표를 얻을 수 있는 간단한 방법을 보여 드리겠습니다. 예를 재구성하기 위해 이전 글에서 다중 통화 Expert Advisor를 사용합니다. 테스트 완료 시 .csv 파일에 모든 기호에 대한 거래 내역 및 균형 곡선을 기록하는 기능으로 향상됩니다. 또한 보고서에 다른 열을 추가하여 모든 로컬 최대값의 감소를 표시합니다.

데이터 파일을 연결할 수 있도록 설정한 엑셀 북을 만들어 봅시다. 책은 항상 열 수 있으므로 다른 테스트를 실행하기 전에 책을 닫을 필요가 없습니다. 테스트가 완료되면 특정 키를 눌러 데이터를 새로 고치기만 하면 보고서와 차트에서 변경 사항을 볼 수 있습니다.


Expert Advisor 개발

EA에는 큰 변화가 없으며 몇 가지 기능만 추가할 것입니다. 기본 파일에 기호 균형에 대한 구조와 배열을 추가하는 것으로 시작하겠습니다.

//--- Arrays for balances
struct Balance
  {
   double            balance[];
  };
//--- Array of balances for all symbols
Balance symbol_balance[];

그런 다음 테스트 보고서를 생성하고 Expert Advisor의 기본 파일에 포함하는 별도의 Report.mqh 포함 파일을 만듭니다(아래 코드에서 강조 표시된 줄 참조).

//--- Include custom libraries
#include "Include/Auxiliary.mqh"
#include "Include/Enums.mqh"
#include "Include/Errors.mqh"
#include "Include/FileFunctions.mqh"
#include "Include/InitializeArrays.mqh"
#include "Include/Report.mqh"
#include "Include/ToString.mqh"
#include "Include/TradeFunctions.mqh"
#include "Include/TradeSignals.mqh"

포지션 및 기호 속성에 대해 프로젝트에 이미 있는 것과 같은 거래 속성 구조를 먼저 생성해 보겠습니다. 이를 위해 속성 식별자 열거를 Enums.mqh 파일에 추가합니다.

//+------------------------------------------------------------------+
//| Enumeration of deal properties                                   |
//+------------------------------------------------------------------+
enum ENUM_DEAL_PROPERTIES
  {
   D_SYMBOL     = 0, // Deal symbol
   D_COMMENT    = 1, // Deal comment
   D_TYPE       = 2, // Deal type
   D_ENTRY      = 3, // Deal entry - entry in, entry out, reverse
   D_PRICE      = 4, // Deal price
   D_PROFIT     = 5, // Deal result (profit/loss)
   D_VOLUME     = 6, // Deal volume
   D_SWAP       = 7, // Cumulative swap on close
   D_COMMISSION = 8, // Deal commission
   D_TIME       = 9, // Deal time
   D_ALL        = 10 // All of the above mentioned deal properties
  };

또한 Report.mqh 파일 에서 거래 속성 구조와 거래 속성을 반환하는 GetHistoryDealProperties() 함수를 만듭니다. 이 함수는 거래 티켓과 속성 식별자라는 두 가지 매개변수를 허용합니다.

아래에서 구조 및 GetHistoryDealProperties() 함수의 코드를 볼 수 있습니다.

//--- Deal properties in the history
struct HistoryDealProperties
  {
   string            symbol;     // Symbol
   string            comment;    // Comment
   ENUM_DEAL_TYPE    type;       // Deal type
   ENUM_DEAL_ENTRY   entry;      // Direction
   double            price;      // Price
   double            profit;     // Profit/Loss
   double            volume;     // Volume
   double            swap;       // Swap
   double            commission; // Commission
   datetime          time;       // Time
  };
//--- Variable of deal properties
HistoryDealProperties  deal;
//+------------------------------------------------------------------+
//| Gets deal properties by ticket                                   |
//+------------------------------------------------------------------+
void GetHistoryDealProperties(ulong ticket_number,ENUM_DEAL_PROPERTIES history_deal_property)
  {
   switch(history_deal_property)
     {
      case D_SYMBOL     : deal.symbol=HistoryDealGetString(ticket_number,DEAL_SYMBOL);                 break;
      case D_COMMENT    : deal.comment=HistoryDealGetString(ticket_number,DEAL_COMMENT);               break;
      case D_TYPE       : deal.type=(ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket_number,DEAL_TYPE);    break;
      case D_ENTRY      : deal.entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket_number,DEAL_ENTRY); break;
      case D_PRICE      : deal.price=HistoryDealGetDouble(ticket_number,DEAL_PRICE);                   break;
      case D_PROFIT     : deal.profit=HistoryDealGetDouble(ticket_number,DEAL_PROFIT);                 break;
      case D_VOLUME     : deal.volume=HistoryDealGetDouble(ticket_number,DEAL_VOLUME);                 break;
      case D_SWAP       : deal.swap=HistoryDealGetDouble(ticket_number,DEAL_SWAP);                     break;
      case D_COMMISSION : deal.commission=HistoryDealGetDouble(ticket_number,DEAL_COMMISSION);         break;
      case D_TIME       : deal.time=(datetime)HistoryDealGetInteger(ticket_number,DEAL_TIME);          break;
      case D_ALL        :
         deal.symbol=HistoryDealGetString(ticket_number,DEAL_SYMBOL);
         deal.comment=HistoryDealGetString(ticket_number,DEAL_COMMENT);
         deal.type=(ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket_number,DEAL_TYPE);
         deal.entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket_number,DEAL_ENTRY);
         deal.price=HistoryDealGetDouble(ticket_number,DEAL_PRICE);
         deal.profit=HistoryDealGetDouble(ticket_number,DEAL_PROFIT);
         deal.volume=HistoryDealGetDouble(ticket_number,DEAL_VOLUME);
         deal.swap=HistoryDealGetDouble(ticket_number,DEAL_SWAP);
         deal.commission=HistoryDealGetDouble(ticket_number,DEAL_COMMISSION);
         deal.time=(datetime)HistoryDealGetInteger(ticket_number,DEAL_TIME);                           break;
         //---
      default: Print("The passed deal property is not listed in the enumeration!");                          return;
     }
  }

또한 일부 거래 속성을 문자열 값으로 변환하는 여러 함수가 필요합니다. 이러한 단순 함수는 전달된 값이 비어 있거나 0이면 대시("-")를 반환합니다. ToString.mqh 파일에 작성해 보겠습니다.

//+------------------------------------------------------------------+
//| Returns the symbol name, otherwise - dash                        |
//+------------------------------------------------------------------+
string DealSymbolToString(string deal_symbol)
  {
   return(deal_symbol=="" ? "-" : deal_symbol);
  }
//+------------------------------------------------------------------+
//| Converts deal type to string                                     |
//+------------------------------------------------------------------+
string DealTypeToString(ENUM_DEAL_TYPE deal_type)
  {
   string str="";
//---
   switch(deal_type)
     {
      case DEAL_TYPE_BUY                      : str="buy";                      break;
      case DEAL_TYPE_SELL                     : str="sell";                     break;
      case DEAL_TYPE_BALANCE                  : str="balance";                  break;
      case DEAL_TYPE_CREDIT                   : str="credit";                   break;
      case DEAL_TYPE_CHARGE                   : str="charge";                   break;
      case DEAL_TYPE_CORRECTION               : str="correction";               break;
      case DEAL_TYPE_BONUS                    : str="bonus";                    break;
      case DEAL_TYPE_COMMISSION               : str="commission";               break;
      case DEAL_TYPE_COMMISSION_DAILY         : str="commission daily";         break;
      case DEAL_TYPE_COMMISSION_MONTHLY       : str="commission monthly";       break;
      case DEAL_TYPE_COMMISSION_AGENT_DAILY   : str="commission agent daily";   break;
      case DEAL_TYPE_COMMISSION_AGENT_MONTHLY : str="commission agent monthly"; break;
      case DEAL_TYPE_INTEREST                 : str="interest";                 break;
      case DEAL_TYPE_BUY_CANCELED             : str="buy canceled";             break;
      case DEAL_TYPE_SELL_CANCELED            : str="sell canceled";            break;
      //--- Unknown deal type
      default : str="unknown";
     }
//---
   return(str);
  }
//+------------------------------------------------------------------+
//| Converts direction of deal to string                             |
//+------------------------------------------------------------------+
string DealEntryToString(ENUM_DEAL_ENTRY deal_entry)
  {
   string str="";
//---
   switch(deal_entry)
     {
      case DEAL_ENTRY_IN    : str="in";            break;
      case DEAL_ENTRY_OUT   : str="out";           break;
      case DEAL_ENTRY_INOUT : str="in/out";        break;
      case DEAL_ENTRY_STATE : str="status record"; break;
      //--- Unknown direction type
      default : str="unknown";
     }
//---
   return(str);
  }
//+------------------------------------------------------------------+
//| Converts volume to string                                        |
//+------------------------------------------------------------------+
string DealVolumeToString(double deal_volume)
  {
   return(deal_volume<=0 ? "-" : DoubleToString(deal_volume,2));
  }
//+------------------------------------------------------------------+
//| Converts price to string                                         |
//+------------------------------------------------------------------+
string DealPriceToString(double deal_price,int digits)
  {
   return(deal_price<=0 ? "-" : DoubleToString(deal_price,digits));
  }
//+------------------------------------------------------------------+
//| Converts deal result to string                                   |
//+------------------------------------------------------------------+
string DealProfitToString(string deal_symbol,double deal_profit)
  {
   return((deal_profit==0 || deal_symbol=="") ? "-" : DoubleToString(deal_profit,2));
  }
//+------------------------------------------------------------------+
//| Converts swap to string                                          |
//+------------------------------------------------------------------+
string DealSwapToString(double deal_swap)
  {
   return(deal_swap<=0 ? "-" : DoubleToString(deal_swap,2));
  }

이제 보고서용 데이터를 준비하고 LastTest.csv 파일에 쓰는 CreateSymbolBalanceReport() 함수를 작성할 준비가 되었습니다. 매우 간단합니다. 먼저 헤더를 작성한 다음(테스트가 둘 이상의 기호에 대해 실행된 경우 문자열이 조정되는 방식에 유의) 보고서에 필요한 거래 속성이 파일에 추가로 기록되는 문자열로 연속적으로 연결됩니다.

다음은 CreateSymbolBalanceReport() 함수의 코드입니다.

//+------------------------------------------------------------------+
//| Creates the test report on deals in .csv format                  |
//+------------------------------------------------------------------+
void CreateSymbolBalanceReport()
  {
   int    file_handle =INVALID_HANDLE; // File handle
   string path        ="";             // File path

//--- If an error occurred when creating/getting the folder, exit
   if((path=CreateInputParametersFolder())=="")
      return;
//--- Create file to write data in the common folder of the terminal
   file_handle=FileOpen(path+"\\LastTest.csv",FILE_CSV|FILE_WRITE|FILE_ANSI|FILE_COMMON);
//--- If the handle is valid (file created/opened)
   if(file_handle>0)
     {
      int    digits          =0;   // Number of decimal places in the price
      int    deals_total     =0;   // Number of deals in the specified history
      ulong  ticket          =0;   // Deal ticket
      double drawdown_max    =0.0; // Maximum drawdown
      double balance         =0.0; // Balance
      //---
      string delimeter       =","; // Delimiter
      string string_to_write ="";  // To generate the string for writing

      //--- Generate the header string
      string headers="TIME,SYMBOL,DEAL TYPE,ENTRY TYPE,VOLUME,PRICE,SWAP($),PROFIT($),DRAWDOWN(%),BALANCE";
      //--- If more than one symbol is involved, modify the header string
      if(SYMBOLS_COUNT>1)
        {
         for(int s=0; s<SYMBOLS_COUNT; s++)
            StringAdd(headers,","+InputSymbols[s]);
        }
      //--- Write the report headers
      FileWrite(file_handle,headers);
      //--- Get the complete history
      HistorySelect(0,TimeCurrent());
      //--- Get the number of deals
      deals_total=HistoryDealsTotal();
      //--- Resize the array of balances according to the number of symbols
      ArrayResize(symbol_balance,SYMBOLS_COUNT);
      //--- Resize the array of deals for each symbol
      for(int s=0; s<SYMBOLS_COUNT; s++)
         ArrayResize(symbol_balance[s].balance,deals_total);
      //--- Iterate in a loop and write the data
      for(int i=0; i<deals_total; i++)
        {
         //--- Get the deal ticket
         ticket=HistoryDealGetTicket(i);
         //--- Get all the deal properties
         GetHistoryDealProperties(ticket,D_ALL);
         //--- Get the number of digits in the price
         digits=(int)SymbolInfoInteger(deal.symbol,SYMBOL_DIGITS);
         //--- Calculate the overall balance
         balance+=deal.profit+deal.swap+deal.commission;
         //--- Generate a string for writing via concatenation
         StringConcatenate(string_to_write,
                           deal.time,delimeter,
                           DealSymbolToString(deal.symbol),delimeter,
                           DealTypeToString(deal.type),delimeter,
                           DealEntryToString(deal.entry),delimeter,
                           DealVolumeToString(deal.volume),delimeter,
                           DealPriceToString(deal.price,digits),delimeter,
                           DealSwapToString(deal.swap),delimeter,
                           DealProfitToString(deal.symbol,deal.profit),delimeter,
                           MaxDrawdownToString(i,balance,max_drawdown),delimeter,
                           DoubleToString(balance,2));

         //--- If more than one symbol is involved, write their balance values
         if(SYMBOLS_COUNT>1)
           {
            //--- Iterate over all symbols
            for(int s=0; s<SYMBOLS_COUNT; s++)
              {
               //--- If the symbols are equal and the deal result is non-zero
               if(deal.symbol==InputSymbols[s] && deal.profit!=0)
                 {
                  //--- Display the deal in the balance for the corresponding symbol
                  //    Take into consideration swap and commission
                  symbol_balance[s].balance[i]=symbol_balance[s].balance[i-1]+
                                               deal.profit+
                                               deal.swap+
                                               deal.commission;
                  //--- Add to the string
                  StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                 }
               //--- Otherwise write the previous value
               else
                 {
                  //--- If the deal type is "Balance" (the first deal)
                  if(deal.type==DEAL_TYPE_BALANCE)
                    {
                     //--- the balance is the same for all symbols
                     symbol_balance[s].balance[i]=balance;
                     StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                    }
                  //--- Otherwise write the previous value to the current index
                  else
                    {
                     symbol_balance[s].balance[i]=symbol_balance[s].balance[i-1];
                     StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                    }
                 }
              }
           }
         //--- Write the generated string
         FileWrite(file_handle,string_to_write);
         //--- Mandatory zeroing out of the variable for the next string
         string_to_write="";
        }
      //--- Close the file
      FileClose(file_handle);
     }
//--- If the file could not be created/opened, print the appropriate message
   else
      Print("Error creating file: "+IntegerToString(GetLastError())+"");
  }

위 코드에서 강조 표시된 MaxDrawdownToString() 함수는 로컬 최대값에서 모든 감소를 계산하고 새로운 로컬 최대값의 시간에 대한 문자열 표현을 반환합니다. 다른 모든 경우에 함수는 "-"(대시)를 포함하는 문자열을 반환합니다.

//+------------------------------------------------------------------+
//| Returns the maximum drawdown from the local maximum              |
//+------------------------------------------------------------------+
string MaxDrawdownToString(int deal_number,double balance,double &max_drawdown)
  {
//--- The string to be displayed in the report
   string str="";
//--- To calculate the local maximum and drawdown
   static double max=0.0;
   static double min=0.0;
//--- If this is the first deal
   if(deal_number==0)
     {
      //--- No drawdown yet
      max_drawdown=0.0;
      //--- Set the initial point as the local maximum
      max=balance;
      min=balance;
     }
   else
     {
      //--- If the current balance is greater than in the memory
      if(balance>max)
        {
         //--- calculate the drawdown using the previous values
         max_drawdown=100-((min/max)*100);
         //--- update the local maximum
         max=balance;
         min=balance;
        }
      else
        {
         //--- Return zero value of the drawdown
         max_drawdown=0.0;
         //--- Update the minimum
         min=fmin(min,balance);
        }
     }
//--- Determine the string for the report
   if(max_drawdown==0)
      str="-";
   else
      str=DoubleToString(max_drawdown,2);
//--- Return result
   return(str);
  }

따라서 모든 보고서 생성 기능이 준비되었습니다. 우리는 위의 모든 것을 어떻게 사용해야 하는지 보기만 하면 됩니다. 테스트 완료 시 호출되는 OnTester() 함수가 필요합니다. MQL5 Reference에서 이 기능에 대한 자세한 설명을 확인하세요.

OnTester() 함수의 본문에 몇 줄의 코드를 작성하여 보고서가 생성되어야 하는 조건을 지정하기만 하면 됩니다. 해당 코드 조각은 아래에 제공됩니다.

//+------------------------------------------------------------------+
//| Handler of the event of testing completion                       |
//+------------------------------------------------------------------+
double OnTester()
  {
//--- Write the report only after testing
   if(IsTester() && !IsOptimization() && !IsVisualMode())
      //--- Generate the report and write it to the file
      CreateSymbolBalanceReport();
//---
   return(0.0);
  }

이제 Strategy Tester에서 Expert Advisor를 실행하면 테스트가 끝나면 공통 터미널 폴더 C:\ProgramData\MetaQuotes\Terminal\Common\Files에 생성된 Expert Advisor 폴더를 볼 수 있습니다. 그리고 Expert Advisor 폴더에 LastTest.csv 보고서 파일이 생성됩니다. 메모장으로 파일을 열면 다음과 같이 표시됩니다.

그림 1. .csv 형식의 보고서 파일

그림 1. .csv 형식의 보고서 파일입니다.

Excel에서 차트 만들기

생성된 파일을 Excel에서 열면 각 데이터 유형이 별도의 열에 있음을 확인할 수 있습니다. 이렇게 하면 데이터 보기가 훨씬 더 편리해집니다. 이 시점에서 기술적으로 차트를 만들고 파일을 *.xlsx 형식의 Excel 책으로 저장할 준비가 되었습니다. 그러나 나중에 테스트를 실행하고 책을 다시 열면 여전히 이전 데이터가 표시됩니다.

LastTest.csv 파일이 이미 Excel에서 사용되는 동안 데이터를 새로 고치려고 하면 Expert Advisor가 다른 응용 프로그램에서 사용 중인 동안 쓰기 위해 파일을 열 수 없기 때문에 파일이 업데이트되지 않습니다.

그림 2. Excel 2010의 .csv 형식 보고서 파일

그림 2. Excel 2010의 .csv 형식 보고서 파일입니다.

우리의 경우에 사용할 수 있는 솔루션이 있습니다. 먼저 원하는 폴더에 *.xlsx 형식의 Excel 책을 만듭니다. 그런 다음 파일을 열고 데이터 탭으로 이동합니다.

그림 3. Excel 2010의 데이터 탭

그림 3. Excel 2010의 데이터 탭.

이 탭의 리본에서 텍스트에서 옵션을 선택합니다. "LastTest.csv" 파일을 선택해야 하는 위치에 텍스트 파일 가져오기 대화상자가 나타납니다. 파일을 선택하고 열기 버튼을 클릭하세요. 텍스트 가져오기 마법사 - 1/3단계 대화 상자가 아래와 같이 팝업됩니다.

그림 4. "텍스트 가져오기 마법사 - 1/3단계" 대화 상자

그림 4. "텍스트 가져오기 마법사 - 1/3단계" 대화 상자.

위와 같이 설정을 조정하고 다음 >을 클릭합니다. 여기서(2/3단계) 데이터 파일에 사용되는 구분 기호를 지정해야 합니다. 우리 파일에서는 ","(쉼표)입니다.

그림 5. "텍스트 가져오기 마법사 - 2/3단계" 대화 상자

그림 5. "텍스트 가져오기 마법사 - 2/3단계" 대화 상자.

다음 >을 클릭하여 텍스트 가져오기 마법사 - 3/3단계로 진행합니다. 여기에서 모든 열의 데이터 형식으로 일반을 그대로 둡니다. 나중에 형식을 변경할 수 있습니다.

그림 6. "텍스트 가져오기 마법사 - 3/3단계" 대화 상자

그림 6. "텍스트 가져오기 마법사 - 3/3단계" 대화 상자.

마침 버튼을 클릭하면 데이터 가져오기를 위한 워크시트와 셀을 지정해야 하는 데이터 가져오기 창이 나타납니다.

그림 7. Excel 2010에서 데이터를 가져올 셀 선택

그림 7. Excel 2010에서 데이터를 가져올 셀을 선택합니다.

일반적으로 왼쪽 상단 셀 A1을 선택합니다. 확인을 클릭하기 전에 속성... 버튼을 클릭하여 외부 데이터 범위 속성을 설정하세요. 아래와 같은 대화 상자가 표시됩니다.

그림 8. Excel 2010의 텍스트 파일에서 데이터를 가져올 때 외부 데이터 범위 속성

그림 8. Excel 2010의 텍스트 파일에서 데이터를 가져올 때 외부 데이터 범위 속성.

위와 같이 정확하게 설정을 조정하고 현재 및 다음 창에서 확인을 클릭하세요.

결과적으로 데이터는 .csv 파일을 로드한 것과 동일하게 나타납니다. 그러나 이제 Excel 책을 닫지 않고도 MetaTrader 5에서 반복 테스트를 실행할 수 있습니다. 테스트를 실행한 후 Ctrl+Alt+F5 단축키를 사용하거나 데이터 탭 리본의 모두 새로고침 버튼을 사용하여 데이터를 새로고침하기만 하면 됩니다.

탭 리본의 조건부 서식 옵션을 사용하여 데이터 표현에 필요한 시각적 속성을 설정할 수 있습니다.

그림 9. Excel 2010의 조건부 서식

그림 9. Excel 2010의 조건부 서식.

이제 Excel 차트에 데이터를 표시해야 합니다. 한 차트는 모든 균형 차트를 표시하고 다른 차트는 로컬 최대값의 모든 감소를 히스토그램으로 표시합니다.

먼저 대차 대조표에 대한 다이어그램을 만들어 보겠습니다. 모든 저울의 헤더와 전체 데이터 배열을 위에서 아래로 선택합니다(Shift 키를 누른 상태에서 End 키를 누른 다음 아래쪽 화살표 b2> 키). 이제 삽입 탭에서 원하는 차트 유형을 선택하세요.

그림 10. Excel 2010에서 차트 유형 선택

그림 10. Excel 2010에서 차트 유형 선택.

결과적으로 편의를 위해 다른 워크시트로 이동할 수 있는 차트가 생성됩니다. 이렇게 하려면 간단히 선택하고 Ctrl+X(잘라내기)를 누르십시오. 그런 다음 새로 생성된 워크시트로 이동하여 A1 셀을 선택하고 Ctrl+V(붙여넣기)를 누릅니다.

기본 설정으로 생성된 차트는 아래 이미지와 같습니다.

그림 11. 기본 설정으로 차트의 모양과 느낌.

그림 11. 기본 설정으로 차트의 모양과 느낌.

차트의 모든 요소를 ​​사용자 정의할 수 있습니다. 크기, 색상, 스타일 등을 변경할 수 있습니다.

위 이미지에서 가로축은 거래 건수를 나타냅니다. 대신 날짜를 표시하도록 수정해 보겠습니다. 이를 위해 차트를 마우스 오른쪽 버튼으로 클릭하고 컨텍스트 메뉴에서 데이터 선택 옵션을 선택합니다. 데이터 소스 선택 대화 상자가 나타납니다. 수정 버튼을 클릭한 다음 시간 열에서 필요한 데이터 범위를 선택하고 확인을 클릭하세요.

그림 12. "데이터 소스 선택" 대화 상자

그림 12. "데이터 소스 선택" 대화 상자.

직접 드로다운 차트를 만들어 첫 번째 차트 아래에 배치합니다. 이제 필요한 경우 시각적 속성을 사용자 지정할 수 있습니다. 개인적으로 저는 보통 이렇게 합니다.

그림 13. Excel 2010의 사용자 지정 차트.

그림 13. Excel 2010의 사용자 지정 차트.


결론

따라서 테스트 결과가 상당히 괜찮은 Excel 차트를 얻었습니다. 내 미래 글 중 하나에서 더 유익한 보고서를 만드는 방법을 보여 드리겠습니다. 글에 첨부된 파일은 귀하가 고려할 수 있도록 Expert Advisor의 파일과 함께 다운로드 가능한 아카이브입니다.

아카이브에서 파일을 추출한 후 ReportInExcel 폴더를 MetaTrader 5\MQL5\Experts 디렉토리에 넣습니다. 또한 EventsSpy.mq5 지표는 MetaTrader 5\MQL5\Indicators 디렉토리에 있어야 합니다.

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

파일 첨부됨 |
eventsspy__4.mq5 (7.59 KB)
reportinexcel.zip (26.73 KB)
MQL5 Cookbook: 과적합의 영향 줄이기 및 따옴표 부족 처리 MQL5 Cookbook: 과적합의 영향 줄이기 및 따옴표 부족 처리
어떤 거래 전략을 사용하든 항상 미래의 이익을 보장하기 위해 어떤 매개변수를 선택해야 하는지에 대한 질문이 있을 것입니다. 이 글에서는 동시에 여러 기호 매개변수를 최적화할 수 있는 Expert Advisor의 예를 제공합니다. 이 방법은 매개변수 과적합의 영향을 줄이고 단일 기호의 데이터가 연구에 충분하지 않은 상황을 처리하기 위한 것입니다.
MQL5 Cookbook: 매개변수 수에 제한이 없는 다중 통화 Expert Advisor 개발 MQL5 Cookbook: 매개변수 수에 제한이 없는 다중 통화 Expert Advisor 개발
이 글에서는 무제한의 매개변수를 허용하면서 거래 시스템 최적화를 위해 단일 매개변수 세트를 사용하는 패턴을 만들 것입니다. 기호 목록은 표준 텍스트 파일(*.txt)로 생성됩니다. 각 기호에 대한 입력 매개변수도 파일에 저장됩니다. 이렇게 하면 Expert Advisor의 입력 매개변수 수에 대한 터미널 제한을 피할 수 있습니다.
MQL5 프로그램 디버깅 MQL5 프로그램 디버깅
이 글은 주로 언어를 이미 배웠지만 아직 프로그램 개발을 완전히 마스터하지 못한 프로그래머를 대상으로 합니다. 그것은 몇 가지 디버깅 기술을 보여주고 저자와 다른 많은 프로그래머의 결합된 경험을 보여줍니다.
MQL5 Cookbook: 다중 통화 Expert Advisor - 간단하고 깔끔하며 빠른 접근 MQL5 Cookbook: 다중 통화 Expert Advisor - 간단하고 깔끔하며 빠른 접근
이 글에서는 다중 통화 Expert Advisor에 적합한 간단한 접근 방식의 구현에 대해 설명합니다. 이는 동일한 조건에서 각 기호에 대해 다른 매개변수를 사용하여 테스트/거래를 위해 Expert Advisor를 설정할 수 있음을 의미합니다. 예를 들어, 필요한 경우 코드를 약간 변경하여 추가 기호를 추가할 수 있는 방식으로 두 개의 기호에 대한 패턴을 만들 것입니다.