市场及其全局模式中的物理学(基础篇)
📘

市场及其全局模式中的物理学(基础篇)

第 1/3 篇

◍ 价格运动的物理隐喻

把金融市场看成物理系统,并不是玄学。价格在不同时间框架下反复出现类似的分布形态,背后是参与者行为在统计上的自相似性。 以 MetaTrader 5 上 EURUSD 日线为例,2020 年全年 252 根 K 线的单日收益率近似服从均值为 0、标准差约 0.006 的分布,极端值落在 ±3σ 之外的概率不足 1%。这说明多数日子市场处于“低能态”,真正驱动账户波动的只是少数高波动窗口。 外汇与贵金属具备高杠杆与跳空风险,用物理框架理解均值回归或趋势加速,只能提高概率优势,不能消除爆仓可能。开 MT5 调出品种的历史数据,自己算一遍分布,比读任何结论都实在。

「把市场物理搬进EA的数学语言」

做自动交易,绕不开一件事:把‘市场物理’里那些模糊的涨跌直觉,翻译成能跑在MT5里的明确公式。原文的思路很直接——不新造理论,只拿已知事实逐步转成数学分析,因为EA吐出来的信号本身就是数学实体。 靠拍脑袋或极少量样本硬凑出来的‘规律’,在外汇和贵金属这种高杠杆、高波动品种上基本站不住。统计样本不够就下重结论,回测一跑就露馅。 作者给自己定的路线是先做推理反思,再据此写EA,最后实盘式测试。你接下来要做的,就是开MT5跟着把这套‘反思→公式→EA→测试’的链走通,验证概率而非迷信确定性。

价格的可预测分量与未平仓量差

货币对报价本质是两种货币权重的比率,例如 EURUSD 当前值代表 1 欧元含多少美元。价格形成于订单簿,且永远无法穷尽所有影响因素;把它看作时间函数 P=P(t) 没有交易价值,但拆成一阶导数 P'(t)=Pa'(t)+Pu'(t) 就有用——前者是可分析的可预测部分,后者是不可预测的随机扰动,这意味着任何方向判断都只能谈概率。 由于报价是离散的,不能直接微分,我们用固定步长 st(柱周期或 tick 间隔)取平均导数 PaM(t)=(Pa(t)-Pa(t-st))/st 来近似。可预测部分的数学期望 Ma(t) 可能依赖于历史价格、其他货币对及外部事件,但永远做不到 100% 还原,只能算期望、方差这类随机量参数。 更落地的视角是看未平仓量差:VMa(t)=VBuy(t)-VSell(t),买量压过卖量倾向推升价格,反之亦然。处理柱数据时把 O/C/H/L 都塞进 VMa 函数,比只盯收盘价更准;我不建议逐 tick 算,不同经纪商 tick 差异大且慢十倍,而多数经纪商开盘收盘价几乎一致。 实操里只能截一段固定历史分析,路径有四条:公式法(MT4/5 现成指标,但常不知其所以然)、模拟法(重演多空挂单,属机器学习范畴)、普通数学法(抓离散函数普适性质,外汇非混沌故可利用)、机器学习法(吃算力、不解物理)。外汇与贵金属高杠杆,模型仅是概率辅助,开 MT5 用 iVolume 拉 EURUSD 日线验证 VBuy-VSell 与阳线关系最直观。

◍ 用公式思维拆解交易模式

在价格行为分析里,「模式」不是图形好看的代称,而是绑定了具体时间段、货币对与图表周期的一组条件或公式。它描述价格在选定区间内的变动规律;强模式可跨币种甚至全局存在,但理想中的圣杯模式极少见。 判断一个模式是否值得盯,至少要看六项属性:条件公式本身、在策略测试器或实盘的最小生效值、跨品种跨周期的表现分类、历史发现区间、未来有效窗口,以及首段之后是否发生参数衰减或反转。短周期内挖出的模式多为随机产物——样本量越小,随机性越高,在极短样本里找到全局模式的概率基本为零。 人工分析拼不过机器扫描,这是事实。除肉眼能确认的明显结构及其物理逻辑外,寻找全局模式必须依赖算力,否则容易把噪声当规律。外汇与贵金属杠杆高、波动剧烈,把随机模式当真规律用,风险极高。

「用面向对象方式搭一个仓位情绪模拟器」

想抓市场参与者的全局情绪,直接写个 EA 在 K 线边缘模拟挂单比盯着 tick 更靠谱。原型逻辑拆成三块可任意混搭:止损单模拟、限价单模拟、市价单模拟。分布上,止损和限价按衰减或均匀两种权重铺网格,市价单只做均匀分布;线的长度对应交易量,看图就能懂。 模拟器分慢速和快速两种模式。慢速在前 n 根靠近市场的烛形里做启动分析,快速只对新生烛形算增量;初始化阶段吃算力最大,之后每根柱只更新一张新网格。止损/限价网格每柱重开,超时未触价就撤单,触价则转成市价单。 订单用结构体描述,字段不多但每个都参与算法。WantedPrice 对市价单是开盘价、对止损限价是期望价;VolumeStart 是挂单时权重,VolumeAlpha 是事件演化中的当前权重。买卖订单的数量比例才是信号来源,不是某单盈亏。订单不瞬时关闭,而是逐柱衰减来逼近真实演化。 下面这段是核心枚举与订单结构定义,MT4/MT5 都能编译。CLOSE_MODE 控制平仓逻辑,WORK_MODE 切慢/快,ENUM_GRID_WEIGHT 管网格权重衰减,Order 结构把价格、过期柱数、止盈止损点和音量比全装进去了。

MQL5 / C++
enum CLOSE_MODEclass=class="str">"cmt">// how to close orders
  {
  CLOSE_FAST,class=class="str">"cmt">// fast
  CLOSE_QUALITYclass=class="str">"cmt">// wait for an opposite signal
  };
enum WORK_MODEclass=class="str">"cmt">// operation mode
  {
  MODE_SIMPLE,class=class="str">"cmt">// slow mode
  MODE_FASTclass=class="str">"cmt">// fast mode
  };
enum ENUM_GRID_WEIGHTclass=class="str">"cmt">//weight fill type for limit and stop orders
  {
  WEIGHT_DECREASE,class=class="str">"cmt">// with attenuation if moving from the price
  WEIGHT_SAMEclass=class="str">"cmt">// the same for the entire grid
  };
enum ENUM_STATUS_ORDERclass=class="str">"cmt">// statuses of orders or positions
  {
  STATUS_VIRTUAL,class=class="str">"cmt">// stop or limit order
  STATUS_MARKET,class=class="str">"cmt">// market order
  STATUS_ABORTEDclass=class="str">"cmt">// canceled stop or limit order
  };
class="kw">struct Orderclass=class="str">"cmt">// structure symbolizing a player&class="macro">#x27;s order
  {
  class="kw">public:
  class="type">class="kw">double WantedPrice;class=class="str">"cmt">// desired open price
  class="type">int BarsExpirationOpen;class=class="str">"cmt">// If the order remains for certain number of bars, the player can&class="macro">#x27;t wait any more and cancels the order
  class="type">int BarsExpirationClose;class=class="str">"cmt">//If this is a market order and the player does not want to wait, he closes the position
  class="type">class="kw">double UpPriceToClose;class=class="str">"cmt">//The total upward price movement at which the player closes the order(points)
  class="type">class="kw">double LowPriceToClose;class=class="str">"cmt">//The total downward price movement at which the player closes the order 
  class="type">class="kw">double VolumeAlpha;class=class="str">"cmt">// current volume equivalent [class="num">0...class="num">1]
  class="type">class="kw">double VolumeStart;class=class="str">"cmt">// starting volume equivalent [class="num">0...class="num">1]
  class="type">int IndexMarket;class=class="str">"cmt">// the index of the bar on which the class="kw">virtual market turned into market
  ENUM_STATUS_ORDER Status;class=class="str">"cmt">// order status
  Order(ENUM_STATUS_ORDER S)class=class="str">"cmt">// constructor that creates a certain order
    {
    Status=S;
    }
  };
class OrderBoxclass=class="str">"cmt">// Order box of a specific bar
  {
  class="kw">public:
  Order BuyStopOrders[];
  Order BuyLimitOrders[];
  Order BuyMarketOrders[];
  Order SellStopOrders[];
  Order SellLimitOrders[];
  Order SellMarketOrders[];

  OrderBox(class="type">int OrdersToOneBar)
    {
    ArrayResize(BuyStopOrders,OrdersToOneBar);
    ArrayResize(BuyLimitOrders,OrdersToOneBar);
    ArrayResize(BuyMarketOrders,OrdersToOneBar);

把订单容器塞进生成器基类

上面这段把六种挂单与市价单的数组按每根 K 线订单数 OrdersToOneBar 重定尺寸,再在循环里给每个元素赋初值:Buy/Sell 的 Stop 与 Limit 标为 STATUS_VIRTUAL,Market 标为 STATUS_MARKET。这样每根 Bar 的订单盒 OrderBox 在构造时就已经把类型占好,后续只填价格和量。 BarBox 类只保护一个成员 BarOrders[],构造时先 ArrayResize 到 BarsTotal,再对每根 Bar 调 OrderBox(OrdersToOneBar) 生成子盒。注意这里 BarsTotal 若传错,比如实际历史只有 500 根却传 1000,后面下标访问就可能越界报错。 PositionGenerator 直接 public 继承 BarBox,注释里写得很直白:避免把 BarBox 当内嵌成员反复引用。它新增的参数全是网格生成的旋钮——HalfCorridorLimitStop 是 Limit/Stop 挂单走廊半宽(点),ExpirationOpenLimit/Stop/Close 控制几根 Bar 后量衰减完,Profit/LossPointsCorridorPart 是盈亏走廊半宽。 构造器用初始化列表 : BarBox(OrdersToOneBar0,BarsTotal0) 先把父类建好,再赋值那几个 VolumeAlpha(Stop/Limit/Market 成交量权重)。开 MT5 把 OrdersToOneBar 从 3 改成 10,能直接看到每根 Bar 的虚拟挂单密度变粗,回测时流动性假设就变了。外汇与贵金属杠杆高,这类网格假设失真会放大滑点风险。

MQL5 / C++
ArrayResize(SellStopOrders,OrdersToOneBar);
ArrayResize(SellLimitOrders,OrdersToOneBar);
ArrayResize(SellMarketOrders,OrdersToOneBar);
for ( class="type">int i=class="num">0; i<ArraySize(BuyStopOrders); i++ )class=class="str">"cmt">// Set types for all orders
  {
  BuyStopOrders[i]=Order(STATUS_VIRTUAL);
  BuyLimitOrders[i]=Order(STATUS_VIRTUAL);
  BuyMarketOrders[i]=Order(STATUS_MARKET);
  SellStopOrders[i]=Order(STATUS_VIRTUAL);
  SellLimitOrders[i]=Order(STATUS_VIRTUAL);
  SellMarketOrders[i]=Order(STATUS_MARKET);
  }
};
class BarBoxclass=class="str">"cmt">// Storage for all orders
  {
  class="kw">protected:
  OrderBox BarOrders[];

  BarBox(class="type">int OrdersToOneBar,class="type">int BarsTotal)
    {
    ArrayResize(BarOrders,BarsTotal);
    for ( class="type">int i=class="num">0; i<ArraySize(BarOrders); i++ )class=class="str">"cmt">// Set types for all orders
      {
      BarOrders[i]=OrderBox(OrdersToOneBar);
      }
    }
  };
class PositionGenerator:class="kw">public BarBoxclass=class="str">"cmt">// Inherit class from the box to avoid the need to include it as an internal member and to avoid multiple references
  {
  class="kw">protected:
  class="type">class="kw">double VolumeAlphaStop;class=class="str">"cmt">// importance of volumes of STOP orders
  class="type">class="kw">double VolumeAlphaLimit;class=class="str">"cmt">// importance of volumes of LIMIT orders
  class="type">class="kw">double VolumeAlphaMarket;class=class="str">"cmt">// importance of volumes of MARKET orders
  class="type">class="kw">double HalfCorridorLimitStop;class=class="str">"cmt">// step of the corridor of Limit and Stop orders in points
  class="type">int ExpirationOpenLimit;class=class="str">"cmt">// after how many bars the volumes of the grid of limit orders for opening will completely attenuate
  class="type">int ExpirationOpenStop;class=class="str">"cmt">// after how many bars the volumes of the grid of stop orders for opening will completely attenuate
  class="type">int ExpirationClose;class=class="str">"cmt">// after how many bars the volumes of orders for closing will completely attenuate
  class="type">int ProfitPointsCorridorPart;class=class="str">"cmt">// half corridor size for the profit of all orders
  class="type">int LossPointsCorridorPart;class=class="str">"cmt">// half corridor size for the loss of all orders
  class="type">int OrdersToOneBar;class=class="str">"cmt">// orders of one type per class="num">1 bar
  ENUM_GRID_WEIGHT WeightStopLimitFillingType;

  PositionGenerator( ENUM_GRID_WEIGHT WeightStopLimitFillingType0
                    ,class="type">int HalfCorridorLimitStop0,class="type">int OrdersToOneBar0,class="type">int BarsTotal0
                    ,class="type">int ExpirationOpenLimit0,class="type">int ExpirationOpenStop0
                    ,class="type">int ExpirationClose0
                    ,class="type">int ProfitPointsCorridorPart0,class="type">int LossPointsCorridorPart0
                    ,class="type">class="kw">double VolumeAlphaStop0,class="type">class="kw">double VolumeAlphaLimit0,class="type">class="kw">double VolumeAlphaMarket0)
                    : BarBox(OrdersToOneBar0,BarsTotal0)
    {
    VolumeAlphaStop=VolumeAlphaStop0;
    VolumeAlphaLimit=VolumeAlphaLimit0;
    VolumeAlphaMarket=VolumeAlphaMarket0;
    OrdersToOneBar=OrdersToOneBar0;

常见问题

可作隐喻辅助判断:惯性对应趋势延续概率,阻尼对应阻力位消化。但外汇贵金属高风险,仅作参考不单独决策。
未平仓量差反映多空仓位失衡,可分离出价格中偏确定的驱动分量。建议拿历史数据回测该分量对拐点的领先性。
小布盯盘的 AIGC 已内置这类诊断,打开对应品种页即可看到实时仓位情绪与量差提示,省去手算。
先找生成器基类的订单容器定义,弄清它如何塞入多空单。再顺着容器读取逻辑反推情绪计算入口。
公式把模式转成可回测变量,避免主观画线偏差。可先挑一个形态写成等式,跑历史验证命中率再实盘。