通过该库,您可以从 *.gz 文件中解密 GZIP 压缩包,或从使用这种格式压缩的网站中解密响应。已对最多包含 0.5 GB 文本的文件进行了测试。
程序库可通过第 4 个字节中的标志自动检查存档是压缩文件还是来自网站的压缩数据,在第二种情况下,数据不包含文件名。
用于解压缩的输入数据必须用 char 类型的数组表示。
终端函数 CryptDecode(CRYPT_ARCH_ZIP, tmp, key, tx) 用于解压缩;
GZIP 类包含以下方法
isGZIP(char& gz[])
- 对接收到的数据的前三个字符进行检查,以确定它是否是 GZIP 格式压缩的。
检查完成后,可以调用 unGZIP 方法的重载之一:
bool unGZIP(char& gz[], char& tx[], string& fname, bool printTime=false){}
就速度和内存消耗而言,unGZIP 是首选的使用情况。在解压缩过程中,字符数组 tx 将被填充。然后可以用 CSV 或 JSON 解析器处理其中的数据。这样,我们就能得到结果,而无需将数组粘合成字符串,然后再用字符串或其他字符进行分割。
如果仍然需要获取字符串,可以使用其中一个重载:
bool unGZIP(char& gz[], string& out, bool printTime=false, uint codepage=CP_ACP){}
如果解包成功,且解包后的字符串在字符串输出中,则返回 true
或
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;} //字符串 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(); //字符串 csvRow[];int columns=0, next=0; char sep=',', newLine='\n'; //while(getCSVRow(tx, csvRow, columns, next, sep, newLine) && !IsStopped()){//get next row // 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);// 分别处理 1 行 - 比 parseCSV 快 5-10%,而且 e 的内存可容纳 1 个大数组。 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 个字符和后 100 个字符将被打印出来。
然后,可以将数组发送给 CSV 或 JSON 解析器。对于 JSON,kodobase 中有一个 JASON 库。它可以解析以字符数组形式接收的数据。
解压 120 MB 压缩 CSV 文件时的输出示例,源文件为 463 MB:
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 主线(绿色)。这一改进版本可帮助交易者识别趋势强度和潜在方向变化,减少错误信号。该指标擅长确认既定趋势,并在实际价格反转之前发出动能减弱的警告,因此对趋势跟踪策略和确定最佳进出场点都很有价值。

此 MQL5 自定义指标可检测价格行为与威严震荡指标 (AO) 之间的背离,从而发出潜在市场反转或持续的信号。它在图表上绘制买入/卖出箭头,将 AO 显示为柱状图,并绘制趋势线以突出显示背离。

AutoCloseOnProfitLoss 智能交易系统(EA)是 MetaTrader 5 的一款功能强大的自动化工具,可在达到预定的盈利或亏损目标时关闭所有未结头寸。

用于监控单一符号的多头和空头掉期的简单实用程序。如果您的经纪商指定的掉期以点数而不是账户货币计算,该工具会自动将点数转换为账户货币。周三掉期为三倍。可在输入中调整水平和垂直对齐方式。