Files
LSTM-Quantitative-Trading-E…/LSTM_EA.mq5
T
2025-10-27 19:45:33 +08:00

120 lines
4.1 KiB
Plaintext

//+------------------------------------------------------------------+
//| LSTM_EA.mq5 |
//| LSTM量化交易教学示例 |
//+------------------------------------------------------------------+
#property copyright "LSTM Trading Example"
#property version "1.00"
#resource "\\Files\\lstm_model.onnx" as uchar lstm_model[]
#include <Trade\Trade.mqh>
input double LotSize = 0.01; // 手数
input int StopLoss = 100; // 止损点数
input int TakeProfit = 150; // 止盈点数
long model_handle;
CTrade trade;
// 归一化参数(从训练脚本自动生成)
double data_min[5] = {0.95383, 0.95586, 0.95351, 0.95383, 9.0};
double data_max[5] = {1.23394, 1.23485, 1.23327, 1.23396, 24004.0};
//+------------------------------------------------------------------+
int OnInit()
{
model_handle = OnnxCreateFromBuffer(lstm_model, ArraySize(lstm_model));
if(model_handle == INVALID_HANDLE)
{
Print("ONNX模型加载失败");
return INIT_FAILED;
}
// 设置输入形状: [batch_size=1, seq_len=10, features=5]
ulong input_shape[] = {1, 10, 5};
if(!OnnxSetInputShape(model_handle, 0, input_shape))
{
Print("设置ONNX输入形状失败");
return INIT_FAILED;
}
// 设置输出形状: [batch_size=1, output_size=1]
ulong output_shape[] = {1, 1};
if(!OnnxSetOutputShape(model_handle, 0, output_shape))
{
Print("设置ONNX输出形状失败");
return INIT_FAILED;
}
Print("ONNX模型加载成功,准备交易EURUSD H1");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
OnnxRelease(model_handle);
}
//+------------------------------------------------------------------+
void OnTick()
{
// 仅在新K线时执行
static datetime last_bar = 0;
datetime current_bar = iTime(_Symbol, PERIOD_H1, 0);
if(current_bar == last_bar) return;
last_bar = current_bar;
// 准备输入数据: [1, 10, 5]
// 使用double避免在传参或计算时发生不必要的类型转换警告
double inputs[50];
for(int i = 0; i < 10; i++)
{
double bar_open = iOpen(_Symbol, PERIOD_H1, i);
double bar_high = iHigh(_Symbol, PERIOD_H1, i);
double bar_low = iLow(_Symbol, PERIOD_H1, i);
double bar_close = iClose(_Symbol, PERIOD_H1, i);
// 使用double存储成交量,避免精度或类型转换警告
double bar_volume = (double)iVolume(_Symbol, PERIOD_H1, i);
// 归一化(结果仍为double)
inputs[i*5 + 0] = (bar_open - data_min[0]) / (data_max[0] - data_min[0]);
inputs[i*5 + 1] = (bar_high - data_min[1]) / (data_max[1] - data_min[1]);
inputs[i*5 + 2] = (bar_low - data_min[2]) / (data_max[2] - data_min[2]);
inputs[i*5 + 3] = (bar_close - data_min[3]) / (data_max[3] - data_min[3]);
inputs[i*5 + 4] = (bar_volume - data_min[4]) / (data_max[4] - data_min[4]);
}
// 运行推理
// 输出也使用double,确保与输入数组类型一致
double output[1];
if(!OnnxRun(model_handle, ONNX_DEFAULT, inputs, output))
{
Print("ONNX推理失败");
return;
}
double current_price = iClose(_Symbol, PERIOD_H1, 0);
double predicted_price = output[0] * (data_max[3] - data_min[3]) + data_min[3];
// 交易逻辑: 预测价格上涨买入,下跌卖出
if(PositionsTotal() == 0)
{
if(predicted_price > current_price * 1.0001)
{
double sl = current_price - StopLoss * _Point;
double tp = current_price + TakeProfit * _Point;
trade.Buy(LotSize, _Symbol, 0, sl, tp);
Print("买入 | 当前:", current_price, " 预测:", predicted_price);
}
else if(predicted_price < current_price * 0.9999)
{
double sl = current_price + StopLoss * _Point;
double tp = current_price - TakeProfit * _Point;
trade.Sell(LotSize, _Symbol, 0, sl, tp);
Print("卖出 | 当前:", current_price, " 预测:", predicted_price);
}
}
}
//+------------------------------------------------------------------+