당사 팬 페이지에 가입하십시오
- 조회수:
- 63
- 평가:
- 게시됨:
-
이 코드를 기반으로 한 로봇이나 지표가 필요하신가요? 프리랜스로 주문하세요 프리랜스로 이동
이 라이브러리를 사용하면 *.gz 파일 또는 이 형식으로 압축된 사이트의 응답에서 GZIP 아카이브를 해독할 수 있습니다. 최대 0.5GB의 텍스트가 포함된 파일에 대해 테스트되었습니다.
라이브러리는 4바이트의 플래그를 통해 아카이브가 압축 파일인지 사이트의 압축 데이터인지 자동으로 확인할 수 있으며, 두 번째 경우에는 데이터에 파일 이름이 포함되어 있지 않습니다.
압축 해제를 위한 입력 데이터는 문자 유형의 배열로 표현되어야 합니다.
압축 해제에는 터미널 함수 CryptDecode(CRYPT_ARCH_ZIP, tmp, key, tx)가 사용됩니다;
GZIP 클래스에는 메서드가 포함되어 있습니다:
isGZIP(char& gz[])
- 는 수신된 데이터의 처음 세 문자를 검사하여 GZIP 형식으로 압축되었는지 확인합니다.
이 검사 후, unGZIP 메서드의 오버로드 중 하나를 호출할 수 있습니다:
bool unGZIP(char& gz[], char& tx[], string& fname, bool printTime=false){}
속도와 메모리 소비 측면에서 선호되는 사용 사례입니다. 압축을 푸는 동안 문자 배열 tx가 채워집니다. 그런 다음 이 배열의 데이터를 CSV 또는 JSON 파서로 처리할 수 있습니다. 이렇게 하면 배열을 문자열로 붙인 다음 문자열이나 다른 문자로 나누지 않고도 결과를 얻을 수 있습니다.
그래도 문자열을 가져와야 하는 경우 오버로드 중 하나를 사용할 수 있습니다:
bool unGZIP(char& gz[], string& out, bool printTime=false, uint codepage=CP_ACP){}
언패킹이 성공하면 참을 반환하고, 언패킹된 문자열이 문자열 아웃에 있으면
또는
string unGZIP(char& gz[], bool printTime=false, uint codepage=CP_ACP){}
문자열을 반환합니다. 압축 해제가 실패하면 문자열이 비어 있습니다.
데이터를 하나의 문자열로 연결할 때는 주의해야 합니다.
0.5GB의 데이터가 있는 아카이브의 압축을 풀었다면 문자열에 0.5GB가 더 필요하고, 이를 문자열 배열로 분할하면 0.5GB가 더 필요합니다. 이 모든 작업에는 시간 비용도 추가됩니다.
웹사이트에서 압축된 데이터를 읽은 다음 파일에서 읽는 사용 사례 예시: (이 스크립트는 다운로드용으로 첨부되어 있습니다.)
#property copyright "Copyright 2023, Forester" #property link "https://www.mql5.com" #property version "1.00" #include <GZIP.mqh> GZIP gzip; void OnStart(){ Print("GZipped webpage read sample:"); string url="https://............"; char out[]; if(http_req(url, out,"GET","Accept-Encoding: gzip, deflate\r\n", 1,0)){ if(gzip.isGZIP(out)){ Print("GZIP detected"); string txt; if(!gzip.unGZIP(out, txt, 1, CP_UTF8)){return;}//CP_ACP Print(txt); }else{ Print("No GZIP");Print(CharArrayToString(out, 0, WHOLE_ARRAY, CP_UTF8)); } } Print("File read sample:"); bool is_common=1; string fn="3.csv.gz"; bool is_zip=1; int h; if(is_zip){ h = FileOpen(fn,FILE_READ|FILE_BIN|FILE_READ|(is_common?FILE_COMMON:0)); }else{ h = FileOpen(fn,FILE_READ|FILE_CSV|FILE_ANSI|(is_common?FILE_COMMON:0)); } if( h!=INVALID_HANDLE){ Print ("Start gzip"); char gz[],tx[]; FileReadArray(h, gz); FileClose(h); if(gzip.isGZIP(gz)){ Print("GZIP detected"); string fname; if(!gzip.unGZIP(gz, tx,fname,1)){return;} //string txt; if(!unGZIP(gz, txt, 1, CP_ACP)){return;}//CP_UTF8 //string txt=unGZIP(gz, 1, CP_ACP);if(txt==""){return;} if(fname!=NULL){Print("File name: ",fname,", file size: ",ArraySize(tx));} string t= CharArrayToString(tx,0,100);Print("Filr content: ",t);t= CharArrayToString(tx,ArraySize(tx)-100,100);Print("... ",t); //ulong mcs = GetMicrosecondCount(); //string csvRow[];int columns=0, next=0; char sep=',', newLine='\n'; //while(getCSVRow(tx, csvRow, columns, next, sep, newLine) && !IsStopped()){//다음 행 가져오기 // for(int c=0; c<columns; c++){ //Print(); // } //Print(next); //} //Print("CSV 구문 분석 시간: ",(GetMicrosecondCount()-mcs)," mcs"); //ArrayPrint(csvRow); }else{} } } int getCSVRow(char& csv[], string& outAr[], int& cols, int& next, char& sep, char& newLine){//다음 행 가져오기 for(int i=next; i<ArraySize(csv); i++){ if(csv[i] == newLine){ cols=StringSplit(CharArrayToString(csv,next,i-next),sep,outAr);// 한 줄을 개별적으로 처리 - parseCSV보다 5~10% 빠르며, e는 하나의 큰 배열을 위한 메모리를 가지고 있습니다. next=i+1; return true; } } return false; } bool http_req(string url, char& out[],string method="GET",string headers_request=NULL, bool printTime=false,bool debug=false){ ulong mcs = (printTime?GetMicrosecondCount():0); bool retVal=false; ResetLastError(); char data[];string headers=NULL; int r=WebRequest(method, url, headers_request, 5000, data, out, headers); if(r==-1){Print("Error in WebRequest. Err code =",GetLastError());MessageBox("It is necessary to add the address '"+url+"' to the list of allowed URLs in the 'Advisors' tab","Error",MB_ICONINFORMATION);} else{if(r==200){ retVal= true; }else{PrintFormat("Download error '%s', responce code %d",url,r);Print("Error in WebRequest. Err code =",GetLastError());}}if(debug){PrintFormat("Responce headers: %s\r\nResponce:",headers);Print(CharArrayToString(out));}// if(printTime){Print("WebRequest time: ",(GetMicrosecondCount()-mcs)," mcs");} return retVal; }
이 예에서는 파일 폴더에서 파일을 읽고 배열로 압축을 해제합니다.
압축이 풀린 파일의 처음과 마지막 100자가 인쇄됩니다.
그런 다음 배열을 CSV 또는 JSON 파서로 보낼 수 있습니다. JSON의 경우 kodobase에 JASON 라이브러리가 있습니다. 이 라이브러리는 문자 배열로 받은 데이터를 파싱할 수 있습니다.
120MB의 압축된 CSV 파일을 풀었을 때의 출력 예시, 소스 파일은 463MB입니다:
2025.05.12 15:08:40.510 GZipped webpage read sample:
2025.05.12 15:08:41.319 WebRequest time: 809637 mcs
2025.05.12 15:08:41.319 GZIP detected
2025.05.12 15:08:41.319 UnGZIP time: 3 mcs
2025.05.12 15:08:41.319 {"retCode":0,"retMsg":"OK","result":{"category":"linear","list":[... Юя
2025.05.12 15:08:41.319 File read sample:
2025.05.12 15:08:41.320 Start gzip
2025.05.12 15:08:41.384 GZIP detected
2025.05.12 15:08:42.582 UnGZIP time: 1198136 mcs
2025.05.12 15:08:42.593 File name: BTCUSD2025-05-09.csv, file size: 486006135
2025.05.12 15:08:42.593 Filr content: timestamp,symbol,side,size,price,tickDirection,trdMatchID,grossValue,homeNotional,foreignNotional,RP
2025.05.12 15:08:42.593 ... 36.00,ZeroPlusTick,e92fbea7-1471-591e-95f7-4dc0edde771c,971.4774228646926,1,9.714774228646926e-06,0
압축을 푸는 데 약 1.2초가 걸렸습니다.
MetaQuotes Ltd에서 러시아어로 번역함.
원본 코드: https://www.mql5.com/ru/code/59309

ADX(평균 방향성 지수) 평활화 인디케이터는 이중 지수 평활화 필터를 적용하여 표준 ADX를 향상시켜 노이즈를 줄이고 보다 선명한 추세 신호를 제공합니다. 평활화된 +DI(파란색), -DI(빨간색), 기본 ADX 선(녹색) 등 세 개의 선이 표시됩니다. 이 개선된 버전은 트레이더가 잘못된 신호를 줄이면서 추세 강도와 잠재적 방향 변화를 식별하는 데 도움이 됩니다. 이 인디케이터는 기존 추세를 확인하고 실제 가격 반전이 일어나기 전에 모멘텀 약화를 경고하는 데 탁월하므로 추세 추종 전략과 최적의 진입/청산 시점을 결정하는 데 유용합니다.

현재 스프레드 값, 주문 중지까지의 최소 거리(스톱 레벨), 거래 동결까지의 거리(동결 레벨)를 표시합니다.