English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5: MetaTrader5로 상품선물거래위원회(CFTC) 보고서 분석하기

MQL5: MetaTrader5로 상품선물거래위원회(CFTC) 보고서 분석하기

MetaTrader 5 | 5 7월 2021, 13:05
113 0
Aleksey Sergan
Aleksey Sergan


개요

MetaQuotes가 개발한 MetaTrader5 터미널은 객체 지향 프로그래밍을 이용하는 MQL5 언어를 사용합니다. 따라서 MQL4와는 호환이 되지 않지만 대신 객체 지향 언어가 갖는 무궁무진한 가능성을 자랑하죠. 따라서 이 글은 이미 기존의 MQL4에 익숙하며 MQL5를 새로 배우고자 하는 투자자들을 대상으로 합니다.

이 글에서는 CFTC 보고서 내 여러 종류의 데이터를 불러오고 분석할 수 있는 도구 개발 방법을 알아보겠습니다. 해당 주제는 이미 Meta COT 프로젝트-MetaTrader4를 통한 새로운 CFTC 보고서 분석법에서 다룬 적이 있기 때문에, 개념은 대강 알고 계실거라 생각하고 전에 다루지 않은 세부 사항 위주로 글을 쓰겠습니다.

우리의 목표는 중간 계산이나 변환을 거치지 않고 상품선물거래위원회에서 제공하는 파일로부터 직접 데이터를 추출할 수 있는 단일 인디케이터를 개발하는 것입니다. 이 인디케이터는 활용도가 높습니다. 데이터 플로팅이라든지, 다른 인디케이터의 데이터로 활용하거나, 자동 분석 스크립트로 사용될 수 있고, 액스퍼트 어드바이저의 매매 전략 개발에 사용될 수도 있죠.


1. COT 보고서의 종류

보고서는 Current Legacy Report(COT), Supplemental Commodity Index(CIT), Current Disaggregated Report(DCOT)의 세 종류로 나뉘며, 각각의 차이점은 표 1에서 확인 가능합니다.

명칭
Current Legacy Reports Supplemental Commodity Index Current Disaggregated Reports
약식 명칭 COT CIT DCOT
 참조
Current Legacy Reports
Supplemental Commodity Index
Current Disaggregated Reports
참조용 최근 데이터

deacot2010.zip

dea_cit_txt_2010.zip

fut_disagg_txt_2010.zip

투자자 그룹
비상업상업미보고 비상업상업미보고지수 거래자 생산자/상인/가공업자/사용자
스왑 딜러
자산 관리
기타 보고
미보고

표 1. COT 보고서의 종류  

선물 시장 포지션을 보고해야 하는 투자자들에 과한 정보 및 분류 기준, 보고서 발행 기간 등에 관한 정보는 윌리엄스의 저서인 'Trade Stocks and Commodities With the Insiders: Secrets of the COT Report'와 관련 자료 내 Meta COT 프로젝트-MetaTrader4를 통한 새로운 CFTC 보고서 분석법에 설명되어 있습니다.

이 글에서는 위의 차료들이 다루지 않는 두 개의 보고서에 대해 알아보겠습니다. 

CITCommitments of Index Traders의 약자입니다. CIT 보고서는 2007년부터 발행되고 있는데요. 현재 https://cftc.gov/dea/options/deaviewcit.htm에서 확인 가능합니다. 지수 거래자는 헤저 또는 투기자들과 다른 그룹으로 분류되어 있습니다.

Supplemental Report에 대한 설명은 https://www.cftc.gov/MarketReports/CommitmentsofTraders/AbouttheCOTReports/index.htm에서 확인 가능합니다. 지수 거래자들은 일반적으로 롱포지션을 취하며 한 계약에서 다른 계약으로의 롤오버를 진행합니다.

2009년 이래로 거래위원회는 Disaggregated Commitments of Traders Report(DCOT)를 발행하고 있으며, 관련 정보는 설명에서 찾아볼 수 있습니다.

DCOT 보고서는 투자자를 생산자, 가공업자, 상인, 사용자; 스왑딜러; 관리 통화; 및 기타 보고의 네 가지 카테고리로 분류하기 때문에 COT 보고서 보다 투명성이 높습니다.

  • 생산자/상인/가공업자/사용자. '생산자/상인/가공업자/사용자' 그룹은 실물 생산, 가공, 포장 및 처리에 적극적으로 참여하는 독립체이며 이와 관련된 리스크 헷지 목적으로 선물 시장을 이용합니다.
  • 스왑 딜러. '스왑 딜러'는 주로 상품 스왑 거래를 하며 이러한 거래와 관련된 리스크 헷지 목적으로 선물 시장을 이용합니다. 스왑 딜러의 거래 상대방은 헷지 펀드와 같은 투기 거래자 혹은 실물 시장에서 발생하는 리스크를 관리하고자 하는 전통적인 의미의 투자자 또는 기관입니다.
  • 자산 관리사. 해당 보고서는 CTA, CPO 또는 CFTC가 인정하는 미등록 투자 기관을 '자산 관리사'로 칭합니다. 여기에 속하는 투자자들은 고객을 대신해 선물 거래를 관리하고 진행하죠.
  • 기타 보고. 위의 세 가지 카테고리로 분류되지 않는 모든 투자자가 여기에 속합니다.

보고서에 포함된 전체 상품 목록은 부록 2에 나와 있습니다. CIT 보고서와 DCOT 보고서에 대한 포함 여부도 표시되어 있습니다.


2. CSV 파일 외부 데이터를 이용하는 COT 인디케이터 작성하기

인디케이터는 다음과 같이 작동합니다. 인디케이터의 입력 변수에 보고서 종류(표 1 참조), 데이터 종류 및 투자자 분류가 정의되어 있습니다.

다음은 데이터 종류의 예입니다.

  • 넷 롱
  • 넷 롱 미결제약정 이자율
  • 넷 롱 윌리엄스 인덱스
  • 미결제약정

이 밖에도 여러 종류가 있습니다. 현재 심볼은 데이터 파일에 포함되어 있습니다(다운로드 및 압축 해제는 하단 참조). 데이터 액세스 및 다운로드를 위해 CCFTCReport 클래스를 사용하겠습니다.

인디케이터는 다음의 구조를 갖습니다.

2.1. 상수

상수 정의에는 enum 자료형이 사용됩니다. 인디케이터가 지원하는 보고서의 종류는 다음과 같습니다.
enum cot_type_report // type of report
{ 
  COT, DCOT, CIT
};

투자자 그룹

enum cot_type_traders // types of traders
{
  noncommercial,      // Non-commercial 
  commercial,         // Commercial
  nonreportable,      // Non-reportable
  index,              // Index traders
  producer,           // Producers
  swapdealers,        // Swap dealers
  managedmoney,       // Managed money
  otherreportables    // Other reportable traders 
};

인디케이터에서 사용 가능한 자료형

enum cot_type_data    // type of COT data
{   
  netlongs,           // net longs
  netlongsrate,       // net longs rate in the open interest
  willams_index,      // Williams index
  openinterest        // Open interest
}; 

2.2. 클래스

하나의 변수에 여러 개의 객체를 저장하기 위해서는 구조 및 클래스를 사용하면 됩니다. 그러나 동적 배열 또는 문자열 값을 갖는 두 변수는 배치할 수 없습니다. 이것이 바로 우리가 구조 대신 클래스를 이용해 COT 기록과 데이터 지정 메소드를 저장한 이유이죠.

class cot_record                                // class for data record of COT report
  {
public:
   datetime          COT_DATE;                  //date 
   double            COT_OPENINTEREST;          //open interest 
   double            COT_LONGNONCOM;            //longs of non-commercial traders
   double            COT_SHORTNONCOM;           //shorts of non-commercial traders 
   double            COT_LONGCOM;               //longs of commercial traders
   double            COT_SHORTCOM;              //shorts of commercial traders 
   double            COT_LONGNONREPORTABLE;     //longs of the other non-reportable traders
   double            COT_SHORTNONREPORTABLE;    //shorts of the other non-reportable traders
   double            COT_LONGINDEX;             //longs of index traders
   double            COT_SHORTINDEX;            //shorts of index traders
   double            COT_LONGPRODUCER;          //longs of Producer/Merchant/Processor/User
   double            COT_SHORTPRODUCER;         //shorts of Producer/Merchant/Processor/User
   double            COT_LONGSWAPDEALERS;       //longs of Swap Dealers
   double            COT_SHORTSWAPDEALERS;      //shorts of Swap Dealers
   double            COT_LONGMANAGEDMONEY;      //longs of Managed Money traders
   double            COT_SHORTMANAGEDMONEY;     //shorts of the Managed Money traders
   double            COT_LONGOTHERREPORTABLES;  //Other Reportables
   double            COT_SHORTOTHERREPORTABLES;
   string            COT_ID;                    //instrument identifier
   string            COT_NAME;                  //instrument (symbol) name 

   void copyvar(const cot_record &from)         // copying contents (values of variables) from one class to another
     {
      COT_ID                    = from.COT_ID;
      COT_NAME                  = from.COT_NAME;
      COT_DATE                  = from.COT_DATE;
      COT_OPENINTEREST          = from.COT_OPENINTEREST;
      COT_LONGNONCOM            = from.COT_LONGNONCOM;
      COT_SHORTNONCOM           = from.COT_SHORTNONCOM;
      COT_LONGCOM               = from.COT_LONGCOM;
      COT_SHORTCOM              = from.COT_SHORTCOM;
      COT_LONGNONREPORTABLE     = from.COT_LONGNONREPORTABLE;
      COT_SHORTNONREPORTABLE    = from.COT_SHORTNONREPORTABLE;
      COT_LONGINDEX             = from.COT_LONGINDEX;
      COT_SHORTINDEX            = from.COT_SHORTINDEX;
      COT_LONGPRODUCER          = from.COT_LONGPRODUCER;
      COT_SHORTPRODUCER         = from.COT_SHORTPRODUCER;
      COT_LONGSWAPDEALERS       = from.COT_LONGSWAPDEALERS;
      COT_SHORTSWAPDEALERS      = from.COT_SHORTSWAPDEALERS;
      COT_LONGMANAGEDMONEY      = from.COT_LONGMANAGEDMONEY;
      COT_SHORTMANAGEDMONEY     = from.COT_SHORTMANAGEDMONEY;
      COT_LONGOTHERREPORTABLES  = from.COT_LONGOTHERREPORTABLES;
      COT_SHORTOTHERREPORTABLES = from.COT_SHORTOTHERREPORTABLES;
     };
  };

지금부터는 독자 여러분이 COT 보고서 CSV 포맷을 잘 알고 있다고 생각하겠습니다. 해당 내용은 Meta COT 프로젝트-MetaTrader4를 통한 새로운 CFTC 보고서 분석법이라는 글에서 다룬 바 있습니다. 해당 타입의 클래스 인스턴스는 COT 보고서의 한 줄을 저장하기 위해 쓰입니다. 해당 클래스 인스턴스 배열을 이용하면 COT 기록 필드에 쉽게 액세스할 수 있겠죠. 데이터 저장 및 액세스를 위한 CCFTCReport 클래스가 완성됐습니다.

class CCFTCReport                    // COT report
  {
private:
   cot_type_report   type;           //type of current report 
   cot_record        data[];         //cot report data
   int               sizedata;       //number of records in the current report
   string            idsymbol;       //symbol identifier in cot ("CFTC Contract Market Code" field)
   string            terminalsymbol; //symbol name in the client terminal
public:
   void ~CCFTCReport(){ sizedata=0; };  
   bool              Init( cot_type_report passedtype, string sym="" ); //initialization of class instance
   bool              LoadFile( string filename );                       //load data from file
   string            Name();                                            //returns short report name
   bool              Type(cot_type_report passedtype);                  //sets type of report
   cot_type_report Type(){return(type);};                               //returns report type
   bool              TestGroup( cot_type_traders type_trader );         //check for the presence of specified group of traders
   bool              DefineIdSymbol();                                  //definition of id in the cot report
   bool              GetString( int handle, cot_record& arr );          //gets line (record) from csv file   
   string            GetFieldCommaDelimited(string &str);               //gets field from csv string
   double            At(datetime time,cot_type_traders type_trader,cot_type_data typedata=netlongs); //gets data from the report
  };

CCFTCReport 클래스 인스턴스는 COT, CIT 또는 DCOT 보고서 내 전체 심볼쌍에 대한 내용을 포함합니다. 필요한 열거형과 클래스는 'cot.mqh'에 포함되어 있습니다.

2.3. 입력 변수

input 함수를 이용해 인풋 변수를 정의합니다. 투자자 그룹, 데이터형 및 COT 보고서 형식을 입력할 수 있습니다.

input cot_type_traders type_trader = noncommercial;  //type of traders
input cot_type_data    type_data   = netlongs;       //type of the indicator
input cot_type_report  type_report = COT;            //type of report

2.4. OnInit 함수

인디케이터는 OnInit 함수를 가지며, 이는 보고서 파일에서 데이터를 다운로드하거나 입력 변수를 확인하거나 인디케이터 버퍼 지정에 사용됩니다.

INDICATOR_DATA 속성으로 초기화되는 버퍼는 차트에 플로팅되는 데이터를 포함합니다. INDICATOR_CALCULATIONS 속성으로 초기화되는 버퍼는 중간 계산을 포함하죠.

SetIndexBuffer( 0, BufferData, INDICATOR_DATA );
IndicatorSetString(INDICATOR_SHORTNAME,indname);
SetIndexBuffer( 1, BufferCalculations, INDICATOR_CALCULATIONS );

2.5. OnCalculate함수

이 함수는 필요한 데이터 선택, 요청된 데이터 계산 및 플로팅에 사용됩니다.

자세히 살펴보겠습니다. 두 번째 호출 방식을 사용하겠습니다.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &Time[],
                const double &Open[],
                const double &High[],
                const double &Low[],
                const double &Close[],
                const long &TickVolume[],
                const long &Volume[],
                const int &Spread[]){

계산과 플로팅을 위한 바를 정합시다.

int pos=rates_total-prev_calculated-1;
if( pos >= rates_total-1 )pos--;

요소는 반드시 시계열 형태로 인덱싱되어야 합니다.

ArraySetAsSeries(Time, true);
ArraySetAsSeries(BufferData, true);
ArraySetAsSeries(BufferCalculations, true);

몇 번 시도 해보니 인디케이터 버퍼와 연결된 시계열 인덱싱을 사용하는 게 좋더라고요. OnCalculate 함수로 전달되는 배열도 마찬가지입니다. 가장 최근 요소에 0값을 갖는 인덱스를 부여하는 거죠.

연산 루프는 다음과 같습니다. 

for(int i=pos;i>=0;i--)
{
    cot_type_data passed = type_data;
    if(type_data==netlongs || type_data==netlongsrate || type_data==willams_index)
    {
      // For the types of the data (net longs, net longs rate, Williams Index) it returns net longs 
      // Further calculations are based on these data.
      passed = netlongs;
    }
    double res = Report.At(Time[i], type_trader, type_data ); //get report data
    BufferCalculations[i] = res;
    BufferData[i]         = CalcData( type_data, i, Time );
  }

BufferCalculations 배열에 COT 보고서에 선택된 1차 데이터가 저장되죠.

BufferData 배열은 차트에 플로팅될 데이터를 갖고 있습니다. 보고서에 포함된 정보(넷 롱, 미결제약정)일 수도 있고 계산된 값(롱 이자율, 윌리엄스 인덱스)일 수도 있죠. 이번에 설명할 부분에 대해서는 아직 깔끔한 해결 방법을 찾지 못했는데요. OnCalculate 함수로 전달된 배열이 향후에 필요하게 될 수 있습니다. 반면 함수로 전달된 배열만 액세스할 수 있게 되죠. 그래서 코드가 지저분해지는 것 같아요.

CalcData 함수 호출입니다.

BufferData[i]         = CalcData( type_data, i, Time );

CalcData 함수는 CalcIndex 함수를 호출합니다.

double CalcData( cot_type_data type_data, int i, const datetime& Time[] )
{
  // net longs rate in the open interest
  if( type_data == netlongsrate ) return( BufferCalculations[ i ] / Report.At( Time[i], type_trader, openinterest ));
  // Williams Index
  if( type_data == willams_index )return( CalcIndex( i, Time, BufferCalculations ) );

  return(BufferCalculations[i]);        
}

CalcIndex 함수에서는 시계열에 대한 액세스가 필요해서 호출 계층대로 전달할 수밖에 없었어요. 배열이 8개가 되면 어떻게 될지 상상해보세요.


3. 데이터 파일 다운로드

모든 링크는 표 1에 포함되어 있습니다. 연도별로 별도의 파일이 생성되어 있으며 파일명에 연도가 표시되어 있습니다. 예를 들어 https://www.cftc.gov/sites/default/files/files/dea/history/deacot2010.zip 파일은 2010년도 보고서를 포함하고 https://www.cftc.gov/sites/default/files/files/dea/history/deacot2009.zip 파일은 2009년 보고서를 포함하는 식이죠.

전체 파일을 다운로드 받아 클라이언트 터미널 디렉터리의 \MQL5\files\에 압축 풀기하세요. 연도별로 별도의 폴더를 만들어야 합니다. 폴더의 이름 형식을 deacotXXXX로 정하고 XXXX에는 연도를 입력하세요. 그러면 다음의 디렉토리 구조를 갖게 됩니다.

그림 1. 리포트 디렉토리 구조

데이터 준비 과정은 간소화될 수 있습니다. CFTC 웹사이트 업데이트 여부 확인 및 다운로드된 파일을 정해진 폴더에 저장하는 일은 'Cotdownloader' 스크립트로 실행됩니다. 스크립트 커널(데이터 다운로드)는 WININET_TEST 스크립트를 기반으로 실행되죠. 저는 관련 자료'가격 히스토그램(마켓 프로파일) 및 MQL5 구현'에서 다룬 CProgressBar 클래스를 사용했습니다. 외부 애플리케이션은 윈도우 API로 실행되며 관련 내용은 '실거래를 위한 트레이딩 로봇 자동 최적화'에서 찾아볼 수 있습니다..

스크립트 사용법은 간단합니다. 차트에 갖다붙이기만 하면 되죠. 작동을 시작하면 데이터 다운로드 관련 정보가 차트의 진행바에 표시되며 액스퍼트 탭에 텍스트 메세지가 나타납니다.

그림 2. 데이터 다운로드 프로세스


4. 사용 예시

인디케이터를 실행하려면 우선 통화쌍 차트를 선택하고 입력 변수를 설정해야 합니다.


그림 3. COT 인디케이터 입력 변수

열거형 데이터 값과 각종 변수를 사용하는 대신 사용자 친화적인 방식을 사용할 수 있게 됐습니다. 변수 이름을 대체하려면 입력 변수 선언 시 주석을 설정하면 됩니다.

input cot_type_traders type_trader = noncommercial;  //Type of traders
input cot_type_data    type_data   = netlongs;       //Type of the indicator
input cot_type_report  type_report = COT;            //Type of report

데이터 값의 경우도 마찬가지입니다. 열거형을 선언할 때 주석에 설명을 달면 되죠.

enum cot_type_data    // types of data
{   
  netlongs,           // Net longs
  netlongsrate,       // Net longs rate in open interest
  willams_index,      // Williams Index
  openinterest        // Open Interest
};

올바른 입력 변수가 입력되고 파일이 다운로드되면 인디케이터가 별도의 창에 나타날 것입니다.


그림 4. COT 인디케이터

에러 발생 시 '도구상자' 창의 '엑스퍼트' 탭에 나타납니다.

그림 5. 에러 메세지


5. 릴리스 노트

해당 인디케이터는 모든 기능을 갖춘 완성품이 아닙니다. 간단한 코드로도 원하는 결과를 얻을 수 있다는 것을 보여드리기 위한 예시입니다. 클라이언트 터미널 세팅에서 COT 보고서 데이터를 커스터마이징 할 수 있게 해주는 모듈 등은 아직 개발되지 않은 상태죠. 해당 기능은 DefineIdSymbol 함수 내부에서 구현됩니다. 라인의 예시를 볼까요.

bool CCFTCReport::DefineIdSymbol()
  {
   idsymbol="";
   if(terminalsymbol=="USDLFX" || terminalsymbol=="DX_CONT" || StringFind(terminalsymbol,"DX")==0)idsymbol="098662";
   //U.S. DOLLAR INDEX - CE FUTURES U.S.
   if( terminalsymbol == "FC_CONT" || StringFind( terminalsymbol, "FC")== 0)idsymbol = "061641";  //FEEDER CATTLE 
   if( terminalsymbol == "LC_CONT" || StringFind( terminalsymbol, "LC")== 0)idsymbol = "057642";  //LIVE CATTLE 
   if( terminalsymbol == "QM_CONT" || StringFind( terminalsymbol, "QM")== 0)idsymbol = "067651";
   //CRUDE OIL, LIGHT SWEET - NEW YORK MERCANTILE EXCHANGE

리포트의 통화쌍을 클라이언트 터미널에서 불러오려면 해당 코드를 직접 수정해서 사용해야 합니다. 저는 브로코트레이더4의 설정을 이용했습니다. 본문의 예시를 위해서는 Alpari-Demo 서버의 Metaquotes-Demo에서 데모 계정으로 작업했습니다. 현재 DCOT 보고서에서는 XAUUSD(금)과 XAGUSD(은)의 두 가지 상품만 사용 가능합니다. 

서버에 금융 상품이 없는 CIT 보고서는 현재 지원되지 않고 있습니다. 그러나 차후 코드 수정과 주석 해제를 통해 간단한 방법으로 CIT 보고서를 지원하도록 할 수 있습니다.


6. iCustom으로 COT 인디케이터 사용하기

저는 그림 3에서 보이는 형식의 인디케이터는 사용하지 않습니다. MQL5의 iCustom 함수를 이용하면 기존의 커스텀 인디케이터를 재사용할 수 있습니다.

6.1. 새로운 인디케이터 만들기

COT 보고서에는 다양한 시각적 분석 방법이 있습니다. 그 중 하나는 히스토그램인데요. 히스토그램은 각 투자자 그룹의 포지션을 색깔로 구분합니다.

COTnet 인디케이터를 사용해 서로 다른 투자자 그룹(비상업 및 상업)의 포지션을 그려 봅시다. 사용자는 넷 롱, 넷 롱 이자율, 윌리엄스 인덱스.중에서 데이터 형식을 선택할 수 있습니다:

'MQL5: 나만의 인디케이터 만들기'에서 이야기했듯, MQL5 마법사를 사용하면 과정이 간단해지죠. 결과적으로 인디케이터 코드(MQL5 마법사로 드로잉 스타일 생성)는 다음과 같아집니다.

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//---- plot Noncommercial
#property indicator_label1  "Noncommercial"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  5
//---- plot Commercial
#property indicator_label2  "Commercial"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  5
//--- indicator buffers
입력 변수, 전역 변수 및 전처리기 지시문은 클래스 라이브러리를 포함합니다.
#include <cot.mqh>
input cot_type_data    type_data   = netlongs;  // Indicator's type
double         NoncommercialBuffer[];
double         CommercialBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int handlecomm, handlenoncomm;

OnInit 함수 코드는 다음과 같습니다.

int OnInit()
{
   SetIndexBuffer(0,NoncommercialBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,CommercialBuffer,INDICATOR_DATA);
   cot_type_traders td = commercial;
   cot_type_report  tr = COT; 
   handlecomm = iCustom(NULL, 0, "cot", td, type_data, tr );
   td = noncommercial;
   handlenoncomm = iCustom(NULL, 0, "cot", td, type_data, tr );
   return(0);
}
커스텀 인디케이터를 어떻게 사용할지 생각해 봅시다(비상업 투자자의 경우). iCustom 함수 첫 호출 이후 다음의 매개 변수(보고서에 필요)가 함수로 전달됩니다.
  • NULL–현재 클라이언트 터미널 심볼
  • 0–현재 타임프레임
  • 'cot'–커스텀 인디케이터 파일명(확장자 제외)
  •  td =commercial(우리에게 필요한 투자자 그룹)
  •  type_data=입력 변수로 특정된 인디케이터 종류
  •  tr=COT–보고서 종류

이제 핸들이 생겼으니 핸들을 이용해 인디케이터 데이터를 더 가져오도록 하겠습니다.

OnCalculate 함수를 이용해 인디케이터에서 데이터를 가져옵니다.
  if(BarsCalculated(handlecomm)<rates_total || BarsCalculated(handlenoncomm)<rates_total) return(0);
  int to_copy = clctocopy(rates_total, prev_calculated );
  if( !copycotbuf(handlecomm, CommercialBuffer, to_copy ) )
  {
    Print("Error in data of commercial traders");
    return( 0 );
  }

  if( !copycotbuf(handlenoncomm, NoncommercialBuffer, to_copy ) )
  {
    Print("Error in data of non-commercial traders");
    return( 0 );
  }
  return(rates_total);

우리가 공들여 쓴 짧은 코드의 결과는 다음과 같네요.


그림 6. cotnet 인디케이터

6.2. iCustom도 스크립트에서 사용할 수 있습니다.

통계 추정치 계산을 위한 cotsignals 스크립트를 작성해 보겠습니다.

COT 보고서의 다양한 데이터를 이용해서 어떤 통계적 이점을 얻을 수 있는지 알아보죠. 가장 간단한 방법은 주간 캔들의 색깔이 올바르게 결정될 확률을 추측해 보는 겁니다. 다음을 가정해 봅시다.
  • 비상업적 투자자의 넷 롱 신호는 캔들과 색깔이 같습니다. 또한 양의 값을 갖는 경우 주간 추세는 상승 추세이고 음의 값을 가지면 주간 추세가 하락 추세임을 의미합니다.
  • 캔들의 색깔(흰색/검은색)은 비상업적 투자자의 넷 롱 확장 및 축소와 직접적인 관련이 있습니다.
  • 비상업적 투자자의 넷 롱을 기반으로 계산된 윌리엄스 인덱스 값에 따라 캔들은 흰색 또는 검은색으로 나타납니다. 과매수(75% 이상)된 경우 검은색을 띠며, 과매도(25% 이하)인 경우 흰색을 띠죠.

COT 보고서의 데이터를 이용할게요. 여러가지 예제를 참고하여 여러분만의 COT 데이터 분석 방법을 개발해 수익 창출에 활용하세요. 이번에는 3년 간의 데이터인 150주 동안의 바 기록을 확인하겠습니다. 스크립트 작성에 앞서 필요한 데이터형과 클래스를 정의합니다.

사용 가능한 통계 자료에 대한 열거형은 다음과 같습니다.

enum cot_type_statistics   //types of statistics, used for calculation 
{  
  speculantsign,           //Sign of non-commercial traders' net longs 
  speculantchange,         //Volume changes of non-commercial traders' longs 
  willamszones             //Overbought/oversold zones of Williams Index
};

특정 심볼에 대한 통계 자료를 얻기 위해 다음의 특수 클래스를 생성합니다.

class CCOTStatistic
{
  private:
    
    int bars ;                            // number of weekly bars in symbol history
    string symbol;                        // symbol name in Client Terminal
    double netlongsspeculantsdata[];      // data for speculators' net longs 
    double willamsindexspeculantsdata[];  // data for speculators' Williams index net longs   
    cot_type_statistics liststatistic[];  // list of statistics
  public:
    //initialization and initial setup
    void Init( string symbol_passed, cot_type_statistics& listpassed[] );
    //Get the forecast for the direction 
    int GetCotSignalDirection( int ibar, cot_type_statistics type_stat   );
    bool Get( double& probably[] );       // returns statistics
};

요청된 자료는 겟방식으로 반환됩니다. 어떻게 작동하는지 설명하겠습니다. 우선 커스텀 인디케이터를 사용해 필요한 배열에 데이터를 채웁니다. 비상업적 투자자(투기자)의 넷 롱 값과 윌리엄스 인덱스 값이 필요하죠.

if (!LoadDataFromCOTIndicator(symbol, PERIOD_W1, noncommercial, netlongs, COT, netlongsspeculantsdata, bars))
   return(false);
  // we have got the data - speculators' net longs
if (!LoadDataFromCOTIndicator(symbol, PERIOD_W1, noncommercial, willams_index, COT, willamsindexspeculantsdata, bars))
   return(false);
  // we have got the data - speculators' Williams Index

통계 계산(주간 캔들의 색깔을 예측하는 한 가지 매개 변수만 계산) 코드는 다음과 같습니다.

for(int istat = 0; istat < ArraySize(liststatistic); istat++)
  {
   int cntsignals = 0;
   int cntsucsess = 0;
   for(int i=bars-1; i>=0; i--)
     {
      double colorcandle=iClose(symbol,PERIOD_W1,i)-iOpen(symbol,PERIOD_W1,i);
      if(symbol=="USDCHF" || symbol=="USDCAD" || symbol=="USDJPY") colorcandle=-colorcandle;
      double cotdirection=GetCotSignalDirection(i,liststatistic[istat]);
      if(cotdirection==0)continue;                 //no signal
      cntsignals++;
      if(cotdirection*colorcandle>0) cntsucsess++; //color and direction are same
     }

   if(cntsignals!=0) probably[istat]=1.*cntsucsess/cntsignals;

   Print("Calculation complete for ",symbol,GetStringTypeStatistic(liststatistic[istat]),
                 " the correct forecast probability=",DoubleToString(probably[istat],2));
   Print("Total signals:",cntsignals,"success:",cntsucsess);
  }
LoadDataFromCOTIndicator 함수는 꽤 복잡합니다. 인디케이터에서 데이터를 얻으려면 여러 번의 확인 과정을 거쳐야 하기 때문이죠. 자세히 살펴봅시다.
bool LoadDataFromCOTIndicator( string           symbol,        //symbol name
                               ENUM_TIMEFRAMES  timeframe,     //timeframe
                               cot_type_traders type_trader,   //group of traders type
                               cot_type_data    type_data  ,   //indicator type 
                               cot_type_report  type_report,   //report type
                               double&          loadto[],      //output data array
                               int              nbars   )      //number of requested bars 
{     
  
  int cothandle;
  nbars+=10 ; //for reserve
  cothandle = iCustom( symbol , timeframe, "cot", type_trader, type_data, type_report );

마지막 라인은 버퍼에서 데이터를 불러오는 데에 사용할 수 있는 커스텀 인디케이터의 핸들에 대한 내용입니다.

인디케이터가 성공적으로 작성되었는지 확인해 봅니다.

  if( cothandle == INVALID_HANDLE ){
    Print("Error in indicator creation for symbol ", symbol );
    return(false);
  }

필요한 과거 데이터를 확인합니다.

int n = BarsSinh( symbol, timeframe );
  if(  n < nbars    )
{ 

과거 데이터가 부족하면 불러오면 됩니다.

Print("Loading history for ", symbol ); //, " start at ", loadtm  
    CheckLoadHistory( symbol ,timeframe,   loadtm );
    n = BarsSinh( symbol, timeframe );
    if( n < nbars )
    {
      Print("Not enough history for the "+symbol, " total ", n, "bars");
      return(false);
    }
  }

BarsSinh 함수(특정 심볼 및 타임프레임의 바 개수 반환)와 CheckLoadHistory 함수(과거 기록 다운로드)는 MQL5 레퍼런스스크립트 코드를 기반으로 합니다.

인디케이터 버퍼에서 데이터를 가져오기에 앞서 데이터가 준비되었는지 확인해야 합니다. 핸들이 있다고 해서 연산이 완료된 건 아니니까요.

다음의 호출을 통해 데이터를 확인하고 연산이 완료될 때까지 기다립니다.

if( !WaitForCalculcateIndicator( cothandle ) ){
    Print("Timeout for the COT indicator calculation");
    return(false);
  }

데이터가 준비되면 복사합니다.

int res = CopyBuffer(cothandle, 0, 0, nbars, loadto );

데이터가 성공적으로 복사되었는지 확인합니다.

if( res != nbars ){
    Print("Error in obtaining the data, ", MyErrorDescription(_LastError) );
    return(false);
  }

이제 마지막 단계입니다.

return(true);

데이터를 획득했고, 함수 매개 변수를 통해 전달된 배열로 반환했습니다.

통계 결과는 CSV 파일로 나오며, 이를 위해 CCOTOutFile 클래스를 생성했습니다.

class CCOTOutFile
{
  private:
   string  filename;
   int     handle; 
  public:
    bool Init( string passedname );
    void PutString( string symbol, double& probably[] );
    void PutHeader( cot_type_statistics& arrheaders[] ) ;
    void ~CCOTOutFile(){       FileClose(handle);    }
};

이 클래스는 출력 데이터가 포함된 파일을 생성하며 .csv 형식의 문자열을 작성하고, 헤더를 만들며 클래스 인스턴스 삭제 시 해당 파일을 종료합니다.

필요한 라이브러리를 이미 작성했으므로 스크립트 코드는 짧습니다.

입력 변수는 라이브러리에 포함되어 있습니다.

input int      NBars =150; //History depth W1
#include <common.mqh>
#include <cot.mqh>

분석용 심볼 목록

string listsymbols[] = {"EURUSD", "GBPUSD", "USDCHF", "USDCAD", "USDJPY", "AUDUSD", "XAUUSD"};

객체 초기화

void OnStart()
{
  CCOTOutFile outfile;  //file with results
  if( !outfile.Init("cotw1signals.csv") )return;

연산용 통계 자료 목록

  cot_type_statistics list_statistic[]= // statistic types list
  { speculantsign, speculantchange, willamszones };

CSV 파일 헤더
작성하기

outfile.PutHeader( list_statistic ); //writing CSV file header

메인 루프에는 각 심볼 및 신호에 대한 통계가 포함되어 있으며 파일에 결과를 작성합니다.

  for( int i = 0; i < ArraySize(listsymbols); i++  ) //for all symbols in the list
 {  
    Print( "Analysis for "+listsymbols[i] );
    CCOTStatistic stat;
    stat.Init( listsymbols[i ], list_statistic );
    double probably[];                               //probability of a signal
    if( !stat.Get( probably ) )
    {
      Print( "Error in statistics calculation for the symbol ", listsymbols[i] );
      return;
    }  
    outfile.PutString( listsymbols[i], probably );   //write string to .csv file
  }
  Print("Calculation complete.");
}

해당 스크립트는 Alpari-Demo 서버에서 테스트 되었습니다. MetaQuotes-Demo 서버에서 실행하게 되면 'XAUUSD 심볼 통계 연산 에러'라고 뜰 겁니다. 아직 해당 심볼이 없으니까요.

스크립트를 실행하면 다음과 같은 파일을 얻게 됩니다.


부가 설명을 위해 엑셀에서 파일을 열겠습니다. 평균 값을 계산하고 확률 히스토그램을 만듭니다.

그림 8. 확률 예측

예측 결과는 모든 심볼에서 동일하게 나타납니다. 신호별 예측된 확률 값의 평균은 다음과 같습니다.
  • 0.54–비상업 투자자 사인
  • 0.50–비상업 투자자 넷 롱 거래량 변화
  • 0.48–윌리엄스 인덱스 과매수/과매도 구간

비상업 투자자의 넷 롱에 대한 예측 결과가 가장 긍정적이라는 걸 알 수 있죠. 윌리엄스 인덱스 구간에 대한 예측 결과가 가장 나쁘군요. 0.48이라는 값은 윌리엄스 인덱스의 과매수 구간에서도 흰 캔들이 생길 확률이 0.52와 같음을 의미합니다. 과매도 구간에서는 검은 캔들이 생성되죠. 따라서 윌리엄스가 제안하는 방식은 그다지 합리적이지 않습니다. 더 큰 타임프레임(월 단위 이상)을 사용하면 어쩌면 결과가 나아질 수도 있겠죠. 이렇게 데모 서버와 COT 보고서에 포함된 모든 심볼을 이용해 봤습니다.


결론

MQL5는 트레이딩 시스템 개발에 필요한 작업을 프로그래밍할 수 있는 도구이다.
  • 복잡한 알고리즘을 갖는 인디케이터는 외부 데이터 액세스에 사용된다.
  • 스크립트와 엑스퍼트 어드바이저에서 인디케이터를 재사용할 수 있다.
  • 통계적, 양적 분석을 위한 나만의 알고리즘을 구현할 수 있다.
장점
  • OOP가 디버깅 소요 시간을 크게 감소시킨다.
  • 디버거가 있다.
  • MQL4에서 MQL5로 넘어가기 쉽다.
  • 객체 지향 모델 구현은 사용하기 쉽다. 
  • 관련 정보가 많다. 
  • 윈도우 API와 결합해 플랫폼을 연장하면 인터넷에도 접속할 수 있다.

단점

과거 데이터에 대한 접근이 어렵다.  
  • 시간열 접근에 필요한 기본 함수(MQL4의 Time[], Oopen[], Close[] 등)가 없다.
  • 데이터 액세스 시 여러 번의 확인 과정이 필요하며 세부 사항까지 이해하고 있어야 한다.

디버거가 있기는 하지만 인디케이터 디버깅 등의 유용한 기능은 별로 없다. 배열이나 클래스와 같은 복합 객체에 대한 확인도 불가능하다. 제가 이 글을 쓰면서 느낀 장점과 단점을 나열해 봤습니다.


부록 1. 파일 목록

모든 파일은 클라이이언트 터미널 폴더에 위치합니다. sources.zip 파일을 클라이언트 터미널에 압축 해제하세요.

 번호파일명
명칭
 1 MQL5\Files\unzip.exe
 .zip 파일 압축 해제용 윈도우 애플리케이션
 2 MQL5\Include\Cdownloader.mqh
 CFTC 온라인 아카이브 다운로드용 클래스
 3 MQL5\Include\ClassProgressBar.mqh
 차트창 다운로드 진행 상황 표시용 CProgressBar 클래스
 4 MQL5\Include\common.mqh
 모든 인디케이터와 스크립트에서 사용 가능한 공통 함수 및 상수
 5 MQL5\Include\cot.mqh
 COT 보고서 데이터 선택용 CCFTCReport 클래스
 6 MQL5\Include\ErrorDescription.mqh
 에러 라이브러리
 7 MQL5\Indicators\cot.mq5
 COT 기본 인디케이터
 8 MQL5\Indicators\cotnet.mq5
 cot.mq5를 커스텀 인디케이터로 이용한 cotnet 인디케이터
 9 MQL5\Scripts\cotdownloader.mq5
 온라인 아카이브 파일 다운용 cotdownloader 스크립트
 10 MQL5\Scripts\cotsignals.mq5
 COT 보고서 분석의 예인 cotsignals 스크립터


표 2. 파일 목록


부록 2. COT 보고서 심볼쌍 목록

번호
심볼명
거래소 종목코드 클라이언트 터미널 종목코드 CIT 포함 여부 DCOT 포함 여부
 1 밀-시카고거래소  001602 ZW x x
 2 밀-캔자스 시티 상품 거래소  001612   x x
 3 밀-미네아폴리스 곡물 시장  001626     x
 4 옥수수-시카고거래소  002602 ZC x x
 5 귀리-시카고거래소 004603 ZO   x
 6 대두-시카고거래소  005602 ZS x x
 7 소두-시카고거래소  005603     x
 8 유황 금융 상품-시카고기후거래소  006261     x
 9 탄소 금융 상품-시카고기후거래소  006268     x
 10 2009 RGGI CO2 배출권 2009-시카고기후거래소  00626U      x
 11 대두유-시카고 상품 거래소  007601 ZL x x
 12 미국 국채-시카고거래소  020601 ZB    
 13 미국 장기 국채-시카고거래소  020604      
 14 걸프 #6 연료 3.0% 유황 스왑-뉴욕상업거래소  02165A      x
 15 뉴욕 RFO 1.0% 유황 스왑-뉴욕상업거래소  02165B      x
 16 유럽 1% 연료 NWE 캘린더 스왑-뉴욕상업거래소  02165C      x
 17 유럽 3.5% 연료 RTD 캘린더 스왑-뉴욕상업거래소  02165E      x
 18 싱가포르 연료 180 캘린더 스왑-뉴욕상업거래소  02165G      x
 19 EW 연료 스프레드 스왑-뉴욕상업거래소  02165I      x
 20 뉴욕 1% 대 걸프 3% 연료 스프레드-뉴욕상업거래소  02165T      x
 21 NO. 2 난방유 022651     x
 22 싱가포르 가스 오일 스왑-뉴욕상업거래소  02265J      x
 23 싱가포르 가스 오일/로테르담 가스오일 스왑-뉴욕상업거래소  02265T      x
 24 뉴욕상업거래소 난방유/로테르담 가스 오일-뉴욕상업거래소  02265U      x
 25 가스 오일(ICE) 스왑-뉴욕상업거래소  02265V      x
 26 업 다운 걸프 해안 USLD 대 HO 스프레드 스왑-뉴욕상업거래소  022A13      x
 27 싱가포르 가스 오일 BALMO 스왑-뉴욕상업거래소  022A22      x
 28 천연 가스 ICE 헨리 허브-ICE OTC  023391     x
 29 천연 가스-뉴욕상업거래소  023651 QG   x
 30 MICHCON 베이시스 스왑-뉴욕상업거래소  02365A      x
 31 M-3 베이시스 스왑-뉴욕상업거래소  02365C      x
 32 TCO 베이시스 스왑-뉴욕상업거래소  02365D       
 33 NGPL TXOK 베이시스 스왑-뉴욕상업거래소  02365G      x
 34 NGPL MIDCON 베이시스 스왑-뉴욕상업거래소  02365K      x
 35 WAHA 베이시스 스왑-뉴욕상업거래소  02365O      x
 36 휴스턴 선박 채널 인덱스 스왑-뉴욕상업거래소  023A10      x
 37 CBT 에탄올-시카고거래소  025601     x
 38 시카고 에탄올 스왑-뉴욕상업거래소  025651     x
 39 대두박-시카고거래소  026603 ZM   x
 40 일본 C&F 나프타 스왑-뉴욕상업거래소  03265C      x
 41 면화 No. 2-ICE미국선물거래소  033661 CT x x
 42 헨리 허브 베이시스 스왑-뉴욕상업거래소  035652     x
 43 휴스턴 선박 채널 베이시스 스왑-뉴욕상업거래소  035653     x
 44 NW PIPE ROCKIES 베이시스 스왑 뉴욕상업거래소  035654     x
 45 PANHANDLE 베이시스 스왑-뉴욕상업거래소  035655     x
 46 헨리 허브 스왑-뉴욕상업거래소  03565B       
 47 헨리 허브 PENULTIMATE 가스 스왑-뉴욕상업거래소  03565C      x
 48 현미-시카고거래소  039601 ZR   x
 49 냉동 농축 오렌지주스-ICE미국선물거래소  040701 JO   x
 50 미국 2년물 국채-시카고거래소  042601      
 51 미국 10년물 국채-시카고거래소  043602 ZN    
 52 미국 5년물 국채-시카고거래소  044601      
 53 30일물 연방 기금-시카고거래소  045601 ZQ    
 54 클래스 III 우유-시카고상업거래소  052641     x
 55 돈육-시카고상업거래소  054642 HE x x
 56 생우-시카고상업거래소  057642 LC x x
 57 랜덤 렝스 목재-시카고상업거래소  058643 LB   x
 58 비육우-시카고상업거래소  061641 FC x x
 59 PJM 월간 전력-뉴욕상업거래소  064657     x
 60 ISO-NE LMP 스왑-뉴욕상업거래소  06465H      x
 61 PJM CAL MONTH OFF PK LMP 스왑-뉴욕상업거래소  06465M      x
 62 ISO NEW ENG OFF PK LMP 스왑-뉴욕상업거래소  06465S      x
 63 CINERGY CAL MONTH LMP 스왑-뉴욕상업거래소  064A01      x
 64 CINERGY OFF PEAK LMP 스왑-뉴욕상업거래소  064A02       
 65 PJM N ILL PEAK DAY AHEAD-뉴욕상업거래소  064A34      x
 66 PJM JCPL PEAK DAY AHEAD-뉴욕상업거래소  064A48      x
 67 PJM PEPCO PEAK DAY AHEAD-뉴욕상업거래소  064A50      x
 68 PJM PSEG PEAK DAY AHEAD-뉴욕상업거래소  064A54      x
 69 PJM WESTERN PEAK DAY AHEAD-뉴욕상업거래소  064A56       
 70 PJM WESTERN PEAK 실시간-뉴욕상업거래소  064A58      x
 71 PJM WESTERN OFF PEAK 실시간-뉴욕상업거래소  064A59      x
 72 ISO NEW ENG INT HUB PEAK 스왑-뉴욕상업거래소  064A60      x
 73 MW IND TRANS PEAK 스왑-뉴욕상업거래소  064A62      x
 74 NYISO ZONE 5 MW PEAK 스왑-뉴욕상업거래소  064A66       
 75 ISO NEW ENG HUB OFF PEAK 스왑-뉴욕상업거래소  064A78       
 76 MT BELVIEU 프로판 5 DEC 스왑-뉴욕상업거래소  06665O       
 77 MT BELVIEU 에탄 5 DEC 스왑-뉴욕상업거래소  06665P      x
 78 MT BELV NORM 부탄 5 DEC 스왑-뉴욕상업거래소  06665Q      x
 79 MT BELV NAT 가솔린 5 DEC 스왑-뉴욕상업거래소  06665R      x
 80 저유황 경질유-ICE유럽선물거래소  067411     x
 81 저유황 경질유-뉴욕상업거래소 067651 QM   x
 82 WTI 원유 캘린더 스왑-뉴욕상업거래소  06765A      x
 83 두바이 원유 캘린더 스왑-뉴욕상업거래소  06765G      x
 84 저유황 경질유 증거금-뉴욕상업거래소  06765I      x
 85 브렌트유 증거금-뉴욕상업거래소  06765J      x
 86 브렌트유(ICE) 캘린더 스왑-뉴욕상업거래소  06765N      x
 87 브렌트-두바이유 스왑-뉴욕상업거래소  06765O      x
 88 코코아-ICE미국선물거래소  073732 CC x x
 89 팔라듐-뉴욕상업거래소  075651 PA   x
 90 백금-뉴욕상업거래소  076651 PL   x
 91 설탕 No.11-ICE미국선물거래소  080732 SB x x
 92 커피 C-ICE미국선물거래소  083731 KC x x
 93 은-상품거래소  084691 SI,XAGUSD,ZI   x
 94 구리-등급 #1 -상품거래소  085692 HG   x
 95 금-상품거래소  088691 GC,GOLD,XAUUSD   x
 96 러시아 루블-시카고상업거래소  089741 USDRUB,USDRUR    
 97 캐나다 달러-시카고상업거래소  090741 6C,USDCAD    
 98 스위스 프랑-시카고상업거래소  092741 6S,USDCHF    
 99 멕시코 페소-시카고상업거래소  095741      
 100 영국 파운드 스털링-시카고상업거래소  096742 6B,GBPUSD    
 101 일본 엔-시카고상업거래소  097741 6J,USDJPY    
 102 미국 달러 지수-ICE미국선물거래소  098662 DX    
 103 유로FX-시카고상업거래소 099741 6E,EURUSD    
 104 GTAB(RBOB)-뉴욕상업거래소  111659 XRB   x
 105 RBOB 캘린더 스왑-뉴욕상업거래소  11165K      x
 106 뉴질랜드 달러-시카고상업거래소  112741 6N,NZDUSD    
 107 VIX 선물-CBOE선물거래소  011700      
 108 다우 존스 산업평균지수-시카고거래소  124601      
 109 3개월물 유로달러-시카고상업거래소  132741      
 110 S&P 500 지수-시카고상업거래소  138741      
 111 E-MINI S&P 500 지수 - 시카고상업거래소  13874A  ES,SPX    
 112 나스닥 100 지수-시카고상업거래소  209741 NQ    
 113 MINI 나스닥 100 지수-시카고상업거래소  209742      
 114 다우 존스 UBS ER-시카고거래소  221602      
 115 호주 달러-시카고상업거래소  232741 6A,AUDUSD    
 116 러셀 2000 MINI 지수 선물-ICE미국선물거래소  23977A       
 117 닛케이 평균주가-시카고상업거래소  240741      
 118 닛케이 평균주가 달러-시카고상업거래소  240743      
 119 E-MINI MSCI EAFE 지수-시카고상업거래소  244741      
 120 E-MINI MSCI 신흥국 지수-시카고상업거래소  244742      
 121 10년물 금리 스왑-시카고거래소  246602      
 122 5년물 금리 스왑-시카고거래소  247602      
 123 S&P GSCI 지수-시카고상업거래소  256741      
 124 싱가포르 연료유 스왑-뉴욕상업거래소  26265D       
 125 E-MINI S&P 400 지수-시카고상업거래소  33874A       
 126 GULF JET NY 난방유 스프레드 스왑-뉴욕상업거래소  86465A      x
 127 싱가포르 연료유 가스오일 스프레드 스왑-뉴욕상업거래소  86465C      x
 128 JET CIF NWE/GASOIL 선물-뉴욕상업거래소  86465D      x
 129 걸프 #6 연료 크랙 스왑-뉴욕상업거래소  86565A      x
 130 3.5% 연료 로테르담 크랙 스프레드-뉴욕상업거래소  86565C      x
 131 나프타 크랙 스프레드-뉴욕상업거래소  86665A      x
 132 가스 오일 크랙 스프레드-뉴욕상업거래소  86765C      x


표 3. COT 보고서 심볼쌍 목록


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

파일 첨부됨 |
sources.zip (211.23 KB)
MQL5 이벤트 핸들링: 빠르게 MA 피리어드 바꾸기 MQL5 이벤트 핸들링: 빠르게 MA 피리어드 바꾸기
피리어드가 13인 단일 MA 인디케이터가 차트에 적용되었다고 상상해 봅시다. 피리어드를 20으로 바꾸고 싶은데, 인디케이터 속성 대화 상자에서 13을 20으로 바꾸고 싶지는 않네요. 맨날 쓰는 방법이니까 너무 지루하잖아요. 특히 인디케이터 코드를 열어서 수정하고 싶지가 않습니다. 버튼 하나만 눌러서 해결하고 싶은데요. 키보드의 위쪽 화살표가 딱이겠네요. 이 글에서는 그 방법을 찾아볼게요.
초보자를 위한 실용적인 MQL5 디지털 필터 구현 초보자를 위한 실용적인 MQL5 디지털 필터 구현
자동 매매 시스템 관련 포럼에서 자주 언급되는 것 중 하나가 디지털 필터입니다. 그러니 MQL5에서 사용할 수 있는 디지털 필터 표준 코드를 꼭 제공해 드려야죠. 이 글에서는 '뉴비들을 위한 MQL5 커스텀 인디케이터'에 있는 간단한 SMA 인디케이터 코드를 조금 더 복잡하지만 보편적으로 사용할 수 있는 디지털 필터로 변환하는 법을 알아보겠습니다. 본문의 내용은 직전 글과 이어집니다. 프로그래밍 오류 수정법과 텍스트 변환 방법에 대한 설명 역시 포함되어 있습니다.
그래픽 컨트롤 옵션이 있는 인디케이터 만들기 그래픽 컨트롤 옵션이 있는 인디케이터 만들기
시장 분위기가 무엇인지 안다면 MACD 인디케이터(이동 평균 수렴 확산 지수)도 아실 겁니다. 컴퓨터 분석이 가능해지면서 투자자들이 사용하기 시작한 가격 변동을 파악할 수 있는 아주 뛰어난 분석 도구죠. 이 글에서는 MACD 지표를 어떤 식으로 변형할 수 있는지 알아보고 그래픽 설정 변경이 가능한 하나의 인디케이터로 변형된 MACD 지표를 구현해 보겠습니다.
WCF 서비스를 통해 MetaTrader5에서 .NET 애플리케이션으로 인용문 내보내기 WCF 서비스를 통해 MetaTrader5에서 .NET 애플리케이션으로 인용문 내보내기
MetaTrader5에서 다른 애플리케이션으로 인용문을 내보내고 싶으신가요? MQL5와 DLL이 함께라면 문제 없어요! 이 글은 MetaTrader5에서 .NET 애플리케이션으로 인용문을 내보내는 방법에 대한 설명입니다. 개인적으로는 .NET 플랫폼을 이용하는 게 훨씬 재밌고, 합리적이고, 간편하네요. 안타깝게도 MetaTrader5는 아직 .NET 형식을 지원하지 않기 때문에 예전과 같이 .NET 형식을 지원하는 win32 dll을 중간층으로 사용하겠습니다.