教程 · 单套解锁 教程 · EA量化教学

EA07 PowerLanguage/EasyLanguage 策略

使用手册 + 操作教程 共 19 章全部免费开放,一步一步把软件用起来;核心知识点 7 章,¥69 一次解锁讲透原理。

作者 枢汇安全课堂 更新 2026-10-13 阅读 67 收录 EA量化教学 · 26 章
本课程 · 单套解锁
¥69¥104
单品永久解锁 · 会员可阅 · 一次购买终身使用
✓使用手册 + 操作教程 共 19 章全文免费 ✓核心知识点 7 章,¥69 一次解锁 ✓支持电脑 / 手机 · 永久免费更新
注册后解锁核心知识点
免费学习区 使用手册 + 操作教程 共 19 章全部免费开放 · 核心知识点 7 章为付费内容 ¥69 解锁核心知识点
PART ONE

使用手册

功能在哪 · 是什么 · 怎么调出来

一、PowerLanguage / EasyLanguage 是什么

1、两种语言的关系

  • EasyLanguage:TradeStation 在 1980 年代发明的策略语言,类 Pascal 语法,接近英文口语
  • PowerLanguage:MultiCharts 对 EasyLanguage 的高度兼容复刻,绝大多数代码可以直接复制过去用
  • 两语言都是事件驱动 + 逐 Bar 计算:每根K线收盘时从头到尾把代码跑一遍

2、与其他策略语言的差别

语言平台语法风格
EasyLanguage / PowerLanguageTradeStation / MultiCharts类 Pascal,像写英文句子
MQL4 / MQL5MT4 / MT5类 C,逐笔事件驱动
Pine ScriptTradingView类 Python,序列化计算
白话注解:EasyLanguage 是"期货界的英语"。1980 年代 TradeStation 发明的,后来 MultiCharts 几乎一模一样地复刻过来。学一个,两个平台都能用。它最大的特点是"像人话"——Buy next bar at market; 翻译过来就是"下一根K线开盘市价买入",不需要学多少编程概念。

3、三种脚本类型

类型用途能不能自动下单
Indicator(指标)画线、标记、报警不能
Signal(信号/策略)产生买卖信号,可回测可实盘能
Function(函数)可复用的计算模块—

写自动交易,用的就是 Signal。

PART TWO

操作教程

一步一步 · 跟着做完一件事

二、程序结构与声明顺序

1、官方要求的声明顺序

EasyLanguage 要求代码按固定顺序组织:

  1. Inputs(参数声明)
  2. Variables(变量声明)
  3. 变量赋值语句
  4. Plot 语句(仅指标用)
  5. 买卖语句(仅策略用)
Inputs: FastLen(10); { 1. 参数 }
Variables: FastMA(0), n(0); { 2. 变量 }
FastMA = Average(Close, FastLen); { 3. 赋值 }
n = CurrentBar; { 3. 赋值 }
Plot1(FastMA, "Fast"); { 4. 画线(指标) }
If ... Then Buy ...; { 5. 下单(策略) }

2、语言基本规则

  • 不区分大小写:close 和 Close 是同一个词。但建议固定大小写提高可读性
  • 每条语句以分号 ; 结尾
  • 注释:单行用 //,多行用 { } 大括号
  • 非执行词:of、the、at 等词只为提高可读性,执行时被跳过
  • 回车、空格、缩进不影响执行,仅为可读性服务

3、常用标点速记

标点作用
;语句结束
( )函数参数 / 声明初始值
,分隔参数或多个声明
[ ]历史偏移(取过去K线)或数组下标
" "文本字符串(如订单名、Plot 名)
{ }多行注释
//单行注释

三、Inputs 参数与 Variables 变量

1、Inputs:用户可调的参数

Inputs:
FastLength(10), { 默认 10 }
SlowLength(30), { 默认 30 }
StopLoss(500), { 默认 500(美元) }
TakeProfit(1000); { 默认 1000(美元) }
  • 括号里是默认值,加到图表后可以在"格式化"对话框里改
  • 改参数不用改代码,回测优化就是批量改 Inputs 试出最优组合

2、Variables:内部变量

Variables:
FastMA(0), { 数值型,初始 0 }
IsReady(False), { 布尔型 }
Tag("LE"); { 字符串型 }
  • 类型由初始值决定:数字、布尔(True/False)、字符串
  • 每根新K线,变量保持上一根的值继续算(除非声明为临时变量 Value1/Value2…,它们每根K线自动清零)

3、手数:代码说了算

下单时不写手数,就用策略属性(Strategy Properties)里 Trade size 的设置;代码里写了手数,就以代码为准:

Buy ("LE") 500 shares Next Bar at Market;
Sell Short ("SE") 10 contracts Next Bar at Market;
  • shares 和 contracts 是同义词,股票用 shares 顺眼,期货用 contracts 顺眼
  • 手数可以是变量,实现动态仓位(见第十八章)

四、价格数据与历史引用

1、基础价格序列

保留字含义
Open / High / Low / Close(或 O/H/L/C)当前K线开高低收
Volume(或 V)成交量
Date / Time当前K线日期/时间

2、历史偏移 [n]

Close[1] { 上一根K线收盘价 }
High[2] { 前两根K线最高价 }
Average(Close, 10)[1] { 均线在上一根K线的值 }
  • [0] 是当前K线,[1] 是上一根,以此类推

3、跨周期引用:HighD / LowD / CloseD / OpenD 家族

【注意】警告:常见误解纠正。 HighD(1) 不是"上一根K线的最高价"——它是前一个交易日(日线级别)的最高价。这个家族的正确含义:

函数含义
HighD(1)前一交易日的最高价(分钟图、Tick图、日线图上都可用)
LowD(1)前一交易日的最低价
CloseD(1)前一交易日的收盘价
OpenD(0)今天的开盘价(0 = 今日,1 = 前一交易日)

官方使用要点:

  • 参数 PeriodsAgo 表示"往前数几个交易日",0 = 今天
  • 图表里必须加载了足够的历史数据。比如要在 5 分钟图上取 25 天前的日内高点,图上至少要有 26 个完整交易日的 5 分钟数据;数据不够时函数返回 -1
  • 函数以午夜零点作为"新的一天"分界。如果你交易夜盘品种、想按"收盘即隔天"来分日,官方建议改用 HighSession / LowSession 系列
  • 家族还包括周线月线年版:HighW / HighM / HighY(低开收同理)

官方示例——在前一日高点挂空头限价单:

SellShort Next Bar at HighD(1) Limit;

4、其他常用序列函数

Highest(High, 20) { 最近 20 根K线的最高价 }
Lowest(Low, 20) { 最近 20 根K线的最低价 }

五、常用内置函数

1、均线与波动率

函数签名说明
AverageAverage(Price, Length)简单移动平均 SMA
XAverageXAverage(Price, Length)指数移动平均 EMA
AvgTrueRangeAvgTrueRange(Length)ATR 真实波幅均值
StandardDevStandardDev(Price, Length, 1)标准差。第 3 参 =1 是总体标准差(除以 N),=2 是样本标准差(除以 N-1)
白话注解:手写布林带时第三参要填 1。填 2 会算出样本标准差,带宽比标准布林带更宽,这是最经典的"ddof 坑"。

2、经典指标

函数签名说明
RSIRSI(Close, 14)相对强弱指数
MACDMACD(Price, FastLen, SlowLen)MACD 值 = 快 EMA − 慢 EMA,三参数
BollingerBandBollingerBand(Price, Length, NumDevs)布林带。NumDevs 正数取上轨,负数取下轨
ADXADX(Length)平均趋向指数

【注意】警告 1:MACD(Close, 12, 26, 9) 是错误写法。内置 MACD 函数只接受三个参数。想要"信号线(DEA)",要自己对 MACD 值再取均值:

Variables: MacdLine(0), SignalLine(0);
MacdLine = MACD(Close, 12, 26); { DIF:三参数 }
SignalLine = XAverage(MACD(Close, 12, 26), 9); { DEA:手动二次平均 }

【注意】警告 2:布林带函数名是 BollingerBand,不存在 Bollinger(Close, 20, 2) 这个函数。官方签名 BollingerBand(Price, Length, NumDevs),NumDevs 为标准差倍数:

Variables: UpBand(0), LoBand(0);
UpBand = BollingerBand(Close, 20, 2); { 上轨 }
LoBand = BollingerBand(Close, 20, -2); { 下轨 }

两个警告都对照 TradeStation 官方函数帮助页核实过。

3、数学与取整

MaxList(A, B, C) { 取最大 }
MinList(A, B, C) { 取最小 }
Floor(4.5) { 向下取整 = 4 }
Ceiling(4.5) { 向上取整 = 5 }
Round(142.3215, 2) { 四舍五入到 2 位 = 142.32 }
Abs(-3) { 绝对值 }
Power(2, 10) { 2 的 10 次方 }

六、四个下单指令与五种委托方式

1、四个下单指令

指令作用
Buy建立多头(有空仓会先平空再开多)
Sell Short建立空头
Sell平掉多头
BuyToCover平掉空头

【注意】警告:平空指令是 BuyToCover,一个词连写,不是 Buy To Cover。

官方语法骨架(方括号部分可选,只有指令词和委托方式是必填):

Buy [("订单名")] [手数 shares/contracts] [委托方式];

2、五种委托方式(官方枚举)

写法含义
this bar on close当前K线收盘价成交
next bar at open(= next bar at market)下一根K线开盘市价
next bar at 价格 limit下一根K线限价单
next bar at 价格 stop下一根K线止损单
Buy ("LE") Next Bar at Market; { 下一根开盘市价开多 }
Buy ("LE") 10 Contracts Next Bar at 50 Stop; { 突破 50 止损单开多 }
Buy 2 Shares Next Bar at 100 Limit; { 100 以下限价开多 }
Sell ("LX") Next Bar at Market; { 平多 }
BuyToCover ("SX") Next Bar at Market; { 平空 }
If Time = 1500 Then Sell This Bar on Close; { 收盘平仓 }

3、This Bar 的三条官方铁律(错误码核实)

TradeStation 官方语法错误码表明确列出:

错误码规则
30262市价单只能用于 next bar。Buy This Bar at Market 直接报错
30263止损单和限价单只能用于 next bar,不能放在 this bar
30264this bar 只能搭配 on close,别无选择
白话注解:因为代码永远是在"当前K线收盘"这一刻跑的,当前K线已经走完了,你不可能在它的盘中"现在"成交。想今天收盘走人,只能写 Sell This Bar on Close;想盘中止损,只能提前一根K线挂好 next bar at 价格 Stop。

4、委托生命周期:一根 Bar

策略委托只活一根K线:下一根K线内没成交的限价/止损单会被取消,不会一直挂着。想持续挂单,必须每根K线重新满足条件重新发单。这个特性和 MT4 的挂单完全不同,迁移过来的人经常踩。

5、给订单起名

多个进场信号混在一个策略里时,给每个进场起名字,图表箭头和绩效报告里都能分清是谁下的:

Buy ("Breakout") Next Bar at Highest(High, 20)[1] + 1 Point Stop;
Buy ("Pullback") Next Bar at Average(Close, 20) Limit;

起名后还能把平仓单绑定到指定进场单(在 Sell 语句里用 From Entry 语法指定),实现分批分次出场。

七、持仓与绩效查询

1、MarketPosition:持仓方向

If MarketPosition = 1 Then ... { 持多 }
If MarketPosition = -1 Then ... { 持空 }
If MarketPosition = 0 Then ... { 空仓 }

MarketPosition(1) { 前一个仓位的方向(参数 = 往前数第几个仓位,最多 10) }

【注意】注意:MarketPosition 只告诉你方向,不告诉你手数。

2、CurrentContracts:持仓手数

If CurrentContracts = 10 Then ...

只有数量没有方向——和 MarketPosition 正好互补。两个一起用才知道"持多 10 手"。

3、进出场明细

函数含义
EntryPrice(Num)第 Num 个仓位(0=当前,最多回看 10 个)的进场价
EntryDate(Num) / EntryTime(Num)进场日期/时间
BarsSinceEntry(Num)距离第 Num 个仓位进场过了几根K线。只在策略内有效

【注意】BarsSinceEntry 的官方特别提醒:它的返回值在 this bar 单和 next bar 单下行为不同——next bar 进场的,在"发单那根K线收盘"和"成交那根K线"都返回 0;this bar 进场的,发单那根返回的是旧仓位的值。做"进场满 N 根K线离场"时务必用实盘同款委托方式回测。

4、绩效与浮动盈亏

OpenPositionProfit { 当前浮动盈亏(美元) }
NetProfit { 已平仓净利累计(美元) }
TotalTrades { 已完成交易笔数 }

官方示例——浮盈达标就走:

If OpenPositionProfit >= 200 Then Begin
    Sell Next Bar at Market;
    BuyToCover Next Bar at Market;
End;

5、当日进场次数:EntriesToday / ExitsToday

If EntriesToday(CurrentDate) >= 3 Then ...
   { 今天已进场 3 次就不再进场。只在策略内可用,最多回看 10 个仓位 }
  • 参数填日期(如 CurrentDate 或 Date),返回当天进场次数
  • 对应还有 ExitsToday
  • 夜盘坑见第十七章

6、图表周期判断

BarType { 0=Tick 1=分钟 2=日线 3=周线 4=月线 }
BarInterval { 分钟线的分钟数,如 5 分钟图返回 5 }

If BarType = 1 and BarInterval = 5 Then ... { 只在 5 分钟图生效 }

7、品种属性:让止损代码跨品种通用

保留字含义
MinMove / PriceScale最小跳动价格 = MinMove / PriceScale(即 Point)
Point一个最小跳动单位的价格值
BigPointValue价格整数变动 1 对应的美元价值(如 E-mini S&P = 50)
白话注解:写 + 1 Point 平台自动换成该品种的最小跳动值;写美元金额时乘 BigPointValue 把"几点"换算成"几美元"。有了这两个词,同一套代码换品种不用改数字。

八、内置止损六件套与单位陷阱

1、六个内置止损指令(官方全表)

指令作用
SetStopLoss(Amount)亏损达 Amount 触发市价离场
SetProfitTarget(Amount)盈利达 Amount 触发市价离场
SetBreakEven(Floor)浮盈超过 Floor 后,止损上移到进场价
SetDollarTrailing(Amount)从最大浮盈回撤 Amount 触发离场(美元追踪止损)
SetPercentTrailing(Floor, Pct)浮盈超过 Floor 后,从峰值利润回撤 Pct(小数,如 0.5 = 50%)触发离场
SetExitOnClose收盘强制平仓

2、最大的单位陷阱:Amount 是美元,不是点!

官方文档原文:SetStopLoss 的 Amount 参数是 "Amount of loss, in dollars"(亏损金额,单位美元)。旧教程里"SetStopLoss(50) = 止损 50 点"是错误理解:

口径切换词Amount 的含义
SetStopPosition(默认,可不写)Amount = 整个仓位的美元盈亏
SetStopContract / SetStopShare(同义)Amount = 每手/每股的美元盈亏

官方两个对照示例:

{ 整仓口径:500 股 MSFT,SetStopLoss(200) = 全仓亏 200 美元离场,即每股 0.4 美元 }
SetStopPosition; { 默认,可省略 }
SetStopLoss(200);

{ 每股口径:SetStopLoss(0.6) = 每股亏 0.6 美元离场,500 股全仓亏 300 美元 }
SetStopShare;
SetStopLoss(0.6);

3、跨品种通用的正确姿势:SetStopContract + BigPointValue

官方教程给出的模板——把"点数"换算成美元再交给内置止损:

Inputs: StopPts(5);
Vars: StopAmt(0);

StopAmt = StopPts * BigPointValue; { 点数 → 美元 }
SetStopContract;
SetStopLoss(StopAmt); { 每手亏 StopPts 个大点离场 }

4、内置止损的三个特性(官方原文核实)

  1. 进场当根 Bar 就生效:内置止损由策略引擎内部逐 tick 监控,不受逐 Bar 计算限制——长周期图(30 分钟/小时/日线)上尤其有用,不用等下一根K线才知道止损打掉了
  2. 触发即市价单:打掉就发市价单离场,信号名固定为 Stop Loss 等
  3. 断网即失效:官方明确注明,这种止损单由你本机电脑监控,一旦断开网络连接,止损就不再工作。实盘必须理解这一点(详见第二十一章)
白话注解:内置止损是"引擎帮你盯",不是"交易所服务器帮你盯"。它不是送进券商的真止损单。电脑关了、网断了、软件崩了,止损就没了。想挂真止损到交易所,得手写 next bar at 价格 Stop 的离场单(配合支持持续挂单的券商设置)。

九、交叉判断 Crosses Over / Under

1、官方写法

If FastMA Crosses Over SlowMA Then ... { 上穿 }
If FastMA Crosses Under SlowMA Then ... { 下穿 }

Crosses Over / Crosses Under 两个词必须成对出现,官方错误码 30291 明确:只写 Crosses 不带 Over/Under 直接报语法错。

2、两个官方错误码

错误码规则
30291Cross 后面缺 Over/Under → 报错
30292两个常量之间不能 Cross(10 Crosses Over 15 报错——常数永远不会穿越)

3、等价函数写法

内置也有函数形式的交叉判断:

CrossesAbove(FastMA, SlowMA) { 返回 True 当根K线发生上穿 }
CrossesBelow(FastMA, SlowMA)

自己手写等价逻辑则是一根K线的状态组合:

GoldenCross = FastMA > SlowMA and FastMA[1] <= SlowMA[1];

手写版的好处是能精确控制"上一根相等算不算穿越"这类边界条件。

十、Next Bar 执行模型与未来函数

1、执行模型

  • 策略代码在每根K线收盘时执行一遍
  • 此时发出的委托在下一根K线上成交(市价=开盘价)
  • 所以策略天然没有"用当前K线收盘价信号、又按同一价格成交"的作弊空间

2、未来函数从哪来

虽然框架帮你防了大部分,这些写法照样能造出未来函数:

  1. 引用未收盘数据做决策还按当根价格成交:IOG 模式下用 Close[0](还在跳动的当前价)判断并立即发单,历史回测会用收盘值模拟、实盘却是半截价——回测虚高
  2. Highest/Lowest 包含当前未走完的 Bar:突破策略里 Highest(High, 20) 包含了当前Bar,买点实际永远高于"真实突破价"。规范写法用 Highest(High, 20)[1]——上一根为止的 20 根最高
  3. 指标回看长度不足:MaxBarsBack 太小会让指标从头算错若干根

3、MaxBarsBack

任何用到 Close[100] 或 100 周期均线的策略,都要求平台往前加载足够的历史Bar。两个办法:

  • 策略属性里手动设置 MaxBarsBack ≥ 你用到的最大回看长度
  • 或选 Auto Detect 让平台自己猜(偶尔猜小了,前几十根K线信号不可信,回测开头那段别当真)

十一、限价/止损单的"一根 Bar 寿命"与追单

1、问题:委托当根未成交就取消

{ 想在突破位挂买单,但下一根没碰到就没了 }
If MarketPosition = 0 Then
    Buy Next Bar at Highest(High, 20)[1] + 1 Point Stop;

策略委托的生命只有一根K线。好处是不会留一堆陈年旧单;坏处是条件消失后单就没了。

2、解决:状态变量保持条件

Inputs: SetupLen(3);
Variables: PendBuy(False), Trigger(0);

{ 盘整 3 根后记录触发价,进入挂单状态 }
If MarketPosition = 0 and Highest(High, SetupLen)[1] = Lowest(High, SetupLen)[1] + 3 * Point Then Begin
    PendBuy = True;
    Trigger = Highest(High, SetupLen)[1] + 1 Point;
End;

{ 挂单状态持续期间,每根K线都重发委托 }
If PendBuy and MarketPosition = 0 Then
    Buy Next Bar at Trigger Stop;

{ 已进场就清状态 }
If MarketPosition = 1 Then PendBuy = False;

3、限价单与止损单的方向约定

买方向逻辑
Buy at X LimitX 或更低成交(低价接)
Buy at X StopX 或更高成交(突破追)
Sell at X LimitX 或更高成交(高价出)
Sell at X StopX 或更低成交(跌破走)

方向写反了,委托每根都会被立即取消或立即成交,回测里表现为"莫名秒进秒出"。

十二、IOG 逐笔计算

1、什么是 IOG

Intrabar Order Generation(逐 Bar 内下单):默认模式下策略每根K线收盘才算一次;打开 IOG 后,实时行情每个 tick 都会触发计算(历史回测按开高低收四个点模拟),可以在K线内部反复进出。

2、打开方式

  • MultiCharts:Format Signal → Properties 勾选 Intrabar Order Generation;.NET 信号也可用类特性 [IOGMode(IOGMode.Enabled)]
  • TradeStation:Format Strategy → Calculation 勾选 Intrabar Order Generation

3、IOG 的代价(官方明确)

  1. 历史回测精度依赖数据:逐Bar模拟只有开高低收四个点,实盘 tick 走势复杂得多——IOG 策略回测与实盘差异天然大
  2. 每 Bar 进出次数要设限:MC 官方提供三档——每根 Bar 限一次进场+一次出场 / 只许一次进场一次出场 / 不限次数。不限次数+震荡行情=疯狂来回打脸
  3. 与"下一根开盘"模式互斥:MC 官方注明,[IOGMode(IOGMode.Enabled)] 和 [CalcAtOpenNextBar(true)] 两个特性同时用会直接报错

4、MC 特有:开盘计算模式

MC .NET 支持 [CalcAtOpenNextBarAttribute(true)]:改为在下一根K线开盘时用当前收盘数据计算。此时下一根开盘价已经真实可知:

double o_next_bar = Bars.Open[-1]; { 下一根的开盘价 }
double h = Bars.High[0]; { 已收盘那根的最高价 }
if (o_next_bar > h) sellshort_order.Send(); { 跳空高开做空 }

官方示例用它写"跳空策略":开盘跳空向上就做空、跳空向下就做多。传统"next bar at market"模式下开盘价是估不出来的,这个模式才写得出来。

白话注解:新手建议老实待在默认逐 Bar 收盘模式。IOG 是给剥头皮和高频准备的,回测可信度先掉一半,还得自己处理防重复下单。

十三、多数据流 Data2

1、引用第二个品种

图表上可以插入多个数据流(不同品种或不同周期),代码里用 Data 编号引用:

If Close of Data2 > Average(Close of Data2, 50) Then ...
If Average(Close, 4) of Data2 > 0 Then ...

2、官方限制:next bar 价格禁止混用副数据流

官方错误码 30265:同一个策略里,既引用 Open Next Bar / Time Next Bar 这类"下一根价格",又引用 Data2 副数据流,直接报错。官方建议:拆成两个策略分别挂图。

{ 同一个策略里这两句并存会触发 30265: }
If Open Next Bar > High Then SellShort Next Bar at Open Next Bar + Range Limit; { 用了 next bar 价格 }
If Average(Close, 4) of Data2 > 0 Then ... { 用了 Data2 }

3、使用注意

  • Data2 的K线周期和 Data1 不同步时,Close of Data2 取的是"Data2 上最近一根已收盘K线"的值
  • Data2 数据加载不足会让策略前期信号全错,检查图表加载量

十四、Print 调试与格式化输出

1、Print 语句

Print(Date, " ", Time, " Close=", Close, " MP=", MarketPosition);
  • 输出到编辑器的打印日志(PowerEditor 的 Output / Print Log 窗口)
  • 回测时逐根输出,排查"为什么这根没进场"全靠它

2、格式化数字

默认打印可能糊成一团,用 :宽度:小数位 格式:

Print(Close:5:2, " ", MyValue:8:5); { 5 位宽 2 位小数;外汇期货常用 5 位小数 }

3、文件输出

FileAppend("C:\temp\log.txt", NumToStr(Close, 2) + NewLine);

【注意】官方限制:文件路径不能超 260 字符、不能含非法字符,路径写错直接报语法错。Print 够用就别用文件。

十五、防重复下单与每日次数限制

1、防重复:持仓守卫

信号条件可能连续几根K线都成立,不加守卫会反复进场:

{ 只在空仓时进场 }
If MarketPosition = 0 and FastMA Crosses Over SlowMA Then
    Buy Next Bar at Market;

{ 反手场景:持多才允许翻空,反之亦然 }
If MarketPosition = 1 and FastMA Crosses Under SlowMA Then
    Sell Short Next Bar at Market;

2、EntriesToday 限次与"夜盘重置"坑

If MarketPosition = 0 and Condition1 and EntriesToday(CurrentDate) < 3 Then
    Buy Next Bar at Market;

官方口径:EntriesToday 只能在策略里用,最多回看 10 个仓位。 它按自然日(午夜)重置——夜盘品种半夜翻日,次数限制会在盘中突然清零,约束失效。想按"交易日"控制次数,用手动计数器:

Variables: TradesCounter(0), MP(0);

MP = MarketPosition;

{ 发现仓位方向从 0 变成非 0 → 新进场,计数 +1 }
If MP <> 0 and MP[1] = 0 Then
    TradesCounter = TradesCounter + 1;

{ 跨日清零(分钟图) }
If Date <> Date[1] Then
    TradesCounter = 0;

If TradesCounter < 15 and Condition1 and MarketPosition = 0 Then
    Buy Next Bar at Market;

手动计数器还能按你自定义的时间点重置(比如美股日盘开盘清零),灵活性远超 EntriesToday。

十六、TradeStation 与 MultiCharts 差异对照

1、平台定位

维度TradeStationMultiCharts
语言EasyLanguagePowerLanguage(兼容 EL)
编辑器EasyLanguage PowerEditorPowerLanguage Editor(独立窗口)
编译/校验Verify(校验)按钮F7 编译
经纪商绑定与 TradeStation 券商深度绑定独立软件,支持多家经纪商与数据源接入
.NET 扩展无(用自家 C# / TSData 组件体系)PowerLanguage .NET(C#)

2、代码兼容性

  • 绝大多数核心语法一致:Inputs/Variables/Buy/Sell Short/SetStopLoss/MarketPosition 等两边通用
  • 个别函数实现细节与默认参数不同,复制代码后先编译看报错,再逐个修
  • 回测设置项名称不同(TS 在 Format Strategy 的 Calculation 页,MC 在 Properties 页),功能基本对应
白话注解:国内用户用 MultiCharts 更多(能接国内期货公司通道);TradeStation 适合美股期货用户。学语言时不用纠结平台,语法 95% 以上通用。

十七、PowerLanguage .NET(C# 扩展)

1、适用场景

纯 PowerLanguage 写不动的逻辑(复杂循环、外部数据接口、自定义集合运算),MultiCharts 提供 .NET 版本,用 C# 写策略。官方手册结构:Signal 类继承 SignalObject,核心是三个生命周期方法。

2、官方核实过的最小骨架

【注意】警告:老教程里 Exec.Buy("LE", 1, ...)、Bars.Close[0].EMA(10)、CrossAbove(fast, slow) 这类写法在 PowerLanguage .NET 里不存在(对照 MultiCharts 官方《How to Create a .NET Strategy》教程核实)。官方下单模式是 OrderCreator 创建订单对象 + Send() 发送:

public class MyFirstSignal : SignalObject
{
    public MyFirstSignal(object _ctx) : base(_ctx) { }

[Input] public int FastLength { get; set; } // 输入参数 = 带特性 [Input] 的属性
    [Input] public int SlowLength { get; set; }

private IOrderMarket m_LE; // 订单对象
    private IOrderMarket m_SE;
    private IOrderMarket m_LX;
    private IOrderMarket m_SX;
    private ISeries<double> m_fast;
    private ISeries<double> m_slow;

protected override void Create() // 启动时执行一次:建对象
    {
        m_LE = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "LE", EOrderAction.Buy));
        m_SE = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "SE", EOrderAction.SellShort));
        m_LX = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "LX", EOrderAction.Sell));
        m_SX = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, "SX", EOrderAction.BuyToCover));
    }

protected override void StartCalc() // 每次计算开始:初始化变量
    {
        m_fast = new AverageSeries(Bars.Close, FastLength);
        m_slow = new AverageSeries(Bars.Close, SlowLength);
    }

protected override void CalcBar() // 每根K线执行
    {
        if (m_fast[1] <= m_slow[1] && m_fast[0] > m_slow[0])
m_LE.Send(); // 金叉:发送下一根市价买单
        if (m_fast[1] >= m_slow[1] && m_fast[0] < m_slow[0])
            m_SE.Send();
    }
}

3、关键概念对照表(官方手册核实)

PowerLanguagePowerLanguage .NET
Inputs: Len(10);[Input] public int Length { get; set; },默认值写在构造函数
Variables: x(0);C# 字段 / VariableSeries<double>(跨Bar保持的序列)
Buy Next Bar at Market;OrderCreator.MarketNextBar(new SOrderParameters(...)) 创建,Send() 发送
Close[1]Bars.Close[1]
Average(Close, 10)new AverageSeries(Bars.Close, 10) 等系列类
逐 Bar 收盘计算CalcBar();开盘计算加 [CalcAtOpenNextBarAttribute(true)]
IOG 勾选[IOGMode(IOGMode.Enabled)](与 CalcAtOpenNextBar 互斥)
—Bars.OpenNextBar() / Bars.Open[-1] 取下一根开盘价(开盘计算模式专用)

4、EOrderAction 四枚举(官方教程核实)

枚举对应 PowerLanguage
EOrderAction.BuyBuy
EOrderAction.SellShortSell Short
EOrderAction.SellSell(平多)
EOrderAction.BuyToCoverBuyToCover(平空)

5、使用建议

能用纯 PowerLanguage 就用纯的:调试快、资料多、社区代码能直接抄。.NET 版只在需要复杂计算、访问外部 .NET 库、或做界面化工具时才上。

十八、实盘部署与自动化

1、启动自动化

MultiCharts:

  1. 信号加入图表 → Format Signal → Properties
  2. 勾选 Enable Automation(自动化),选好账户与方向许可(只允许多/只允许空/双向)
  3. 确认 Strategy Properties 里的默认手数、进出规则
  4. 观察信号箭头与 Tracker(策略追踪器)确认下单正常

TradeStation:Format Strategy → Automation 页,勾选实盘账户自动化,逐项确认确认弹窗。

2、断线风险:内置止损不是交易所止损

第九章说过,这里在实盘语境下再说一遍。官方原文:内置止损(SetStopLoss 等)产生的离场单由你的电脑监控,达到条件才发市价单——

  • 断网 → 止损失效
  • 断电、软件崩溃 → 止损失效
  • 策略引擎重算/重载图表时可能出现状态不一致

实盘必做:

  1. 能挂到交易所的真止损就挂真止损(券商端支持的服务器侧 GTC 止损单)
  2. 桌面客户端 7×24 跑策略必须配 VPS:远程 Windows 服务器,装平台、登账户、挂图,电脑关机策略照跑
  3. VPS 上关掉 Windows 自动更新重启,或设置开完机自动登录并自启平台
  4. 每天开盘前人工检查:图表还活着吗?信号状态正常吗?持仓对得上吗?

3、回测 实盘的过桥清单

  • 回测加了手续费与滑点吗?
  • 用模拟盘(Simulation / Paper Trading 账户)跑过至少一个月吗?
  • 先小手数实盘验证成交质量(滑点、拒单、部分成交)了吗?
  • 最大回撤你能承受三倍吗?(实盘回撤几乎必然大于回测)
  • 参数是否过拟合?(同一参数在多个时间段、多个品种上都试过吗)
回测 ≠ 实盘,业绩不代表未来收益。自动化只是执行工具,执行得再快,策略本身没优势就是亏得更快。

十九、从 MQL4 迁移对照表

1、概念映射

MQL4EasyLanguage / PowerLanguage迁移要点
OnInit() / start() / OnTick()无显式函数,整个代码每根Bar跑一遍心法转变:EL 是"每根收盘过一遍全代码"
iMA(...)Average(Close, Len)EL 直接写价格序列,不用传 symbol/timeframe
OrderSend(OP_BUY...)Buy Next Bar at Market;EL 委托只能下一根Bar生效(或 this bar on close)
OrdersTotal() / 持仓查询MarketPosition / CurrentContracts方向和手数分两个保留字
OrderClose()Sell / BuyToCover Next Bar at Market;平多/平空是两个不同指令
Point / MarketInfo(MODE_TICKVALUE)Point / BigPointValueBigPointValue = 价格整数 1 的美元价值
Ask / Bid无直接对应(策略按 Bar 成交模型)EL 是 Bar 级撮合,不直接盯买卖价
止损随单送交易所SetStopLoss 本机监控 / 手写 next bar stop 单EL 内置止损断线失效,见第二十一章
回测:策略测试器图表内直接回测 + Strategy Performance Report回测与图表信号同一套引擎

2、思维转换三条

  1. 从"事件回调"到"逐Bar全量重算":MQL4 想的是"tick 来了执行函数";EL 想的是"每根K线收盘,把整套逻辑从头过一遍"
  2. 从"随时下单"到"下一根Bar成交":EL 的市价单没有"当场成交"概念(IOG 模式除外),信号→成交天然隔一根Bar
  3. 从"仓位自由管理"到"策略仓位模型":EL 平台自带仓位记账(进场名、绩效报告),多数时候不用自己遍历订单
付费专享 · 核心知识点 7 章

继续阅读:核心知识点,搞懂原理

EA07 PowerLanguage/EasyLanguage 策略 — 共 26 章,已免费阅读 19 章,剩余 7 章核心知识点讲透「为什么这样、点了会怎样」。

二十、开发环境与第一个策略
二十一、回测与策略绩效报告
二十二、完整策略精讲:双均线 + ATR 止损
二十三、常见坑 Top10
二十四、常见问题 FAQ 与一页纸速查
二十五、学习路线
…等共 7 章核心内容
✍️ 注册后扫码购买 🔐 已有账号,去登录 单套 ¥69 永久 · 会员可阅
SERVICE & PRICING
服务收费说明 · 明码标价,无隐藏收费
全部课程统一 ¥39-69,买一套永久使用。以下为购买与使用的完整流程。
01先免费试读

每套教程的「使用手册」部分均可免费阅读,先确认内容是否适合自己再决定,不必盲买。

02扫码付款

选定课程后点「立即解锁」,页面展示收款二维码与客服微信,扫码转账即可,无需注册海外支付。

03获取卡密

付款完成后客服第一时间发送卡密号与卡密密码,站内消息与微信同步通知。

04兑换解锁

在用户中心「兑换卡密」输入卡密号与密码,系统即时解锁全部章节,无需二次付款。

一次付费,终身可用 · 解锁后课程永久留在账号里,不限次数、不限时间阅读 持续免费更新 · 平台改版、规则变化时课程同步修订
RECOMMEND
相关教程推荐 · 同栏目更多上手机会

💬 用户评价 (0)

🔒 登录并成为会员后可发表评价
还没有评价 · 成为第一个评价的人吧 🎯