价格行为分析工具包开发(第34部分):借助高级数据采集管道将原始市场数据转化为预测模型
引言
价格行为和未来价格轨迹完全依赖于历史表现:关键支撑位和阻力位从过去的价格波动中固化形成,而暴涨暴跌交易者常常发现自己被突然的尖峰行情打乱节奏 —— 或者为时已晚,无法抓住行情。如果没有系统化的方法来收集、处理过去的数据并从中学习,每一笔交易都只是猜测。
在本期 "价格行为分析工具包开发" 中,我们推出一个端到端框架,通过机器学习将原始的 MetaTrader 5 历史数据转化为高精度的实时交易信号。引擎的两部分协同工作:
MQL5 数据获取
- 自动化分块: 挂载在任意 MetaTrader 5 图表上的轻量级脚本,将多品种 K 线历史切割为大小安全的 JSON 载荷。如果数据块超过 14 MiB,它会动态将分块大小减半 —— 因此您永远不会触及 MetaTrader 5 的上传限制,也无需再手动导出 CSV。
- 可靠传输: 每个载荷通过 WebRequest 以 POST 方式发送,内置重试机制和详细日志。您可以获得关于分块范围、HTTP 状态码和任何错误的清晰反馈,确保训练集中没有数据缺口。
Python 机器学习后端
- 统一特征矩阵: 传入的历史数据和智能交易系统生成的日志被合并并向量化为单一表格,计算尖峰幅度、MACD 背离、RSI、ATR、卡尔曼推导的趋势斜率、包络带,以及基于 Prophet 的未来差值 —— 全部在一处完成。
- 异步模型编译与缓存: Prophet 模型每个品种拟合一次(缓存一小时),梯度提升分类器按需训练,因此实时分析永远不会停滞。如果个别品种数据稀疏,全局回退模型可确保覆盖。
- 全面的 API 与命令行界面: Flask 端点(/upload_history、/upload_spike_csv、/analyze)处理批量历史回填、实时采集循环和实时信号请求,而统一的命令行界面涵盖历史导入、训练、回测和诊断。
在任何模型学会预判暴涨暴跌尖峰之前,它需要可靠的、大容量的历史数据。历史数据获取模块是我们的数据主力:
- 与图表无关的一致性: 无论您测试哪个品种或周期(M1、H1 等),提供相同的品种和时间周期选择参数将始终返回相同的数据集 —— 这是可复现研究的必要条件。
- 大小限制合规: 每个 JSON 载荷保持在 14 MiB 以下,永远不会冒触及 MetaTrader 5 16 MiB 上限或数据发送不完整的风险。
- 低延迟运行: 即使 20,000 根 K 线也能在远低于一秒的时间内上传完成,使得批量历史回填和实时轮询都可行,且不会拖慢 MetaTrader 5。
- 集中日志与审计: 打印输出显示分块索引、载荷大小、HTTP 响应详情和重试次数 —— 因此您可以精确追踪哪些数据在何时到达了您的 Python 引擎。
有了这个基础,我们的管道保证了丰富、一致的历史数据供给,这是训练模型所必需的 —— 这些模型能够在价格尖峰让您措手不及之前检测到它们并采取行动。
后续章节预告:
- 我们将剖析特征工程套件,展示如何将原始 K 线转化为预测输入。
- 深入探讨模型训练、缓存策略和性能调优。
- 演示如何将这些模型部署回 MetaTrader 5,用于图表上的信号提醒和交易执行。
在本系列结束时,您将拥有一个坚如磐石、全自动化的工具包 —— 从历史数据采集到实时机器学习驱动的交易信号,旨在让您在快速变化的暴涨暴跌市场中获得优势。
实现
MQL5 数据获取
本节说明如何在 MQL5 中实现数据获取;请按照以下分步说明将其集成到您的项目中。
脚本元数据与输入参数
脚本顶部声明了版权、版本和作者等元数据,随后是用户可配置的输入参数。这些包括:
- DaysBack:要获取多少天的历史数据。
- Timeframe:图表时间周期(例如 M1)。
- StartChunkBars:尝试发送的初始数据切片大小。
- Timeout_ms:等待 Python 服务器响应的时长。
- MaxRetry:POST 失败时的重试次数。
- PauseBetween_ms:POST 请求之间的暂停时长。
- PythonURL:本地 Python 服务器端点地址。
这些输入参数使脚本能够适应各种需求和网络环境。
#property strict #property script_show_inputs #property version "1.0" input int DaysBack = 120; // how many days of history to fetch input ENUM_TIMEFRAMES Timeframe = PERIOD_M1; // timeframe for bars input int StartChunkBars = 5000; // initial slice size (bars) input int Timeout_ms = 120000; // WebRequest timeout in ms input int MaxRetry = 3; // retry attempts per chunk input int PauseBetween_ms = 200; // gap between chunk posts input string PythonURL = "http://127.0.0.1:5000/upload_history";
常量与内联辅助函数
设置了几个#define常量,用于控制最大 JSON 大小(MAX_BYTES)和最小分块大小(MIN_CHUNK)。然后定义了辅助函数,如 L2S(长整型转字符串)和 D2S(双精度浮点数转字符串),用于格式化数值。add()函数将值追加到正在构建的 JSON 字符串中,并可选择添加逗号,简化脚本后续的 JSON 构建过程。
#define MAX_BYTES 14000000 // keep under MT5’s 16 MiB limit #define MIN_CHUNK 1000 // don’t slice smaller than this many bars inline string L2S(long v) { return StringFormat("%I64d", v); } inline string D2S(double v) { return StringFormat("%.5f", v); } void add(string& s, const string v, bool comma) { s += v; if(comma) s += ","; }
JSON 构建函数
BuildJSON()函数从历史数据数组(时间、收盘价、最高价、最低价)的切片构建 JSON 字符串。它构建一个整洁的 JSON 结构,表示从from到to的一段历史 K 线,适合发送到 Python 后端。这种方法确保了数据一致性和紧凑性,同时使每个分块可独立序列化。
string BuildJSON( const string& sym, const long& T[], const double& C[], const double& H[], const double& L[], int from, int to ) { // start JSON with symbol & time array string j = "{\"symbol\":\"" + sym + "\",\"time\":["; for(int i = from; i < to; i++) add(j, L2S(T[i]), i < to - 1); j += "],\"close\":["; // append close prices for(int i = from; i < to; i++) add(j, D2S(C[i]), i < to - 1); // likewise for high j += "],\"high\":["; for(int i = from; i < to; i++) add(j, D2S(H[i]), i < to - 1); // and low j += "],\"low\":["; for(int i = from; i < to; i++) add(j, D2S(L[i]), i < to - 1); j += "]}"; return j; }
带重试逻辑的 POST 发送函数
PostChunk()负责使用 WebRequest 将 JSON 分块发送到 Python 服务器。它构建 HTTP 头,将 JSON 转换为字节数组,并在连接失败或 HTTP 错误时处理最多 MaxRetry 次重试。每次尝试都会记录状态信息,便于调试传输失败。如果所有重试都失败,跳过该分块并中止进程。
bool PostChunk(const string& json, int from, int to) { // convert the JSON string into a UTF‑8 char array char body[]; StringToCharArray(json, body, 0, StringLen(json), CP_UTF8); char reply[]; string hdr = "Content-Type: application/json\r\n", rep_hdr; for(int r = 1; r <= MaxRetry; r++) { int http = WebRequest("POST", PythonURL, hdr, Timeout_ms, body, reply, rep_hdr); if(http != -1 && http < 400) { PrintFormat("Chunk %d-%d HTTP %d %s", from, to, http, CharArrayToString(reply, 0, WHOLE_ARRAY, CP_UTF8)); return true; } // on failure, log and retry PrintFormat("Chunk %d-%d retry %d failed (http=%d err=%d)", from, to, r, http, GetLastError()); Sleep(500); } return false; }
OnStart () 中的主逻辑
主程序首先记录上传器已就绪,然后根据当前服务器时间和DaysBack参数推导出请求的历史时间窗口(t1...t2)。使用CopyRates()获取该窗口的 OHLC 数据,并将结果拆分为单独的数组 —— 时间戳、收盘价、最高价和最低价 —— 以便信息可以高效序列化。
K 线数据分块传输。循环从用户定义的StartChunkBars大小开始,通过BuildJSON()将该切片转换为 JSON 载荷,并验证载荷小于 MAX_BYTES。如果载荷超过限制,将分块大小减半,直到载荷符合大小要求或达到回退阈值 MIN_CHUNK。符合要求的分块通过PostChunk()发送到 Python 后端,脚本暂停 PauseBetween_ms 时长,然后继续处理下一个切片。
int OnStart() { Print("History Ingestor v1.0 ready (timeout=", Timeout_ms, " ms)"); datetime t2 = TimeCurrent(); datetime t1 = t2 - (datetime)DaysBack * 24 * 60 * 60; // 1) Pull bar history from MT5 MqlRates r[]; int total = CopyRates(_Symbol, Timeframe, t1, t2, r); if(total <= 0) { Print("CopyRates error ", GetLastError()); return INIT_FAILED; } ArraySetAsSeries(r, false); // 2) Unpack into simple arrays long T[]; double Cl[], Hi[], Lo[]; ArrayResize(T, total); ArrayResize(Cl, total); ArrayResize(Hi, total); ArrayResize(Lo, total); for(int i = 0; i < total; i++) { T[i] = r[i].time; Cl[i] = r[i].close; Hi[i] = r[i].high; Lo[i] = r[i].low; } // 3) Loop over the data in chunks for(int i = 0; i < total;) { int step = StartChunkBars; bool sent = false; // adaptively shrink chunk until it fits while(step >= MIN_CHUNK) { int to = MathMin(total, i + step); string js = BuildJSON(_Symbol, T, Cl, Hi, Lo, i, to); double size = double(StringLen(js)) / 1e6; PrintFormat("Testing %d–%d size=%.2f MB", i, to, size); if(StringLen(js) < MAX_BYTES) { // post & advance index if(!PostChunk(js, i, to)) return INIT_FAILED; i = to; sent = true; Sleep(PauseBetween_ms); break; } step /= 2; } // abort if even the minimum chunk is too big if(!sent) { Print("Unable to fit minimum chunk – aborting"); return INIT_FAILED; } } Print("Upload finished: ", total, " bars."); return INIT_SUCCEEDED; }
要在 MetaEditor 中设置 "历史数据获取器",打开 MetaTrader 5 并按 F4 启动 MetaEditor,然后选择:
文件 → 新建 → MQL5 脚本
为其命名(例如 HistoryIngestor)并完成向导;用完整代码(包括 #property 声明和 OnStart 函数)替换生成的模板,保存到 Scripts 文件夹,按 F7 编译 —— 确认 "0 错误,0 警告"。回到 MetaTrader 5 的导航器,在脚本下找到 HistoryIngestor,将其拖到图表上,在输入对话框中调整参数,如:
DaysBack、Timeframe、分块大小、超时和 PythonURL
请确保在以下位置允许您的 PythonURL 域名:
工具 → 选项 → 专家顾问
这是 WebRequest 调用所必需的,并确保加载了足够的图表历史数据,以便 CopyRates 可以获取请求的 K 线。点击确定后,监控 "专家" 和 "日志" 选项卡,查看上传进度以及任何重试或错误消息。
Python 机器学习后端
该系统依赖一系列 Python 库(包括用于尖峰检测的模型),但本文主要关注数据采集;其他组件将在后续文章中介绍。以下是第三方库的完整列表及其用途,随后是使用的标准库模块:
第三方库
- numpy, pandas:数组和 DataFrame 处理
- pyarrow(或 fastparquet):列式数据序列化
- flask:轻量级 Web API
- MetaTrader5:市场数据获取
- ta:技术分析指标
- scikit-learn, joblib:模型训练与持久化
- prophet, cmdstanpy:时间序列预测
- pykalman:卡尔曼滤波
- pytz:时区支持
您可以使用以下命令安装它们:
pip install numpy pandas pyarrow flask MetaTrader5 ta scikit-learn \ joblib prophet cmdstanpy pykalman pytz
安装 prophet 时会自动拉取 tqdm、holidays 和 lunarcalendar 等依赖。
内置库(无需安装):
os, sys, logging, warnings, argparse, threading, io, datetime, pathlib, typing, time
| 包 | 在脚本中的用途 | 使用位置 |
|---|---|---|
| Numpy | 大型数组的向量化数学运算;Pandas、TA-lib、scikit-learn 的基础 | 所有特征辅助函数(np.diff、np.std、predict_proba 等) |
| pandas | 时间序列 DataFrame、快速 CSV/Parquet 读写、滚动窗口 | /upload_history 中构建 DataFrame、去重、特征工程、模型训练、回测 |
| pyarrow (or fastparquet) | df.to_parquet ()/read_parquet () 的引擎;比 CSV 更小更快,保留纳秒级时间戳 | 按品种存储上传历史到磁盘 |
| flask | 轻量级 HTTP 服务器,提供 /upload_history、/upload_spike_csv、/analyze 端点,JSON 与 Python 互转 | 所有 REST 端点 |
| MetaTrader 5 | 无头 MetaTrader 5 终端的 Python 桥接:登录、copy_rates_range、品种订阅 | 历史导入、实时 collect_loop、回测器 |
| ta | 纯 Python 技术分析指标(MACD、RSI、ATR) | macd_div、rsi_val、offline_atr 特征 |
| scikit-learn | 机器学习核心(StandardScaler + GradientBoostingClassifier + Pipeline) | 模型训练、/analyze 和回测中的概率推理 |
| joblib | scikit 模型的快速(反)序列化;实现按品种模型缓存 | 所有读写 models/*.pkl 的 joblib.dump/load |
| cmdstanpy | Prophet 编译到的 Stan 后端;没有它 Prophet 无法拟合 | Prophet 在 fit () 期间间接导入 |
| pykalman | 线性卡尔曼滤波平滑;返回最后 5 根 K 线斜率 | kalman_slope () 特征 |
| pytz | datetime 对象的显式 UTC 本地化,避免经纪商时间与系统时间混淆 | 历史 / 回测范围转换 |
| prophet | 低频趋势预测;提供 "delta" 特征(未来价格估计) | prophet_delta () 辅助函数和异步编译缓存 |
接下来,我们将深入研究处理数据收集和存储的代码部分 —— 就在模型训练之前。
通过 WebRequest 接收 MetaTrader 5 历史数据
在 Python 端,设置了一个轻量级 Flask API(通常运行在http://127.0.0.1:5000/upload_history)来处理传入的 HTTP POST 请求。当 MQL5 脚本 POST 包含历史数据(品种名称、时间戳、OHLC 数组)的 JSON 载荷时,该 Flask 端点解析并验证数据。这避免了手动 CSV 处理,确保 Python 后端可以使用上传器从任何 MetaTrader 5 图表或 EA 脚本自动实时接收数据。
@app.route('/upload_history', methods=['POST']) def upload_history(): data = request.get_json() df = pd.DataFrame({ 'time': pd.to_datetime(data['time'], unit='s'), 'close': data['close'], 'high': data['high'], 'low': data['low'] }) symbol = data['symbol'] os.makedirs('uploaded_history', exist_ok=True) df.to_parquet(f'uploaded_history/{symbol}.parquet', index=False) return jsonify({"status": "ok", "rows": len(df)})
数据存储与预处理
接收后,JSON 载荷被解析为 Pandas DataFrame,并可选地存储在本地文件(如.parquet、.csv 或.feather)或写入时间序列数据库。这提供了持久性,允许系统根据需要重放过去的市场状况。获取的 K 线数据经过清洗、去重和时间戳索引,确保重复上传或会话间行为一致。预处理还可能包括时区标准化或零成交量 K 线过滤。
def load_preprocess(symbol): df = pd.read_parquet(f'uploaded_history/{symbol}.parquet') df.drop_duplicates(subset='time', inplace=True) df.set_index('time', inplace=True) return df
特征工程管道
原始 OHLC 历史被转换为丰富的特征矩阵,包含经典技术指标和机器学习相关指标。这些特征可能包括尖峰幅度(自定义公式)、MACD 值、RSI、ATR、卡尔曼滤波斜率和 Prophet 生成的趋势差值。这些特征使模型能够理解短期波动率和长期趋势背景 —— 这对于正确预测价格尖峰或显著突破至关重要。
def generate_features(df): df['return'] = df['close'].pct_change() df['volatility'] = df['return'].rolling(10).std() df['range'] = df['high'] - df['low'] df['spike'] = (df['range'] > df['range'].rolling(50).mean() * 2).astype(int) return df.dropna()
按品种模型缓存与管理
对于每个获取的品种,Python 系统维护一个按品种的机器学习模型。这些模型要么使用上传的历史数据全新训练,要么增量更新。它们通过 joblib、Pickle 或 ONNX 序列化,并存储在专用缓存中。这种设计使得在需要输出信号时可以轻松加载每个品种的最新模型,同时实现可复现性和速度。
def train_model(symbol, df): X = df[['return', 'volatility', 'range']] y = df['spike'] model = RandomForestClassifier(n_estimators=100) model.fit(X, y) os.makedirs('models', exist_ok=True) joblib.dump(model, f'models/{symbol}_model.pkl') return model
训练与推理的命令行和 API 访问
Python 工具提供命令行工具(例如python train.py --symbol BOOM500)和实时 Flask 端点(例如 /predict),用于触发模型训练、运行回测或获取实时预测。这种双接口支持批处理操作以及与 EA 或仪表板的实时集成。例如,模型训练完成后,MQL5 EA 可以稍后查询 /predict 端点并接收 "买入"、"卖出" 或 "无操作" 信号。
@app.route('/predict', methods=['POST']) def predict(): data = request.get_json() features = pd.DataFrame([data['features']]) model = joblib.load(f"models/{data['symbol']}_model.pkl") prediction = model.predict(features)[0] return jsonify({'signal': 'BUY' if prediction == 1 else 'NO ACTION'})
历史回填、重训练与持续学习
该系统也可以连续模式运行 —— 监听新的历史切片或实时 K 线的到达,并触发定期重训练或信号生成。这支持自适应模型随着市场行为演变保持最新,这在 Boom/Crash 等合成品种中特别有价值,它们的波动率或尖峰频率可能随时间变化。
def backfill_and_train(symbol): df = load_preprocess(symbol) df = generate_features(df) train_model(symbol, df)
日志、监控与调试工具
为支持透明度,Python 端记录每次上传、特征生成步骤、模型训练事件和提供的信号。这些日志可选地保存到文件或外部仪表板。这使得管道可审计,帮助追踪模型行为,并确保开发者和交易者都能理解为什么做出某些预测。
def log_upload(symbol, rows): logging.info(f"{symbol} upload received with {rows} rows.")
历史数据获取
在本节中,我将演示我们的自动化系统如何运行。在 MetaTrader 5 和 Python 端配置好环境后,我们首先使用命令提示符导航到 Python 脚本所在的目录:您的文件夹路径C:\Users\hp>cd C:\Users\hp\Pictures\Saved Pictures\Analysis EA然后使用以下命令启动服务器: python script_name.py serve您应该看到服务器成功启动 —— 在我的案例中,控制台显示如下:
* Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000
服务器启动并运行后,只需将脚本拖到 MetaTrader 5 图表上 —— 数据获取和集成将立即开始。

MetaTrader 5 专家选项卡日志:
2025.07.28 22:37:58.239 History Ingestor (Crash 1000 Index,M1) HistoryUploader v3.20 (timeout=120000 ms) ready 2025.07.28 22:37:58.365 History Ingestor (Crash 1000 Index,M1) Test 0-5000 size=0.22 MB 2025.07.28 22:38:01.895 History Ingestor (Crash 1000 Index,M1) Chunk 0-5000 HTTP 200 {"rows_written":4990,"status":"ok"} 2025.07.28 22:38:01.895 History Ingestor (Crash 1000 Index,M1) 2025.07.28 22:38:02.185 History Ingestor (Crash 1000 Index,M1) Test 5000-10000 size=0.22 MB 2025.07.28 22:38:07.794 History Ingestor (Crash 1000 Index,M1) Chunk 5000-10000 HTTP 200 {"rows_written":4990,"status":"ok"} 2025.07.28 22:38:07.794 History Ingestor (Crash 1000 Index,M1) 2025.07.28 22:38:08.118 History Ingestor (Crash 1000 Index,M1) Test 10000-15000 size=0.22 MB 2025.07.28 22:38:13.531 History Ingestor (Boom 1000 Index,M1) HistoryUploader v3.20 (timeout=120000 ms) ready 2025.07.28 22:38:13.677 History Ingestor (Boom 1000 Index,M1) Test 0-5000 size=0.24 MB 2025.07.28 22:38:17.710 History Ingestor (Boom 1000 Index,M1) Chunk 0-5000 HTTP 200 {"rows_written":4990,"status":"ok"}
Python 控制台日志如下:
Crash 1000 Index 4990 rows 22:38:01 INFO 127.0.0.1 - - [28/Jul/2025 22:38:01] "POST /upload_history HTTP/1.1" 200 - 22:38:01 DEBUG cmd: where.exe tbb.dll cwd: None 22:38:02 DEBUG Adding TBB (C:\Users\hp\AppData\Local\Programs\Python\Python313\Lib\site-packages\ prophet\stan_model\cmdstan-2.33.1\stan\lib\stan_math\lib\tbb) to PATH 22:38:02 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\0j91e5cb.json 22:38:02 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\lzpoq1nb.json 22:38:02 DEBUG idx 0 22:38:02 DEBUG running CmdStan, num_threads: None 22:38:02 DEBUG CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313 \\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=46049', 'data', 'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\0j91e5cb.json', 'init=C:\\Users\\hp\\ AppData\\Local\\Temp\\tmpjw4u6es7\\lzpoq1nb.json', 'output', 'file=C:\\Users\\hp\\AppData\\ Local\\Temp\\tmpjw4u6es7\\prophet_modelo4ioyzqc\\prophet_model-20250728223802.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000'] 22:38:02 - cmdstanpy - INFO - Chain [1] start processing 22:38:02 INFO Chain [1] start processing 22:38:07 DEBUG cmd: where.exe tbb.dll cwd: None Crash 1000 Index 4990 rows 22:38:07 INFO 127.0.0.1 - - [28/Jul/2025 22:38:07] "POST /upload_history HTTP/1.1" 200 - 22:38:07 DEBUG TBB already found in load path 22:38:07 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\flzd3tj5.json 22:38:08 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\et_obcyf.json 22:38:08 DEBUG idx 0 22:38:08 DEBUG running CmdStan, num_threads: None 22:38:08 DEBUG CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313 \\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=15747', 'data' , 'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\flzd3tj5.json', 'init=C:\\Users\\hp \\AppData\\Local\\Temp\\tmpjw4u6es7\\et_obcyf.json', 'output', 'file=C:\\Users\\hp\\AppData\\ Local\\Temp\\tmpjw4u6es7\\prophet_modelgjfhjsn1\\prophet_model-20250728223808.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000'] 22:38:08 - cmdstanpy - INFO - Chain [1] start processing 22:38:08 INFO Chain [1] start processing 22:38:10 - cmdstanpy - INFO - Chain [1] done processing 22:38:10 INFO Chain [1] done processing 22:38:10 INFO Prophet compiled for Crash 1000 Index 22:38:15 - cmdstanpy - INFO - Chain [1] done processing 22:38:15 INFO Chain [1] done processing 22:38:15 INFO Prophet compiled for Crash 1000 Index 22:38:17 DEBUG cmd: where.exe tbb.dll cwd: None Boom 1000 Index 4990 rows 22:38:17 INFO 127.0.0.1 - - [28/Jul/2025 22:38:17] "POST /upload_history HTTP/1.1" 200 - 22:38:17 DEBUG TBB already found in load path 22:38:17 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\9tu4ni1m.json 22:38:17 DEBUG input tempfile: C:\Users\hp\AppData\Local\Temp\tmpjw4u6es7\dbjg87e6.json 22:38:17 DEBUG idx 0 22:38:17 DEBUG running CmdStan, num_threads: None 22:38:17 DEBUG CmdStan args: ['C:\\Users\\hp\\AppData\\Local\\Programs\\Python\\Python313 \\Lib\\site-packages\\prophet\\stan_model\\prophet_model.bin', 'random', 'seed=45546', 'data', 'file=C:\\Users\\hp\\AppData\\Local\\Temp\\tmpjw4u6es7\\9tu4ni1m.json', 'init=C:\\Users\\hp \\AppData\\Local\\Temp\\tmpjw4u6es7\\dbjg87e6.json', 'output', 'file=C:\\Users\\hp\\AppData \\Local\\Temp\\tmpjw4u6es7\\prophet_modele7mw_egb\\prophet_model-20250728223817.csv', 'method=optimize', 'algorithm=lbfgs', 'iter=10000'] 22:38:17 - cmdstanpy - INFO - Chain [1] start processing 22:38:17 INFO Chain [1] start processing Crash 1000 Index 4990 rows 22:38:18 INFO 127.0.0.1 - - [28/Jul/2025 22:38:18] "POST /upload_history HTTP/1.1" 200 - 22:38:23 - cmdstanpy - INFO - Chain [1] done processing 22:38:23 INFO Chain [1] done processing 22:38:24 INFO Prophet compiled for Boom 1000 Index Boom 1000 Index 4990 rows 22:38:27 INFO 127.0.0.1 - - [28/Jul/2025 22:38:27] "POST /upload_history HTTP/1.1" 200 - Crash 1000 Index 4990 rows 22:38:28 INFO 127.0.0.1 - - [28/Jul/2025 22:38:28] "POST /upload_history HTTP/1.1" 200 - Boom 1000 Index 4990 rows 22:38:37 INFO 127.0.0.1 - - [28/Jul/2025 22:38:37] "POST /upload_history HTTP/1.1" 200 - Crash 1000 Index 4990 rows 22:38:38 INFO 127.0.0.1 - - [28/Jul/2025 22:38:38] "POST /upload_history HTTP/1.1" 200 - 22:38:49 DEBUG cmd: where.exe tbb.dll
日志显示,Crash 1000 和 Boom 1000 两个指数的 4,990 行历史数据均已成功获取并 POST 到 Python 服务器(HTTP 200),随后 cmdstanpy 驱动的 CmdStan 运行优化链为每个指数编译 Prophet 模型 —— 确认了每个链的开始和完成,以及两个品种最终的 "Prophet 已编译" 消息。
结论
我们已成功在 MetaTrader 5 中收集历史价格数据,将其转发到 Python 服务,并存储用于模型训练 ——MetaTrader 5 的 "专家" 选项卡和我们电脑的控制台日志中都有相应证据。这个健壮的数据获取管道为我们的尖峰检测系统奠定了基础。接下来,我们将在 Python 中训练检测模型,并通过 MQL5 智能交易系统将其集成回 MetaTrader 5,以便在交易平台上直接生成和接收实时信号。我们已成功在 MetaTrader 5 中收集历史价格数据,将其转发到 Python 服务,并存储用于模型训练 ——MetaTrader 5 的 "专家" 选项卡和我们电脑的控制台日志中都有相应证据。这个健壮的数据获取管道为我们的尖峰检测系统奠定了基础。
接下来,我们将在 Python 中训练检测模型,并通过 MQL5 智能交易系统将其集成回 MetaTrader 5,以便在交易平台上直接生成和接收实时信号。
如果您在设置过程中遇到任何困难,请随时与我联系。
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/18979
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
使用机器学习检测与分类分形模式
新手在交易中的10个基本错误
在 MQL5 中实现保本机制(第 2 部分):基于 ATR 和风险回报比的保本机制