价格走势角度分析:用于预测金融市场的混合模型(基础篇)
混合模型怎么看价格走势
在 MT5 生态里,单纯用均线或裸 K 做预测,容易被震荡扫损。把统计模型和价格行为叠加成混合模型,是近年一类可行思路:用概率侧过滤噪音,用形态侧抓触发点。 Yevgeniy Koshtenko 于 2026 年 6 月 9 日在 MetaTrader 5 渠道发布的相关内容,获得 328 次查看与 12 条互动,说明这类交叉验证方法在实盘社群里有真实讨论度。 外汇与贵金属杠杆高,混合模型只降低盲判概率,不消除方向误判风险;任何信号都先在模拟盘跑一轮再上真仓。
「把价格坡度当成可计算的地形」
有经验的交易者看图表,往往凭感觉判断一段上涨或下跌的「陡不陡」。但这种坡度感如果只停留在肉眼,就永远停在主观层面,没法直接变成下单依据。 价格走势和山体地形其实同构:峰、谷、缓坡、断崖都对应着不同的角度。MT5 里一段行情从低点拉到高点,用两点坐标算出的斜率,就是这段「山坡」的几何特征,数值越大代表推升越急。 把角度从视觉直觉转成数学量,是算法交易能落地的前提。后面会用 MQL5 把这段斜率算出来,你开 MT5 随便拖一根折线就能验证同样的数。
◍ 连续价格点之间的角度才是隐藏信号
EURUSD 常规图表上肉眼可见的是 K 线和柱体,但相邻两个价格点连成的线段与水平轴存在一个精确数学夹角:正值为上行、负值为下行,绝对值越大斜率越陡。这一层角度结构平时被形态和趋势线掩盖,却比肉眼画的趋势线更接近价格运动的真实几何。 交易员用趋势线斜率判断方向几十年,本质只是粗略草图;连续点间的逐段角度相当于标出每个坡面精确度数的地形图。这些角度彼此不等,会自成序列与节奏,后续段落会说明这种角度序列如何用于推断短期走势倾向。 外汇与贵金属杠杆高、跳空频繁,角度陡升陡降常伴随假突破,任何基于角度的推断都只是概率倾向,需结合实盘波动验证。
把江恩角度线改成可量化的连续数据流
江恩在20世纪初就主张价格与时间存在数学关系,可用图表线斜率表达,但他那套靠人工从关键点拉角度线的做法有两个老毛病:解读太主观,且是为固定比例尺的纸图设计的,挪到数字图表就失真。 作者换了一条路:不去挑“重要点”画线,而是逐点测量相邻两个价格坐标之间的夹角,得到一条类似市场心电图的连续角度序列。关键在于先把时间轴与价格轴做归一化,让两轴在各自变化区间内尺度可比,这样算出的角度才不依赖绝对价位或K线周期。 经典江恩迷恋45°或26.25°这类“神奇角”,这里改成丢给机器学习去筛哪些角度模式对后市有统计意义。回测观察里有个可验证现象:当角度符号从接近0跳到接近+45°时,市场出现强劲定向波动的概率明显抬高——这点恰好和江恩的1:1线直觉吻合,但多了数学与统计背书。外汇与贵金属杠杆高、滑点大,这类信号只作概率参考,不能直接当入场指令。 整体思路是保留“价时交汇处找几何”的哲学,把主观绘画变成客观测量。开MT5自己写个两段收盘价的atan2夹角脚本,跑一遍归一化前后的角度分布,就能看出纸面江恩和量化版差在哪。
「EURUSD 角度序列里藏着的启动前兆」
把角度量准之后,下一步不是急着下单,而是先盯 EURUSD 日线连续几个月的角度轨迹。我们把每一次转向、每一段斜率变化都记下来,最初看着像噪声,但拉长时间窗后,非随机结构就浮出来了。 一个可复现的现象是:在价格明显上行之前,角度往往先走一小段负向(轻微向下倾斜),随后进入中性区,再接一连串幅度递增的正向角度。这个顺序在样本里反复出现,不是单次巧合。 打个比方,像陀螺起跳前先晃两下蓄力,欧元图表在剧烈波动前也会“摇摆”出特定角度链。但光靠肉眼归纳撑不起策略——外汇和贵金属杠杆高、反转快,主观 pattern 容易过拟合。 要把猜测变成可校验的假设,得用数学工具收口。机器学习适合干这个:它能把几个月的角度序列喂进去,帮你看清哪些前置结构真有统计意义,哪些只是幸存者偏差。
◍ 把角度算进可训练的特征集
直接拉 MT5 实时报价比手算省事。用 Python 接 MetaTrader5 库,指定 EURUSD、M5 周期、回看 60 天,就能把历史 rates 转成 DataFrame,时间列顺手从 Unix 秒换成可读 datetime。 裸坐标算角度是个坑:时间轴单位是秒、价格轴单位是点,刻度完全不对等,直接 atan2 出来的角度没有物理意义。做法是把时间序列按总秒数展开,再用 price_range / time_range 做缩放,让两轴可比。 create_angular_features 里第一个点没有前置点,角度填 nan;从第二根 K 线开始,拿缩放后的时间与收盘价喂给 calculate_angle,垂直情况单独返回 ±90 度。跑完之后每条数据都挂了一个 angle 字段,这就是价格斜率的数学快照。 光有单点角度不够喂模型。把最近若干根的角度做统计展开,每个样本能长出 30 多个描述角度行为的特征,外汇与贵金属波动剧烈、杠杆高风险,这类特征仅作概率参考,实盘前请在 MT5 里先回测验证。
class="kw">import MetaTrader5 as mt5 from class="type">class="kw">datetime class="kw">import class="type">class="kw">datetime, timedelta class="kw">import pandas as pd class="kw">import numpy as np class="kw">import math def get_mt5_data(symbol=&class="macro">#x27;EURUSD&class="macro">#x27;, timeframe=mt5.TIMEFRAME_M5, days=class="num">60): if not mt5.initialize(): print(f"Initialization error MT5: {mt5.last_error()}") class="kw">return None # Determine period for downloading data start_date = class="type">class="kw">datetime.now() - timedelta(days=days) rates = mt5.copy_rates_range(symbol, timeframe, start_date, class="type">class="kw">datetime.now()) mt5.shutdown() # Transform data into convenient format df = pd.DataFrame(rates) df[&class="macro">#x27;time&class="macro">#x27;] = pd.to_datetime(df[&class="macro">#x27;time&class="macro">#x27;], unit=&class="macro">#x27;s&class="macro">#x27;) class="kw">return df def calculate_angle(p1, p2): # p1 и p2 - tuples(time_normalized, price) x1, y1 = p1 x2, y2 = p2 # Handling vertical lines if x2 - x1 == class="num">0: class="kw">return class="num">90 if y2 > y1 else -class="num">90 # Calculating an angle in radians and convert it to degrees angle_rad = math.atan2(y2 - y1, x2 - x1) angle_deg = math.degrees(angle_rad) class="kw">return angle_deg def create_angular_features(df): # Create copy DataFrame angular_df = df.copy() # Normalizing time series for correct calculation of angles angular_df[&class="macro">#x27;time_num&class="macro">#x27;] = (angular_df[&class="macro">#x27;time&class="macro">#x27;] - angular_df[&class="macro">#x27;time&class="macro">#x27;].min()).dt.total_seconds() # Find ranges for normalization time_range = angular_df[&class="macro">#x27;time_num&class="macro">#x27;].max() - angular_df[&class="macro">#x27;time_num&class="macro">#x27;].min() price_range = angular_df[&class="macro">#x27;close&class="macro">#x27;].max() - angular_df[&class="macro">#x27;close&class="macro">#x27;].min() # Normalization for comparable scales scale_factor = price_range / time_range angular_df[&class="macro">#x27;time_scaled&class="macro">#x27;] = angular_df[&class="macro">#x27;time_num&class="macro">#x27;] * scale_factor # Calculate angles between sequential points angles = [] angles.append(np.nan) # Angle not defined for the first point for i in range(class="num">1, len(angular_df)): current_point = (angular_df[&class="macro">#x27;time_scaled&class="macro">#x27;].iloc[i], angular_df[&class="macro">#x27;close&class="macro">#x27;].iloc[i]) prev_point = (angular_df[&class="macro">#x27;time_scaled&class="macro">#x27;].iloc[i-class="num">1], angular_df[&class="macro">#x27;close&class="macro">#x27;].iloc[i-class="num">1]) angle = calculate_angle(prev_point, current_point) angles.append(angle) angular_df[&class="macro">#x27;angle&class="macro">#x27;] = angles