//+------------------------------------------------------------------+ //| CustomRatesReplace.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #define CUSTOM_SYMBOL_NAME Symbol()+".C" // 사용자 지정 심볼명 #define CUSTOM_SYMBOL_PATH "Forex" // 심볼을 생성할 그룹 명 #define CUSTOM_SYMBOL_ORIGIN Symbol() // 사용자 정의 심볼의 기반이 되는 심볼 명 #define DATARATES_COUNT 4 // 저널에 보내진 바의 개수 //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- 사용자 정의 심볼을 생성할 때 오류 코드를 가져옵니다. int create=CreateCustomSymbol(CUSTOM_SYMBOL_NAME, CUSTOM_SYMBOL_PATH, CUSTOM_SYMBOL_ORIGIN); //--- 오류 코드가 0(심볼 생성 성공)도 아니고 5304(심볼이 이미 생성됨)도 아닌 경우 - 그대로 둠 if(create!=0 && create!=5304) return; //--- 표준 심볼 바의 개수를 가져옵니다. int bars=Bars(CUSTOM_SYMBOL_ORIGIN, PERIOD_M1); //--- 표준 심볼 분 시간대의 모든 바의 데이터를 MqlRates 배열로 가져옵니다. MqlRates rates[]={}; ResetLastError(); if(CopyRates(CUSTOM_SYMBOL_ORIGIN, PERIOD_M1, 0, bars, rates)!=bars) { PrintFormat("CopyRates(%s, PERIOD_M1, 0, %d) failed. Error %d", CUSTOM_SYMBOL_ORIGIN, bars, GetLastError()); return; } //--- 복사된 데이터를 사용자 정의 심볼의 분 히스토리로 설정합니다. ResetLastError(); if(CustomRatesUpdate(CUSTOM_SYMBOL_NAME, rates)<0) { PrintFormat("CustomRatesUpdate(%s) failed. Error %d", CUSTOM_SYMBOL_NAME, GetLastError()); return; } //--- 과거 데이터를 업데이트한 후 사용자 정의 심볼의 바의 개수를 가져옵니다. bars=Bars(CUSTOM_SYMBOL_NAME, PERIOD_M1); //--- 사용자 정의 심볼 분 시간대의 모든 바의 데이터를 MqlRates 배열로 가져옵니다. ResetLastError(); if(CopyRates(CUSTOM_SYMBOL_NAME, PERIOD_M1, 0, bars, rates)!=bars) { PrintFormat("CopyRates(%s, PERIOD_M1, 0, %d) failed. Error %d", CUSTOM_SYMBOL_NAME, bars, GetLastError()); return; } //--- 저널에 있는 사용자 정의 심볼 분 히스토리의 마지막 DATARATES_COUNT 바를 출력합니다. int digits=(int)SymbolInfoInteger(CUSTOM_SYMBOL_NAME, SYMBOL_DIGITS); PrintFormat("Last %d bars of the custom symbol's minute history:", DATARATES_COUNT); ArrayPrint(rates, digits, NULL, bars-DATARATES_COUNT, DATARATES_COUNT); //--- 사용자 정의 기호 분 히스토리에서 어미에서 두 번째 데이터 바를 변경합니다. datetime time_from= rates[bars-3].time; datetime time_to = rates[bars-2].time; //--- 끝에서 두 번째 바의 모든 가격을 'rates' 배열에 있는 이 바의 시가와 동일하게 만듭니다. rates[bars-3].high=rates[bars-3].open; rates[bars-3].low=rates[bars-3].open; rates[bars-3].close=rates[bars-3].open; rates[bars-2].high=rates[bars-2].open; rates[bars-2].low=rates[bars-2].open; rates[bars-2].close=rates[bars-2].open; //--- 기존 바를 수정된 'rates' 배열의 데이터로 바꿉니다. ResetLastError(); int replaced=CustomRatesUpdate(CUSTOM_SYMBOL_NAME, rates); if(replaced<0) { PrintFormat("CustomRatesUpdate(%s) failed. Error %d", CUSTOM_SYMBOL_NAME, GetLastError()); return; } //--- 과거 데이터의 두 바를 변경한 후 사용자 정의 심볼 바의 개수를 다시 가져옵니다. bars=Bars(CUSTOM_SYMBOL_NAME, PERIOD_M1); //--- 사용자 정의 심볼 분 �Q 주기의 모든 바의 데이터를 다시 가져옵니다. ResetLastError(); if(CopyRates(CUSTOM_SYMBOL_NAME, PERIOD_M1, 0, bars, rates)!=bars) { PrintFormat("CopyRates(%s, PERIOD_M1, 0, %d) failed. Error %d", CUSTOM_SYMBOL_NAME, bars, GetLastError()); return; } //--- 저널에 업데이트된 사용자 정의 바 분 히스토리의 마지막 DATARATES_COUNT 바를 인쇄합니다. PrintFormat("\nLast %d bars after applying CustomRatesUpdate() with %d replaced bars:", DATARATES_COUNT, replaced); ArrayPrint(rates, digits, NULL, bars-DATARATES_COUNT, DATARATES_COUNT); //--- 차트 주석에 스크립트 종료 키에 대한 힌트를 표시합니다. Comment(StringFormat("Press 'Esc' to exit or 'Del' to delete the '%s' symbol and exit", CUSTOM_SYMBOL_NAME)); //--- Esc 또는 Del 키를 눌러 무한 루프를 종료할 때까지 기다립니다. while(!IsStopped() && TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)==0) { Sleep(16); //--- Del 키를 누르면 생성된 사용자 정의 심볼 및 해당 데이터가 삭제됩니다. if(TerminalInfoInteger(TERMINAL_KEYSTATE_DELETE)<0) { //--- 바 데이터 삭제 int deleted=CustomRatesDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX); if(deleted>0) PrintFormat("%d history bars of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME); //--- 틱 데이터 삭제 deleted=CustomTicksDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX); if(deleted>0) PrintFormat("%d history ticks of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME); //--- 심볼 삭제 if(DeleteCustomSymbol(CUSTOM_SYMBOL_NAME)) PrintFormat("Custom symbol '%s' deleted successfully", CUSTOM_SYMBOL_NAME); break; } } //--- 종료하기 전에 차트를 삭제 Comment(""); /* 결과: 사용자 정의 심볼 분 히스토리의 마지막 4개 바: [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2024.07.29 13:37:00 1.08394 1.08396 1.08388 1.08390 16 1 0 [1] 2024.07.29 13:38:00 1.08389 1.08400 1.08389 1.08398 35 1 0 [2] 2024.07.29 13:39:00 1.08398 1.08410 1.08394 1.08410 29 1 0 [3] 2024.07.29 13:40:00 1.08409 1.08414 1.08408 1.08414 14 1 0 250820개의 바에 대체된 CustomRatesUpdate()를 적용한 후 마지막 4개 바: [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2024.07.29 13:37:00 1.08394 1.08396 1.08388 1.08390 16 1 0 [1] 2024.07.29 13:38:00 1.08389 1.08389 1.08389 1.08389 35 1 0 [2] 2024.07.29 13:39:00 1.08398 1.08398 1.08398 1.08398 29 1 0 [3] 2024.07.29 13:40:00 1.08409 1.08414 1.08408 1.08414 14 1 0 */ } //+------------------------------------------------------------------+ //| Create a custom symbol, return an error code | //+------------------------------------------------------------------+ int CreateCustomSymbol(const string symbol_name, const string symbol_path, const string symbol_origin=NULL) { //--- 사용자 정의 심볼의 기반이 될 심볼명을 정의합니다. string origin=(symbol_origin==NULL ? Symbol() : symbol_origin); //--- 사용자 정의 심볼 생성에 실패했고 오류 5304가 아닌 경우 저널에 이를 보고합니다. ResetLastError(); int error=0; if(!CustomSymbolCreate(symbol_name, symbol_path, origin)) { error=GetLastError(); if(error!=5304) PrintFormat("CustomSymbolCreate(%s, %s, %s) failed. Error %d", symbol_name, symbol_path, origin, error); } //--- 성공 return(error); } //+------------------------------------------------------------------+ //| Remove a custom symbol | //+------------------------------------------------------------------+ bool DeleteCustomSymbol(const string symbol_name) { //--- 종합시세 창에서 심볼 숨기기 ResetLastError(); if(!SymbolSelect(symbol_name, false)) { PrintFormat("SymbolSelect(%s, false) failed. Error %d", GetLastError()); return(false); } //--- 사용자 정의 심볼 삭제에 실패한 경우 이를 저널에 보고하고 'false'를 반환합니다. ResetLastError(); if(!CustomSymbolDelete(symbol_name)) { PrintFormat("CustomSymbolDelete(%s) failed. Error %d", symbol_name, GetLastError()); return(false); } //--- 성공 return(true); } |