输入/搜索内容
入门
欢迎使用发明者量化交易平台
快速开始
密钥安全性
平台基础
账号与计费
实盘计费与充值
子账号
交易所
通用协议
本地凭据文件
交易所特殊说明
证券与期货
加密货币
托管者
策略库
实盘
编写策略
开发工具
回测系统
进阶专题
数据与研究
对外接口

用各种编程语言编写策略:各语言的说明,策略结构(生命周期、主循环、事件驱动),策略参数,交互控件,模板类库,内置库,以及策略界面文字的多语言写法。

在发明者量化交易平台上,可以使用哪些编程语言来编写我的策略呢?

支持的编程语言

发明者量化交易平台支持使用JavaScript、TypeScript、Python、Rust、PINE、My语言、Blockly可视化以及Workflow工作流来编写和设计交易策略。

平台支持用JavaScript编写策略。运行时基于 QuickJS 引擎,支持async/await、class、BigInt等现代语法;实盘时策略在托管者上运行,回测时在浏览器端的回测系统中运行。在代码中加入// @ts-check即可改用 TypeScript 编写,见 TypeScript。

策略结构与参数

策略入口为function main(),可选的init()、onexit()、onerror(msg)由托管者自动调用,见 策略结构。界面参数是同名的全局变量,可以直接读取,也可以在代码中修改,见 策略参数。

错误与返回值

API 函数调用失败(交易所返回错误、网络问题等)时返回null,并在日志中输出错误信息。使用返回值之前先判断,或者用 _C 重试:

javascript
function main() { var ticker = exchange.GetTicker() // 调用失败时返回 null if (ticker) { Log(ticker) } // 失败时自动重试,直到返回有效数据 var account = _C(exchange.GetAccount) Log(account) }

程序异常(例如读取undefined的属性)和接口业务报错的日志中会显示出错位置在策略代码中的行号,便于调试和排查。

字符串与ArrayBuffer

JavaScript 的字符串是 UTF-16 编码。平台 API 返回的文本如果不是合法的 UTF-8 字节序列,为了不丢失数据,会返回ArrayBuffer(原始字节)。所有可以传入字符串的 API 参数也都接受ArrayBuffer。

javascript
function stringToHex(str) { let hex = '' for (let i = 0; i < str.length; i++) { const charCode = str.charCodeAt(i).toString(16) hex += charCode.length === 1 ? '0' + charCode : charCode } return hex } function main() { // “𠮷”的 Unicode 码点超出 16 位,在 JavaScript 字符串中占两个 UTF-16 码元 const inputString = "abc𠮷123" // Encode 按 UTF-8 编码后输出 hex const encodedHex = Encode("raw", "string", "hex", inputString) Log(encodedHex) // 616263f0a0aeb7313233 // charCodeAt 取的是 UTF-16 码元,“𠮷”被写成 d842、dfb7,结果不是 UTF-8 编码 const manuallyEncodedHex = stringToHex(inputString) Log(manuallyEncodedHex) // 616263d842dfb7313233 // 合法的 UTF-8 字节可以还原为字符串 const decodedString = Encode("raw", "hex", "string", encodedHex) Log(decodedString) // abc𠮷123 // 不是合法的 UTF-8 字节,返回 ArrayBuffer // (如果 inputString 改为 "abcG123",两种编码结果相同,这里得到的是字符串) const outputD = Encode("raw", "hex", "string", manuallyEncodedHex) Log(outputD instanceof ArrayBuffer) // true // 查看 ArrayBuffer 中的原始字节 const bufferD = new Uint8Array(outputD) let hexBufferD = '' for (let i = 0; i < bufferD.length; i++) { hexBufferD += bufferD[i].toString(16).padStart(2, '0') } Log(hexBufferD) // 616263d842dfb7313233 }

异步与多线程

  • setTimeout/clearTimeout:回调在主线程调用Sleep()等待期间执行;main()返回时还没到期的定时器会先执行完,再调用onexit()。
  • fetch(url):返回Promise,结果为响应对象(ok、status、headers属性,text()、json()直接返回内容)。托管者中的fetch在调用时就同步完成请求,返回的是已经完成的Promise,所以用Promise.all组合多个fetch并不会并发请求。
  • 交易所 API(例如exchange.GetTicker())是同步阻塞调用,包装进Promise或async函数也不会并发执行。
  • 需要并发时使用 exchange.Go、HttpQuery_Go,或者用 Thread 创建线程,见 JavaScript多线程。
javascript
async function main() { let resp = await fetch("https://www.okx.com/api/v5/market/books?instId=BTC-USDT") if (resp.ok) { Log(resp.json()) } else { Log("status:", resp.status) } }

库与依赖

JavaScript 策略可以直接使用内置的TA指标库和talib指标库,各语言可用的内置库见 内置库。其它第三方 JavaScript 库可以在运行时下载后用eval加载,示例见同一页。

TypeScript 不是单独的语言选项:创建策略时选择JavaScript,在代码中加入一行// @ts-check(或点击策略编辑区右上角的「TypeScript」按钮),平台就按 TypeScript 处理,在回测和实盘运行前先编译为 JavaScript。通过 AI/MCP 工具保存策略时,语言可以直接写typescript,平台按 JavaScript 策略保存,并在代码开头自动加上//@ts-check,见 AI接入。

静态类型检查能在编写时发现参数个数、属性名、类型用错之类的问题,编辑器的补全也更准确。

最小示例:

ts
// @ts-check interface Signal { side: "buy" | "sell" price: number } function getSignal(ticker: ITicker, ma: number): Signal | null { if (ticker.Last > ma) { return {side: "buy", price: ticker.Last} } if (ticker.Last < ma) { return {side: "sell", price: ticker.Last} } return null } function main() { while (true) { const records = exchange.GetRecords() const ticker = exchange.GetTicker() if (records && ticker && records.length > 20) { const ma = TA.MA(records, 20) const signal = getSignal(ticker, ma[ma.length - 1]) if (signal) { Log(signal.side, signal.price) } } Sleep(60 * 1000) } }

平台 API 的类型声明由策略编辑器内置提供,不需要在代码中引用:全局函数、exchange对象、ITicker、IRecord、IOrder、IPosition等数据结构接口,以及TA、talib等。运行时的语言特性、API 和库与 JavaScript 策略相同,见 JavaScript。

平台支持用Python 3编写策略,不支持 Python 2。实盘以及在托管者上进行的回测,使用托管者所在机器上安装的 Python 解释器运行策略。

解释器

托管者按以下顺序查找解释器,使用第一个能启动、并且版本为 Python 3 的程序:

  1. 环境变量PYTHON_BIN指定的解释器;
  2. python3;
  3. python。

需要使用指定的解释器(例如虚拟环境中的 Python)时,在启动托管者之前设置环境变量:

bash
export PYTHON_BIN=/opt/venv/bin/python3

策略代码首行的#!python3、#!python2等写法不再用于选择解释器。

策略结构与参数

策略入口为def main(),可选的init()、onexit()由托管者自动调用(Python 不支持onerror()),见 策略结构。界面参数是同名的全局变量;在函数中给参数重新赋值时,需要先用global声明。

错误与返回值

API 函数调用失败时返回None,并在日志中输出错误信息。使用返回值之前先判断,或者用_C()重试。策略中未捕获的异常会结束运行,错误信息记录在日志中。

输出

print()的输出写到托管者进程的标准输出,不会出现在实盘日志里。需要显示在日志中的内容请用 Log。

第三方库

策略可以导入解释器中已经安装的任何库。安装时要使用托管者运行策略的那个解释器,例如:

bash
python3 -m pip install numpy # 设置了 PYTHON_BIN 时 $PYTHON_BIN -m pip install numpy

使用talib需要在托管者所在机器上安装 TA-Lib(talib包)和numpy。

自定义模块

策略运行时的当前目录和PYTHONPATH是托管者为本次运行创建的临时目录,运行结束后会被删除;放在托管者程序目录下(例如logs/storage/<实盘ID>/)的.py文件不会被自动找到。导入自己编写的模块有两种方式:

  • 把模块安装到解释器的site-packages中(例如做成包用pip install安装,或者直接复制到site-packages目录);
  • 在策略中先把模块所在目录的绝对路径加入sys.path,再导入。

例如模块文件/home/user/fmz_modules/mymath.py:

python
# mymath.py def add(a, b): return a + b

策略代码:

python
import sys sys.path.append("/home/user/fmz_modules") # 模块所在目录的绝对路径 import mymath def main(): Log("mymath.add(1, 2):", mymath.add(1, 2))

把核心代码做成模块放在自己的托管者上,策略代码中只保留调用部分,也是一种不把核心代码上传到平台的做法。

平台支持用Rust编写策略。Rust 策略先编译再运行:回测时由平台服务器编译,在浏览器端的回测系统中运行;实盘时编译通过后在托管者上运行。策略编辑器为 Rust 集成了rust-analyzer,提供代码补全与实时诊断。

策略结构

策略代码只需要一个fn main()。平台 API(exchange、exchanges、TA、Log!、_C!等)已经自动导入,不需要写use或mod声明。

可选的fn init()、fn onexit()由托管者自动调用,定义即可,不需要注册:init()在main()之前执行;onexit()在main()正常返回、实盘被停止、策略panic时都会执行。Rust 不支持onerror()。详见 策略结构。

rust
fn init() { Log!("初始化"); } fn main() { // 可能失败的 API 返回 Result<T>,_C! 宏在失败时重试,直到调用成功 let ticker = _C!(exchange.GetTicker(None)); Log!("Last:", ticker.Last); } fn onexit() { Log!("策略退出,执行扫尾处理"); }

日志等部分功能以宏的形式提供(注意感叹号):Log!()、LogStatus!()、Panic!()、_G!()、_C!();LogProfit()、Sleep()、_D()、_N()、HttpQuery()等是普通函数。

参数类型

界面参数以同名的全局常量注入策略,只能读取,不能在代码中修改(需要变化的值请复制到局部变量)。类型由参数种类决定:

参数种类Rust 类型
数字型f64
布尔型bool
字符串&str
下拉框(单选)f64(选项索引);选项绑定了字符串数据时为&str
下拉框(多选)&[i64]、&[f64]或&[&str];选项值类型混杂时为 JSON 文本&str
加密串&str或Decrypted(可解引用为str)
  • 整数用途需要自行转换,例如let n = Period as usize;。
  • 选填参数没有填写时为该类型的零值:0.0、""、false,多选下拉框为空。
  • 加密串参数在服务端不能预先解密时(例如私有托管者),注入为static的Decrypted类型,第一次使用时才解密。它实现了Display,可以直接用于format!;传给Log!或其它需要&str的地方写&*参数名(对&str类型的参数同样适用):
rust
fn main() { let key: &str = &*ApiKey; // ApiKey 为加密串参数 Log!("key length:", key.len()); }
  • 参数名与代码中的其它名字冲突时,可以用args::参数名引用参数。

错误与返回值

可能失败的 API 调用返回Result<T>,用 Rust 惯用的方式处理(JavaScript 中失败返回null):

rust
fn main() { // 方式一:模式匹配 if let Ok(ticker) = exchange.GetTicker(None) { Log!(ticker); } // 方式二:_C! 宏在失败时重试,直到调用成功 let ticker = _C!(exchange.GetTicker(None)); Log!(ticker); }

可选参数(例如GetTicker的symbol参数)不传时用None占位,传值时直接传入,例如exchange.GetTicker("BTC_USDT")。

JSON

平台 API 返回的原始 JSON 文本(例如exchange.IO()的返回值、各结构体的Info字段)用内置的JSONParse()解析,得到Option<JsonValue>;用v["key"]、v[0]取子节点,用as_f64()、as_str()、as_bool()等方法取值。JsonValue实现了Display,v.to_string()或format!("{}", v)得到紧凑的 JSON 文本。SDK 没有提供构造 JSON 的便捷接口,生成 JSON 文本可以用format!拼接,或者引入serde_json。

第三方 crate

策略源码是唯一的代码文件(没有单独的Cargo.toml)。在源码最顶部用---包裹的 frontmatter 声明依赖,构建时合并进Cargo.toml:

rust
--- [dependencies] serde_json = "1" --- /*backtest start: 2024-01-01 00:00:00 end: 2024-02-01 00:00:00 period: 1h */ fn main() { let v: serde_json::Value = serde_json::from_str(r#"{"a": 1}"#).unwrap(); Log!("a:", v["a"].to_string()); }
  • frontmatter 必须在源码开头,前面只能有空行;/*backtest ... */回测配置块要放在 frontmatter 结束的---之后。策略中还没有回测配置块时,「保存回测设置」会把配置块插入到源码最前面,这时需要把它移到 frontmatter 之后(之后再保存会在原位置更新)。
  • 策略和它引用的模板类库中,依赖块只能写在其中一处,两处都写会编译失败。
  • 编译环境中没有系统 OpenSSL,需要 TLS 的 crate(HTTP/WebSocket 客户端等)请选用纯 Rust 实现的rustls(例如tokio-tungstenite开启rustls-tls-webpki-roots特性),避免依赖native-tls/openssl-sys;WebSocket 连接优先使用内置的 Dial 函数,不需要第三方 crate。

内置库

Rust 策略可以使用TA指标库,不支持talib,见 内置库。

平台支持My语言(麦语言)编写和设计策略,兼容文华麦语言的大部分语法、指令和函数。My语言鼓励积木式编程,将复杂算法拆解为函数模块。通过简洁的语法、专用数据结构和强大的金融函数库,支持复杂金融逻辑的实现。以模块化方式构建应用,提升开发效率和代码可维护性。

My语言策略范例:基于平移布林通道的系统

mylang
M := 12; // 参数范围 1, 20 N := 3; // 参数范围 1, 10 SDEV := 2; // 参数范围 1, 10 P := 16; // 参数范围 1, 20 // 该策略为趋势跟踪交易策略,适用较大周期,如日线。 // 该模型仅用作模型开发案例,依此入市,风险自负。 //////////////////////////////////////////////////////// // 平移BOLL通道计算 MID:=MA(C,N); // 计算中轨 TMP:=STD(C,M)*SDEV; // 计算标准差 DISPTOP:=REF(MID,P)+TMP; // 平移BOLL通道上轨 DISPBOTTOM:=REF(MID,P)-TMP; // 平移BOLL通道下轨 // 系统入场 H>=DISPTOP,BPK; L<=DISPBOTTOM,SPK; AUTOFILTER;

平台支持并兼容Trading View的PINE语言脚本。PINE语言是一种轻量级但功能强大的策略编程语言,用于创建可进行回测和实盘交易的技术指标与策略。活跃的社区已创作了超过10万个PINE脚本。
用户可以轻松获取并应用各种技术分析工具和交易策略;能够借助社区脚本快速实现交易想法,无需从零开始编写代码,从而大幅缩短开发周期;帮助新手和资深交易员学习并理解不同的技术指标、策略及编程概念。

PINE语言策略示例:超级趋势策略

pine
strategy("supertrend", overlay=true) [supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod")) plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr) plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr) if direction < 0 if supertrend > supertrend[2] strategy.entry("entry long", strategy.long) else if strategy.position_size < 0 strategy.close_all() else if direction > 0 if supertrend < supertrend[3] strategy.entry("entry short", strategy.short) else if strategy.position_size > 0 strategy.close_all()

平台支持Blockly可视化编程方式。借助Blockly编辑器,用户可以通过拼接图形块(类似积木)来表达代码概念,如变量、逻辑表达式、循环等。这种方式使编程过程无需过多关注繁琐的语法细节,而是可以直接按照编程原则进行操作。通过图形块的排列组合,用户能够轻松理解编程逻辑,实现创意想法,非常适合培养策略设计兴趣,快速入门程序化和量化交易。

平台支持 Workflow 工作流方式编写策略。工作流是一种可视化的策略设计方式,通过节点连接和配置来构建交易逻辑,无需编写代码即可实现策略。

工作流特点:

  • 可视化拖拽设计,所见即所得
  • 预置丰富的功能节点(数据获取、指标计算、条件判断、交易执行等)
  • 降低编程门槛,适合快速搭建和验证策略
  • 支持回测功能,可视化查看节点执行状态

学习资源:

JavaScript(含 TypeScript)、Python、Rust策略由几个约定名称的函数组成,托管者在固定的时机调用它们。My语言、PINE、Blockly、Workflow 策略不需要编写这些函数。

生命周期函数

函数是否必须调用时机
main()必须入口函数,策略的主体。main()返回,策略即运行结束。
init()可选在main()之前调用一次,用于初始化。
onexit()可选策略退出时调用,用于扫尾(撤单、平仓、保存状态等)。
onerror(msg)可选仅JavaScript:main()因未捕获的异常结束时调用,msg为错误信息。调用了onerror()就不再调用onexit()。
destroy()可选仅JavaScript模板类库:策略退出时,在onexit()或onerror()之后调用,见 模板类库。

退出时调用哪个函数:

退出原因JavaScriptPythonRust
main()正常返回onexit()onexit()onexit()
停止实盘onexit()onexit()onexit()
未捕获的异常、paniconerror(msg)都不调用onexit()

注意事项:

  • onexit()、onerror()最长执行 5 分钟(时长由服务端按任务下发,默认 5 分钟),超时会被强制结束。
  • 回测中策略通常是不停轮询的死循环,回测结束时main()并没有正常返回,处理方法见 onexit()。
  • JavaScript策略的main()返回时,用threading创建的子线程会被终止;还没有到期的setTimeout回调会先执行完,再调用onexit()。
  • JavaScript、Python模板类库可以定义自己的init(),在模板加载时执行,早于策略的init()。

主循环与事件驱动

大多数策略在main()中写一个循环:每轮获取数据、计算、下单,然后Sleep()等待下一轮,见 主循环。也可以等待行情、订单等事件到达后再处理,见 事件驱动。全部 API 函数的分类速查见 API函数速查。

init() 为用户实现的初始化函数。策略开始运行时,会首先自动执行 init() 函数,以完成策略中设计的初始化任务。

示例

javascript
function main(){ Log("First line of code executed!", "#FF0000") Log("Exiting!") } // 初始化函数 function init(){ Log("Initializing!") }
python
def main(): Log("First line of code executed!", "#FF0000") Log("Exiting!") def init(): Log("Initializing!")
rust
fn main() { Log!("First line of code executed!", "#FF0000"); Log!("Exiting!"); } // 初始化函数 fn init() { Log!("Initializing!"); }

onexit()由用户实现,在策略退出时处理扫尾工作,可以不定义。最长执行 5 分钟,超时会被强制结束。各语言在哪些情况下调用onexit(),见 策略结构。

示例

  • 测试onexit()函数:

    javascript
    function main(){ Log("Starting, will stop after 5 seconds and execute cleanup function!") Sleep(1000 * 5) } // 扫尾函数实现 function onexit(){ var beginTime = new Date().getTime() while(true){ var nowTime = new Date().getTime() Log("Program stop countdown..cleanup started, elapsed time:", (nowTime - beginTime) / 1000, "seconds!") Sleep(1000) } }
    python
    import time def main(): Log("Starting, will stop after 5 seconds and execute cleanup function!") Sleep(1000 * 5) def onexit(): beginTime = time.time() * 1000 while True: ts = time.time() * 1000 Log("Program stop countdown..cleanup started, elapsed time:", (ts - beginTime) / 1000, "seconds!") Sleep(1000)
    rust
    fn main() { Log!("Starting, will stop after 5 seconds and execute cleanup function!"); Sleep(1000 * 5); } // 扫尾函数实现 fn onexit() { let beginTime = Unix() * 1000; loop { let nowTime = Unix() * 1000; Log!("Program stop countdown..cleanup started, elapsed time:", (nowTime - beginTime) / 1000, "seconds!"); Sleep(1000); } }
  • 回测系统中,策略通常写成不停轮询的死循环,回测数据结束时main()并没有正常返回,JavaScript、Python策略因此不会执行onexit()。可以在回测中(IsVirtual()为真)捕获回测结束时抛出的异常(EOF),让main()返回,从而执行onexit()。Rust策略在回测结束时 API 调用返回Err,退出循环即可。

    javascript
    function main() { if (exchange.GetName().startsWith("Futures_")) { Log("Exchange is futures") exchange.SetContractType("swap") } else { Log("Exchange is spot") } if (IsVirtual()) { try { onTick() } catch (e) { Log("error:", e) } } else { onTick() } } function onTick() { while (true) { var ticker = exchange.GetTicker() LogStatus(_D(), ticker ? ticker.Last : "--") Sleep(500) } } function onexit() { Log("Executing cleanup function") }
    python
    def main(): if exchange.GetName().startswith("Futures_"): Log("Exchange is futures") else: Log("Exchange is spot") if IsVirtual(): try: onTick() except Exception as e: Log(e) else: onTick() def onTick(): while True: ticker = exchange.GetTicker() LogStatus(_D(), ticker["Last"] if ticker else "--") Sleep(500) def onexit(): Log("Executing cleanup function")
    rust
    fn onTick() { loop { match exchange.GetTicker(None) { Ok(ticker) => LogStatus!(_D(None), ticker.Last), Err(e) => { // 回测结束时API调用返回Err,退出循环使main返回,从而触发onexit()扫尾函数 Log!("error:", e); break; } } Sleep(500); } } fn main() { if exchange.GetName().starts_with("Futures_") { Log!("Exchange is futures"); let _ = exchange.SetContractType("swap"); } else { Log!("Exchange is spot"); } onTick(); } fn onexit() { Log!("Executing cleanup function"); }

onerror(msg)只有JavaScript(含 TypeScript)策略支持:main()因未捕获的异常结束时调用,参数msg为异常的错误信息。调用了onerror()就不再调用onexit()。最长执行 5 分钟,超时会被强制结束。回测系统不支持该函数。

Python、Rust策略不支持onerror()。

示例

javascript
function main() { var arr = [] Log(arr[6].Close) // 这里故意引发一个程序异常 } function onerror(msg) { Log("Error:", msg) }
python
# Python 不支持
rust
// Rust 不支持

策略通常在main()中写一个循环:每轮获取行情、计算信号、下单,然后调用 Sleep 等待下一轮。Sleep()在回测中推进回测时间、控制回溯速度,在实盘中控制轮询间隔,从而控制访问交易所 API 的频率。循环中不调用Sleep()会以最快速度反复请求交易所接口,容易触发交易所的频率限制。需要在托管者上限制 API 调用频率时,见 API限流控制。

示例

  • 基本框架:

    javascript
    function onTick(){ // 在这里写策略逻辑,将会不断调用,例如打印行情信息 Log(exchange.GetTicker()) } function main(){ while(true){ onTick() // Sleep函数主要用于数字货币策略的轮询频率控制,防止访问交易所API接口过于频繁 Sleep(60000) } }
    python
    def onTick(): Log(exchange.GetTicker()) def main(): while True: onTick() Sleep(60000)
    rust
    fn onTick() { // 在这里写策略逻辑,将会不断调用,例如打印行情信息 Log!(exchange.GetTicker(None)); } fn main() { loop { onTick(); // Sleep函数主要用于数字货币策略的轮询频率控制,防止访问交易所API接口过于频繁 Sleep(60000); } }
  • 举个最简单的例子:每隔1秒钟在交易所挂一个价格为100、数量为1的买单,可以这样写:

    javascript
    function onTick(){ // 这个仅仅是例子,回测或者实盘会很快把资金全部用于下单,实盘请勿使用 exchange.Buy(100, 1) } function main(){ while(true){ onTick() // 暂停多久可自定义,单位为毫秒,1秒等于1000毫秒 Sleep(1000) } }
    python
    def onTick(): exchange.Buy(100, 1) def main(): while True: onTick() Sleep(1000)
    rust
    fn onTick() { // 这个仅仅是例子,回测或者实盘会很快把资金全部用于下单,实盘请勿使用 let _ = exchange.Buy(100, 1); } fn main() { loop { onTick(); // 暂停多久可自定义,单位为毫秒,1秒等于1000毫秒 Sleep(1000); } }
  • 按K线更新处理的策略(On Bar):最新一根K线的时间变化时才执行onTick():

    javascript
    function onTick() { Log("K-line updated, new BAR generated") } function main() { var exName = exchange.GetName() if (exName.includes("Futures_")) { exchange.SetContractType("swap") } var lastTs = 0 while (true) { var r = _C(exchange.GetRecords) if (r.length > 0 && r[r.length - 1].Time != lastTs) { onTick() lastTs = r[r.length - 1].Time } Sleep(1000) } }
    python
    def onTick(): Log("K-line updated, new BAR generated") def main(): exName = exchange.GetName() if "Futures_" in exName: exchange.SetContractType("swap") lastTs = 0 while True: r = _C(exchange.GetRecords) if len(r) > 0 and r[-1]["Time"] != lastTs: onTick() lastTs = r[-1]["Time"] Sleep(1000)
    rust
    fn onTick() { Log!("K-line updated, new BAR generated"); } fn main() { let exName = exchange.GetName(); if exName.contains("Futures_") { let _ = exchange.SetContractType("swap"); } let mut lastTs = 0; loop { let r = _C!(exchange.GetRecords(None, None, None)); if r.len() > 0 && r[r.len() - 1].Time != lastTs { onTick(); lastTs = r[r.len() - 1].Time; } Sleep(1000); } }

除了按固定间隔轮询,策略也可以等待事件到达后再处理,减少无效请求,也能更快地响应行情变化。

EventLoop

EventLoop 等待exchange.Go()、HttpQuery_Go()等并发任务完成、WebSocket 连接有可读数据、线程消息等事件;有事件时返回事件信息,策略再去读取对应的数据。第一次调用EventLoop()时才开始记录事件,所以先调用一次EventLoop(-1)再发起并发任务:

javascript
function main() { EventLoop(-1) // 开始记录事件,避免错过之后发生的事件 var r1 = exchange.Go("GetTicker") var r2 = exchange.Go("GetDepth") var ev = EventLoop(1000) // 等待任意一个并发任务完成,最多等 1 秒 Log("event:", ev) Log("ticker:", r1.wait(), "depth:", r2.wait()) }

ctx.subscribe / ctx.poll

JavaScript和Rust策略还可以使用托管者的事件订阅接口:ctx.subscribe()订阅某个账户、某个品种的行情或订单回报,返回流 ID;ctx.poll()取出下一条事件(可以设置等待超时),策略按事件的kind分别处理。Python策略不支持。

javascript
function main() { ctx.subscribe(0, "BTC_USDT", {channel: "ticker"}) // 第一个参数是账户在 exchanges 中的下标 ctx.subscribe(0, "", {channel: "orders"}) // 订单回报 while (true) { const ev = ctx.poll([], 1000) // [] 表示所有订阅,最多等 1 秒 if (!ev) { continue } if (ev.kind === 1) { Log("ticker:", ev.symbol, ev.bid, ev.ask, ev.last) } else if (ev.kind === 16) { Log("order:", ev.id, ev.state, ev.filledQty) } } }
  • channel可选"ticker"、"bbo"、"depth"、"trade"、"kline"(interval为周期秒数)、"orders"。
  • 事件的kind:1 为 ticker,3 为深度(事件只表示订单簿已更新,档位用ctx.book(ev.ex, ev.symbol, n)读取),4 为成交,5 为 K 线,16 为订单回报。
  • 行情类订阅消费不及时会只保留最新数据或丢弃最旧的数据,订单回报不会丢弃,策略需要持续调用ctx.poll()。

Rust策略中的写法为ctx::subscribe()、ctx::poll(),事件为原始结构,价格、数量是定点整数:

rust
fn main() { let s = ctx::subscribe(0, "BTC_USDT", ctx::SubOpts::ticker()).unwrap(); loop { match ctx::poll(&[s], Some(1000)) { ctx::Polled::Event(ev) => Log!("event kind:", ev.kind), ctx::Polled::Stopped => break, _ => {} } } }

按API手册的分类列出全部函数、结构体和常量,每项一句话说明,点击名称查看完整文档。本页由doc_tools/gen_api_index.py根据手册生成。

内置函数

Global

名称说明
Version返回当前系统版本号。
IsVirtual用于判断策略的运行环境是否为回测系统。
GetOS获取托管者所在设备的操作系统信息。
GetPid获取实盘进程的 ID。
GetMeta获取在生成策略注册码时写入的Meta值。
Sleep休眠函数,使程序暂停运行一段指定的时间。
Unix获取当前时刻的秒级时间戳。
UnixNano获取当前时刻的纳秒级时间戳。
_D将毫秒级时间戳或Date对象转换为时间字符串。
GetCommand获取策略的交互命令。
GetLastError获取最近一次的错误信息。
SetErrorFilter过滤错误日志。
_N格式化浮点数。
_C重试函数,用于对接口调用进行容错处理。
_Cross返回数组arr1与数组arr2的交叉周期数。
JSON.parseJSON.parse函数是ECMAScript标准内建对象JSON的方法,用于解码(解析)JSON字符串。
JSON.stringifyJSON.stringify函数是ECMAScript标准内置对象JSON的方法,用于将JavaScript值转换为JSON字符串。
Encode该函数根据传入的参数对数据进行编码。
MD5计算参数data的 MD5 哈希值。
UUID创建一个 UUID。

Log

名称说明
LogLog()函数用于输出日志。
LogStatus在回测系统或实盘页面的状态栏中输出信息。
LogProfit记录并打印盈亏数值,并根据盈亏数值绘制收益曲线。
LogProfitReset清空所有收益日志及收益图表。
LogReset清除日志。
LogVacuum用于在调用 LogReset() 函数清除日志后,回收 SQLite 删除数据时所占用的存储空间。
EnableLog启用或禁用订单信息的日志记录。
Chart自定义图表绘图函数。
KLineChart该函数用于采用类似Pine语言的绘图方式,在策略运行时进行自定义绘图。
console.log用于在实盘页面的「调试信息」栏中输出调试信息。
console.error用于在实盘页面的「调试信息」栏中输出错误信息。
exchange.Logexchange.Log()函数用于在日志栏区域输出下单、撤单日志。

Market

名称说明
exchange.GetTicker获取当前设置的交易对、合约代码所对应现货或合约的Ticker结构,即行情数据。
exchange.GetTickersexchange.GetTickers()函数用于获取交易所的聚合行情数据(Ticker结构的数组)。
exchange.GetDepth获取当前设置的交易对、合约代码所对应的现货或合约的Depth结构,即订单簿数据。
exchange.GetTrades获取当前设置的交易对、合约代码所对应的现货或合约的Trade结构数组,即市场的成交数据。
exchange.GetRecords获取当前设置的交易对、合约代码所对应的现货或合约的Record结构数组,即K线数据。
exchange.GetMarketsexchange.GetMarkets()函数用于获取交易所的市场信息。
exchange.GetRawJSON获取当前交易所对象(exchange、exchanges)最近一次rest请求返回的原始内容。
exchange.SetDataexchange.SetData()函数用于设置策略运行时所加载的数据。
exchange.GetDataexchange.GetData()函数用于获取由exchange.SetData()函数加载的数据,或外部链接提供的数据。

Trade

名称说明
exchange.Buyexchange.Buy()函数用于下买单。
exchange.Sellexchange.Sell()函数用于下达卖单。
exchange.CreateOrderexchange.CreateOrder()函数用于下单。
exchange.ModifyOrderexchange.ModifyOrder()函数用于修改现有的普通订单,可修改订单的价格和数量。
exchange.CancelOrderexchange.CancelOrder()函数用于取消订单。
exchange.GetOrderexchange.GetOrder()函数用于获取订单信息。
exchange.GetOrdersexchange.GetOrders()函数用于获取当前未完成的订单。
exchange.GetHistoryOrdersexchange.GetHistoryOrders()函数用于获取当前交易对、合约的历史订单,并支持指定具体的交易品种。
exchange.CreateConditionOrderexchange.CreateConditionOrder()函数用于创建条件单。
exchange.ModifyConditionOrderexchange.ModifyConditionOrder()函数用于修改现有的条件单,可修改条件单的下单量、触发条件和执行价格。
exchange.CancelConditionOrderexchange.CancelConditionOrder()函数用于取消条件单。
exchange.GetConditionOrderexchange.GetConditionOrder()函数用于获取指定条件单的信息。
exchange.GetConditionOrdersexchange.GetConditionOrders()函数用于获取未完成的条件单(尚未触发或尚未取消的条件单)。
exchange.GetHistoryConditionOrdersexchange.GetHistoryConditionOrders()函数用于获取当前交易对、合约的历史条件单(包括已触发、已取消、已过期的条件单),并支持指定具体的交易品种。

Account

名称说明
exchange.GetAccountexchange.GetAccount()函数用于请求交易所账户信息。
exchange.GetAssetsexchange.GetAssets函数用于请求交易所账户的资产信息。

Futures

名称说明
exchange.SetContractTypeexchange.SetContractType()函数用于设置exchange交易所对象当前的合约代码。
exchange.GetContractTypeexchange.GetContractType()函数用于获取exchange交易所对象当前设置的合约代码。
exchange.SetDirectionexchange.SetDirection()函数用于设置调用exchange.Buy函数、exchange.Sell函数进行期货合约下单时的订单方向。
exchange.SetMarginLevelexchange.SetMarginLevel()函数用于设置symbol参数所指定的交易对、合约的杠杆值。
exchange.GetPositionsexchange.GetPositions()函数用于获取持仓信息;GetPositions()函数是交易所对象exchange的成员函数。
exchange.GetFundingsexchange.GetFundings()函数用于获取当前周期的资金费率数据。

Exchange

名称说明
exchange.GetNameexchange.GetName()函数用于获取当前交易所对象所绑定的交易所名称。
exchange.GetLabelexchange.GetLabel()函数用于获取配置交易所对象时设置的自定义标签。
exchange.GetCurrencyexchange.GetCurrency()函数用于获取当前设置的交易对。
exchange.SetCurrencyexchange.SetCurrency()函数用于切换交易所对象exchange当前的交易对。
exchange.GetQuoteCurrencyexchange.GetQuoteCurrency()函数用于获取当前交易对的计价币名称,即quoteCurrency。
exchange.GetPeriod获取回测或实盘运行策略时,在发明者量化交易平台网站页面上所设置的 K 线周期,即调用 exchange.GetRecords() 函数且不传入参数时使用的默认 K 线周期。
exchange.SetMaxBarLen设置K线的最大长度。
exchange.SetPrecisionexchange.SetPrecision()函数用于设置exchange交易所对象的价格与下单量的精度,设置后系统会自动忽略数据中超出精度的多余部分。
exchange.GetRate获取交易所对象当前设置的汇率。
exchange.SetRate设置交易所对象当前的汇率。
exchange.SetBaseexchange.SetBase()函数用于设置exchange交易所对象所使用的交易所API接口基地址。
exchange.GetBaseexchange.GetBase() 函数用于获取当前交易所 API 接口的基础地址。
exchange.SetProxyexchange.SetProxy()函数用于设置exchange交易所对象的代理配置。
exchange.SetTimeoutexchange.SetTimeout()函数用于设置exchange交易所对象rest请求的超时时间。
exchange.Encodeexchange.Encode()函数用于执行签名与加密计算。

IO

名称说明
exchange.IOexchange.IO()函数用于调用交易所对象相关的其它接口。
exchange.IO("api", ...)exchange.IO("api", ...)调用交易所未封装的原始REST接口,签名由平台自动处理。
exchange.IO("currency", ...)exchange.IO("currency", ...)在运行时切换交易所对象的当前交易对。
exchange.IO("base", ...)exchange.IO("base", ...)切换交易接口的基地址,exchange.IO("mbase", ...)切换行情接口的基地址。
exchange.IO(mode, value)exchange.IO(mode, value)切换交易所的交易模式:模拟盘/实盘、全仓/逐仓、双向/单向持仓、统一账户、杠杆模式、自成交预防等。
exchange.IO("rate", ...)exchange.IO("rate", ...)与exchange.IO("quota", ...)限制API函数的调用频率。

Network

名称说明
HttpQuery发送HTTP请求。
HttpQuery_Go发送Http请求,是HttpQuery函数的异步版本。
Dial用于原始 Socket 访问,支持 tcp、udp、tls、unix 协议。
Mail发送邮件。
Mail_GoMail函数的异步版本。

Storage

名称说明
_G持久化保存数据。
DBExec数据库接口函数。
SetChannelData在频道上发布最新的状态数据。
GetChannelData订阅指定实盘的频道数据。

Threads

名称说明
exchange.Go多线程异步支持函数,可将所有受支持函数的操作转换为异步并发执行。
EventLoop监听事件,当任意WebSocket有可读数据,或exchange.Go()、HttpQuery_Go()等并发任务完成后返回。

Threads/threading

名称说明
ThreadThread()函数用于创建并发线程。
getThreadgetThread()函数用于根据指定的线程ID获取线程对象。
mainThreadmainThread()函数用于获取主线程的线程对象,即策略中main()函数所在的线程。
currentThreadcurrentThread()函数用于获取当前线程的线程对象。
LockLock()函数用于创建线程锁对象。
ConditionCondition()函数用于创建一个条件变量对象,该对象用于在多线程并发环境中实现线程间的同步与通信。
EventEvent()函数用于创建一个线程事件对象,该对象用于线程间的同步,允许一个线程等待另一个线程的通知或信号。
DictDict()函数用于创建一个字典对象,用于在并发线程间传递和共享数据。
ServeServe()函数在策略进程内创建Http服务、TCP服务、Websocket服务(基于Http协议),返回Server对象。
pendingpending函数用于获取当前策略程序中正在运行的并发线程数量。

Threads/Thread

名称说明
peekMessagepeekMessage()函数用于从线程接收消息。
postMessagepostMessage()函数用于向线程发送消息。
joinjoin()函数用于等待线程退出,并回收系统资源。
terminateterminate()函数用于强制终止线程,释放创建线程时占用的硬件资源。
getDatagetData()函数用于访问线程环境中记录的变量。
setDatasetData()函数用于在线程环境中存储变量。
idid()函数用于返回当前多线程对象实例的threadId。
namename()函数用于返回当前多线程对象实例的名称。
eventLoopeventLoop() 函数用于监听当前线程接收到的事件。

Threads/ThreadLock

名称说明
acquireacquire()函数用于请求线程锁(加锁)。
releaserelease()函数用于释放线程锁(解锁)。

Threads/ThreadEvent

名称说明
setset()函数用于设置事件信号。
clearclear()函数用于清除信号。
waitwait()函数用于设置事件(信号)等待,在事件(信号)被设置之前会阻塞;支持设置超时参数。
isSetisSet()函数用于判断事件(信号)是否已被设置。

Threads/ThreadCondition

名称说明
notifynotify()函数用于唤醒一个正在等待的线程(如果存在)。
notifyAllnotifyAll()函数用于唤醒所有正在等待的线程。
waitwait()函数用于在特定条件下使线程进入等待状态。
acquireacquire()函数用于请求线程锁(加锁)。
releaserelease()函数用于释放线程锁(解锁)。

Threads/ThreadDict

名称说明
getget()函数用于获取字典对象中记录的键值。
setset()函数用于设置键值对。

Threads/Server

名称说明
addraddr()函数返回服务实际监听的地址和端口。
closeclose()函数停止接收新连接,正在执行的处理函数继续执行完(优雅关闭)。
stopstop()函数先关闭服务(同close()),再强制结束所有正在执行的处理函数线程。
joinjoin()函数等待服务关闭且所有处理函数执行完毕。
pendingpending()函数返回当前正在执行的处理函数数量,即正在处理的连接或请求数。

Web3

名称说明
exchange.IO("abi", ...)在发明者量化交易平台中,区块链相关的各种功能和调用主要通过exchange.IO()函数实现。
exchange.IO("api", blockChain, ...)exchange.IO("api", "eth", ...)调用方式用于调用以太坊RPC方法(配置Web3交易所对象时需选择eth)。
exchange.IO("encode", ...)exchange.IO("encode", ...)函数的这种调用方式用于数据编码。
exchange.IO("encodePacked", ...)exchange.IO("encodePacked", ...)函数用于执行encodePacked编码操作。
exchange.IO("decode", ...)exchange.IO("decode", ...)调用方式用于对数据进行解码。
exchange.IO("hash", ...)exchange.IO("hash", ...)函数的调用方式用于计算哈希摘要、HMAC,以及使用交易所对象配置的私钥签名等,参数与Encode函数相同。
exchange.IO("key", ...)exchange.IO("key", ...)函数用于切换私钥的调用方式。
exchange.IO("sign", ...)exchange.IO("sign", ...)调用方式用于使用secp256k1私钥对32字节哈希进行签名,返回r、s、v等签名数据,适用于EIP-712结构化数据签名(如ERC-20 Permit授权、1inch限价单)等需要链下签名的场景。
exchange.IO("signTypedData", ...)exchange.IO("signTypedData", ...)函数的调用方式用于按照EIP-712标准对结构化数据进行签名,一次调用即可完成类型哈希、域分隔符、结构体哈希和摘要的计算并签名,适用于ERC-20 Permit、Permit2、UniswapX、CoW、1inch限价单等场景。
exchange.IO("signMessage", ...)exchange.IO("signMessage", ...)调用方式用于按照EIP-191标准(personal_sign)对消息进行签名,签名结果与ethers的signMessage、钱包的personal_sign一致,常用于DApp登录、链下鉴权等场景。
exchange.IO("api", ...)exchange.IO("api", ...)调用方式用于调用智能合约的方法。
exchange.IO("call", ...)exchange.IO("call", ...)调用方式通过eth_call模拟执行智能合约的任意方法(包括会修改链上状态的写入方法),该过程不签名、不广播交易、不消耗gas,适用于链上询价、交易预演以及检查交易能否成功执行。
exchange.IO("multicall", ...)exchange.IO("multicall", ...)调用方式用于通过Multicall3合约在一次请求中批量读取多个合约调用的结果,适用于批量查询余额、流动池状态、报价等数据,可有效减少RPC请求次数。
exchange.IO("logs", ...)exchange.IO("logs", ...)调用方式用于查询合约的事件日志(eth_getLogs),并按ABI进行解码。
exchange.IO("waitReceipt", ...)exchange.IO("waitReceipt", ...)调用方式用于等待交易上链并达到指定的确认数,返回交易回执及解码后的事件日志。
exchange.IO("nonce", ...)exchange.IO("nonce", ...)函数的调用方式用于查看、同步或设置发送交易时使用的nonce计数。
exchange.IO("speedUp", ...)exchange.IO("speedUp", ...)调用方式用于对卡住(长时间未上链)的交易进行加价重发:保持接收地址、金额、调用数据和gas上限不变,仅提高手续费。
exchange.IO("cancelTx", ...)exchange.IO("cancelTx", ...)调用方式用于取消尚未上链的交易:使用与原交易相同的nonce,以更高的手续费发送一笔转给自己的0金额交易;该交易先上链后,原交易即失效。
exchange.IO("toUnits", ...)exchange.IO("toUnits", ...)函数的调用方式用于将可读数量换算为链上整数。
exchange.IO("fromUnits", ...)exchange.IO("fromUnits", ...)调用方式用于将链上整数值换算为可读数量,整个换算过程基于字符串进行精确计算,不经过浮点数运算,避免精度损失。
exchange.IO("uniswapV3", ...)exchange.IO("uniswapV3", ...)调用方式用于集中流动性(Uniswap V3)相关的计算,包括tick、价格与sqrtPriceX96之间的换算,以及流动性与代币数量之间的换算。
exchange.IO("contracts", ...)exchange.IO("contracts", ...)调用方式用于获取当前链(或指定链)的常用合约地址,包括主流代币、Multicall3、Permit2,以及Uniswap V3、PancakeSwap V3的Factory、路由、QuoterV2和头寸管理合约。
exchange.IO("address")exchange.IO("address")函数的调用方式用于获取exchange交易所对象配置的钱包的地址。
exchange.IO("base", ...)exchange.IO("base", ...)调用方式用于设置RPC节点地址,支持设置多个节点互为备用。
exchange.IO("sendBase", ...)exchange.IO("sendBase", ...)调用方式用于设置仅用于广播交易的节点。

Uniswap

名称说明
exchange.IO("transfer", ...)exchange.IO("transfer", ...)调用方式用于从Uniswap交易所对象所配置的钱包中转出链上原生币(如ETH、BNB)或ERC20代币。
exchange.IO("receipt", ...)以exchange.IO("receipt", ...)方式调用该函数,可查询Uniswap交易所对象所发出交易(如下单、转账等)的回执,也可等待交易上链。
exchange.IO("route", ...)exchange.IO("route", ...)调用用于在Uniswap交易所对象上询价:列出一笔兑换在各条候选路径上的报价以及最优路径,不会实际下单。
exchange.IO("simulate", ...)exchange.IO("simulate", ...)调用方式按照Uniswap交易所对象的下单逻辑(路径选择、询价、价格保护)构造兑换交易,仅在链上进行模拟执行(eth_call),不签名、不广播,也不消耗gas。
exchange.IO("token", ...)exchange.IO("token", ...)函数的调用方式用于在Uniswap交易所对象上登记代币,或者列出代币表。
exchange.IO("wrap", ...)exchange.IO("wrap", ...)函数的调用方式用于在Uniswap交易所对象上把原生币(ETH、BNB)包装成包装币(WETH、WBNB),1:1兑换,没有滑点,只花gas。
exchange.IO("unwrap", ...)exchange.IO("unwrap", ...)函数的调用方式用于在Uniswap交易所对象上把包装币(WETH、WBNB)解包成原生币(ETH、BNB),1:1兑换,没有滑点,只花gas。
exchange.IO("approve", ...)以exchange.IO("approve", ...)方式调用该函数,可在Uniswap交易所对象上设置代币授权模式。
exchange.IO("slippage", ...)exchange.IO("slippage", ...)函数的此种调用方式用于为Uniswap交易所对象设置市价单的滑点保护。
exchange.IO("deadline", ...)exchange.IO("deadline", ...)调用方式用于在Uniswap交易所对象上设置交易的截止时间。
exchange.IO("gasMultiplier", ...)exchange.IO("gasMultiplier", ...)调用方式用于在Uniswap交易所对象上设置gas上限倍数。

TA

名称说明
TA.MACDTA.MACD()函数用于计算指数平滑异同移动平均线(MACD)指标。
TA.KDJTA.KDJ()函数用于计算随机指标(KDJ)。
TA.RSITA.RSI()函数用于计算相对强弱指标(RSI)。
TA.ATRTA.ATR()函数用于计算平均真实波幅指标(ATR)。
TA.OBVTA.OBV()函数用于计算能量潮指标(OBV)。
TA.MATA.MA()函数用于计算移动平均线指标(Moving Average)。
TA.EMATA.EMA()函数用于计算指数移动平均线(EMA)指标。
TA.BOLLTA.BOLL()函数用于计算布林带指标。
TA.AlligatorTA.Alligator()函数用于计算鳄鱼线指标(Alligator)。
TA.CMFTA.CMF()函数用于计算蔡金资金流量指标(Chaikin Money Flow)。
TA.HighestTA.Highest()函数用于计算周期内最高价。
TA.LowestTA.Lowest()函数用于计算周期最低价。
TA.SMATA.SMA()函数用于计算简单移动平均线(SMA)指标。

Talib/OverlapStudies

名称说明
talib.BBANDStalib.BBANDS()函数用于计算Bollinger Bands(布林带)。
talib.DEMAtalib.DEMA()函数用于计算Double Exponential Moving Average(双指数移动平均线)。
talib.EMAtalib.EMA()函数用于计算Exponential Moving Average(指数移动平均线)。
talib.HT_TRENDLINEtalib.HT_TRENDLINE()函数用于计算Hilbert Transform - Instantaneous Trendline(希尔伯特变换瞬时趋势线)。
talib.KAMAtalib.KAMA()函数用于计算Kaufman自适应移动平均线(Kaufman Adaptive Moving Average)。
talib.MAtalib.MA()函数用于计算Moving average(移动平均线)。
talib.MAMAtalib.MAMA()函数用于计算MESA自适应移动平均线(MESA Adaptive Moving Average)。
talib.MIDPOINTtalib.MIDPOINT()函数用于计算MidPoint over period(中点价格)。
talib.MIDPRICEtalib.MIDPRICE()函数用于计算Midpoint Price over period(中点价格)。
talib.SARtalib.SAR()函数用于计算抛物线转向指标(Parabolic SAR)。
talib.SAREXTtalib.SAREXT()函数用于计算Parabolic SAR - Extended(增强型抛物线转向指标)。
talib.SMAtalib.SMA()函数用于计算Simple Moving Average(简单移动平均线)。
talib.T3talib.T3()函数用于计算Triple Exponential Moving Average (T3) (三重指数移动平均)。
talib.TEMAtalib.TEMA()函数用于计算Triple Exponential Moving Average(三重指数移动平均线)。
talib.TRIMAtalib.TRIMA()函数用于计算Triangular Moving Average(三角移动平均线)。
talib.WMAtalib.WMA()函数用于计算Weighted Moving Average(加权移动平均)。

Talib/MomentumIndicators

名称说明
talib.ADXtalib.ADX()函数用于计算Average Directional Movement Index(平均趋向指数)。
talib.ADXRtalib.ADXR()函数用于计算平均趋向指数评级(Average Directional Movement Index Rating)。
talib.APOtalib.APO()函数用于计算Absolute Price Oscillator(绝对价格振荡器)。
talib.AROONtalib.AROON()函数用于计算Aroon(阿隆指标)。
talib.AROONOSCtalib.AROONOSC()函数用于计算Aroon Oscillator(阿隆震荡指标)。
talib.BOPtalib.BOP()函数用于计算Balance Of Power(均势指标)。
talib.CCItalib.CCI()函数用于计算Commodity Channel Index(商品通道指数)。
talib.CMOtalib.CMO()函数用于计算Chande Momentum Oscillator(钱德动量摆动指标)。
talib.DXtalib.DX()函数用于计算Directional Movement Index(动向指数)。
talib.MACDtalib.MACD()函数用于计算Moving Average Convergence/Divergence(移动平均收敛发散指标)。
talib.MACDEXTtalib.MACDEXT()函数用于计算MACD with controllable MA type(可控移动平均类型的MACD)。
talib.MACDFIXtalib.MACDFIX()函数用于计算Moving Average Convergence/Divergence Fix 12/26(移动平均收敛/发散固定12/26)。
talib.MFItalib.MFI()函数用于计算Money Flow Index(资金流量指数)。
talib.MINUS_DItalib.MINUS_DI()函数用于计算负向指标(Minus Directional Indicator)。
talib.MINUS_DMtalib.MINUS_DM()函数用于计算负向运动指标(Minus Directional Movement)。
talib.MOMtalib.MOM()函数用于计算Momentum(动量指标)。
talib.PLUS_DItalib.PLUS_DI()函数用于计算Plus Directional Indicator(正向指标)。
talib.PLUS_DMtalib.PLUS_DM()函数用于计算Plus Directional Movement(正向运动指标)。
talib.PPOtalib.PPO()函数用于计算Percentage Price Oscillator(价格振荡百分比)。
talib.ROCtalib.ROC()函数用于计算*变动率指标(Rate of change):((price/prevPrice)-1)100。
talib.ROCPtalib.ROCP()函数用于计算价格变化率百分比:(price-prevPrice)/prevPrice。
talib.ROCRtalib.ROCR()函数用于计算价格变化率比值:(price/prevPrice)。
talib.ROCR100talib.ROCR100()函数用于计算Rate of change ratio 100 scale: (price/prevPrice)*100(价格变化率比例100倍)。
talib.RSItalib.RSI()函数用于计算Relative Strength Index(相对强弱指标)。
talib.STOCHtalib.STOCH()函数用于计算随机指标(STOCH指标)。
talib.STOCHFtalib.STOCHF()函数用于计算快速随机指标(Stochastic Fast)。
talib.STOCHRSItalib.STOCHRSI()函数用于计算随机相对强弱指数(Stochastic Relative Strength Index)。
talib.TRIXtalib.TRIX()函数用于计算1-day Rate-Of-Change (ROC) of a Triple Smooth EMA(三重指数平滑移动平均线的一日变化率)。
talib.ULTOSCtalib.ULTOSC()函数用于计算Ultimate Oscillator(极限振荡器)。
talib.WILLRtalib.WILLR()函数用于计算Williams' %R(威廉指标)。

Talib/VolumeIndicators

名称说明
talib.ADtalib.AD()函数用于计算Chaikin A/D Line(累积/派发线指标)。
talib.ADOSCtalib.ADOSC()函数用于计算Chaikin A/D Oscillator(佳庆指标)。
talib.OBVtalib.OBV()函数用于计算On Balance Volume(能量潮指标)。

Talib/VolatilityIndicators

名称说明
talib.ATRtalib.ATR()函数用于计算**Average True Range(平均真实波幅)**指标。
talib.NATRtalib.NATR()函数用于计算Normalized Average True Range(归一化平均真实范围)。
talib.TRANGEtalib.TRANGE()函数用于计算**True Range(真实范围)**指标。

Talib/CycleIndicators

名称说明
talib.HT_DCPERIODtalib.HT_DCPERIOD()函数用于计算Hilbert Transform - Dominant Cycle Period(希尔伯特变换主导周期)。
talib.HT_DCPHASEtalib.HT_DCPHASE()函数用于计算希尔伯特变换主周期相位(Hilbert Transform - Dominant Cycle Phase)。
talib.HT_PHASORtalib.HT_PHASOR()函数用于计算Hilbert Transform - Phasor Components(希尔伯特变换-相量分量)。
talib.HT_SINEtalib.HT_SINE()函数用于计算Hilbert Transform - SineWave(希尔伯特变换 - 正弦波)。
talib.HT_TRENDMODEtalib.HT_TRENDMODE()函数用于计算Hilbert Transform - Trend vs Cycle Mode(希尔伯特变换 - 趋势与周期模式)。

Talib/PriceTransform

名称说明
talib.AVGPRICEtalib.AVGPRICE()函数用于计算Average Price(平均价格)。
talib.MEDPRICEtalib.MEDPRICE()函数用于计算Median Price(中位数价格)。
talib.TYPPRICEtalib.TYPPRICE()函数用于计算典型价格(Typical Price)。
talib.WCLPRICEtalib.WCLPRICE()函数用于计算Weighted Close Price(加权收盘价)。

Talib/StatisticFunctions

名称说明
talib.LINEARREGtalib.LINEARREG()函数用于计算**Linear Regression(线性回归)**指标。
talib.LINEARREG_ANGLEtalib.LINEARREG_ANGLE()函数用于计算Linear Regression Angle(线性回归角度)。
talib.LINEARREG_INTERCEPTtalib.LINEARREG_INTERCEPT()函数用于计算线性回归截距(Linear Regression Intercept)。
talib.LINEARREG_SLOPEtalib.LINEARREG_SLOPE()函数用于计算Linear Regression Slope(线性回归斜率)。
talib.STDDEVtalib.STDDEV()函数用于计算标准偏差(Standard Deviation)。
talib.TSFtalib.TSF()函数用于计算Time Series Forecast(时间序列预测)。
talib.VARtalib.VAR()函数用于计算方差(Variance)。

Talib/MathTransform

名称说明
talib.ACOStalib.ACOS()函数用于计算向量三角反余弦函数(Vector Trigonometric ACos)。
talib.ASINtalib.ASIN()函数用于计算向量三角反正弦函数(Vector Trigonometric ASin)。
talib.ATANtalib.ATAN()函数用于计算向量三角反正切函数(Vector Trigonometric ATan)。
talib.CEILtalib.CEIL()函数用于计算向上取整(Vector Ceil)。
talib.COStalib.COS()函数用于计算Vector Trigonometric Cos(向量三角余弦函数)。
talib.COSHtalib.COSH()函数用于计算向量三角双曲余弦值(Vector Trigonometric Cosh)。
talib.EXPtalib.EXP()函数用于计算向量算术指数函数(Vector Arithmetic Exp)。
talib.FLOORtalib.FLOOR()函数用于计算向量向下取整(Vector Floor)。
talib.LNtalib.LN()函数用于计算向量自然对数(Vector Log Natural)。
talib.LOG10talib.LOG10()函数用于计算Vector Log10(对数函数)。
talib.SINtalib.SIN()函数用于计算Vector Trigonometric Sin(正弦值)。
talib.SINHtalib.SINH()函数用于计算向量三角双曲正弦函数(Vector Trigonometric Sinh)。
talib.SQRTtalib.SQRT()函数用于计算向量平方根(Vector Square Root)。
talib.TANtalib.TAN()函数用于计算向量三角正切值(Vector Trigonometric Tan)。
talib.TANHtalib.TANH()函数用于计算向量三角双曲正切函数(Vector Trigonometric Tanh)。

Talib/MathOperators

名称说明
talib.MAXtalib.MAX()函数用于计算指定周期内的最大值(Highest value over a specified period)。
talib.MAXINDEXtalib.MAXINDEX()函数用于计算指定周期内最大值的索引位置(Index of highest value over a specified period)。
talib.MINtalib.MIN()函数用于计算指定周期内的最小值(Lowest value over a specified period)。
talib.MININDEXtalib.MININDEX()函数用于计算指定周期内最小值的索引位置(Index of lowest value over a specified period)。
talib.MINMAXtalib.MINMAX()函数用于计算指定周期内的最小值和最大值(Lowest and highest values over a specified period)。
talib.MINMAXINDEXtalib.MINMAXINDEX()函数用于计算指定周期内最低值和最高值的索引位置(Indexes of lowest and highest values over a specified period)。
talib.SUMtalib.SUM()函数用于计算求和(Summation)。

Talib/PatternRecognition

名称说明
talib.CDL2CROWStalib.CDL2CROWS()函数用于计算Two Crows(K线形态--两只乌鸦)。
talib.CDL3BLACKCROWStalib.CDL3BLACKCROWS()函数用于计算Three Black Crows(K线图形态--三只黑乌鸦)。
talib.CDL3INSIDEtalib.CDL3INSIDE()函数用于计算Three Inside Up/Down(K线形态:三内上下震荡)。
talib.CDL3LINESTRIKEtalib.CDL3LINESTRIKE()函数用于计算Three-Line Strike(K线图:三线震荡)。
talib.CDL3OUTSIDEtalib.CDL3OUTSIDE()函数用于计算Three Outside Up/Down(K线形态:三外包线)。
talib.CDL3STARSINSOUTHtalib.CDL3STARSINSOUTH()函数用于计算Three Stars In The South(K线形态:南方三星)。
talib.CDL3WHITESOLDIERStalib.CDL3WHITESOLDIERS()函数用于计算Three Advancing White Soldiers(K线形态:三白兵)。
talib.CDLABANDONEDBABYtalib.CDLABANDONEDBABY()函数用于计算弃婴形态(K线图:Abandoned Baby)。
talib.CDLADVANCEBLOCKtalib.CDLADVANCEBLOCK()函数用于计算Advance Block(K线形态:推进阻挡)。
talib.CDLBELTHOLDtalib.CDLBELTHOLD()函数用于计算Belt-hold(K线形态:腰带线)。
talib.CDLBREAKAWAYtalib.CDLBREAKAWAY()函数用于计算Breakaway(K线形态:分离形态)。
talib.CDLCLOSINGMARUBOZUtalib.CDLCLOSINGMARUBOZU()函数用于计算**收盘光头光脚线(Closing Marubozu)**K线形态。
talib.CDLCONCEALBABYSWALLtalib.CDLCONCEALBABYSWALL()函数用于计算Concealing Baby Swallow(K线图:藏婴吞没形态)。
talib.CDLCOUNTERATTACKtalib.CDLCOUNTERATTACK()函数用于计算反击线形态(K线图:反击)。
talib.CDLDARKCLOUDCOVERtalib.CDLDARKCLOUDCOVER()函数用于计算乌云盖顶(Dark Cloud Cover)K线形态。
talib.CDLDOJItalib.CDLDOJI()函数用于计算Doji(K线图:十字星)。
talib.CDLDOJISTARtalib.CDLDOJISTAR()函数用于计算Doji Star(K线图:十字星)。
talib.CDLDRAGONFLYDOJItalib.CDLDRAGONFLYDOJI()函数用于计算Dragonfly Doji(K线形态:蜻蜓十字星)。
talib.CDLENGULFINGtalib.CDLENGULFING()函数用于计算吞没形态(Engulfing Pattern)。
talib.CDLEVENINGDOJISTARtalib.CDLEVENINGDOJISTAR()函数用于计算Evening Doji Star(K线形态:黄昏十字星)。
talib.CDLEVENINGSTARtalib.CDLEVENINGSTAR()函数用于计算**Evening Star(K线图:黄昏之星)**形态。
talib.CDLGAPSIDESIDEWHITEtalib.CDLGAPSIDESIDEWHITE()函数用于计算Up/Down-gap side-by-side white lines (K线图:上/下间隙并排白色线条)。
talib.CDLGRAVESTONEDOJItalib.CDLGRAVESTONEDOJI()函数用于计算**墓碑十字线(Gravestone Doji)**K线形态。
talib.CDLHAMMERtalib.CDLHAMMER()函数用于计算锤子线(K线形态:锤子)。
talib.CDLHANGINGMANtalib.CDLHANGINGMAN()函数用于计算Hanging Man(K线形态:吊人线)。
talib.CDLHARAMItalib.CDLHARAMI()函数用于计算Harami Pattern(K线图:阴阳线模式)。
talib.CDLHARAMICROSStalib.CDLHARAMICROSS()函数用于计算Harami Cross Pattern(K线图:十字星孕线形态)。
talib.CDLHIGHWAVEtalib.CDLHIGHWAVE()函数用于计算High-Wave Candle(K线图:长脚十字线)。
talib.CDLHIKKAKEtalib.CDLHIKKAKE()函数用于计算Hikkake Pattern(K线图:陷阱模式)。
talib.CDLHIKKAKEMODtalib.CDLHIKKAKEMOD()函数用于计算Modified Hikkake Pattern(K线图:改良陷阱模式)。
talib.CDLHOMINGPIGEONtalib.CDLHOMINGPIGEON()函数用于计算Homing Pigeon(K线形态:信鸽形态)。
talib.CDLIDENTICAL3CROWStalib.CDLIDENTICAL3CROWS()函数用于计算Identical Three Crows(K线形态:相同三只乌鸦)。
talib.CDLINNECKtalib.CDLINNECK()函数用于计算颈内线形态(K线图:颈内线)。
talib.CDLINVERTEDHAMMERtalib.CDLINVERTEDHAMMER()函数用于计算倒锤形态(K线图:倒锤)。
talib.CDLKICKINGtalib.CDLKICKING()函数用于计算Kicking(K线形态:踢腿形态)。
talib.CDLKICKINGBYLENGTHtalib.CDLKICKINGBYLENGTH()函数用于计算Kicking - bull/bear determined by the longer marubozu (K线图:踢牛/踢熊)。
talib.CDLLADDERBOTTOMtalib.CDLLADDERBOTTOM()函数用于计算Ladder Bottom(K线形态:梯底)。
talib.CDLLONGLEGGEDDOJItalib.CDLLONGLEGGEDDOJI()函数用于计算长腿十字线(K线形态:Long Legged Doji)。
talib.CDLLONGLINEtalib.CDLLONGLINE()函数用于计算长线蜡烛形态(K线图:长线)。
talib.CDLMARUBOZUtalib.CDLMARUBOZU()函数用于计算**Marubozu(K线图:光头光脚)**模式。
talib.CDLMATCHINGLOWtalib.CDLMATCHINGLOW()函数用于计算Matching Low(K线图:匹配低点)。
talib.CDLMATHOLDtalib.CDLMATHOLD()函数用于计算Mat Hold(K线形态:垫住)。
talib.CDLMORNINGDOJISTARtalib.CDLMORNINGDOJISTAR()函数用于计算Morning Doji Star(K线形态:早晨十字星)。
talib.CDLMORNINGSTARtalib.CDLMORNINGSTAR()函数用于计算Morning Star(K线形态:晨星)。
talib.CDLONNECKtalib.CDLONNECK()函数用于计算On-Neck Pattern(K线图:颈上线形态)。
talib.CDLPIERCINGtalib.CDLPIERCING()函数用于计算Piercing Pattern(K线图:穿透形态)。
talib.CDLRICKSHAWMANtalib.CDLRICKSHAWMAN()函数用于计算Rickshaw Man(K线形态:车夫线)。
talib.CDLRISEFALL3METHODStalib.CDLRISEFALL3METHODS()函数用于计算Rising/Falling Three Methods(K线形态:上升/下降三法)。
talib.CDLSEPARATINGLINEStalib.CDLSEPARATINGLINES()函数用于计算分离线形态(K线图:分离线)。
talib.CDLSHOOTINGSTARtalib.CDLSHOOTINGSTAR()函数用于计算Shooting Star(K线形态:流星)。
talib.CDLSHORTLINEtalib.CDLSHORTLINE()函数用于计算短线蜡烛图形态(K线图:短线)。
talib.CDLSPINNINGTOPtalib.CDLSPINNINGTOP()函数用于计算Spinning Top(K线形态:陀螺)。
talib.CDLSTALLEDPATTERNtalib.CDLSTALLEDPATTERN()函数用于计算Stalled Pattern(K线图:停滞模式)。
talib.CDLSTICKSANDWICHtalib.CDLSTICKSANDWICH()函数用于计算Stick Sandwich(K线形态:棍子三明治)。
talib.CDLTAKURItalib.CDLTAKURI()函数用于计算**Takuri (Dragonfly Doji with very long lower shadow) (K线图:托里)**蜡烛图形态。
talib.CDLTASUKIGAPtalib.CDLTASUKIGAP()函数用于计算Tasuki Gap(K线图:翼隙)。
talib.CDLTHRUSTINGtalib.CDLTHRUSTING()函数用于计算Thrusting Pattern(K线图:推进模式)。
talib.CDLTRISTARtalib.CDLTRISTAR()函数用于计算三星形态(K线图:三星模式)。
talib.CDLUNIQUE3RIVERtalib.CDLUNIQUE3RIVER()函数用于计算Unique 3 River(K线形态:独特三河)。
talib.CDLUPSIDEGAP2CROWStalib.CDLUPSIDEGAP2CROWS()函数用于计算向上跳空双乌鸦形态(K线图:双飞乌鸦)。
talib.CDLXSIDEGAP3METHODStalib.CDLXSIDEGAP3METHODS()函数用于计算上行/下行缺口三方法(K线形态识别)。

OS

名称说明
ListFilesResult文件列表对象,用于记录目录列表信息。
FileStat文件统计信息对象。

OS/os

名称说明
open以指定模式打开文件。
fgets一次性读取整个文件的内容。
fputs向文件写入内容。
mmap内存映射文件,返回文件的二进制数据。
getRootDir获取文件操作的根目录路径。
listFiles列出指定目录中的文件和子目录。
exists检查指定的文件或目录是否存在。
remove删除指定文件。
mkdir创建目录。
rmdir删除目录及其所有内容。
rename重命名文件或移动文件。
stat获取文件的详细统计信息。
exit退出程序。

OS/File

名称说明
close关闭文件并释放相关资源。
puts向文件写入一个或多个字符串。
printf格式化写入数据到文件。
flush刷新文件缓冲区,确保数据写入磁盘。
tell获取当前文件指针的位置。
seek将文件指针移动到指定位置。
eof检查文件指针是否已到达文件末尾。
read从文件中读取数据。
write向文件写入字符串数据。
getline从文件中读取下一行内容。
toString获取文件对象的字符串表示形式。

结构体

名称说明
Ticker市场行情数据结构。
Depth市场深度数据结构。
OrderBook市场深度中的订单结构。
Trade市场成交记录的数据结构。
RecordK线柱的数据结构,标准的OHLC格式,用于绘制K线图和技术指标计算分析。
Market交易品种市场信息的数据结构。
Order订单结构。
Condition条件单配置信息结构,用于设置条件单的触发条件和执行价格。
Account账户信息的数据结构。
Asset具体币种资产信息的数据结构。
Position合约仓位信息的数据结构。
Funding交易品种资金费率信息的数据结构,仅加密货币永续合约支持资金费率功能。

OtherStruct

名称说明
HttpQuery-options此JSON结构用于配置HttpQuery函数和HttpQuery_Go函数发送HTTP请求的各项参数。
HttpQuery-return该JSON结构是调用HttpQuery函数时,在参数options结构中将debug字段指定为true后,HttpQuery函数在调试模式下返回的数据结构。
LogStatus-table此JSON结构用于配置策略状态栏中显示的表格内容。
LogStatus-btnTypeOne该JSON结构用于配置状态栏中的按钮控件,按钮控件JSON结构可以嵌入到状态栏表格JSON结构中。
LogStatus-btnTypeTwo此JSON结构用于配置状态栏中的按钮控件,按钮控件JSON结构可以嵌入到状态栏表格JSON结构中。
Chart-options此JSON用于配置自定义绘图函数Chart()的图表设置信息,图表库使用Highcharts。
KLineChart-options此JSON用于设置自定义绘图函数KLineChart的图表配置信息。
SetData-data该JSON用于设置exchange.SetData()函数所要加载的数据。
EventLoop-return该JSON是EventLoop()函数返回的数据结构。
DBExec-return该JSON是DBExec()函数返回的数据结构;使用Dial()函数创建的对象的exec()方法执行SQL语句时,也返回此JSON数据结构。
Thread.join-return该JSON是Thread对象的成员函数join()返回的数据结构,用于保存JavaScript语言策略中并发线程的相关信息。

内置变量与常量

EXCHANGE

名称说明
exchangeexchange 是一个交易所对象,也是在策略实盘设置、回测设置中添加的第一个交易所对象。
exchangesexchanges 是一个交易所对象数组,包含在策略实盘设置或回测设置中添加的所有交易所对象,其中 exchanges[0] 即为 exchange。

ORDER_STATE

名称说明
ORDER_STATE_PENDINGORDER_STATE_PENDING是Order结构中的Status属性的值,表示订单状态为待处理状态。
ORDER_STATE_CLOSEDORDER_STATE_CLOSED是Order结构中的Status属性的值,表示订单状态为已完成。
ORDER_STATE_CANCELEDORDER_STATE_CANCELED 是 Order 结构中 Status 属性的值,表示订单状态为已取消。
ORDER_STATE_UNKNOWNORDER_STATE_UNKNOWN是Order结构中的Status属性的值,表示订单状态为未知状态(其他状态)。

ORDER_TYPE

名称说明
ORDER_TYPE_BUYORDER_TYPE_BUY是Order结构中的Type属性值,表示买入订单类型。
ORDER_TYPE_SELLORDER_TYPE_SELL是Order结构中的Type属性值,用于表示卖单类型。

ORDER_CONDITION_TYPE

名称说明
ORDER_CONDITION_TYPE_OCOORDER_CONDITION_TYPE_OCO是Condition结构中的ConditionType属性的值,表示OCO订单(One-Cancels-the-Other,一触即撤订单)。
ORDER_CONDITION_TYPE_TPORDER_CONDITION_TYPE_TP 是 Condition 结构中的 ConditionType 属性值,表示止盈单(Take Profit)。
ORDER_CONDITION_TYPE_SLORDER_CONDITION_TYPE_SL 是 Condition 结构中的 ConditionType 属性值,表示止损单(Stop Loss)。
ORDER_CONDITION_TYPE_GENERICORDER_CONDITION_TYPE_GENERIC 是 Condition 结构中的 ConditionType 属性值,表示通用条件单。

POSITION_DIRECTION

名称说明
PD_LONGPD_LONG是Position结构中的Type属性值,表示多头仓位类型。
PD_SHORTPD_SHORT是Position结构中的Type属性值,表示空头仓位类型。

ORDER_OFFSET

名称说明
ORDER_OFFSET_OPENORDER_OFFSET_OPEN是Order结构中Offset属性的取值,表示该订单为开仓操作。
ORDER_OFFSET_CLOSEORDER_OFFSET_CLOSE是Order结构中Offset属性的取值,表示订单为平仓方向。

PERIOD

名称说明
PERIOD_M1表示1分钟K线周期的常量,数值为60。
PERIOD_M3表示3分钟K线周期的常量,其值为180。
PERIOD_M5表示5分钟K线周期的常量,数值为300。
PERIOD_M15表示15分钟K线周期的常量,其值为900。
PERIOD_M30表示30分钟K线周期的常量,其值为1800秒。
PERIOD_H1表示1小时K线周期的常量,数值为3600。
PERIOD_H2表示2小时K线周期的常量,数值为7200。
PERIOD_H4表示4小时K线周期的常量,数值为14400。
PERIOD_H6表示6小时K线周期的常量,数值为21600。
PERIOD_H12表示12小时K线周期的常量,数值为43200。
PERIOD_D1表示1日K线周期的常量,数值为86400。
PERIOD_D3表示3日K线周期的常量,数值为259200。
PERIOD_W1表示1周K线周期的常量,数值为604800秒。

LOG_TYPE

名称说明
LOG_TYPE_BUYLOG_TYPE_BUY是exchange.Log函数的LogType参数可选值,用于设置exchange.Log函数打印的日志类型为买单日志。
LOG_TYPE_SELLLOG_TYPE_SELL是exchange.Log函数的LogType参数可选值,用于设置exchange.Log函数打印卖单日志。
LOG_TYPE_CANCELLOG_TYPE_CANCEL是exchange.Log函数的LogType参数可选值,用于设置exchange.Log函数打印撤销订单日志。

策略界面上设置的策略参数,在策略代码中以同名的全局变量(Rust 中为全局常量)出现,直接用变量名访问:

  • JavaScript、My语言:可以直接读取参数,也可以在代码中修改参数变量。
  • Python:可以直接读取;在函数中给参数变量重新赋值时,需要先用global声明。
  • Rust:参数是常量,只能读取,不能修改;各种参数对应的类型见 Rust。
  • PINE:使用input()函数创建界面参数。
  • Blockly可视化:没有界面参数。

策略参数设置界面

变量(命名举例)描述类型默认值(说明)组件配置(说明)备注
pNum参数pNum的描述数字型(number)举例设置默认值为:100,Rust策略中为f64用于设置当前参数绑定的界面控件的:组件类型、最小值、最大值、分组、过滤器等参数pNum的备注,pNum的值为数值类型
pBool参数pBool的描述布尔型(true/false)使用开关控件设置默认值,不具备选填控件同上参数pBool的备注,pBool的值为布尔类型
pStr参数pStr的描述字符串(string)举例设置默认值为:abc同上参数pStr的备注,pStr的值为字符串类型
pCombox参数pCombox的描述下拉框(selected)设置选项中的某一个选项或多个选项同上参数pCombox的备注,pCombox的值可能有多种形式
pSecretStr参数pSecretStr的描述加密串(string)举例设置默认值为:xyz同上参数pSecretStr的备注,pSecretStr的值为字符串类型

界面参数,在策略编辑页面代码编辑区下方策略参数区设置,需要注意:
1、参数设置的默认值选项中「选填」控件默认为选填状态,可以改变该控件的状态,设置当前参数为必填。设置参数默认值为必填后,如果策略在回测/实盘时没有设置该参数则无法进行回测/启动实盘。
2、界面参数在策略代码中的变量名不要设置为当前编程语言的保留字(关键字)。
3、在回测/实盘界面鼠标放在参数绑定的控件上时,会显示设置的参数备注信息。
4、参数的「描述」即参数绑定的控件的显示名称。
5、参数的「变量」即以上表格中的:pNum、pBool、pStr、pCombox、pSecretStr。在策略代码中是以全局变量形式存在的,也就是说可以在代码中修改策略参数(Rust 除外:Rust 中参数是全局常量,不能修改)。
6、对于「加密串」和「字符串」类型的参数,默认值输入时不需要加引号,输入均作为字符串处理。「加密串」参数的使用与「字符串」参数相同,加密字符串会被加密发送,不会明文传输。
7、「字符串」类型的参数如果设置为「选填」,当参数绑定的控件中不填写参数时,参数变量的值为空字符串;
同理,如果是「数字型」的参数,参数变量的值为空值。
同理,如果是「下拉框」的参数,参数变量的值为空值。
同理,如果是「加密串」的参数,参数变量的值为空值。
Rust策略中,没有填写的选填参数为该类型的零值:数字为0,字符串、加密串为空字符串,布尔为false。
8、对于下拉框类型的界面参数,例如变量名为pCombox。在「组件配置」中没有开启「支持多选」时,pCombox的值为当前选中的选项索引或具体数据(给选项绑定数据时)。
如果开启了「支持多选」时,pCombox的值为一个数组,数组包含所有当前选中的选项的索引或具体数据(给选项绑定数据时)。

策略界面参数和策略交互控件都有「组件配置」选项,用于设置参数(或交互控件)对应的界面控件,以及最小值、最大值、分组、过滤器等。

各种类型支持的组件:

  • 数字型(number)
    输入框控件(默认)、时间选择器控件、滑动输入条控件。
  • 布尔型(true/false)
    仅支持开关控件(默认)。
  • 字符串(string)
    输入框控件(默认)、文本框控件、时间选择器控件、颜色选择器控件、币种、交易代码。
  • 下拉框(selected)
    下拉框控件(默认)、分段控制器控件、币种、交易代码。
  • 加密串(string),仅策略参数
    仅支持加密输入框控件(默认)。
  • 按钮(button),仅交互控件
    只有一个按钮控件(默认),没有输入项。

分组

在组件配置的「分组」输入框中输入一个标签名,可以把若干个策略参数划分到同一个分组中(代替平台旧功能「策略分组」)。交互控件同样可以分组(代替旧功能「交互控件分组」)。

过滤器

策略参数的组件配置中,「过滤器」输入框可以填写判定表达式,控制参数是否可用(代替平台旧功能「参数依赖」)。
过滤器默认为空,不做任何过滤;可以设置:a > b、a == 1、a、!a、a >= 1 && a <= 10等。过滤条件为真时,当前参数可用。

  • 设置过滤器a == 1:该参数是否可用取决于参数a的值,a等于1时可用,否则不可用。
  • 设置过滤器a >= 1 && a <= 10:a大于等于1并且小于等于10时可用,否则不可用。
  • 设置过滤器!a:过滤条件为「非a」;a可以是布尔值,也可以是数值(!0为真)。

  • 回测系统中的参数保存
    在回测时如果希望将策略参数保存,可以在策略参数修改后点击「保存回测设置」按钮,参考 回测配置与保存。

    变量描述类型默认值
    number数值类型数字型(number)1
    string字符串字符串(string)Hello FMZ
    combox下拉框下拉框(selected)1|2|3
    bool布尔值布尔型(true/false)true
    numberA@isShowA数值A数字型(number)2
    isShowA是否显示numberA参数布尔型(true/false)false

    设置后的策略参数以代码形式保存在策略中,例如:

    javascript
    /*backtest start: 2020-02-29 00:00:00 end: 2020-03-29 00:00:00 period: 1d args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]] */
    python
    '''backtest start: 2020-02-29 00:00:00 end: 2020-03-29 00:00:00 period: 1d args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]] '''
    rust
    /*backtest start: 2020-02-29 00:00:00 end: 2020-03-29 00:00:00 period: 1d args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]] */

    Rust策略如果在开头用 frontmatter 声明了依赖,回测配置块要放在 frontmatter 之后,见 Rust。

  • 实盘参数导入导出
    运行实盘时需要保存实盘配置的参数数据,可以点击策略实盘页面中「参数设置」选项,再点击「导出参数」按钮,导出的策略参数将以json文件保存。
    导出的策略参数配置也可以再次导入实盘,点击「导入参数」按钮即可把保存的策略实盘参数导入到当前实盘,导入后点击「更新参数」按钮保存生效。

JavaScript、Python、Rust、My语言策略可以设计交互控件,策略的交互控件用来在策略实盘运行时给运行的策略程序发送交互指令。对于JavaScript、Python、Rust语言类型的策略,在策略代码中使用 GetCommand 函数获取交互控件产生的消息。交互控件的「组件配置」与策略参数相同,见 组件配置。

交互控件

在策略中设计好处理交互控件消息的代码,在实盘时使用交互控件可以实现(不限于)诸如以下功能:

  • 手动平掉策略持仓。
  • 动态修改策略参数,避免重启策略实盘。
  • 切换策略逻辑。
  • 触发打印某些调试信息、数据,用来测试某些功能。

变量(命名举例)描述类型默认值(说明)组件配置(说明)备注
cmdNum交互控件cmdNum的描述数字型(number)默认值选填,可留空用于设置当前交互项绑定的界面控件的:组件类型、最小值、最大值、分组等交互控件cmdNum的备注
cmdBool交互控件cmdBool的描述布尔型(true/false)默认值必选,开启或关闭同上交互控件cmdBool的备注
cmdStr交互控件cmdStr的描述字符串(string)默认值选填,可留空同上交互控件cmdStr的备注
cmdCombox交互控件cmdCombox的描述下拉框(selected)默认值选填,可留空同上交互控件cmdCombox的备注
cmdBtn交互控件cmdBtn的描述按钮(button)按钮控件不绑定输入项同上交互控件cmdBtn的备注

交互控件触发后发送给策略的消息(字符串):

  • 数字型
    在交互控件cmdNum的输入框中输入交互数据:123后,点击交互控件cmdNum的按钮。策略程序中的GetCommand()函数会收到消息:cmdNum:123。
  • 布尔型
    在交互控件cmdBool的开关控件上设置为打开,点击交互控件cmdBool的按钮。策略程序中的GetCommand()函数会收到消息:cmdBool:true。
  • 字符串
    在交互控件cmdStr的输入框中输入交互数据:abc后,点击交互控件cmdStr的按钮。策略程序中的GetCommand()函数会收到消息:cmdStr:abc。
  • 下拉框
    在交互控件cmdCombox的下拉框中选中第二个选项后,点击交互控件cmdCombox的按钮。策略程序中的GetCommand()函数会收到消息:cmdCombox:1,1表示选中的选项的索引,第一个选项索引为0,第二个选项索引为1。
  • 按钮
    点击交互控件cmdBtn的按钮。策略程序中的GetCommand()函数会收到消息:cmdBtn。

交互控件的「组件配置」与策略参数相同,见 组件配置。

示例:用交互控件动态修改策略参数

在策略编辑页面的「策略交互」中添加一个字符串类型的交互控件,变量名为changeSymbol。交互控件的设置界面:

设置交互控件

实盘运行时,在该控件的输入框中填入ETH_USDT并点击按钮,GetCommand()会收到消息changeSymbol:ETH_USDT。策略检测到这条消息后更新对应的变量(策略界面上的参数也是全局变量,这里用代码中的全局变量演示):

javascript
// 策略参数 var symbol = "BTC_USDT" function main() { while (true) { var cmd = GetCommand() if (cmd) { var arr = cmd.split(":") if (arr.length == 2 && arr[0] == "changeSymbol") { // 检测到 changeSymbol 控件触发,就会执行参数更新操作 Log("Changed symbol parameter to:", arr[1]) symbol = arr[1] } } LogStatus(_D(), ", Current symbol parameter value:", symbol) Sleep(3000) } }

除了在「策略交互」栏中设计交互控件,还可以在策略状态栏中设计交互控件。目前支持的交互控件种类仅有按钮类型,见 LogStatus。

状态栏中的按钮控件可以分为:

  • 普通按钮控件
    数据结构举例为:

    json
    {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"}
  • 带一个输入数据的按钮控件
    使用input属性设置输入控件选项,数据结构举例为:

    json
    {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Open Quantity", "type": "number", "defValue": 1}}
    json
    { "type": "button", "cmd": "test1", "name": "test1", "input": { "type": "selected", "name": "selected", "label": "Dropdown", "description": "description", "default": 100, "settings": { "multiple": true, "customizable": true, "options":[{"name": "A", "value": 100}, {"name": "B", "value": 200}] } } }
  • 带一组输入数据的按钮控件
    使用group属性设置一组输入控件的选项,数据结构举例为:

    json
    { "type": "button", "cmd": "open", "name": "Open", "group": [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true} ] }
    json
    { "type": "button", "cmd": "test2", "name": "test2", "group": [{ "type": "selected", "name": "selected", "label": "Dropdown", "description": "description", "default": 200, "group": "group1", "settings": { "multiple": true, "options":[{"name": "A", "value": 100}, {"name": "B", "value": 200}] } }, { "type": "string", "name": "string", "label": "Input Box", "description": "description", "default": "ABC", "group": "group1" }] }

将这些按钮控件JSON数据编码为JSON字符串,然后使用`字符包裹住,在状态栏输出。以JavaScript语言为例:

javascript
function main() { var btn = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} LogStatus("`" + JSON.stringify(btn) + "`") }

这些按钮控件也可以写入状态栏表格中,详细例子见 LogStatus。

input字段结构与group字段中单个控件结构一致,以下为详细说明(带注释的 JavaScript 对象):

javascript
{ "type": "selected", // 控件类型(必要字段),支持设置为:number, string, selected, boolean "name": "test", // 名称(group中使用时,为必要字段) "label": "topic", // 标题(必要字段) "description": "desc", // 组件的提示 "default": 1, // 默认值;当前JSON结构中如果不设置settings字段,兼容defValue,可以用defValue代替default "filter": "a>1", // 选择器,不设置该字段表示不过滤(显示控件);设置该字段时,当表达式为真时不过滤(显示控件)。当表达式为假时过滤(不显示控件) // 对于选择器,以当前例子中表达式a>1为例,a指的是type=button的结构中group字段下name为a的控件值,根据此数值判断是否过滤 "group": "group1", // 分组 "settings": {} // 组件配置,各字段见下文 }

组件配置settings各个字段详细说明:

  • settings.required:是否必选。
  • settings.disabled:是否禁用。
  • settings.min:type=number时有效,表示最小值。
  • settings.max:type=number时有效,表示最大值。
  • settings.step:type=number,render=slider时有效,表示步长。
  • settings.multiple:type=selected时有效,表示支持多选。
  • settings.customizable:type=selected时有效,表示支持自定义;用户可以直接在下拉框控件中编辑添加新选项,如果选中新编辑的选项,在触发交互时使用该选项的名称而不是选项代表的值。
  • settings.options:type=selected时有效,表示选择器的选项数据格式:["Option 1", "Option 2"]、[{'name':'xxx','value':0}, {'name':'xxx','value':1}]。
  • settings.render:渲染组件类型。
    type=number时,settings.render不设置(默认数字输入框),可选:slider(滑动条)、date(时间选择器返回时间戳)。
    type=string时,settings.render不设置(默认单行输入框),可选:textarea(多行输入)、date(时间选择器返回yyyy-MM-dd hh:mm:ss)、color(颜色选择器返回#FF00FF)。
    type=selected时,settings.render不设置(默认下拉框),可选:segment(分段选择器)。
    type=boolean时,目前只有默认复选框。

支持双语设置,例如:'选项|options'文本内容会根据当前语言环境适配;以group字段中单个控件为例,完整的例子(JavaScript 对象):

javascript
{ type:'selected', name:'test', label:'选项|options', description:'描述|description', default:0, // 这里default默认值设置0,表示{name:'xxx|yyy',value:0}选项中的value值 filter:'a>1&&a<10', group:'分组|group', settings:{ multiple:true, customizable:true, options:[{name:'xxx|yyy',value:0}] } }

模板类库是发明者量化交易平台中可复用的代码模块,是策略代码的一种类别。支持模板类库的语言有:JavaScript(含 TypeScript)、Python、Rust;Blockly可视化策略可以使用 JavaScript 模板类库提供的积木。创建策略时如果类别设置为模板类库,会在当前登录账号的策略库中创建一个模板类库,创建后不能再修改类别为普通策略。

创建模板类库页面

各语言中导出、调用模板函数的方式:

语言模板中导出策略中调用
JavaScript挂到$上:$.Test = function() {...}$.Test()
Python挂到ext上:ext.Test = Testext.Test()
Rust模板代码并入ext模块,供策略调用的函数声明为pub fnext::Test()
  • 模板中的main()函数在策略中不会执行,只作为单独回测、调试模板时的入口。
  • JavaScript模板可以定义init()和destroy():init()在模板加载时执行(早于策略的init()),destroy()在策略退出时、onexit()或onerror()之后执行。Python模板可以定义init(),在模板加载时执行。
  • Rust模板和策略都可以用 frontmatter 声明第三方 crate,但依赖块只能写在其中一处,两处都写会编译失败。

导出函数为模板类库的接口函数,可以被引用该模板类库的策略调用。

示例

  • 不同的编程语言的模板类库书写格式有所不同,导出函数在模板类库中声明以及实现的例子代码如下:

    javascript
    /* -- 策略引用该模板以后直接用 $.Test() 调用此方法 -- main 函数在策略中不会触发, 只做为模板调试的入口 */ $.Test = function() { Log('Test') } function main() { $.Test() }
    python
    def Test(): Log("template call") # 导出Test函数, 主策略可以通过ext.Test()调用 ext.Test = Test
    rust
    // 策略引用该模板以后直接用 ext::Test() 调用此函数 // 供策略调用的函数必须声明为 pub pub fn Test() { Log!("template call"); }
  • Blockly可视化方式编写的策略使用类库功能可以藉由JavaScript语言的模板类库编写实现,使用以下书写格式编写。

    javascript
    /*blockly { "type": "ext_testA", "message0": "testA|testA", "template": "function(){return 99;}()", "order": "ORDER_ATOMIC", "output": "Number" },{ "type": "ext_MA", "message0": "MA 周期 %1| MA Period %1", "args0": [{ "type": "input_value", "check": "Number" }], "template": "(function(){var r = exchange.GetRecords(); return (!r || r.length < %1) ? false : TA.MA(r, %1); })()", "order": "ORDER_ATOMIC", "output": null, "colour": 85 } */

模板类库也可以设置自己的界面参数,模板类库的参数在模板类库代码中是以全局变量的形式使用的(Rust 中为全局常量)。
例如我们设置了一个模板类库的参数:

模板参数

策略代码中参数的变量名策略界面上显示的参数名称类型默认值
param1模板参数1数字型(number)99

Rust模板的参数是常量,只能读取,不能修改,所以下面的例子在 Rust 中只能实现读取参数:

rust
// 模板代码 pub fn GetParam1() -> f64 { Log!("param1:", param1); param1 }
rust
// 策略代码 fn main() { Log!("Calling ext::GetParam1:", ext::GetParam1()); }

示例

  • 用于测试param1参数的模板类库代码:

    javascript
    $.SetParam1 = function(p1) { param1 = p1 } $.GetParam1 = function() { Log("param1:", param1) return param1 }
    python
    def SetParam1(p1): global param1 param1 = p1 def GetParam1(): Log("param1:", param1) return param1 ext.SetParam1 = SetParam1 ext.GetParam1 = GetParam1
    rust
    // Rust 模板参数是只读常量,不能修改,读取参数的写法见上文
  • 引用以上模板类库例子的策略代码,使用模板类库的导出函数获取参数param1和修改参数param1。

    javascript
    function main () { Log("Calling $.GetParam1:", $.GetParam1()) Log("Calling $.SetParam1:", "#FF0000") $.SetParam1(20) Log("Calling $.GetParam1:", $.GetParam1()) }
    python
    def main(): Log("Calling ext.GetParam1:", ext.GetParam1()) Log("Calling ext.SetParam1:", "#FF0000") ext.SetParam1(20) Log("Calling ext.GetParam1:", ext.GetParam1())
    rust
    // Rust 模板参数是只读常量,不能修改,读取参数的写法见上文

策略引用模板类库时,需要当前登录的发明者量化交易平台账号的策略库中存在可用的模板类库。在策略编辑页面的模板栏中勾选需要引用的模板,保存策略后即可完成引用。

模板引用截图

发明者量化交易平台内置了一些常用库。各语言可用情况:

库JavaScript / TypeScriptPythonRust
TA指标库支持支持支持
talib指标库支持需在托管者所在机器安装 TA-Lib 和 numpy不支持
JSON语言内置JSON标准库jsonJSONParse()/JsonValue

完整的函数列表与参数见手册 TA、Talib。

TA指标库

平台的TA指标库优化了常用指标算法(开源TA库代码)。K 线数量不足以计算指标时,对应位置返回无效值。

javascript
function main(){ var records = exchange.GetRecords() var macd = TA.MACD(records) var atr = TA.ATR(records, 14) // 打印最后一组指标值 Log(macd[0][records.length-1], macd[1][records.length-1], macd[2][records.length-1]) Log(atr[atr.length-1]) }
rust
fn main() { let r = exchange.GetRecords(None, None, None).unwrap(); let macd = TA.MACD(&r, None, None, None); let atr = TA.ATR(&r, 14); Log!(macd[0][r.len() - 1], macd[1][r.len() - 1], macd[2][r.len() - 1]); Log!(atr[atr.len() - 1]); }

talib指标库

javascript
function main() { var records = exchange.GetRecords() var cci = talib.CCI(records, 14) Log(cci) }
python
# Python 需要在托管者所在机器安装 TA-Lib 与 numpy,未安装时调用 talib 会报错提示安装 def main(): records = exchange.GetRecords() cci = talib.CCI(records.High, records.Low, records.Close, 14) Log(cci)

JavaScript:动态加载第三方库

其它第三方 JavaScript 库可以在运行时下载后用eval加载:

javascript
function main() { // via. https://cdnjs.com/libraries eval(HttpQuery("https://cdnjs.cloudflare.com/ajax/libs/mathjs/13.2.0/math.min.js")) Log(math.round(math.e, 3)) // 2.718 Log(math.atan2(3, -3) / math.pi) // 0.75 Log(math.log(10000, 10)) // 4 Log(math.sqrt(-4)) // {"mathjs":"Complex","re":0,"im":2} }

策略名称和策略参数的描述均可采用中文|英文的格式书写,使网页能够自动识别并显示相应的语言。在其它使用场景中,例如策略描述、使用说明等Markdown格式的文本,使用[trans]中文|英文[/trans]或[trans]中文||英文[/trans]同样可以实现语言的自动识别。切换语言后,刷新网页即可生效。此外,在策略代码中,凡是可以写入字符串的函数也支持语言切换,例如Log()函数、LogStatus()函数等。

javascript
function main() { Log("[trans]日志|log[/trans]") var table = { type: "table", title: "[trans]操作|option[/trans]", cols: ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"], rows: [ ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}] // 注意:按钮中不用加[trans]标签 ] } LogStatus("[trans]信息|message[/trans]", "\n`" + JSON.stringify(table) + "`") throw "[trans]错误|error[/trans]" }
python
import json def main(): Log("[trans]日志|log[/trans]") table = { "type": "table", "title": "[trans]操作|option[/trans]", "cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"], "rows": [ ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}] ] } LogStatus("[trans]信息|message[/trans]", "\n`" + json.dumps(table) + "`") raise Exception("[trans]错误|error[/trans]")
rust
fn main() { Log!("[trans]日志|log[/trans]"); let table = r#"{ "type": "table", "title": "[trans]操作|option[/trans]", "cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"], "rows": [ ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}] ] }"#; LogStatus!("[trans]信息|message[/trans]", format!("\n`{}`", table)); Panic!("[trans]错误|error[/trans]"); }