
借助成交量精准洞悉交易动态:超越传统OHLC图表
概述
在技术分析领域,交易者历来主要依赖价格波动作为市场活动的主要指标。本文提出了一种独特的方法,将先进的成交量数学分析与机器学习技术相结合,重点探讨成交量模式如何为理解市场动态提供更深入地认知。我们提供了一个复杂的系统,该系统通过将LSTM神经网络与基于微积分的成交量衍生指标相结合,超越了传统的技术分析方法。 文章分为三个主要部分:第一部分讨论成交量分析的基本重要性及其数学基础;第二部分探讨成交量衍生指标和LSTM预测在识别市场机会中的实际应用;第三部分解释如何利用成交量背离分析、趋势确认和突破验证来优化交易决策。理解成交量的核心功能
特定时间段内交易的股票或合约总数称为成交量,它是市场活动和流动性的关键指标。价格显示市场方向,而成交量则显示市场走势背后的信心,突显趋势的潜在强度和持久性。成交量是价格走势背后的驱动力,能够支持或反驳价格走势,因为成交量大的显著价格变化往往比成交量小的价格变化显示出更高的市场信心。此外,成交量模式通常能够预测价格变化,因此对于那些懂得如何将其与价格走势和市场背景相结合使用的交易者来说,成交量模式是宝贵的指标。 成交量的重要性
简单示例:
成交量分析的至关重要性可以通过一种超越标准分析的复杂数学技术来证明,该技术为交易者提供了一个比仅使用传统指标更先进的框架来理解市场动态。通过仅关注成交量动态(独立于OHLC数据),我们可以利用微积分和机器学习(特别是成交量衍生指标和LSTM神经网络)发现重要的市场洞察。这种新颖的方法利用复杂的数学概念来识别交易和市场参与度的微小变化,在价格走势显现之前提供可能市场走势的早期预警。
通过观察成交量变化率(一阶导数)及其加速度(二阶导数),并结合机器学习预测,交易者可以比使用传统成交量分析技术更精确地识别新趋势和可能的反转。当正确应用时,这种数学基础为市场分析提供了一种强大的方法,在当今算法驱动的市场中尤其有用,因为传统技术分析可能不够充分。
该方法考察三个重要的成交量组成部分:一阶导数(成交量变化率)、二阶导数(成交量变化加速度)以及确认相同成交量衍生指标的未来成交量LSTM预测。EA从标准的MetaTrader声明开始。
EA从标准的MetaTrader声明开始。包括用于订单管理的Trade库和用于预测的自定义Volume_LSTM库。indicator_separate_window属性表示该指标将在单独窗口中显示,并为可视化分配了三个指标缓冲区。#property copyright "Your Name" #property version "1.00" #property strict #property indicator_separate_window #property indicator_buffers 3 #include <Trade\Trade.mqh> #include <Volume_LSTM.mqh> CTrade trade;
参数按逻辑组进行了划分。LSTM配置部分控制神经网络的行为,而入场参数则管理交易规则。每个参数都有其特定用途:LSTM参数控制预测模型的复杂度和记忆能力。交易参数用于定义仓位规模和盈利目标,风险管理参数则设定止损限额和追踪止损。
input group "Configuración LSTM" input bool UseLSTM = true; input int LSTMHiddenSize = 32; input int LSTMLookback = 10; input group "Entry Parameters" input double Lots = 0.1; input double TPPoints = 100; input int Periods = 4; input int AccelBars = 4; input int MaxBarsInTrade = 2; input double ProfitClose = 15; input double MaxDailyLoss = -25; input double TrailingStart = 5; input double TrailingStep = 5;
该函数用于计算成交量的变化率(一阶导数)以及成交量变化的加速度(二阶导数)。它会移动现有导数数据以保留历史记录,将当前成交量与前一成交量之差计算为新的一阶导数,将一阶导数的变化量计算为新的二阶导数,从而为洞察成交量的动量和加速度提供依据。
通过观察成交量的一阶导数,我们本质上是在追踪交易活动随时间推移是增加还是减少。这种成交量波动的模式为我们提供了对市场动量的第一层洞察。持续为正的一阶导数表明市场兴趣在增加,而持续为负的一阶导数则表明市场参与度在下降。
void CalculateDerivatives() { for(int i = 0; i < ArraySize(volumes)-1; i++) { firstDerivative[i] = firstDerivative[i+1]; secondDerivative[i] = secondDerivative[i+1]; } firstDerivative[ArraySize(volumes)-1] = volumes[ArraySize(volumes)-1] - volumes[ArraySize(volumes)-2]; secondDerivative[ArraySize(volumes)-1] = firstDerivative[ArraySize(volumes)-1] - firstDerivative[ArraySize(volumes)-2]; }
这些函数负责管理交易的生命周期,其中TrackNewTrade函数在首个可用位置记录新开仓位,RemoveTrade函数则在仓位平仓时清除相应记录。这两个函数共同维护了交易跟踪系统的完整性。
void TrackNewTrade(ulong ticket) { for(int i = 0; i < ArraySize(openTrades); i++) { if(openTrades[i].ticket == 0) { openTrades[i].ticket = ticket; openTrades[i].openTime = TimeCurrent(); openTrades[i].barsOpen = 0; break; } } } void RemoveTrade(ulong ticket) { for(int i = 0; i < ArraySize(openTrades); i++) { if(openTrades[i].ticket == ticket) { openTrades[i].ticket = 0; openTrades[i].openTime = 0; openTrades[i].barsOpen = 0; break; } } }
该盈亏跟踪函数的功能如下:
- 识别当前交易日
- 计算已平仓交易的已实现盈亏
- 累加未平仓头寸的未实现盈亏
- 跨多笔交易维持每日盈亏跟踪记录
- 协助执行每日亏损限额控制
double GetDailyProfit() { datetime today = StringToTime(TimeToString(TimeCurrent(), TIME_DATE)); if(lastDayChecked != today) { lastDayChecked = today; dailyProfit = 0; HistorySelect(today, TimeCurrent()); int deals = HistoryDealsTotal(); for(int i = 0; i < deals; i++) { ulong ticket = HistoryDealGetTicket(i); if(ticket > 0) { if(HistoryDealGetString(ticket, DEAL_SYMBOL) == _Symbol) dailyProfit += HistoryDealGetDouble(ticket, DEAL_PROFIT); } } } // Add floating P/L double floatingProfit = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionSelectByTicket(ticket)) { if(PositionGetString(POSITION_SYMBOL) == _Symbol) floatingProfit += PositionGetDouble(POSITION_PROFIT); } } return dailyProfit + floatingProfit; }
该追踪止损函数的功能如下:
- 遍历所有未平仓头寸
- 计算每个头寸的点数盈利
- 根据盈利情况更新止损水平
- 实施追踪机制以锁定利润
- 分开处理买入和卖出头寸
void ApplyTrailingStop(double point) { for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket <= 0) continue; if(PositionSelectByTicket(ticket)) { double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT); double currentSL = PositionGetDouble(POSITION_SL); long posType = PositionGetInteger(POSITION_TYPE); // Calculate and update trailing stop double profitPoints; if(posType == POSITION_TYPE_BUY) { profitPoints = (currentPrice - openPrice) / point; if(profitPoints >= TrailingStart) { double newSL = openPrice + (profitPoints - TrailingStep) * point; if(currentSL < newSL || currentSL == 0) { trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP)); } } } // Similar logic for SELL positions } } }
成交量的二阶导数通过展示交易活动的加速或放缓,提供了更为详尽的信息。当二阶导数为正值时,这强烈表明市场动量正在增强,因为它显示成交量不仅在上升,而且上升的速度还在加快。由于这种成交量加速现象表明市场参与者的兴趣正在迅速增加,因此它往往发生在显著的市场波动之前。通过将这些导数与LSTM神经网络对未来成交量模式的预测相结合,我们为预测市场行为提供了一个强有力的框架。LSTM能够识别成交量序列中的复杂模式,这为我们的研究增添了额外的一层验证,有助于判断观察到的成交量趋势是否可能持续。
主要交易逻辑:
- 检查新K线是否形成
- 核实每日亏损限额
- 更新交易信息
- 执行成交量分析
- 如果启用,则生成LSTM预测
- 基于多种因素做出交易决策
- 当满足条件时开仓
void OnTick() { static datetime lastBar = 0; datetime currentBar = iTime(_Symbol, PERIOD_CURRENT, 0); if(lastBar == currentBar) return; lastBar = currentBar; if(GetDailyProfit() < MaxDailyLoss) { CloseAllPositions(); return; } // Update and calculate UpdateTradesInfo(); CheckTimeBasedClose(); if(!CanTrade()) return; // Volume analysis and LSTM prediction // ... volume calculations ... if(UseLSTM && volumePredictor != NULL) { // LSTM prediction logic // ... prediction calculations ... } CalculateDerivatives(); // Trading decisions based on calculations if(consecutiveAccel >= AccelBars) { if((!UseADX && !UseOBV) || ConfirmLongSignal()) { // Open buy position } } else if(consecutiveAccel <= -AccelBars) { if(!UseADX && !UseOBV || ConfirmShortSignal()) { // Open sell position } } }
技术指标计算流程:
- 为指标值设置数据缓冲区
- 从指标句柄中复制指标数据
- 用新值更新本地数组
- 维护用于决策的指标数据
void CalculateADX() { if(!UseADX) return; double adx_buffer[]; double plusdi_buffer[]; double minusdi_buffer[]; ArraySetAsSeries(adx_buffer, true); ArraySetAsSeries(plusdi_buffer, true); ArraySetAsSeries(minusdi_buffer, true); CopyBuffer(adx_handle, MAIN_LINE, 0, ArraySize(adx_main), adx_buffer); CopyBuffer(adx_handle, PLUSDI_LINE, 0, ArraySize(adx_plus), plusdi_buffer); CopyBuffer(adx_handle, MINUSDI_LINE, 0, ArraySize(adx_minus), minusdi_buffer); ArrayCopy(adx_main, adx_buffer); ArrayCopy(adx_plus, plusdi_buffer); ArrayCopy(adx_minus, minusdi_buffer); }
各组件协同工作,共同构建了一个全面的交易系统。该系统融合了成交量分析、LSTM预测和传统技术指标,同时保持了稳健的风险管理实践。
Volume_LSTM.mqh文件实现了一个专门用于预测交易成交量的长短期记忆(LSTM)神经网络。
代码从基础的Matrix2D结构开始,该结构用于处理二维矩阵运算:
struct Matrix2D { double values[]; int rows; int cols; void Init(int r, int c) { rows = r; cols = c; ArrayResize(values, rows * cols); ArrayInitialize(values, 0); } // ... other methods }
实现完成后,LSTM单元将作为一个完整的结构体系:
struct LSTMCell { double forget_gate[]; double input_gate[]; double cell_state[]; double output_gate[]; double hidden_state[]; Matrix2D Wf; // Forget gate weights Matrix2D Wi; // Input gate weights Matrix2D Wc; // Cell state weights Matrix2D Wo; // Output gate weights double bf[]; // Forget gate bias double bi[]; // Input gate bias double bc[]; // Cell state bias double bo[]; // Output gate bias int hidden_size; int input_size; };
该实现过程包含标准的神经网络激活函数:
double Sigmoid(double x) { return 1.0 / (1.0 + MathExp(-x)); } double Tanh(double x) { return (MathExp(x) - MathExp(-x)) / (MathExp(x) + MathExp(-x)); }
采用Xavier/Glorot初始化方法的变体对权重进行初始化:
void InitializeWeights() { double scale = MathSqrt(2.0 / (lstm.input_size + lstm.hidden_size)); // Initialize weight matrices lstm.Wf.Init(lstm.hidden_size, lstm.input_size); lstm.Wi.Init(lstm.hidden_size, lstm.input_size); // ... other initializations // Random initialization with scaling for(int i = 0; i < lstm.hidden_size; i++) { for(int j = 0; j < lstm.input_size; j++) { lstm.Wf.Set(i, j, (MathRand() / 32768.0 - 0.5) * scale); // ... other weight initializations } } }
该实现包含数据标准化处理:
void NormalizeVolumes() { volume_mean = 0; double sum_squared = 0; // Calculate mean for(int i = 0; i < ArraySize(historical_volumes); i++) { volume_mean += historical_volumes[i]; } volume_mean /= ArraySize(historical_volumes); // Calculate standard deviation for(int i = 0; i < ArraySize(historical_volumes); i++) { sum_squared += MathPow(historical_volumes[i] - volume_mean, 2); } volume_std = MathSqrt(sum_squared / ArraySize(historical_volumes)); // Normalize volumes if(volume_std == 0) volume_std = 1; // Prevent division by zero for(int i = 0; i < ArraySize(historical_volumes); i++) { historical_volumes[i] = (historical_volumes[i] - volume_mean) / volume_std; } }
核心预测逻辑:
double PredictNextVolume() { if(!is_initialized) return 0; double input1 = historical_volumes[ArraySize(historical_volumes)-1]; // LSTM forward pass for(int h = 0; h < lstm.hidden_size; h++) { double ft = 0, it = 0, ct = 0, ot = 0; // Calculate gates for(int i = 0; i < lstm.input_size; i++) { ft += lstm.Wf.Get(h, i) * input1; it += lstm.Wi.Get(h, i) * input1; ct += lstm.Wc.Get(h, i) * input1; ot += lstm.Wo.Get(h, i) * input1; } // Apply gates and calculate states lstm.forget_gate[h] = Sigmoid(ft + lstm.bf[h]); lstm.input_gate[h] = Sigmoid(it + lstm.bi[h]); double c_tilde = Tanh(ct + lstm.bc[h]); lstm.cell_state[h] = lstm.forget_gate[h] * lstm.cell_state[h] + lstm.input_gate[h] * c_tilde; lstm.output_gate[h] = Sigmoid(ot + lstm.bo[h]); lstm.hidden_state[h] = lstm.output_gate[h] * Tanh(lstm.cell_state[h]); } // Calculate final prediction double prediction = 0; for(int h = 0; h < lstm.hidden_size; h++) prediction += lstm.hidden_state[h]; prediction /= lstm.hidden_size; return prediction * volume_std + volume_mean; // Denormalize }
结果
EURUSD(欧元兑美元),这是欧元兑美元在30分钟时间周期下的交易结果。相关设置为Setting_eurusd.set
GBPUSD(英镑兑美元),时间框架为30分钟。
对主要货币对进行大规模优化可能会带来更好的交易结果,但受限于时间,本文无法进一步展开阐述。我强烈建议针对每个货币对进行大规模优化,并希望部分用户能在评论区分享新的可能配置方案。
高级技巧
趋势确认
价格上涨时成交量高,表明市场支撑强劲,趋势很可能延续。相反,价格下跌时成交量高,反映出强大的抛售压力,证实了负面趋势。价格波动时成交量低,则反映出趋势疲软或不可持续,往往预示着假突破或市场操纵。
突破验证
高成交量下的突破证实了市场决心,将导致价格持续变化。低成交量下的突破往往产生虚假信号,如“多头陷阱”或“空头陷阱”,且很可能失败。突破时成交量激增有力地验证了这一走势,并表明市场支撑强劲。
成交量背离
成交量背离,即价格和成交量趋势不同,预示着趋势可能反转或趋弱。价格上涨但成交量下降,表明上升趋势正在减弱;而价格下跌但成交量下降,则表明抛售压力减轻,市场可能触底。这些模式与其他指标结合使用时,有助于识别转折点。
结论
通过将前沿的机器学习方法和传统的成交量分析相结合,基于成交量的交易EA提供了一种先进的算法交易方法。该系统不仅利用LSTM神经网络进行成交量预测,还结合了ADX和OBV等传统技术指标,展现出强大的市场研究和交易执行能力。
该EA采用的多层次风险管理策略是其最大亮点,包括严格的每日亏损限额、动态追踪止损以及全面的仓位跟踪。这种对风险管理的重视,加上可调节的入场参数和灵活的交易时段管理,为交易者提供了一个灵活的工具,使其能够适应不同的市场状况,同时遵循严格的交易流程。
最重要的是,通过将成交量导数分析与LSTM预测相结合,构建了一个独特的混合系统。基于这种结合,该EA或许在市场变化完全显现之前就能够察觉到,并且传统指标的验证有助于减少虚假信号。模块化的代码结构也使得未来的优化和易于维护成为可能。
然而,用户应当注意,由于系统复杂,在实盘部署前必须进行精细的回测和参数调整。尽管LSTM组件功能强大,但它需要大量的处理能力和合适的训练数据。尽管存在这些问题,但该EA因其致力于将尖端技术与经过验证的交易理念相结合,对于希望自动化其基于成交量的交易方法的交易者来说,仍是一个有用的工具。
我希望本文有助于从认识到运用OHLCV(开盘价、最高价、最低价、收盘价和成交量)数据,而不仅仅是价格数据。
文件名 | 说明 |
---|---|
MQL5/Profiles/Tester/Setting_eurusd.set | 以欧元兑美元为例的输入设置 |
MQL5/Profiles/Tester/GBPUSD_settings.set | 以英镑兑美元为例的输入设置 |
MQL5/Experts/Volume_high_low_difference_LSTM.mq5 | 示例中使用的EA |
MQL5/Include/Volume_LSTM.mqh | 包含.mqh文件。请记住在EA中更改保存路径 |
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/16445



嗨,谢谢!我不太确定基因......但觉得这很有趣。我会写一篇文章,介绍人字形指标和交易量。我还将继续使用交易量制定更多策略。我正在搬家,需要一些时间来做更多的工作。
你好,我花了几天时间研究交易量和之字形指标,但只得到了盈亏平衡的结果......以后我可能会花更多时间研究,但现在我觉得还不足以写成一篇文章。请你自己试试看,如果这是个好办法,请指正我。)(我发现有趣的是带有 ZigZag 的 ADX ...我可能会用它写一篇文章......刚刚开始......)......我保证以后会再用 ZigZag 检查成交量。