输入/搜索内容
内置函数
Global
Version
Sleep
IsVirtual
Mail
Mail_Go
SetErrorFilter
GetPid
GetLastError
GetCommand
GetMeta
Dial
HttpQuery
HttpQuery_Go
Encode
UnixNano
Unix
GetOS
MD5
DBExec
UUID
EventLoop
__Serve
_G
_D
_N
_C
_Cross
JSON.parse
JSON.stringify
SetChannelData
GetChannelData
Log
Market
Trade
Account
Futures
NetSettings
Threads
threading
Thread
getThread
mainThread
currentThread
Lock
Condition
Event
Dict
pending
Thread
ThreadLock
ThreadEvent
ThreadCondition
ThreadDict
Web3
TA
Talib
talib.CDL2CROWS
talib.CDL3BLACKCROWS
talib.CDL3INSIDE
talib.CDL3LINESTRIKE
talib.CDL3OUTSIDE
talib.CDL3STARSINSOUTH
talib.CDL3WHITESOLDIERS
talib.CDLABANDONEDBABY
talib.CDLADVANCEBLOCK
talib.CDLBELTHOLD
talib.CDLBREAKAWAY
talib.CDLCLOSINGMARUBOZU
talib.CDLCONCEALBABYSWALL
talib.CDLCOUNTERATTACK
talib.CDLDARKCLOUDCOVER
talib.CDLDOJI
talib.CDLDOJISTAR
talib.CDLDRAGONFLYDOJI
talib.CDLENGULFING
talib.CDLEVENINGDOJISTAR
talib.CDLEVENINGSTAR
talib.CDLGAPSIDESIDEWHITE
talib.CDLGRAVESTONEDOJI
talib.CDLHAMMER
talib.CDLHANGINGMAN
talib.CDLHARAMI
talib.CDLHARAMICROSS
talib.CDLHIGHWAVE
talib.CDLHIKKAKE
talib.CDLHIKKAKEMOD
talib.CDLHOMINGPIGEON
talib.CDLIDENTICAL3CROWS
talib.CDLINNECK
talib.CDLINVERTEDHAMMER
talib.CDLKICKING
talib.CDLKICKINGBYLENGTH
talib.CDLLADDERBOTTOM
talib.CDLLONGLEGGEDDOJI
talib.CDLLONGLINE
talib.CDLMARUBOZU
talib.CDLMATCHINGLOW
talib.CDLMATHOLD
talib.CDLMORNINGDOJISTAR
talib.CDLMORNINGSTAR
talib.CDLONNECK
talib.CDLPIERCING
talib.CDLRICKSHAWMAN
talib.CDLRISEFALL3METHODS
talib.CDLSEPARATINGLINES
talib.CDLSHOOTINGSTAR
talib.CDLSHORTLINE
talib.CDLSPINNINGTOP
talib.CDLSTALLEDPATTERN
talib.CDLSTICKSANDWICH
talib.CDLTAKURI
talib.CDLTASUKIGAP
talib.CDLTHRUSTING
talib.CDLTRISTAR
talib.CDLUNIQUE3RIVER
talib.CDLUPSIDEGAP2CROWS
talib.CDLXSIDEGAP3METHODS
talib.AD
talib.ADOSC
talib.OBV
talib.ACOS
talib.ASIN
talib.ATAN
talib.CEIL
talib.COS
talib.COSH
talib.EXP
talib.FLOOR
talib.LN
talib.LOG10
talib.SIN
talib.SINH
talib.SQRT
talib.TAN
talib.TANH
talib.MAX
talib.MAXINDEX
talib.MIN
talib.MININDEX
talib.MINMAX
talib.MINMAXINDEX
talib.SUM
talib.HT_DCPERIOD
talib.HT_DCPHASE
talib.HT_PHASOR
talib.HT_SINE
talib.HT_TRENDMODE
talib.ATR
talib.NATR
talib.TRANGE
talib.BBANDS
talib.DEMA
talib.EMA
talib.HT_TRENDLINE
talib.KAMA
talib.MA
talib.MAMA
talib.MIDPOINT
talib.MIDPRICE
talib.SAR
talib.SAREXT
talib.SMA
talib.T3
talib.TEMA
talib.TRIMA
talib.WMA
talib.LINEARREG
talib.LINEARREG_ANGLE
talib.LINEARREG_INTERCEPT
talib.LINEARREG_SLOPE
talib.STDDEV
talib.TSF
talib.VAR
talib.ADX
talib.ADXR
talib.APO
talib.AROON
talib.AROONOSC
talib.BOP
talib.CCI
talib.CMO
talib.DX
talib.MACD
talib.MACDEXT
talib.MACDFIX
talib.MFI
talib.MINUS_DI
talib.MINUS_DM
talib.MOM
talib.PLUS_DI
talib.PLUS_DM
talib.PPO
talib.ROC
talib.ROCP
talib.ROCR
talib.ROCR100
talib.RSI
talib.STOCH
talib.STOCHF
talib.STOCHRSI
talib.TRIX
talib.ULTOSC
talib.WILLR
talib.AVGPRICE
talib.MEDPRICE
talib.TYPPRICE
talib.WCLPRICE
OS
结构体
内置变量

返回当前系统版本号。

Version()

示例

javascript
function main() { Log("version:", Version()) }
python
def main(): Log("version:", Version())
rust
fn main() { Log!("version:", Version()); }
c++
void main() { Log("version:", Version()); }

返回值

类型描述

string

当前系统版本号,例如:3.6

备注

系统版本号即托管者程序的版本号。

休眠函数,使程序暂停运行一段指定的时间。

Sleep(millisecond)

示例

javascript
function main() { Sleep(1000 * 10) // 等待10秒钟 Log("Waited for 10 seconds") }
python
def main(): Sleep(1000 * 10) Log("Waited for 10 seconds")
rust
fn main() { Sleep(1000 * 10); // 等待10秒钟 Log!("Waited for 10 seconds"); }
c++
void main() { Sleep(1000 * 10); Log("Waited for 10 seconds"); }

参数

名称类型必填描述

millisecond

number

millisecond参数用于设置休眠时长,单位为毫秒。

备注

例如,执行Sleep(1000)函数时,程序将休眠1秒。该函数支持小于1毫秒的休眠操作,例如Sleep(0.1)。支持的最小参数为0.000001,即纳秒级休眠,1纳秒等于1e-6毫秒。

在使用Python语言编写策略时,对于轮询间隔、时间等待等操作,应当使用Sleep(millisecond)函数,而不建议使用Pythontime库的time.sleep(second)函数。因为策略在回测时若使用time.sleep(second)函数,会使策略程序实际等待一段时间(而非在回测系统的时间序列上跳过),从而导致回测速度非常缓慢。

用于判断策略的运行环境是否为回测系统。

IsVirtual()

示例

javascript
function main() { if (IsVirtual()) { Log("Currently in backtest environment.") } else { Log("Currently in live trading environment.") } }
python
def main(): if IsVirtual(): Log("Currently in backtest environment.") else: Log("Currently in live trading environment.")
rust
fn main() { if IsVirtual() { Log!("Currently in backtest environment."); } else { Log!("Currently in live trading environment."); } }
c++
void main() { if (IsVirtual()) { Log("Currently in backtest environment."); } else { Log("Currently in live trading environment."); } }

返回值

类型描述

bool

当策略运行在回测系统环境中时,返回真值,例如:true;当策略运行在实盘环境中时,返回假值,例如:false

备注

用于判断当前运行环境是否为回测系统,以便兼容回测与实盘环境之间的差异。

发送邮件。

Mail(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)

示例

javascript
function main(){ Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body") }
python
def main(): Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body")
rust
fn main() { Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body"); }
c++
void main() { Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body"); }

返回值

类型描述

bool

邮件发送成功时返回真值,例如true;发送失败时返回假值,例如false

参数

名称类型必填描述

smtpServer

string

用于指定邮件发送方的SMTP服务器地址。

smtpUsername

string

用于指定邮件发送方的邮箱地址。

smtpPassword

string

用于指定邮件发送方邮箱的SMTP服务密码。

mailTo

string

用于指定邮件接收方的邮箱地址。

title

string

邮件标题。

body

string

邮件正文。

参考

备注

smtpPassword参数设置的是SMTP服务的密码,而非邮箱登录密码。

设置smtpServer参数时,如需更改端口,可直接在smtpServer参数中附加端口号。例如:QQ 邮箱的smtp.qq.com:587端口经测试可用。

如果出现报错unencryped connection,则需要修改Mail函数的smtpServer参数,其格式为ssl://xxx.com:xxx。例如,QQ 邮箱SMTPssl方式为ssl://smtp.qq.com:465,或使用smtp://xxx.com:xxx

该函数在回测系统中不起作用。

Mail函数的异步版本。

Mail_Go(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)

示例

javascript
function main() { var r1 = Mail_Go("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body") var r2 = Mail_Go("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body") var ret1 = r1.wait() var ret2 = r2.wait() Log("ret1:", ret1) Log("ret2:", ret2) }
python
# 不支持
c++
// 不支持

返回值

类型描述

object

Mail_Go函数立即返回一个并发对象,可以使用该并发对象的wait方法获取邮件发送结果。邮件发送成功返回真值(例如:true),发送失败返回假值(例如:false)。

参数

名称类型必填描述

smtpServer

string

用于指定邮件发送方的SMTP服务器地址。

smtpUsername

string

用于指定邮件发送方的邮箱地址。

smtpPassword

string

邮件发送方邮箱的SMTP授权密码。

mailTo

string

用于指定邮件接收方的邮箱地址。

title

string

邮件标题。

body

string

邮件正文内容。

参考

备注

在回测系统中不起作用。

过滤错误日志。

SetErrorFilter(filters)

示例

  • 过滤常见错误。

    javascript
    function main() { SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused") }
    python
    def main(): SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
    rust
    fn main() { SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused"); }
    c++
    void main() { SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused"); }
  • 过滤指定接口的错误信息。

    javascript
    function main() { // 查询一个不存在的订单(id 为 123),故意触发接口报错 var order = exchange.GetOrder("123") Log(order) // 过滤 http 502 错误和 GetOrder 接口错误;设置错误过滤后,第二次调用 GetOrder 将不再报错 SetErrorFilter("502:|GetOrder") order = exchange.GetOrder("123") Log(order) }
    python
    def main(): order = exchange.GetOrder("123") Log(order) SetErrorFilter("502:|GetOrder") order = exchange.GetOrder("123") Log(order)
    rust
    fn main() { // 查询一个不存在的订单(id 为 123),故意触发接口报错 let orderId = OrderId { S: "123".to_string(), ..Default::default() }; let order = exchange.GetOrder(&orderId); Log!(order); // 过滤 http 502 错误和 GetOrder 接口错误;设置错误过滤后,第二次调用 GetOrder 将不再报错 SetErrorFilter("502:|GetOrder"); let order = exchange.GetOrder(&orderId); Log!(order); }
    c++
    void main() { TId orderId; Order order = exchange.GetOrder(orderId); Log(order); SetErrorFilter("502:|GetOrder"); order = exchange.GetOrder(orderId); Log(order); }

参数

名称类型必填描述

filters

string

正则表达式字符串。

备注

与此正则表达式匹配的错误日志将不再上传至日志系统。该函数可多次调用(无次数限制)以设置多个过滤条件,多次设置的正则表达式会累积并同时生效。可传入空字符串以重置用于过滤错误日志的正则表达式:SetErrorFilter("")。被过滤的日志将不再写入托管者目录下对应实盘 Id 的数据库文件中,从而防止因频繁报错导致数据库文件膨胀。

获取实盘进程的 ID。

GetPid()

示例

javascript
function main(){ var id = GetPid() Log(id) }
python
def main(): id = GetPid() Log(id)
rust
fn main() { let id = GetPid(); Log!(id); }
c++
void main() { auto id = GetPid(); Log(id); }

返回值

类型描述

string

返回实盘进程的 ID。

获取最近一次的错误信息。

GetLastError()

示例

javascript
function main(){ // 由于不存在编号为 123 的订单,因此会触发错误 exchange.GetOrder("123") var error = GetLastError() Log(error) }
python
def main(): exchange.GetOrder("123") error = GetLastError() Log(error)
rust
fn main() { // 由于不存在编号为 123 的订单,因此会触发错误 // Rust 的 GetOrder 接受 &OrderId 参数,字符串 id 需放在 S 字段中 let id = OrderId { S: "123".to_string(), ..Default::default() }; let _ = exchange.GetOrder(&id); let error = GetLastError(); Log!(error); }
c++
void main() { // 订单 ID 的类型为 TId,因此不能传入字符串;此处下单一个不符合交易所规范的订单以触发错误 exchange.GetOrder(exchange.Buy(1, 1)); auto error = GetLastError(); Log(error); }

返回值

类型描述

string

最近一次的错误信息。

备注

该函数在回测系统中不起作用。

获取策略的交互命令。

GetCommand()

示例

  • 检测交互命令,并在检测到交互命令时使用Log函数将其输出。

    javascript
    function main(){ while(true) { var cmd = GetCommand() if (cmd) { Log(cmd) } Sleep(1000) } }
    python
    def main(): while True: cmd = GetCommand() if cmd: Log(cmd) Sleep(1000)
    rust
    fn main() { loop { // Rust 的 GetCommand() 需要传入超时参数(毫秒),返回 Option<String>,无命令时为 None if let Some(cmd) = GetCommand(0) { Log!(cmd); } Sleep(1000); } }
    c++
    void main() { while(true) { auto cmd = GetCommand(); if(cmd != "") { Log(cmd); } Sleep(1000); } }
  • 例如,在策略交互控件中添加一个不带输入框的控件,将其命名为buy,控件描述信息为买入,这是一个按钮控件;再添加一个带输入框的控件,将其命名为sell,控件描述信息为卖出,这是一个由按钮和输入框组合而成的交互控件。在策略中编写交互代码,以响应不同的交互控件:

    javascript
    function main() { while (true) { LogStatus(_D()) var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) var arr = cmd.split(":") if (arr[0] == "buy") { Log("Buy, this control has no quantity") } else if (arr[0] == "sell") { Log("Sell, this control has quantity:", arr[1]) } else { Log("Other control triggered:", arr) } } Sleep(1000) } }
    python
    def main(): while True: LogStatus(_D()) cmd = GetCommand() if cmd: Log("cmd:", cmd) arr = cmd.split(":") if arr[0] == "buy": Log("Buy, this control has no quantity") elif arr[0] == "sell": Log("Sell, this control has quantity:", arr[1]) else: Log("Other control triggered:", arr) Sleep(1000)
    rust
    fn main() { loop { LogStatus!(_D(None)); if let Some(cmd) = GetCommand(0) { Log!("cmd:", cmd); let arr: Vec<&str> = cmd.split(':').collect(); if arr[0] == "buy" { Log!("Buy, this control has no quantity"); } else if arr[0] == "sell" { Log!("Sell, this control has quantity:", arr[1]); } else { Log!("Other control triggered:", arr); } } Sleep(1000); } }
    c++
    #include <iostream> #include <sstream> #include <string> #include <vector> using namespace std; void split(const string& s,vector<string>& sv,const char flag = ' ') { sv.clear(); istringstream iss(s); string temp; while (getline(iss, temp, flag)) { sv.push_back(temp); } return; } void main() { while(true) { LogStatus(_D()); auto cmd = GetCommand(); if (cmd != "") { vector<string> arr; split(cmd, arr, ':'); if(arr[0] == "buy") { Log("Buy, this control has no quantity"); } else if (arr[0] == "sell") { Log("Sell, this control has quantity:", arr[1]); } else { Log("Other control triggered:", arr); } } Sleep(1000); } }

返回值

类型描述

string

返回的命令格式为ControlName:Data,其中ControlName为控件名称,Data为控件中输入的数据。如果交互控件不包含输入框、下拉框等输入组件(例如:不带输入框的按钮控件),则返回的命令格式为ControlName,即仅返回控件名称。

备注

该函数在回测系统中无效。

获取在生成策略注册码时写入的Meta值。

GetMeta()

示例

应用场景范例:使用Meta限制策略可操作的资产数量。

javascript
function main() { // 策略允许的计价币最大资产数值 var maxBaseCurrency = null // 获取创建注册码时的元数据 var level = GetMeta() // 检测Meta对应的条件 if (level == "level1") { // -1为不限制 maxBaseCurrency = -1 } else if (level == "level2") { maxBaseCurrency = 10 } else if (level == "level3") { maxBaseCurrency = 1 } else { maxBaseCurrency = 0.5 } while(1) { Sleep(1000) var ticker = exchange.GetTicker() // 检测资产数值 var acc = exchange.GetAccount() if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) { // 停止执行策略交易逻辑 LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!") continue } // 其它交易逻辑 // 正常输出状态栏信息 LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker) } }
python
def main(): maxBaseCurrency = null level = GetMeta() if level == "level1": maxBaseCurrency = -1 elif level == "level2": maxBaseCurrency = 10 elif level == "level3": maxBaseCurrency = 1 else: maxBaseCurrency = 0.5 while True: Sleep(1000) ticker = exchange.GetTicker() acc = exchange.GetAccount() if maxBaseCurrency != -1 and maxBaseCurrency < acc["Stocks"] + acc["FrozenStocks"]: LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!") continue # 其它交易逻辑 # 正常输出状态栏信息 LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker)
rust
fn main() { // 策略允许的计价币最大资产数值 let maxBaseCurrency; // 获取创建注册码时的元数据,Rust 的 GetMeta() 返回 JsonValue 类型 let meta = GetMeta(); let level = meta.as_str().unwrap_or(""); // 检测Meta对应的条件 if level == "level1" { // -1为不限制 maxBaseCurrency = -1.0; } else if level == "level2" { maxBaseCurrency = 10.0; } else if level == "level3" { maxBaseCurrency = 1.0; } else { maxBaseCurrency = 0.5; } loop { Sleep(1000); let ticker = exchange.GetTicker(None).unwrap(); // 检测资产数值 let acc = exchange.GetAccount().unwrap(); if maxBaseCurrency != -1.0 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks { // 停止执行策略交易逻辑 LogStatus!(_D(None), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!"); continue; } // 其它交易逻辑 // 正常输出状态栏信息 LogStatus!(_D(None), "level:", level, "Strategy running normally! ticker data:\n", ticker); } }
c++
void main() { auto maxBaseCurrency = 0.0; auto level = GetMeta(); if (level == "level1") { maxBaseCurrency = -1; } else if (level == "level2") { maxBaseCurrency = 10; } else if (level == "level3") { maxBaseCurrency = 1; } else { maxBaseCurrency = 0.5; } while(1) { Sleep(1000); auto ticker = exchange.GetTicker(); auto acc = exchange.GetAccount(); if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) { // 停止执行策略交易逻辑 LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!"); continue; } // 其它交易逻辑 // 正常输出状态栏信息 LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker); } }

返回值

类型描述

string

Meta数据。

备注

应用场景:需要对不同的策略租用者进行资金限制。生成注册码时设置的Meta值长度不能超过190个字符。GetMeta()函数仅支持实盘,在回测系统中不起作用。如果生成策略注册码时未设置元数据(Meta),GetMeta()函数将返回空值。

用于原始 Socket 访问,支持 tcpudptlsunix 协议。支持 4 种主流通信协议:mqttnatsamqpkafka。同时支持连接数据库,可用的数据库包括:sqlite3mysqlpostgresclickhouse

Dial(address)
Dial(address, timeout)
Dial(address, options)

示例

  • Dial 函数调用示例:

    javascript
    function main(){ // Dial 支持 tcp://、udp://、tls://、unix:// 协议,可传入一个参数指定超时秒数 var client = Dial("tls://www.baidu.com:443") if (client) { // write 可额外传入一个数字参数指定超时,返回成功发送的字节数 client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while (true) { // read 可额外传入一个数字参数指定超时,单位:毫秒;返回 null 表示出错、超时或 socket 已关闭 var buf = client.read() if (!buf) { break } Log(buf) } client.close() } }
    python
    def main(): client = Dial("tls://www.baidu.com:443") if client: client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while True: buf = client.read() if not buf: break Log(buf) client.close()
    rust
    fn main() { // Dial 支持 tcp://、udp://、tls://、unix:// 协议,可使用 Dial::new(addr, timeout) 指定超时秒数 let mut client = Dial("tls://www.baidu.com:443"); if client.Valid() { // write 的第二个数字参数用于指定超时,返回成功发送的字节数 client.write("GET / HTTP/1.1\nConnection: Closed\n\n", 0); loop { // read 的数字参数用于指定超时,单位:毫秒;返回空字符串表示出错、超时或 socket 已关闭 let buf = client.read(0); if buf == "" { break; } Log!(buf); } client.close(); } }
    c++
    void main() { auto client = Dial("tls://www.baidu.com:443"); if(client.Valid) { client.write("GET / HTTP/1.1\nConnection: Closed\n\n"); while(true) { auto buf = client.read(); if(buf == "") { break; } Log(buf); } client.close(); } }
  • 访问币安(Binance)的 WebSocket 行情接口:

    javascript
    function main() { LogStatus("Connecting...") // 访问币安的 WebSocket 接口 var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if (!client) { Log("Connection failed, exiting") return } while (true) { // read 仅返回调用 read 之后接收到的数据 var buf = client.read() if (!buf) { break } var table = { type: 'table', title: '行情图表', cols: ['币种', '最高', '最低', '买一', '卖一', '最后成交价', '成交量', '更新时间'], rows: [] } var obj = JSON.parse(buf) _.each(obj, function(ticker) { table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)]) }) LogStatus('`' + JSON.stringify(table) + '`') } client.close() }
    python
    import json def main(): LogStatus("Connecting...") client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if not client: Log("Connection failed, exiting") return while True: buf = client.read() if not buf: break table = { "type" : "table", "title" : "行情图表", "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], "rows" : [] } obj = json.loads(buf) for i in range(len(obj)): table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))]) LogStatus('`' + json.dumps(table) + '`') client.close()
    rust
    fn main() { LogStatus!("Connecting..."); // 访问币安的 WebSocket 接口 let mut client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr"); if !client.Valid() { Log!("Connection failed, exiting"); return; } loop { // read 仅返回调用 read 之后接收到的数据 let buf = client.read(0); if buf == "" { break; } let obj = JSONParse(&buf).unwrap(); // Rust SDK 没有 JSON 序列化功能,此处使用字符串拼接来构造状态栏表格的 JSON 文本 let mut rows = String::new(); if let Some(arr) = obj.as_array() { for ticker in arr { if !rows.is_empty() { rows += ","; } rows += &format!(r#"["{}","{}","{}","{}","{}","{}","{}","{}"]"#, ticker["s"].as_str().unwrap_or(""), ticker["h"].as_str().unwrap_or(""), ticker["l"].as_str().unwrap_or(""), ticker["b"].as_str().unwrap_or(""), ticker["a"].as_str().unwrap_or(""), ticker["c"].as_str().unwrap_or(""), ticker["q"].as_str().unwrap_or(""), _D(ticker["E"].as_i64().unwrap_or(0))); } } let table = format!(r#"{{"type":"table","title":"行情图表","cols":["币种","最高","最低","买一","卖一","最后成交价","成交量","更新时间"],"rows":[{}]}}"#, rows); LogStatus!(format!("`{}`", table)); } client.close(); }
    c++
    void main() { LogStatus("Connecting..."); auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr"); if(!client.Valid) { Log("Connection failed, exiting"); return; } while(true) { auto buf = client.read(); if(buf == "") { break; } json table = R"({ "type" : "table", "title" : "行情图表", "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], "rows" : [] })"_json; json obj = json::parse(buf); for(auto& ele : obj.items()) { table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"], ele.value()["q"], _D(ele.value()["E"])}); } LogStatus("`" + table.dump() + "`"); } client.close(); }
  • 访问币安(Binance)的 WebSocket 接口,并设置 wss 请求头。

    javascript
    function main() { let options = {"headers": {"X-MBX-APIKEY": "your access key"}} let random = `fmz${UnixNano()}` let ts = new Date().getTime() let secretKey = "your secret key" let topic = "com_announcement_en" let payload = `random=${random}&topic=${topic}&recvWindow=30000&timestamp=${ts}` let signature = Encode("sha256", "string", "hex", payload, "string", secretKey) let query = `?${payload}&signature=${signature}` Log("query:", query) let conn = Dial(`wss://api.binance.com/sapi/wss${query}`, options) for (var i = 0 ; i < 10 ; i++) { let ret = conn.read() Log(ret) } }
    python
    import time def main(): options = {"headers": {"X-MBX-APIKEY": "your access key"}} random = "fmz" + str(UnixNano()) ts = int(time.time() * 1000) secretKey = "your secret key" topic = "com_announcement_en" payload = f"random={random}&topic={topic}&recvWindow=30000&timestamp={ts}" signature = Encode("sha256", "string", "hex", payload, "string", secretKey) query = f"?{payload}&signature={signature}" Log("query:", query) conn = Dial(f"wss://api.binance.com/sapi/wss{query}", options) for i in range(10): ret = conn.read() Log(ret)
    rust
    fn main() { // Rust 中使用 Dial::with_options(),以 JSON 字符串形式传入 options 设置请求头 let options = r#"{"headers": {"X-MBX-APIKEY": "your access key"}}"#; let random = format!("fmz{}", UnixNano()); let ts = Unix() * 1000; let secretKey = "your secret key"; let topic = "com_announcement_en"; let payload = format!("random={}&topic={}&recvWindow=30000&timestamp={}", random, topic, ts); let signature = Encode("sha256", "string", "hex", &payload, "string", secretKey); let query = format!("?{}&signature={}", payload, signature); Log!("query:", query); let mut conn = Dial::with_options(&format!("wss://api.binance.com/sapi/wss{}", query), options); for _i in 0..10 { let ret = conn.read(0); Log!(ret); } }
    c++
    // 暂不支持
  • 访问 OKX 的 WebSocket 行情接口:

    javascript
    var ws = null function main(){ var param = { "op": "subscribe", "args": [{ "channel": "tickers", "instId": "BTC-USDT" }] } // 调用 Dial 函数时,指定 reconnect=true 即可启用重连模式,指定 payload 即为重连时发送的消息。当 WebSocket 连接断开后,将自动重连并自动发送该消息 ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param)) if(ws){ var pingCyc = 1000 * 20 var lastPingTime = new Date().getTime() while(true){ var nowTime = new Date().getTime() var ret = ws.read() Log("ret:", ret) if(nowTime - lastPingTime > pingCyc){ var retPing = ws.write("ping") lastPingTime = nowTime Log("Sending: ping", "#FF0000") } LogStatus("Current time:", _D()) Sleep(1000) } } } function onexit() { ws.close() Log("Exiting") }
    python
    import json import time ws = None def main(): global ws param = { "op": "subscribe", "args": [{ "channel": "tickers", "instId": "BTC-USDT" }] } ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param)) if ws: pingCyc = 1000 * 20 lastPingTime = time.time() * 1000 while True: nowTime = time.time() * 1000 ret = ws.read() Log("ret:", ret) if nowTime - lastPingTime > pingCyc: retPing = ws.write("ping") lastPingTime = nowTime Log("Sending: ping", "#FF0000") LogStatus("Current time:", _D()) Sleep(1000) def onexit(): ws.close() Log("Exiting")
    rust
    fn main() { let param = r#"{"op":"subscribe","args":[{"channel":"tickers","instId":"BTC-USDT"}]}"#; // 调用 Dial 函数时,指定 reconnect=true 即可启用重连模式,指定 payload 即为重连时发送的消息。当 WebSocket 连接断开后,将自动重连并自动发送该消息 let mut ws = Dial(&format!("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload={}", param)); if ws.Valid() { let pingCyc = 1000 * 20; let mut lastPingTime = Unix() * 1000; loop { let nowTime = Unix() * 1000; let ret = ws.read(0); Log!("ret:", ret); if nowTime - lastPingTime > pingCyc { let retPing = ws.write("ping", 0); lastPingTime = nowTime; Log!("Sending: ping", "#FF0000"); } LogStatus!("Current time:", _D(None)); Sleep(1000); } } // 在 Rust 中,连接对象在离开作用域时会自动关闭,也可以显式调用 ws.close() }
    c++
    auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true"); void main() { json param = R"({ "op": "subscribe", "args": [{ "channel": "tickers", "instId": "BTC-USDT" }] })"_json; objWS.write(param.dump()); if(objWS.Valid) { uint64_t pingCyc = 1000 * 20; uint64_t lastPingTime = Unix() * 1000; while(true) { uint64_t nowTime = Unix() * 1000; auto ret = objWS.read(); Log("ret:", ret); if(nowTime - lastPingTime > pingCyc) { auto retPing = objWS.write("ping"); lastPingTime = nowTime; Log("Sending: ping", "#FF0000"); } LogStatus("Current time:", _D()); Sleep(1000); } } } void onexit() { objWS.close(); Log("Exiting"); }
  • 访问火币交易所的 WebSocket 行情接口:

    javascript
    var ws = null function main(){ var param = {"sub": "market.btcusdt.detail", "id": "id1"} ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param)) if(ws){ while(1){ var ret = ws.read() Log("ret:", ret) // 响应心跳包操作 try { var jsonRet = JSON.parse(ret) if(typeof(jsonRet.ping) == "number") { var strPong = JSON.stringify({"pong" : jsonRet.ping}) ws.write(strPong) Log("Responding to ping, sending pong:", strPong, "#FF0000") } } catch(e) { Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message) } LogStatus("Current time:", _D()) Sleep(1000) } } } function onexit() { ws.close() Log("Executing ws.close()") }
    python
    import json ws = None def main(): global ws param = {"sub" : "market.btcusdt.detail", "id" : "id1"} ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param)) if ws: while True: ret = ws.read() Log("ret:", ret) # 响应心跳包操作 try: jsonRet = json.loads(ret) if "ping" in jsonRet and type(jsonRet["ping"]) == int: strPong = json.dumps({"pong" : jsonRet["ping"]}) ws.write(strPong) Log("Responding to ping, sending pong:", strPong, "#FF0000") except Exception as e: Log("e:", e) LogStatus("Current time:", _D()) Sleep(1000) def onexit(): ws.close() Log("Executing ws.close()")
    rust
    fn main() { let param = r#"{"sub":"market.btcusdt.detail","id":"id1"}"#; let mut ws = Dial(&format!("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload={}", param)); if ws.Valid() { loop { let ret = ws.read(0); Log!("ret:", ret); // 响应心跳包操作,Rust 中使用 JSONParse() 解析,解析失败返回 None if let Some(jsonRet) = JSONParse(&ret) { if jsonRet["ping"].is_number() { let strPong = format!(r#"{{"pong":{}}}"#, jsonRet["ping"].as_i64().unwrap_or(0)); ws.write(&strPong, 0); Log!("Responding to ping, sending pong:", strPong, "#FF0000"); } } LogStatus!("Current time:", _D(None)); Sleep(1000); } } // Rust 中连接对象在离开作用域时自动关闭,也可以显式调用 ws.close() }
    c++
    using namespace std; void main() { json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json; auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump()); if(ws.Valid) { while(true) { auto ret = ws.read(); Log("ret:", ret); // 响应心跳包操作 try { auto jsonRet = json::parse(ret); if(jsonRet["ping"].is_number()) { json pong = R"({"pong" : 0})"_json; pong["pong"] = jsonRet["ping"]; auto strPong = pong.dump(); ws.write(strPong); Log("Responding to ping, sending pong:", strPong, "#FF0000"); } } catch(exception &e) { Log("e:", e.what()); } LogStatus("Current time:", _D()); Sleep(1000); } } } void onexit() { // ws.close(); Log("Executing ws.close()"); }
  • 访问 OKX 的 WebSocket 验证接口:

    javascript
    function getLogin(pAccessKey, pSecretKey, pPassphrase) { // 签名函数,用于生成登录请求 var ts = (new Date().getTime() / 1000).toString() var login = { "op": "login", "args":[{ "apiKey" : pAccessKey, "passphrase" : pPassphrase, "timestamp" : ts, "sign" : exchange.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", pSecretKey) }] } return login } var client_private = null function main() { // 由于 read 函数设置了超时,需过滤超时报错,否则会产生冗余的错误输出 SetErrorFilter("timeout") // 持仓频道的订阅信息 var posSubscribe = { "op": "subscribe", "args": [{ "channel": "positions", "instType": "ANY" }] } var accessKey = "xxx" var secretKey = "xxx" var passphrase = "xxx" client_private = Dial("wss://ws.okx.com:8443/ws/v5/private") client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase))) Sleep(3000) // 登录后不能立即订阅私有频道,需等待服务器响应 client_private.write(JSON.stringify(posSubscribe)) if (client_private) { var lastPingTS = new Date().getTime() while (true) { var buf = client_private.read(-1) if (buf) { Log(buf) } // 检测到连接断开后重连 if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) { Log("Detected disconnection, closing connection, reconnecting") client_private.close() client_private = Dial("wss://ws.okx.com:8443/ws/v5/private") client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase))) Sleep(3000) client_private.write(JSON.stringify(posSubscribe)) } // 发送心跳包 var nowPingTS = new Date().getTime() if (nowPingTS - lastPingTS > 10 * 1000) { client_private.write("ping") lastPingTS = nowPingTS } } } } function onexit() { var ret = client_private.close() Log("Connection closed!", ret) }
    python
    import json import time def getLogin(pAccessKey, pSecretKey, pPassphrase): ts = str(time.time()) login = { "op": "login", "args":[{ "apiKey" : pAccessKey, "passphrase" : pPassphrase, "timestamp" : ts, "sign" : exchange.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", pSecretKey) }] } return login client_private = None def main(): global client_private SetErrorFilter("timeout") posSubscribe = { "op": "subscribe", "args": [{ "channel": "positions", "instType": "ANY" }] } accessKey = "xxx" secretKey = "xxx" passphrase = "xxx" client_private = Dial("wss://ws.okx.com:8443/ws/v5/private") client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase))) Sleep(3000) client_private.write(json.dumps(posSubscribe)) if client_private: lastPingTS = time.time() * 1000 while True: buf = client_private.read(-1) if buf: Log(buf) if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0: Log("Detected disconnection, closing connection, reconnecting") ret = client_private.close() client_private = Dial("wss://ws.okx.com:8443/ws/v5/private") client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase))) Sleep(3000) client_private.write(json.dumps(posSubscribe)) nowPingTS = time.time() * 1000 if nowPingTS - lastPingTS > 10 * 1000: client_private.write("ping") lastPingTS = nowPingTS def onexit(): ret = client_private.close() Log("Connection closed!", ret)
    rust
    fn getLogin(pAccessKey: &str, pSecretKey: &str, pPassphrase: &str) -> String { // 签名函数,用于生成登录请求。Rust 中没有 exchange.Encode 成员函数,因此使用全局 Encode 函数计算签名 let ts = format!("{}", Unix()); let sign = Encode("sha256", "string", "base64", &format!("{}GET/users/self/verify", ts), "string", pSecretKey); format!(r#"{{"op":"login","args":[{{"apiKey":"{}","passphrase":"{}","timestamp":"{}","sign":"{}"}}]}}"#, pAccessKey, pPassphrase, ts, sign) } fn main() { // 由于 read 函数设置了超时,需过滤超时报错,否则会产生冗余的错误输出 SetErrorFilter("timeout"); // 持仓频道的订阅信息 let posSubscribe = r#"{"op":"subscribe","args":[{"channel":"positions","instType":"ANY"}]}"#; let accessKey = "xxx"; let secretKey = "xxx"; let passphrase = "xxx"; let mut client_private = Dial("wss://ws.okx.com:8443/ws/v5/private"); client_private.write(&getLogin(accessKey, secretKey, passphrase), 0); Sleep(3000); // 登录后不能立即订阅私有频道,需等待服务器响应 client_private.write(posSubscribe, 0); if client_private.Valid() { let mut lastPingTS = Unix() * 1000; loop { let buf = client_private.read(-1); if buf != "" { Log!(buf); } // 检测到连接断开后重连 if buf == "" && client_private.write(posSubscribe, 0) == 0 { Log!("Detected disconnection, closing connection, reconnecting"); client_private.close(); client_private = Dial("wss://ws.okx.com:8443/ws/v5/private"); client_private.write(&getLogin(accessKey, secretKey, passphrase), 0); Sleep(3000); client_private.write(posSubscribe, 0); } // 发送心跳包 let nowPingTS = Unix() * 1000; if nowPingTS - lastPingTS > 10 * 1000 { client_private.write("ping", 0); lastPingTS = nowPingTS; } } } }
    c++
    auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private"); json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) { auto ts = std::to_string(Unix()); json login = R"({ "op": "login", "args": [{ "apiKey": "", "passphrase": "", "timestamp": "", "sign": "" }] })"_json; login["args"][0]["apiKey"] = pAccessKey; login["args"][0]["passphrase"] = pPassphrase; login["args"][0]["timestamp"] = ts; login["args"][0]["sign"] = exchange.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", pSecretKey); return login; } void main() { SetErrorFilter("timeout"); json posSubscribe = R"({ "op": "subscribe", "args": [{ "channel": "positions", "instType": "ANY" }] })"_json; auto accessKey = "xxx"; auto secretKey = "xxx"; auto passphrase = "xxx"; client_private.write(getLogin(accessKey, secretKey, passphrase).dump()); Sleep(3000); client_private.write(posSubscribe.dump()); if (client_private.Valid) { uint64_t lastPingTS = Unix() * 1000; while (true) { auto buf = client_private.read(-1); if (buf != "") { Log(buf); } if (buf == "") { if (client_private.write(posSubscribe.dump()) == 0) { Log("Detected disconnection, closing connection, reconnecting"); client_private.close(); client_private = Dial("wss://ws.okx.com:8443/ws/v5/private"); client_private.write(getLogin(accessKey, secretKey, passphrase).dump()); Sleep(3000); client_private.write(posSubscribe.dump()); } } uint64_t nowPingTS = Unix() * 1000; if (nowPingTS - lastPingTS > 10 * 1000) { client_private.write("ping"); lastPingTS = nowPingTS; } } } } void onexit() { client_private.close(); Log("Exiting"); }
  • 访问 CoinEx 的 WebSocket 验证接口:

    javascript
    var conn = null function main() { var accessKey = "your accessKey" var ts = new Date().getTime() var signature = exchange.Encode("sha256", "string", "hex", String(ts), "string", "{{secretkey}}") Log("signature:", signature) var payload = { "id": 1, "method": "server.sign", "params": { "access_id": accessKey, "signed_str": signature, "timestamp": ts, } } Log(`JSON.stringify(payload):`, JSON.stringify(payload)) conn = Dial("wss://socket.coinex.com/v2/futures|compress=gzip&mode=recv&payload=" + JSON.stringify(payload)) if (!conn) { throw "stop" } Log("Dial ... ", conn.read()) // 订阅持仓推送 conn.write(JSON.stringify({ "method": "position.subscribe", "params": {"market_list": ["BTCUSDT"]}, "id": 1 })) while (true) { var msg = conn.read() if (msg) { Log("msg:", msg) } } } function onexit() { conn.close() }
    python
    // 略
    rust
    fn main() { let accessKey = "your accessKey"; let ts = Unix() * 1000; // Rust 没有 exchange.Encode 成员函数,无法使用 {{secretkey}} 模板替换,使用全局 Encode 函数直接传入秘钥计算签名 let signature = Encode("sha256", "string", "hex", &format!("{}", ts), "string", "your secretKey"); Log!("signature:", signature); // Rust SDK 没有 JSON 序列化功能,使用字符串拼接构造 payload 的 JSON 文本 let payload = format!(r#"{{"id":1,"method":"server.sign","params":{{"access_id":"{}","signed_str":"{}","timestamp":{}}}}}"#, accessKey, signature, ts); Log!("payload:", payload); let mut conn = Dial(&format!("wss://socket.coinex.com/v2/futures|compress=gzip&mode=recv&payload={}", payload)); if !conn.Valid() { Panic!("stop"); } Log!("Dial ... ", conn.read(0)); // 订阅持仓推送 conn.write(r#"{"method":"position.subscribe","params":{"market_list":["BTCUSDT"]},"id":1}"#, 0); loop { let msg = conn.read(0); if msg != "" { Log!("msg:", msg); } } }
    c++
    // 略
  • 以下示例演示如何访问 MEXC 交易所的Websocket接口,订阅public.aggre.deals.v3.api.pb频道,并使用protobuf.js解码二进制数据:

    javascript
    let strPushDataV3ApiWrapper = `syntax = "proto3"; option java_package = "com.mxc.push.common.protobuf"; option optimize_for = SPEED; option java_multiple_files = true; option java_outer_classname = "PushDataV3ApiWrapperProto"; message PublicAggreDealsV3Api { repeated PublicAggreDealsV3ApiItem deals = 1; string eventType = 2; } message PublicAggreDealsV3ApiItem { string price = 1; string quantity = 2; int32 tradeType = 3; int64 time = 4; } message PushDataV3ApiWrapper { string channel = 1; oneof body { PublicAggreDealsV3Api publicAggreDeals = 314; } optional string symbol = 3; optional string symbolId = 4; optional int64 createTime = 5; optional int64 sendTime = 6; }` let code = HttpQuery("https://cdnjs.cloudflare.com/ajax/libs/protobufjs/7.5.3/protobuf.js") let exports = {} let module = { exports } new Function("module", "exports", code)(module, exports) let protobuf = module.exports function main() { const PushDataV3ApiWrapper = protobuf.parse(strPushDataV3ApiWrapper).root.lookupType("PushDataV3ApiWrapper") var payload = { "method": "SUBSCRIPTION", "params": [ "[email protected]@100ms@BTCUSDT" ] } // proxy=socks5://x.x.x.x:xxxx var conn = Dial("wss://wbs-api.mexc.com/ws|payload=" + JSON.stringify(payload)) var data = null while (true) { var ret = conn.read() if (ret) { const uint8arrayData = new Uint8Array(ret) const message = PushDataV3ApiWrapper.decode(uint8arrayData) data = PushDataV3ApiWrapper.toObject(message, { longs: String, enums: String, bytes: String, defaults: true, arrays: true, objects: true }) Log("data:", data) } LogStatus(_D(), data) } }
    python
    # 可以使用 Python 中相应的库实现编码与解码。
    c++
    // 略
  • Dial函数连接数据库时返回的连接对象具有2个独有的方法函数:

    • exec(sqlString):用于执行SQL语句,用法与DBExec()函数类似。

    • fd():该函数返回一个句柄(例如句柄变量为handle),用于在其它线程中重连。即使由Dial创建的连接对象已通过close()函数关闭,也可将该句柄传入Dial()函数(例如Dial(handle))以重用连接。

    以下是使用Dial函数连接sqlite3数据库的示例。

    javascript
    var client = null function main() { // client = Dial("sqlite3://:memory:") // 使用内存数据库 client = Dial("sqlite3://test1.db") // 打开/连接托管者所在目录的数据库文件 // 记录句柄 var sqlite3Handle = client.fd() Log("sqlite3Handle:", sqlite3Handle) // 查询数据库中的表 var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'") Log(ret) } function onexit() { Log("Executing client.close()") client.close() }
    python
    // 不支持
    rust
    fn main() { // let mut client = Dial("sqlite3://:memory:"); // 使用内存数据库 let mut client = Dial("sqlite3://test1.db"); // 打开/连接托管者所在目录的数据库文件 // Rust 的连接对象不支持 fd() 方法 // 查询数据库中的表 let ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'"); Log!(format!("{:?}", ret)); Log!("Executing client.close()"); client.close(); }
    c++
    // 不支持

返回值

类型描述

object

如果超时,Dial() 函数返回空值;正常调用时返回一个连接对象。该连接对象包含三个方法:readwriteclose。其中,read 方法用于读取数据,write 方法用于发送数据,close 方法用于关闭连接。read 方法支持以下参数:

  • 不传参数时,函数会阻塞,直到有消息到达时才返回。例如:ws.read()
  • 传入参数时,单位为毫秒,用于指定消息等待的超时时间。例如:ws.read(2000) 表示超时时间为两秒(2000 毫秒)。
  • 以下两个参数仅对 WebSocket 有效:
    传入参数 -1 表示无论是否有消息,函数都立即返回。例如:ws.read(-1)
    传入参数 -2 表示无论是否有消息,函数都立即返回,但只返回最新的消息,缓冲区中的其余消息将被丢弃。例如:ws.read(-2)read() 函数缓冲区说明:

WebSocket 协议推送的数据,如果策略中 read() 函数两次调用之间的时间间隔过长,就可能造成数据累积。这些数据存储在缓冲区中,缓冲区的数据结构为队列,上限为 2000 个。当数据量超过 2000 个后,最新的数据进入缓冲区,最旧的数据将被清除。

场景无参数参数:-1参数:-2参数:2000,单位是毫秒
缓冲区已有数据立即返回最旧数据立即返回最旧数据立即返回最新数据立即返回最旧数据
缓冲区无数据阻塞至有数据时返回立即返回空值立即返回空值等待 2000 毫秒,无数据则返回空值,有数据则返回
WebSocket 连接断开或底层重连时read() 函数返回空字符串(即 ""),write() 函数返回 0,可据此检测该情况。此时可使用 close() 函数关闭连接;如果已设置自动重连,则无需手动关闭,系统底层会自动重连。
------

参数

名称类型必填描述

address

string

请求地址。

timeout

number

超时时间(单位:秒)。

options

object

配置选项。

备注

address参数的详细说明:在标准地址wss://ws.okx.com:8443/ws/v5/public之后,使用|符号进行分隔。如果参数字符串中包含|字符,则使用||作为分隔符。分隔符之后的部分为功能参数设置,各参数之间使用&字符连接。

例如,同时设置ss5代理和压缩参数时,可以写作:

Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

Dial函数的address参数支持的功能参数说明
WebSocket协议数据压缩相关的参数:compress=参数值compress用于指定压缩方式,可选值包括gzip_raw、gzip等。如果所用的gzip并非标准gzip,可以使用扩展方式:gzip_raw
WebSocket协议数据压缩相关的参数:mode=参数值mode用于指定压缩模式,可选dual、send、recv三种。dual表示双向压缩,即同时发送和接收压缩数据;send表示仅发送压缩数据;recv表示仅接收压缩数据并在本地解压缩。
WebSocket协议启用compression设置:enableCompression=true使用enableCompression=false可关闭该设置,默认不启用。
WebSocket协议设置底层自动重连相关的参数:reconnect=参数值reconnect用于设置是否自动重连,reconnect=true表示启用重连。未设置该参数时默认不重连。
WebSocket协议设置底层自动重连相关的参数:interval=参数值interval为重试的时间间隔,单位为毫秒。例如interval=10000表示重试间隔为10秒;未设置时默认为1秒,即interval=1000。
WebSocket协议设置底层自动重连相关的参数:payload=参数值payload为WebSocket重连时需要发送的订阅消息,例如:payload=okok。
socks5代理的相关参数:proxy=参数值proxy用于设置ss5代理,参数值格式为:socks5://name:[email protected]:1080。其中name为ss5服务端的用户名,pwd为ss5服务端的登录密码,1080为ss5服务的端口。

Dial()函数仅支持实盘。

使用Dial函数连接数据库时,连接字符串的编写方式可参考各数据库对应的Go语言驱动项目。

支持的数据库驱动项目连接字符串(Connection String)备注
sqlite3github.com/mattn/go-sqlite3sqlite3://file:test.db?cache=shared&mode=memorysqlite3://前缀表示使用的是sqlite3数据库,调用示例:Dial("sqlite3://test1.db")
mysqlgithub.com/go-sql-driver/mysqlmysql://username:yourpassword@tcp(localhost:3306)/yourdatabase?charset=utf8mb4--
postgresgithub.com/lib/pqpostgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword host=localhost port=5432--
clickhousegithub.com/ClickHouse/clickhouse-goclickhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase--

需要注意,当address参数中设置的payload内容包含字符=或其它特殊字符时,可能会影响Dial函数对address参数的解析,示例如下。

backPack交易所websocket私有接口调用示例:

javascript
var client = null function main() { // base64编码的秘钥对公钥,即在FMZ上配置的access key var base64ApiKey = "xxx" var ts = String(new Date().getTime()) var data = "instruction=subscribe&timestamp=" + ts + "&window=5000" // 由于signEd25519最终返回的是base64编码,其中会有字符"=" var signature = signEd25519(data) // payload 被JSON编码后可能包含字符"=" payload = { "method": "SUBSCRIBE", "params": ["account.orderUpdate"], "signature": [base64ApiKey, signature, ts, "5000"] } client = Dial("wss://ws.backpack.exchange") client.write(JSON.stringify(payload)) if (!client) { Log("Connection failed, exiting") return } while (true) { var buf = client.read() Log(buf) } } function onexit() { client.close() } function signEd25519(data) { return exchange.Encode("ed25519.seed", "raw", "base64", data, "base64", "{{secretkey}}") }

代码中采用以下调用方式可以正常工作:

javascript
client = Dial("wss://ws.backpack.exchange") client.write(JSON.stringify(payload))

如果直接写在payload中则无法正常工作,例如:

javascript
client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))

目前仅JavaScript语言支持在Dial函数中使用mqttnatsamqpkafka通信协议,下面以JavaScript语言策略代码为例,演示mqttnatsamqpkafka四种协议的使用方法:

javascript
// 需要先配置并部署完成各个协议的代理服务器 // 为了便于演示,主题test_topic的订阅(read操作)与发布(write操作)都在当前这个策略中进行 var arrConn = [] var arrName = [] function main() { LogReset(1) conn_nats = Dial("nats://[email protected]:4222?topic=test_topic") conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic") conn_amqp = Dial("amqp://q:[email protected]:5672/?queue=test_Queue") conn_kafka = Dial("kafka://localhost:9092/test_topic") arrConn = [conn_nats, conn_amqp, conn_mqtt, conn_kafka] arrName = ["nats", "amqp", "mqtt", "kafka"] while (true) { for (var i in arrConn) { var conn = arrConn[i] var name = arrName[i] // 写数据 conn.write(name + ", time: " + _D() + ", test msg.") // 读数据 var readMsg = conn.read(1000) Log(name + " readMsg: ", readMsg, "#FF0000") } Sleep(1000) } } function onexit() { for (var i in arrConn) { arrConn[i].close() Log("Closing", arrName[i], "connection") } }

详细介绍请参考文档:探索FMZ:交易策略实盘间通信协议实践

发送 HTTP 请求。

HttpQuery(url)
HttpQuery(url, options)

示例

  • 访问 OKX 公共行情 API 接口的示例。

    javascript
    function main(){ // 一个不带参数的 GET 访问示例 var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time")) Log(info) // 一个带参数的 GET 访问示例 var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT")) Log(ticker) }
    python
    import json import urllib.request def main(): # HttpQuery 不支持 Python,可以使用 urllib/urllib2 库代替 info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8')) Log(info) ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8')) Log(ticker)
    rust
    fn main() { // 一个不带参数的 GET 访问示例,在 Rust 中由返回值类型注解决定返回 Body 字符串(String)或完整应答(HttpRet) let body: String = HttpQuery("https://www.okx.com/api/v5/public/time", None); let info = JSONParse(&body).unwrap(); Log!(info); // 一个带参数的 GET 访问示例 let body2: String = HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT", None); let ticker = JSONParse(&body2).unwrap(); Log!(ticker); }
    c++
    void main() { auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time")); Log(info); auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT")); Log(ticker); }
  • HttpQuery 函数使用代理设置的示例。

    javascript
    function main() { // 本次设置代理并发送 HTTP 请求,无用户名、无密码,此次 HTTP 请求会通过代理发送 HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/") // 本次设置代理并发送 HTTP 请求,输入用户名和密码,仅对 HttpQuery 的当前调用生效;之后再次调用 HttpQuery("http://www.baidu.com") 时不会使用代理 HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/") }
    python
    # HttpQuery 不支持 Python,可以使用 Python 的 urllib2 库
    rust
    fn main() { // 本次设置代理并发送 HTTP 请求,无用户名、无密码,此次 HTTP 请求会通过代理发送 let ret1: String = HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/", None); // 本次设置代理并发送 HTTP 请求,输入用户名和密码,仅对 HttpQuery 的当前调用生效;之后再次调用 HttpQuery("http://www.baidu.com") 时不会使用代理 let ret2: String = HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/", None); }
    c++
    void main() { HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/"); HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/"); }

返回值

类型描述

string / object

返回请求的应答数据。如果返回值为JSON字符串,在JavaScript语言的策略中可以使用JSON.parse()函数解析,在C++语言的策略中可以使用json::parse()函数解析。在参数options结构中,如果debug设置为 true,返回值为对象(JSON);如果debug设置为 false,返回值为字符串。

参数

名称类型必填描述

url

string

HTTP 请求的 URL。

options

object

HTTP 请求的相关设置,例如可以是以下结构:

json
{ method: "POST", body: "a=10&b=20&c=30", charset: "UTF-8", cookie: "session_id=12345; lang=en", debug: false, headers: {"TEST-HTTP-QUERY": "123"}, timeout: 1000 }
  • method: 用于设置请求方法。
  • body: 用于设置请求体内容,通常用于 POST、PUT 等请求。
  • cookie: 用于设置请求中的 Cookie,通常用于携带身份验证信息或会话标识。
  • headers: 用于设置请求头信息,可用于指定内容类型、身份验证信息等。
  • debug: 设置为true时,本次HttpQuery函数调用返回完整的应答报文;设置为false时,仅返回应答报文Body中的数据。
  • timeout: 超时设置,设置为 1000 表示超时时间为 1 秒。
  • charset: 支持对请求的应答数据进行转码,例如:GB18030,支持常用编码。

此结构中的所有字段均为可选,例如可以不设置headers字段。

参考

备注

HttpQuery()函数仅支持JavaScriptC++语言;Python语言可以使用urllib库直接发送 HTTP 请求。HttpQuery()主要用于访问交易所无需签名的接口,例如行情信息等公共接口。

回测系统中可以使用HttpQuery()发送请求(仅支持GET请求)以获取数据。回测时限制访问不同URL的次数为 20 次,并且HttpQuery()的访问会缓存数据;相同的URL第二次访问时,HttpQuery()函数将返回缓存数据,不再发起实际的网络请求。

发送HTTP请求,HttpQuery函数的异步版本。

HttpQuery_Go(url)
HttpQuery_Go(url, options)

示例

异步访问交易所公共接口获取聚合行情数据。

javascript
function main() { // 创建第一个异步线程 var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT") // 创建第二个异步线程 var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers") // 获取第一个异步线程调用的返回值 var tickers1 = r1.wait() // 获取第二个异步线程调用的返回值 var tickers2 = r2.wait() // 打印结果 Log("tickers1:", tickers1) Log("tickers2:", tickers2) }
python
# 不支持
c++
// 不支持

返回值

类型描述

object

HttpQuery_Go()函数立即返回一个并发对象,可以使用该并发对象的wait方法获取HTTP请求的结果。JavaScript语言的策略中可以使用JSON.parse()函数解析返回的数据。

参数

名称类型必填描述

url

string

HTTP请求的URL地址。

options

object

HTTP请求相关配置参数,可以使用以下结构:

json
{ method: "POST", body: "a=10&b=20&c=30", charset: "UTF-8", cookie: "session_id=12345; lang=en", debug: false, headers: {"TEST-HTTP-QUERY": "123"}, timeout: 1000 }
  • debug:设置为true时,此次HttpQuery_Go函数调用返回完整的响应报文。设置为false时仅返回响应报文Body中的数据。
  • timeout:超时设置,设置1000表示1秒超时。

此结构中的所有字段均为可选字段,例如可以不设置headers字段。
HttpQuery_Go函数的options参数与HttpQuery函数的options参数一致,不再赘述。

参考

备注

HttpQuery_Go()函数仅支持JavaScript语言,Python语言可以使用urllib库直接发送HTTP请求。HttpQuery_Go()主要用于访问交易所无需签名的接口,例如行情信息等公共接口。回测系统不支持HttpQuery_Go函数。

该函数根据传入的参数对数据进行编码。

Encode(algo, inputFormat, outputFormat, data)
Encode(algo, inputFormat, outputFormat, data, keyFormat, key)

示例

  • Encode 函数调用示例。

    javascript
    function main() { Log(Encode("raw", "raw", "hex", "example", "raw", "123")) // 6578616d706c65 Log(Encode("raw", "raw", "hex", "example")) // 6578616d706c65 Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "", "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Log(Encode("sha256", "raw", "hex", "example", null, "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Log(Encode("sha256", "raw", "hex", "example", "string", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("raw", "raw", "hex", "123")) // 313233 Log(Encode("raw", "raw", "base64", "123")) // MTIz Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba }
    python
    def main(): Log(Encode("raw", "raw", "hex", "example", "raw", "123")) # 6578616d706c65 Log(Encode("raw", "raw", "hex", "example", "", "")) # 6578616d706c65 Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "", "123")) # 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Log(Encode("sha256", "raw", "hex", "example", "string", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("raw", "raw", "hex", "123", "", "")) # 313233 Log(Encode("raw", "raw", "base64", "123", "", "")) # MTIz Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    rust
    fn main() { // Rust 的 Encode() 函数 6 个参数均为必填;不加密时,keyFormat 和 key 传入空字符串即可 Log!(Encode("raw", "raw", "hex", "example", "raw", "123")); // 6578616d706c65 Log!(Encode("raw", "raw", "hex", "example", "", "")); // 6578616d706c65 Log!(Encode("sha256", "raw", "hex", "example", "raw", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log!(Encode("sha256", "raw", "hex", "example", "", "123")); // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Log!(Encode("sha256", "raw", "hex", "example", "string", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log!(Encode("raw", "raw", "hex", "123", "", "")); // 313233 Log!(Encode("raw", "raw", "base64", "123", "", "")); // MTIz Log!(Encode("sha256", "raw", "hex", "example", "hex", "313233")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log!(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba }
    c++
    void main() { Log(Encode("raw", "raw", "hex", "example", "raw", "123")); // 6578616d706c65 Log(Encode("raw", "raw", "hex", "example")); // 6578616d706c65 Log(Encode("sha256", "raw", "hex", "example", "raw", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "", "123")); // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c Log(Encode("sha256", "raw", "hex", "example", "string", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("raw", "raw", "hex", "123")); // 313233 Log(Encode("raw", "raw", "base64", "123")); // MTIz Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba }
  • 参数algo还支持以下取值:"text.encoder.utf8"、"text.decoder.utf8"、"text.encoder.gbk"、"text.decoder.gbk",用于对字符串进行编码和解码。

    javascript
    function main(){ var ret1 = Encode("text.encoder.utf8", "raw", "hex", "你好") // e4bda0e5a5bd Log(ret1) var ret2 = Encode("text.decoder.utf8", "hex", "string", ret1) Log(ret2) var ret3 = Encode("text.encoder.gbk", "raw", "hex", "你好") // c4e3bac3 Log(ret3) var ret4 = Encode("text.decoder.gbk", "hex", "string", ret3) Log(ret4) }
    python
    def main(): ret1 = Encode("text.encoder.utf8", "raw", "hex", "你好", "", "") # e4bda0e5a5bd Log(ret1) ret2 = Encode("text.decoder.utf8", "hex", "string", ret1, "", "") Log(ret2) ret3 = Encode("text.encoder.gbk", "raw", "hex", "你好", "", "") # c4e3bac3 Log(ret3) ret4 = Encode("text.decoder.gbk", "hex", "string", ret3, "", "") Log(ret4)
    rust
    fn main() { // Rust 的 Encode() 函数6个参数均为必填,不加密时 keyFormat、key 传入空字符串 let ret1 = Encode("text.encoder.utf8", "raw", "hex", "你好", "", ""); // e4bda0e5a5bd Log!(ret1); let ret2 = Encode("text.decoder.utf8", "hex", "string", &ret1, "", ""); Log!(ret2); let ret3 = Encode("text.encoder.gbk", "raw", "hex", "你好", "", ""); // c4e3bac3 Log!(ret3); let ret4 = Encode("text.decoder.gbk", "hex", "string", &ret3, "", ""); Log!(ret4); }
    c++
    void main(){ auto ret1 = Encode("text.encoder.utf8", "raw", "hex", "你好"); // e4bda0e5a5bd Log(ret1); auto ret2 = Encode("text.decoder.utf8", "hex", "string", ret1); Log(ret2); auto ret3 = Encode("text.encoder.gbk", "raw", "hex", "你好"); // c4e3bac3 Log(ret3); auto ret4 = Encode("text.decoder.gbk", "hex", "string", ret3); Log(ret4); }

返回值

类型描述

string

Encode函数返回编码、加密之后的数据。

参数

名称类型必填描述

algo

string

参数algo用于指定编码计算时使用的算法,支持设置为以下值之一:"raw"(不使用算法)、"sign"、"signTx"、"md4"、"md5"、"sha256"、"sha512"、"sha1"、"keccak256"、"sha3.224"、"sha3.256"、"sha3.384"、"sha3.512"、"sha3.keccak256"、"sha3.keccak512"、"sha512.384"、"sha512.256"、"sha512.224"、"ripemd160"、"blake2b.256"、"blake2b.512"、"blake2s.128"、"blake2s.256"。

参数algo还支持"text.encoder.utf8"、"text.decoder.utf8"、"text.encoder.gbk"、"text.decoder.gbk",用于对字符串进行编码或解码。

参数algo同时支持"ed25519"算法,并可搭配不同的哈希算法使用,例如参数algo可写为"ed25519.md5"、"ed25519.sha512"等,也支持ed25519.seed计算。

inputFormat

string

用于指定data参数的数据格式。inputFormat参数支持设置为"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

outputFormat

string

用于指定输出的数据格式。outputFormat参数支持设置为"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

data

string

参数data为所要处理的数据。

keyFormat

string

用于指定key参数的数据格式。keyFormat参数支持设置为"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

key

string

参数keyHMAC加密时使用的密钥。

当参数algo设置为"sign"或"signTx"时,需要传入参数key

当参数algo设置为"raw"时,不会使用key参数进行HMAC加密(因为HMAC加密必须指定算法)。

备注

Encode()函数仅支持实盘。若不传入keykeyFormat参数,则不进行key加密。

获取当前时刻的纳秒级时间戳。

UnixNano()

示例

如果需要获取毫秒级时间戳,可以使用以下代码:

javascript
function main() { var time = UnixNano() / 1000000 Log(_N(time, 0)) }
python
def main(): time = UnixNano() Log(time)
rust
fn main() { let time = UnixNano() / 1000000; Log!(_N(time, 0)); }
c++
void main() { auto time = UnixNano(); Log(time); }

返回值

类型描述

number

UnixNano()函数返回纳秒级时间戳。

参考

获取当前时刻的秒级时间戳。

Unix()

示例

javascript
function main() { var t = Unix() Log(t) }
python
def main(): t = Unix() Log(t)
rust
fn main() { let t = Unix(); Log!(t); }
c++
void main() { auto t = Unix(); Log(t); }

返回值

类型描述

number

返回秒级时间戳。

参考

获取托管者所在设备的操作系统信息。

GetOS()

示例

javascript
function main() { Log("GetOS:", GetOS()) }
python
def main(): Log("GetOS:", GetOS())
rust
fn main() { Log!("GetOS:", GetOS()); }
c++
void main() { Log("GetOS:", GetOS()); }

返回值

类型描述

string

操作系统信息。

备注

例如,在Mac OS操作系统下运行的托管者,调用GetOS()函数可能返回:darwin/amd64。由于苹果电脑采用多种硬件架构,返回值中会附带具体的架构信息。其中,darwinMac OS系统的内核名称。

计算参数data的 MD5 哈希值。

MD5(data)

示例

javascript
function main() { Log("MD5", MD5("hello world")) }
python
def main(): Log("MD5", MD5("hello world"))
rust
fn main() { Log!("MD5", MD5("hello world")); }
c++
void main() { Log("MD5", MD5("hello world")); }

返回值

类型描述

string

MD5 哈希值。

参数

名称类型必填描述

data

string

需要进行 MD5 计算的数据。

参考

备注

调用MD5("hello world")函数后,返回值为:5eb63bbbe01eeed093cb22bb8f5acdc3

数据库接口函数。

DBExec(sql)

示例

  • 支持内存数据库。对于DBExec函数的参数,如果sql语句以:开头,则在内存数据库中执行操作;由于无需写入文件,速度更快。此方式适用于无需持久化保存的数据库操作,例如:

    javascript
    function main() { var strSql = [ ":CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ].join("") var ret = DBExec(strSql) Log(ret) // 增加一条数据 Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) // 查询数据 Log(DBExec(":SELECT * FROM TEST_TABLE;")) }
    python
    def main(): arr = [ ":CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ] strSql = "" for i in range(len(arr)): strSql += arr[i] ret = DBExec(strSql) Log(ret) # 增加一条数据 Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) # 查询数据 Log(DBExec(":SELECT * FROM TEST_TABLE;"))
    rust
    fn main() { let arr = [ ":CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)", ]; let strSql = arr.join(""); let ret = DBExec(&strSql); Log!(format!("{:?}", ret)); // 增加一条数据 Log!(format!("{:?}", DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))); // 查询数据 Log!(format!("{:?}", DBExec(":SELECT * FROM TEST_TABLE;"))); }
    c++
    void main() { string strSql = ":CREATE TABLE TEST_TABLE(\ TS INT PRIMARY KEY NOT NULL,\ HIGH REAL NOT NULL,\ OPEN REAL NOT NULL,\ LOW REAL NOT NULL,\ CLOSE REAL NOT NULL,\ VOLUME REAL NOT NULL)"; auto ret = DBExec(strSql); Log(ret); // 增加一条数据 Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")); // 查询数据 Log(DBExec(":SELECT * FROM TEST_TABLE;")); }
  • 使用 DBExec() 函数创建数据表。

    javascript
    function main() { var strSql = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ].join("") var ret = DBExec(strSql) Log(ret) }
    python
    def main(): arr = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ] strSql = "" for i in range(len(arr)): strSql += arr[i] ret = DBExec(strSql) Log(ret)
    rust
    fn main() { let arr = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)", ]; let strSql = arr.join(""); let ret = DBExec(&strSql); Log!(format!("{:?}", ret)); }
    c++
    void main() { string strSql = "CREATE TABLE TEST_TABLE(\ TS INT PRIMARY KEY NOT NULL,\ HIGH REAL NOT NULL,\ OPEN REAL NOT NULL,\ LOW REAL NOT NULL,\ CLOSE REAL NOT NULL,\ VOLUME REAL NOT NULL)"; auto ret = DBExec(strSql); Log(ret); }
  • 对数据表中的记录执行增、删、查、改操作。

    javascript
    function main() { var strSql = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ].join("") Log(DBExec(strSql)) // 增加一条数据 Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) // 查询数据 Log(DBExec("SELECT * FROM TEST_TABLE;")) // 修改数据 Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)) // 删除数据 Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110)) }
    python
    def main(): arr = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)" ] strSql = "" for i in range(len(arr)): strSql += arr[i] Log(DBExec(strSql)) # 增加一条数据 Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) # 查询数据 Log(DBExec("SELECT * FROM TEST_TABLE;")) # 修改数据 Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)) # 删除数据 Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
    rust
    fn main() { let arr = [ "CREATE TABLE TEST_TABLE(", "TS INT PRIMARY KEY NOT NULL,", "HIGH REAL NOT NULL,", "OPEN REAL NOT NULL,", "LOW REAL NOT NULL,", "CLOSE REAL NOT NULL,", "VOLUME REAL NOT NULL)", ]; let strSql = arr.join(""); Log!(format!("{:?}", DBExec(&strSql))); // 增加一条数据 Log!(format!("{:?}", DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))); // 查询数据 Log!(format!("{:?}", DBExec("SELECT * FROM TEST_TABLE;"))); // 修改数据,Rust 的 DBExec() 函数只接受单个SQL语句字符串参数,不支持 ? 占位符传参,参数值直接写在语句中 Log!(format!("{:?}", DBExec("UPDATE TEST_TABLE SET HIGH=110 WHERE TS=1518970320000;"))); // 删除数据 Log!(format!("{:?}", DBExec("DELETE FROM TEST_TABLE WHERE HIGH=110;"))); }
    c++
    void main() { string strSql = "CREATE TABLE TEST_TABLE(\ TS INT PRIMARY KEY NOT NULL,\ HIGH REAL NOT NULL,\ OPEN REAL NOT NULL,\ LOW REAL NOT NULL,\ CLOSE REAL NOT NULL,\ VOLUME REAL NOT NULL)"; Log(DBExec(strSql)); // 增加一条数据 Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")); // 查询数据 Log(DBExec("SELECT * FROM TEST_TABLE;")); // 修改数据 Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)); // 删除数据 Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110)); }

返回值

类型描述

object

包含sql语句执行结果的对象,例如:

```json

{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}

```

参数

名称类型必填描述

sql

string

sql语句字符串。

参考

备注

  • 通过向函数DBExec()传入参数,可对实盘数据库(SQLite 数据库)进行操作。

    • 可实现对实盘数据库中数据的增、删、查、改等操作,并支持SQLite语法。

    • 实盘数据库中的系统保留表包括:kvdbcfglogprofitchart,请勿对这些表进行操作。

    • 目前不支持事务,不建议执行此类操作,否则会引发系统冲突。

    • DBExec()函数仅支持实盘。

创建一个 UUID。

UUID()

示例

javascript
function main() { var uuid1 = UUID() var uuid2 = UUID() Log(uuid1, uuid2) }
python
def main(): uuid1 = UUID() uuid2 = UUID() Log(uuid1, uuid2)
rust
fn main() { let uuid1 = UUID(); let uuid2 = UUID(); Log!(uuid1, uuid2); }
c++
void main() { auto uuid1 = UUID(); auto uuid2 = UUID(); Log(uuid1, uuid2); }

返回值

类型描述

string

32 位的 UUID。

备注

UUID() 函数仅支持实盘。

监听事件,当任意WebSocket有可读数据,或exchange.Go()HttpQuery_Go()等并发任务完成后返回。

EventLoop()
EventLoop(timeout)

示例

javascript
function main() { var routine_getTicker = exchange.Go("GetTicker") var routine_getDepth = exchange.Go("GetDepth") var routine_getTrades = exchange.Go("GetTrades") // Sleep(2000),如果这里使用Sleep语句,会导致之后的EventLoop函数错过之前的事件。因为等待了2秒,并发的函数已经收到了数据,之后才开始EventLoop监听机制,就会错过这些事件 // 除非在第一行代码就开始调用EventLoop(-1),先初始化EventLoop的监听机制,才不会错过这些事件 // Log("GetDepth:", routine_getDepth.wait()) 如果这里提前调用wait函数取出GetDepth函数并发调用的结果,本次GetDepth函数收到请求结果的事件便不会在EventLoop函数中返回 var ts1 = new Date().getTime() var ret1 = EventLoop(0) var ts2 = new Date().getTime() var ret2 = EventLoop(0) var ts3 = new Date().getTime() var ret3 = EventLoop(0) Log("First concurrent task completed:", _D(ts1), ret1) Log("Second concurrent task completed:", _D(ts2), ret2) Log("Third concurrent task completed:", _D(ts3), ret3) Log("GetTicker:", routine_getTicker.wait()) Log("GetDepth:", routine_getDepth.wait()) Log("GetTrades:", routine_getTrades.wait()) }
python
import time def main(): routine_getTicker = exchange.Go("GetTicker") routine_getDepth = exchange.Go("GetDepth") routine_getTrades = exchange.Go("GetTrades") ts1 = time.time() ret1 = EventLoop(0) ts2 = time.time() ret2 = EventLoop(0) ts3 = time.time() ret3 = EventLoop(0) Log("First concurrent task completed:", _D(ts1), ret1) Log("Second concurrent task completed:", _D(ts2), ret2) Log("Third concurrent task completed:", _D(ts3), ret3) Log("GetTicker:", routine_getTicker.wait()) Log("GetDepth:", routine_getDepth.wait()) Log("GetTrades:", routine_getTrades.wait())
rust
fn main() { // Rust 中 exchange.Go 使用类型化 token(如 Go::GetTicker)而非方法名字符串,无参时传 () let routine_getTicker = exchange.Go(Go::GetTicker, ()); let routine_getDepth = exchange.Go(Go::GetDepth, ()); let routine_getTrades = exchange.Go(Go::GetTrades, ()); // Sleep(2000),如果这里使用Sleep语句,会导致之后的EventLoop函数错过之前的事件。因为等待了2秒,并发的函数已经收到了数据,之后才开始EventLoop监听机制,就会错过这些事件 // 除非在第一行代码就开始调用EventLoop(-1),先初始化EventLoop的监听机制,才不会错过这些事件 // Log!("GetDepth:", routine_getDepth.wait(0)) 如果这里提前调用wait函数取出GetDepth函数并发调用的结果,本次GetDepth函数收到请求结果的事件便不会在EventLoop函数中返回 let ts1 = Unix() * 1000; let ret1 = EventLoop(0); let ts2 = Unix() * 1000; let ret2 = EventLoop(0); let ts3 = Unix() * 1000; let ret3 = EventLoop(0); Log!("First concurrent task completed:", _D(ts1), ret1); Log!("Second concurrent task completed:", _D(ts2), ret2); Log!("Third concurrent task completed:", _D(ts3), ret3); Log!("GetTicker:", routine_getTicker.wait(0).unwrap()); Log!("GetDepth:", routine_getDepth.wait(0).unwrap()); Log!("GetTrades:", routine_getTrades.wait(0).unwrap()); }
c++
void main() { auto routine_getTicker = exchange.Go("GetTicker"); auto routine_getDepth = exchange.Go("GetDepth"); auto routine_getTrades = exchange.Go("GetTrades"); auto ts1 = Unix() * 1000; auto ret1 = EventLoop(0); auto ts2 = Unix() * 1000; auto ret2 = EventLoop(0); auto ts3 = Unix() * 1000; auto ret3 = EventLoop(0); Log("First concurrent task completed:", _D(ts1), ret1); Log("Second concurrent task completed:", _D(ts2), ret2); Log("Third concurrent task completed:", _D(ts3), ret3); Ticker ticker; Depth depth; Trades trades; routine_getTicker.wait(ticker); routine_getDepth.wait(depth); routine_getTrades.wait(trades); Log("GetTicker:", ticker); Log("GetDepth:", depth); Log("GetTrades:", trades); }

返回值

类型描述

object

如果返回的对象不为空值,则返回内容中的Event字段表示事件的触发类型。例如以下返回值结构:

json
{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}

参数

名称类型必填描述

timeout

number

参数timeout用于设置超时时间,单位为毫秒。
timeout设置为0时,函数会一直等待,直到有事件发生才返回;当timeout大于0时,表示设置事件等待的超时时间;当timeout小于0时,则立即返回最近的事件。

参考

备注

代码中首次调用EventLoop()函数时,才会初始化该事件监听机制。如果在事件回调发生之后才首次调用EventLoop(),则会错过此前的事件。系统底层封装的队列结构最多可缓存500个事件回调,如果程序运行过程中没有及时调用EventLoop()函数取出,超出500个缓存上限的较晚事件回调将会丢失。

EventLoop()函数的调用不会影响系统底层WebSocket的缓存队列,也不会影响exchange.Go()等并发函数的缓存,这些缓存中的数据仍需使用各自的方法取出。对于在EventLoop()函数返回之前已经取出的数据,不会在EventLoop()函数中再次产生返回事件。

EventLoop()函数的主要用途是通知策略层:系统底层已接收到新的网络数据,从而以事件驱动整个策略。当EventLoop()函数返回事件时,只需遍历所有数据来源(例如WebSocket连接、exchange.Go()创建的对象)尝试获取数据即可。

EventLoop()函数仅支持实盘。

在主函数main()中调用时,监听主线程的事件。在使用JavaScript语言编写的策略中,也可以在threading.Thread()函数创建的线程的执行函数中调用,用于监听当前线程的事件。

__Serve函数用于创建HTTP服务、TCP服务、WebSocket服务(基于HTTP协议)。

__Serve(serveURI, handler)
__Serve(serveURI, handler, ...args)

示例

javascript
function main() { let httpServer = __Serve("http://:8088?gzip=true", function (ctx) { Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr()) let path = ctx.path() if (path == "/") { ctx.write(JSON.stringify({ path: ctx.path(), method: ctx.method(), headers: ctx.headers(), cookie: ctx.header("Cookie"), remote: ctx.remoteAddr(), query: ctx.rawQuery() })) } else if (path == "/tickers") { let ret = exchange.GetTickers() if (!ret) { ctx.setStatus(500) ctx.write(GetLastError()) } else { ctx.write(JSON.stringify(ret)) } } else if (path == "/wss") { if (ctx.upgrade("websocket")) { // upgrade to websocket while (true) { let r = ctx.read(10) if (r == "") { break } else if (r) { if (r == "ticker") { ctx.write(JSON.stringify(exchange.GetTicker())) } else { ctx.write("not support") } } } Log("websocket closed", ctx.remoteAddr()) } } else { ctx.setStatus(404) } }) let echoServer = __Serve("tcp://:8089", function (ctx) { Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr()) while (true) { let d = ctx.read() if (!d) { break } ctx.write(d) } Log("connect closed") }) Log("http serve on", httpServer, "tcp serve on", echoServer) for (var i = 0; i < 5; i++) { if (i == 2) { // test Http var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true}) Log("retHttp:", retHttp) } else if (i == 3) { // test TCP var tcpConn = Dial("tcp://127.0.0.1:8089") tcpConn.write("Hello TCP Server") var retTCP = tcpConn.read() Log("retTCP:", retTCP) } else if (i == 4) { // test Websocket var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip") wsConn.write("ticker") var retWS = wsConn.read(1000) Log("retWS:", retWS) // no depth wsConn.write("depth") retWS = wsConn.read(1000) Log("retWS:", retWS) } Sleep(1000) } }
python
# 不支持
c++
// 不支持

返回值

类型描述

string

返回一个字符串,记录创建的服务的IP地址、端口。例如:127.0.0.1:8088[::]:8089

参数

名称类型必填描述

serveURI

string

serveURI参数用于配置服务绑定的协议、IP地址、端口等设置,例如:http://0.0.0.0:8088?gzip=true,即:http://:8088?gzip=true

  • TCP协议
    serveURI参数设置例如:tcp://127.0.0.1:6666?tls=true;可以添加证书、私钥例如:tls=true&cert_pem=xxxx&cert_key_pem=xxxx
  • HTTP协议
    serveURI参数设置例如:http://127.0.0.1:6666?gzip=true;可以设置压缩设置:gzip=true
    serveURI参数用于HTTPS例如:https://127.0.0.1:6666?tls=true&gzip=true;可以加入cert_pemcert_key_pem参数来加载证书。

handler

function

handler参数用于传入路由处理函数(HTTP协议)、消息处理函数(TCP协议)、Stream处理函数(WebSocket)。

参数handler传入的回调函数可以定义多个参数,第一个参数为ctx对象(上下文对象)。

arg

string / number / bool / object / array / function / any (平台支持的任意类型)

作为参数handler传入的回调函数的参数的实参,参数arg可能有多个,例如:

javascript
__Serve("http://:8088", function(ctx, a, b, c) { Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c) }, 1, 2, 3)

调用__Serve()函数时传入的参数123对应传入回调函数的参数abc

参考

备注

  • 该函数仅支持JavaScript语言策略。
  • 服务线程与全局作用域隔离,因此不支持闭包或引用外部变量、自定义函数等;但是可以调用平台所有的API函数。
  • WebSocket服务基于HTTP协议实现,可以在path中设置一个路由分支,设计WebSocket消息订阅/推送的实现代码,可以参考本节示例代码。

参数handler传入的回调处理函数接收一个ctx参数。ctx参数为一个上下文对象,用于获取数据和写入数据,具有以下方法:

  • ctx.proto()
    应用于HTTP/TCP协议,调用时返回协议名称。例如:HTTP/1.1tcp
  • ctx.host()
    应用于HTTP协议,调用时返回主机信息:IP地址、端口。
  • ctx.path()
    应用于HTTP协议,调用时返回请求路径。
  • ctx.query(key)
    应用于HTTP协议,调用时返回请求中query查询中key对应的值。例如发送的请求为:http://127.0.0.1:8088?num=123,参数handler传入的回调处理函数中ctx.query("num")调用时返回"123"
  • ctx.rawQuery()
    应用于HTTP协议,调用时返回请求中的原始查询(HTTP请求的query)。
  • ctx.headers()
    应用于HTTP协议,调用时返回请求中的请求头信息。
  • ctx.header(key)
    应用于HTTP协议,调用时返回指定的请求头中的某个key对应的值。例如获取当前请求的headers中的User-Agentctx.header("User-Agent")
  • ctx.method()
    应用于HTTP协议,调用时返回请求方法,例如GETPOST等。
  • ctx.body()
    应用于HTTP协议的POST请求,调用时返回请求的正文。
  • ctx.setHeader(key, value)
    应用于HTTP协议,设置响应报文的请求头信息。
  • ctx.setStatus(code)
    应用于HTTP协议,设置HTTP报文状态码,通常在路由分支最后设置HTTP状态码,默认为200。
  • ctx.remoteAddr()
    应用于HTTP/TCP协议,调用时返回请求中的远程客户端地址、端口。
  • ctx.localAddr()
    应用于HTTP/TCP协议,调用时返回服务本地地址、端口。
  • ctx.upgrade("websocket")
    应用于基于HTTP协议的WebSocket协议实现,切换ctx上下文对象为WebSocket协议;切换成功返回布尔值(真),失败返回布尔值(假)。
  • ctx.read(timeout_ms)
    应用于基于HTTP协议的WebSocket协议实现/TCP协议,读取WebSocket连接的数据,TCP连接的数据,普通HTTP协议中不支持使用该read方法;可以指定超时时间参数timeout_ms,单位毫秒。
  • ctx.write(s)
    应用于HTTP/TCP协议,用于写入字符串数据,可以使用JSON.stringify()编码JSON对象为字符串之后写入。对于WebSocket协议,可以使用该方法将编码后的字符串传递给客户端。

持久化保存数据。该函数实现了一个可持久化保存的全局字典功能,数据以键值对(KV)表的结构永久保存在托管者的本地数据库文件中。

_G()
_G(k)
_G(k, v)

示例

javascript
function main(){ // 设置一个全局变量num,值为1 _G("num", 1) // 更改一个全局变量num,值为字符串ok _G("num", "ok") // 删除全局变量num _G("num", null) // 返回全局变量num的值 Log(_G("num")) // 删除所有全局变量 _G(null) // 返回实盘ID var robotId = _G() }
python
def main(): _G("num", 1) _G("num", "ok") _G("num", None) Log(_G("num")) _G(None) robotId = _G()
rust
fn main() { // 设置一个全局变量num,值为1 _G!("num", 1); // 更改一个全局变量num,值为字符串ok _G!("num", "ok"); // 删除全局变量num _G!("num", null); // 返回全局变量num的值 Log!(_G!("num")); // Rust 不支持 _G!(null) 删除所有全局变量的形式 // 返回实盘ID let robotId = _G!(); }
c++
void main() { _G("num", 1); _G("num", "ok"); _G("num", NULL); Log(_G("num")); _G(NULL); // 不支持 auto robotId = _G(); }

返回值

类型描述

string / number / bool / object / array / 空值

持久化保存的k-v键值对中的键值数据。

参数

名称类型必填描述

k

string / 空值

参数k为所保存键值对中的键名,不区分大小写。

v

string / number / bool / object / array / 空值

参数v为所保存键值对中的键值,可以是任何能够进行JSON序列化的数据。

参考

备注

每个实盘单独对应一个数据库。策略重启或托管者停止运行后,_G()函数保存的数据依然会持续存在。但回测结束后,_G()函数在回测系统中保存的数据将被清除。使用_G()函数持久化保存数据时,应根据硬件设备的内存与硬盘空间合理使用,切勿滥用。

在实盘运行中,当调用_G()函数且不传入任何参数时,_G()函数返回当前实盘的Id

调用_G()函数时,参数v传入空值表示删除对应的k-v键值对。

调用_G()函数时,若仅参数k传入字符串,则_G()函数返回参数k对应的已保存键值。

调用_G()函数时,若仅参数k传入空值,则表示删除所有已记录的k-v键值对。

k-v键值对已持久化保存后,再次调用_G()函数,并传入已持久化保存的键名作为参数k、新的键值作为参数v,即可更新该k-v键值对。

以实盘Id为123456为例,使用_G()函数持久化保存的K-V键值数据存储在该实盘(即策略实例程序)所属托管者目录下的/logs/storage/123456/123456.db3数据库文件中,数据记录在kvdb表内。

将毫秒级时间戳或Date对象转换为时间字符串。

_D()
_D(timestamp)
_D(timestamp, fmt)

示例

  • 获取并打印当前时间字符串:

    javascript
    function main(){ var time = _D() Log(time) }
    python
    def main(): strTime = _D() Log(strTime)
    rust
    fn main() { let time = _D(None); Log!(time); }
    c++
    void main() { auto strTime = _D(); Log(strTime); }
  • 时间戳为1574993606000,使用代码进行转换:

    javascript
    function main() { Log(_D(1574993606000)) }
    python
    def main(): # 在北京时间的服务器上运行结果为:2019-11-29 10:13:26;而在其他地区服务器上的托管者运行此代码,结果则为:2019-11-29 02:13:26 Log(_D(1574993606))
    rust
    fn main() { Log!(_D(1574993606000)); }
    c++
    void main() { Log(_D(1574993606000)); }
  • 使用参数fmt进行格式化,JavaScriptPythonC++语言的格式化字符串有所不同,具体请参看以下示例:

    javascript
    function main() { Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss")) // 2019--11--29 10--13--26 }
    python
    def main(): # 1574993606 为秒级时间戳 Log(_D(1574993606, "%Y--%m--%d %H--%M--%S")) # 2019--11--29 10--13--26
    rust
    fn main() { // Rust 的 _D() 函数不支持 fmt 参数,仅支持默认格式:yyyy-MM-dd hh:mm:ss Log!(_D(1574993606000)); // 2019-11-29 10:13:26 }
    c++
    void main() { Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26 }

返回值

类型描述

string

时间字符串。

参数

名称类型必填描述

timestamp

number / object

毫秒级时间戳或Date对象。

fmt

string

格式化字符串,JavaScript语言默认格式:yyyy-MM-dd hh:mm:ssPython语言默认格式:%Y-%m-%d %H:%M:%SC++语言默认格式:%Y-%m-%d %H:%M:%S

参考

备注

若不传入任何参数,则返回当前时间字符串。在Python策略中使用_D()函数时,需要注意传入的参数为秒级时间戳(JavaScript、C++策略中为毫秒级时间戳,1秒等于1000毫秒)。在实盘中使用_D()函数将时间戳解析为可读时间字符串时,需要注意托管者程序所在操作系统的时区与时间设置,因为_D()函数的解析结果取决于托管者系统的时间。

格式化浮点数。

_N()
_N(num)
_N(num, precision)

示例

  • 例如_N(3.1415, 2)会保留3.1415小数点后两位,删除其余数位,函数返回3.14

    javascript
    function main(){ var i = 3.1415 Log(i) var ii = _N(i, 2) Log(ii) }
    python
    def main(): i = 3.1415 Log(i) ii = _N(i, 2) Log(ii)
    rust
    fn main() { let i = 3.1415; Log!(i); let ii = _N(i, 2); Log!(ii); }
    c++
    void main() { auto i = 3.1415; Log(i); auto ii = _N(i, 2); Log(ii); }
  • 如果需要将小数点左边的N位数字都置为0,可以这样编写:

    javascript
    function main(){ var i = 1300 Log(i) var ii = _N(i, -3) // 查看日志得知为1000 Log(ii) }
    python
    def main(): i = 1300 Log(i) ii = _N(i, -3) Log(ii)
    rust
    fn main() { let i = 1300; Log!(i); let ii = _N(i, -3); // 查看日志得知为1000 Log!(ii); }
    c++
    void main() { auto i = 1300; Log(i); auto ii = _N(i, -3); Log(ii); }

返回值

类型描述

number

根据精度设置格式化后的浮点数。

参数

名称类型必填描述

num

number

待格式化的浮点数。

precision

number

用于设置格式化精度,参数precision为整数,默认值为4。

参考

备注

参数precision可以为正整数或负整数。

重试函数,用于对接口调用进行容错处理。

_C(pfn)
_C(pfn, ...args)

示例

  • 对无参数的函数进行容错处理:

    javascript
    function main(){ var ticker = _C(exchange.GetTicker) // 调整_C()函数重试时间间隔为2秒 _CDelay(2000) var depth = _C(exchange.GetDepth) Log(ticker) Log(depth) }
    python
    def main(): ticker = _C(exchange.GetTicker) _CDelay(2000) depth = _C(exchange.GetDepth) Log(ticker) Log(depth)
    rust
    fn main() { let ticker = _C!(exchange.GetTicker(None)); // 调整_C!()宏重试时间间隔为2秒 _CDelay(2000); let depth = _C!(exchange.GetDepth(None)); Log!(ticker); Log!(depth); }
    c++
    void main() { auto ticker = _C(exchange.GetTicker); _CDelay(2000); auto depth = _C(exchange.GetDepth); Log(ticker); Log(depth); }
  • 对带参数的函数进行容错处理:

    javascript
    function main(){ var records = _C(exchange.GetRecords, PERIOD_D1) Log(records) }
    python
    def main(): records = _C(exchange.GetRecords, PERIOD_D1) Log(records)
    rust
    fn main() { let records = _C!(exchange.GetRecords(None, PERIOD_D1, None)); Log!(records); }
    c++
    void main() { auto records = _C(exchange.GetRecords, PERIOD_D1); Log(records); }
  • 也可用于对自定义函数进行容错处理:

    javascript
    var test = function(a, b){ var time = new Date().getTime() / 1000 if(time % b == 3){ Log("Condition met!", "#FF0000") return true } Log("Retrying!", "#FF0000") return false } function main(){ var ret = _C(test, 1, 5) Log(ret) }
    python
    import time def test(a, b): ts = time.time() if ts % b == 3: Log("Condition met!", "#FF0000") return True Log("Retrying!", "#FF0000") return False def main(): ret = _C(test, 1, 5) Log(ret)
    rust
    fn test(a: i64, b: i64) -> Result<bool> { let time = Unix(); if time % b == 3 { Log!("Condition met!", "#FF0000"); return Ok(true); } Log!("Retrying!", "#FF0000"); Err(Error::Api("retry".to_string())) } fn main() { // Rust 中自定义函数返回 Result 类型即可使用 _C! 宏容错,返回 Err 时会重试 let ret = _C!(test(1, 5)); Log!(ret); }
    c++
    // C++ 不支持这种方式对于自定义函数容错

返回值

类型描述

假值空值以外的所有平台支持的类型(any)。

回调函数执行后的返回值。

参数

名称类型必填描述

pfn

function

参数pfn为函数引用,即一个回调函数

arg

string / number / bool / object / array / function / any (平台支持的任意类型)

回调函数的参数,参数arg可以有多个。参数arg的类型与个数由回调函数的参数决定。

备注

_C()函数会反复调用指定的函数,直到其成功返回为止(当参数pfn所引用的函数被调用时返回空值假值,则会重试调用pfn)。

例如_C(exchange.GetTicker)。默认重试间隔为3秒,可调用_CDelay()函数来设置重试间隔。

例如_CDelay(1000),表示将_C()函数的重试间隔改为1秒。

可以对以下函数进行容错处理(但不限于此):

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPositions()

以上函数均可通过_C()函数调用以实现容错。_C()函数的容错并不局限于上述列出的函数。请注意,参数pfn为函数引用而非函数调用,即应写作_C(exchange.GetTicker),而非_C(exchange.GetTicker())

返回数组arr1与数组arr2的交叉周期数。

_Cross(arr1, arr2)

示例

可以模拟一组数据来测试_Cross(Arr1, Arr2)函数:

javascript
// 快线指标 var arr1 = [1,2,3,4,5,6,8,8,9] // 慢线指标 var arr2 = [2,3,4,5,6,7,7,7,7] function main(){ Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2)) Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1)) }
python
arr1 = [1,2,3,4,5,6,8,8,9] arr2 = [2,3,4,5,6,7,7,7,7] def main(): Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2)) Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
rust
fn main() { // 快线指标 let arr1 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 8.0, 9.0]; // 慢线指标 let arr2 = [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 7.0, 7.0, 7.0]; Log!("_Cross(arr1, arr2) : ", _Cross(&arr1, &arr2)); Log!("_Cross(arr2, arr1) : ", _Cross(&arr2, &arr1)); }
c++
void main() { vector<double> arr1 = {1,2,3,4,5,6,8,8,9}; vector<double> arr2 = {2,3,4,5,6,7,7,7,7}; Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2)); Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1)); }

返回值

类型描述

number

数组arr1与数组arr2的交叉周期数。

参数

名称类型必填描述

arr1

array

元素为number类型的数组。

arr2

array

元素为number类型的数组。

备注

_Cross()函数的返回值为正数时表示上穿的周期数,为负数时表示下穿的周期数,为0时表示当前价格相等。详细使用说明请参阅:内置函数_Cross分析及使用说明

JSON.parse函数是ECMAScript标准内建对象JSON的方法,用于解码(解析)JSON字符串。发明者量化交易平台在此基础上为其扩展了一个参数safeStr

JSON.parse(s)
JSON.parse(s, safeStr)

示例

解码(解析)一个包含大数值的JSON字符串。

javascript
function main() { let s1 = '{"num": 8754613216564987646512354656874651651358}' Log("JSON.parse:", JSON.parse(s1)) // JSON.parse: {"num":8.754613216564987e+39} Log("JSON.parse:", JSON.parse(s1, true)) // JSON.parse: {"num":"8754613216564987646512354656874651651358"} let s2 = '{"num": 123}' Log("JSON.parse:", JSON.parse(s2)) // JSON.parse: {"num":123} Log("JSON.parse:", JSON.parse(s2, true)) // JSON.parse: {"num":123} }
python
# 可以使用Python的第三方库处理大数值数据。
rust
fn main() { // Rust 使用 JSONParse() 函数解析JSON字符串,没有 safeStr 参数 // 超出精度范围的大数值会被解析为 f64 ,可能丢失精度 let s1 = r#"{"num": 8754613216564987646512354656874651651358}"#; Log!("JSONParse:", JSONParse(s1).unwrap()["num"].as_f64().unwrap_or(0.0)); // JSONParse: 8.754613216564987e39 let s2 = r#"{"num": 123}"#; Log!("JSONParse:", JSONParse(s2).unwrap()["num"].as_f64().unwrap_or(0.0)); // JSONParse: 123 }
c++
// 可以使用其它方案处理。

返回值

类型描述

object

返回值为JSON对象。

参数

名称类型必填描述

s

string

该参数为需要解码(解析)的JSON字符串。

safeStr

bool

当该参数设置为true时,若解析过程中遇到可能超出精度范围的数值,会将其以字符串形式返回,以避免精度丢失或数值溢出问题。

备注

JSON.parse()函数能够正确解析包含较大数值的JSON字符串;当safeStr参数设置为真值时,会将较大的数值解析为字符串类型。

safeStr参数位同样支持传入reviver参数,即一个用于转换结果的函数,该函数会针对对象的每个成员调用一次;具体用法可查阅相关资料,此处不再赘述。

仅支持JavaScript语言。

回测系统中不支持JSON.parse()函数的safeStr参数功能。

JSON.stringify函数是ECMAScript标准内置对象JSON的方法,用于将JavaScript值转换为JSON字符串。

JSON.stringify(obj)

示例

将对象序列化为JSON字符串并输出。

javascript
function main() { let s1 = {"num": "8754613216564987646512354656874651651358"} Log("JSON.stringify:", JSON.stringify(s1)) // JSON.stringify: {"num":"8754613216564987646512354656874651651358"} // JSON.stringify(s1) 返回的变量为一个字符串类型 }
python
// 略
c++
// 略

返回值

类型描述

string

返回序列化后的JSON字符串。

参数

名称类型必填描述

obj

string / number / bool / object / array / function / any (平台支持的任意类型)

需要序列化为JSON字符串的值。

备注

仅支持JavaScript语言。

在频道上发布最新的状态数据。该函数用于实盘之间的通信,可将当前实盘的状态数据广播到频道上,供其他实盘订阅获取。

SetChannelData(data)

示例

  • 频道广播端示例 - 发布 BTC 行情价格数据

    javascript
    function main() { var updateId = 0 var robotId = _G() // 获取当前实盘 ID while(true) { // 获取实时市场价格 var ticker = exchange.GetTicker("BTC_USDT") if (!ticker) { Sleep(5000) continue } // 构造当前频道状态数据 var channelState = { robotId: robotId, updateId: ++updateId, timestamp: Date.now(), symbol: "BTC_USDT", lastPrice: ticker.Last, volume: ticker.Volume, high: ticker.High, low: ticker.Low } // 在频道上发布最新状态(覆盖旧状态) SetChannelData(channelState) // 显示当前频道状态 LogStatus("Channel Broadcaster [Bot ID: " + robotId + "]\n" + "Update ID: #" + channelState.updateId + "\n" + "Time: " + _D(channelState.timestamp) + "\n" + "Symbol: " + channelState.symbol + "\n" + "Last Price: $" + channelState.lastPrice.toFixed(2) + "\n" + "Volume: " + channelState.volume.toFixed(4) + "\n" + "High: $" + channelState.high.toFixed(2) + "\n" + "Low: $" + channelState.low.toFixed(2)) Sleep(60000) // 每分钟更新一次频道状态 } }
    python
    def main(): updateId = 0 robotId = _G() # 获取当前实盘 ID while True: # 获取实时市场价格 ticker = exchange.GetTicker("BTC_USDT") if not ticker: Sleep(5000) continue # 构造当前频道状态数据 channelState = { "robotId": robotId, "updateId": updateId + 1, "timestamp": time.time() * 1000, "symbol": "BTC_USDT", "lastPrice": ticker["Last"], "volume": ticker["Volume"], "high": ticker["High"], "low": ticker["Low"] } updateId += 1 # 在频道上发布最新状态(覆盖旧状态) SetChannelData(channelState) # 显示当前频道状态 LogStatus("Channel Broadcaster [Bot ID: {}]\n".format(robotId) + "Update ID: #{}\n".format(channelState["updateId"]) + "Time: {}\n".format(_D(channelState["timestamp"])) + "Symbol: {}\n".format(channelState["symbol"]) + "Last Price: ${:.2f}\n".format(channelState["lastPrice"]) + "Volume: {:.4f}\n".format(channelState["volume"]) + "High: ${:.2f}\n".format(channelState["high"]) + "Low: ${:.2f}".format(channelState["low"])) Sleep(60000) # 每分钟更新一次频道状态
    rust
    fn main() { let mut updateId = 0; let robotId = _G!(); // 获取当前实盘 ID loop { // 获取实时市场价格 let ticker = match exchange.GetTicker("BTC_USDT") { Ok(t) => t, Err(_) => { Sleep(5000); continue; } }; // 构造当前频道状态数据 // Rust 的 SetChannelData 仅接受字符串参数,因此使用 format! 构造 JSON 文本 updateId += 1; let timestamp = Unix() * 1000; let channelState = format!( r#"{{"robotId": {}, "updateId": {}, "timestamp": {}, "symbol": "BTC_USDT", "lastPrice": {}, "volume": {}, "high": {}, "low": {}}}"#, robotId, updateId, timestamp, ticker.Last, ticker.Volume, ticker.High, ticker.Low ); // 在频道上发布最新状态(覆盖旧状态) SetChannelData(&channelState); // 显示当前频道状态 LogStatus!(format!( "Channel Broadcaster [Bot ID: {}]\nUpdate ID: #{}\nTime: {}\nSymbol: BTC_USDT\nLast Price: ${:.2}\nVolume: {:.4}\nHigh: ${:.2}\nLow: ${:.2}", robotId, updateId, _D(timestamp), ticker.Last, ticker.Volume, ticker.High, ticker.Low )); Sleep(60000); // 每分钟更新一次频道状态 } }
    c++
  • 跨平台发送示例 - 模拟外部平台(如 TradingView)向 FMZ 实盘发送数据

    javascript
    // 此示例演示如何使用 HttpQuery 发送 HTTP POST 请求,模拟外部平台向 FMZ 实盘发送数据 // 在实际场景中,外部平台(如 TradingView 的 Webhook 告警 URL、第三方交易系统等)会直接调用 FMZ API 端点 function main() { let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" let robotId = 123456 // 目标实盘 ID(用于接收数据的实盘) let baseUrl = "https://www.fmz.com" while (true) { // 准备待发送的数据(可以是 JSON、文本或其他格式) let sendData = { "action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": Date.now() } // 构造 HTTP POST 请求 let options = { method: "POST", body: JSON.stringify(sendData) // body 可以是 JSON 字符串、普通文本等 } let url = `${baseUrl}/api/v1?method=pub&robot=${robotId}&channel=${uuid}` // 发送数据 let ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) // 每 10 秒发送一次 } }
    python
    # 此示例演示如何使用 HttpQuery 发送 HTTP POST 请求,模拟外部平台向 FMZ 实盘发送数据 # 在实际场景中,外部平台(如 TradingView 的 Webhook 告警 URL、第三方交易系统等)会直接调用 FMZ API 端点 import json def main(): uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" robotId = 123456 # 目标实盘 ID(用于接收数据的实盘) baseUrl = "https://www.fmz.com" while True: # 准备待发送的数据(可以是 JSON、文本或其他格式) sendData = { "action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": time.time() * 1000 } # 构造 HTTP POST 请求 options = { "method": "POST", "body": json.dumps(sendData) # body 可以是 JSON 字符串、普通文本等 } url = "{}/api/v1?method=pub&robot={}&channel={}".format(baseUrl, robotId, uuid) # 发送数据 ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) # 每 10 秒发送一次
    rust
    // 此示例演示如何使用 HttpQuery 发送 HTTP POST 请求,模拟外部平台向 FMZ 实盘发送数据 // 在实际场景中,外部平台(如 TradingView 的 Webhook 告警 URL、第三方交易系统等)会直接调用 FMZ API 端点 fn main() { let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30"; let robotId = 123456; // 目标实盘 ID(用于接收数据的实盘) let baseUrl = "https://www.fmz.com"; loop { // 准备待发送的数据(可以是 JSON、文本或其他格式) let sendData = format!( r#"{{"action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": {}}}"#, Unix() * 1000 ); // 构造 HTTP POST 请求,{:?} 会将 body 转义为合法的 JSON 字符串值 let options = format!(r#"{{"method": "POST", "body": {:?}}}"#, sendData); let url = format!("{}/api/v1?method=pub&robot={}&channel={}", baseUrl, robotId, uuid); // 发送数据 let ret: String = HttpQuery(&url, options.as_str()); Log!("Simulated external platform sending data, result:", ret); Sleep(10000); // 每 10 秒发送一次 } }
    c++

返回值

类型描述

空值

该函数无返回值。

参数

名称类型必填描述

data

object / array / string / number / bool / 空值

需要发布到频道的数据,可以是任何支持JSON序列化的数据结构,通常为包含实盘状态信息的对象。

参考

备注

SetChannelData()函数为非阻塞调用,调用后立即返回,不会等待数据传输完成。

每个实盘都拥有一个独立的频道,频道ID即为实盘ID(可通过_G()函数获取)。

频道上仅保存最新的状态数据,每次调用SetChannelData()都会覆盖之前发布的数据,而非追加历史消息。

频道数据支持跨实盘、跨托管者、跨服务器进行广播,多个实盘可以订阅同一个频道。

订阅端使用GetChannelData()函数订阅频道数据。

频道通信适用于实盘环境,在回测系统中该功能可能受到限制。

传入的数据参数data在JSON序列化后的字节长度不得超过1024字节,超出限制可能导致数据发布失败。建议仅传输必要的状态信息,避免传输过大的数据对象。

发布的数据应根据硬件设备的内存和网络带宽合理使用,避免发布过大的数据对象。

SetChannelData()函数发布的数据不仅可以被FMZ平台内的其他实盘订阅,还支持跨平台数据发送功能。外部平台(如TradingView的Webhook告警、第三方交易系统、监控软件等)可以通过HTTP POST请求向指定的FMZ实盘发送数据。

跨平台发送数据的方式: 外部系统通过HTTP POST请求将数据发送到FMZ平台API端点:https://www.fmz.com/api/v1?method=pub&robot={robotId}&channel={uuid},其中robotId为目标实盘ID,uuid为32位字符的频道标识符。发送的数据在请求body中传递,可以是JSON格式、文本或其他格式。注意:必须先有实盘订阅该UUID频道,外部系统才能成功发送数据;广播的数据会发送到robotId实盘所在托管者下的所有实盘,同一托管者下订阅了该UUID频道的实盘均可接收数据。

订阅指定实盘的频道数据。该函数用于实盘间通信,可获取其他实盘通过SetChannelData()函数发布的最新状态数据。

GetChannelData(channelId)

示例

  • 频道订阅端示例 - 订阅两个实盘的频道数据

    javascript
    function main() { // 需要订阅的两个频道 ID(请根据实际情况修改) var channelId1 = "632799" // 频道 1 的实盘 ID var channelId2 = "632800" // 频道 2 的实盘 ID while(true) { // 订阅频道 1 的当前状态 var state1 = GetChannelData(channelId1) // 订阅频道 2 的当前状态 var state2 = GetChannelData(channelId2) // 构建状态显示 var statusMsg = "频道订阅端 - 当前订阅状态\n\n" // 显示频道 1 状态 statusMsg += "═══ 频道1 [" + channelId1 + "] ═══\n" if (state1 !== null) { statusMsg += "更新ID: #" + state1.updateId + "\n" statusMsg += "时间: " + _D(state1.timestamp) + "\n" statusMsg += "交易对: " + state1.symbol + "\n" statusMsg += "最新价: $" + state1.lastPrice.toFixed(2) + "\n" statusMsg += "成交量: " + state1.volume.toFixed(4) + "\n" } else { statusMsg += "状态: 等待中... (首次调用返回 null)\n" } statusMsg += "\n" // 显示频道 2 状态 statusMsg += "═══ 频道2 [" + channelId2 + "] ═══\n" if (state2 !== null) { statusMsg += "更新ID: #" + state2.updateId + "\n" statusMsg += "时间: " + _D(state2.timestamp) + "\n" statusMsg += "交易对: " + state2.symbol + "\n" statusMsg += "最新价: $" + state2.lastPrice.toFixed(2) + "\n" statusMsg += "成交量: " + state2.volume.toFixed(4) + "\n" } else { statusMsg += "状态: 等待中... (首次调用返回 null)\n" } LogStatus(statusMsg) Sleep(5000) // 每 5 秒订阅一次频道 } }
    python
    def main(): # 需要订阅的两个频道 ID(请根据实际情况修改) channelId1 = "632799" # 频道 1 的实盘 ID channelId2 = "632800" # 频道 2 的实盘 ID while True: # 订阅频道 1 的当前状态 state1 = GetChannelData(channelId1) # 订阅频道 2 的当前状态 state2 = GetChannelData(channelId2) # 构建状态显示 statusMsg = "频道订阅端 - 当前订阅状态\n\n" # 显示频道 1 状态 statusMsg += "═══ 频道1 [{}] ═══\n".format(channelId1) if state1 is not None: statusMsg += "更新ID: #{}\n".format(state1["updateId"]) statusMsg += "时间: {}\n".format(_D(state1["timestamp"])) statusMsg += "交易对: {}\n".format(state1["symbol"]) statusMsg += "最新价: ${:.2f}\n".format(state1["lastPrice"]) statusMsg += "成交量: {:.4f}\n".format(state1["volume"]) else: statusMsg += "状态: 等待中... (首次调用返回 None)\n" statusMsg += "\n" # 显示频道 2 状态 statusMsg += "═══ 频道2 [{}] ═══\n".format(channelId2) if state2 is not None: statusMsg += "更新ID: #{}\n".format(state2["updateId"]) statusMsg += "时间: {}\n".format(_D(state2["timestamp"])) statusMsg += "交易对: {}\n".format(state2["symbol"]) statusMsg += "最新价: ${:.2f}\n".format(state2["lastPrice"]) statusMsg += "成交量: {:.4f}\n".format(state2["volume"]) else: statusMsg += "状态: 等待中... (首次调用返回 None)\n" LogStatus(statusMsg) Sleep(5000) # 每 5 秒订阅一次频道
    rust
    fn main() { // Rust 的 GetChannelData() 函数不接受频道 ID 参数,只能读取当前实盘自身频道 // (即本实盘通过 SetChannelData() 发布)的最新数据,无法订阅其它实盘的频道 loop { // 订阅频道的当前状态 let state = GetChannelData(); // 构建状态显示 let mut statusMsg = String::from("频道订阅端 - 当前订阅状态\n\n"); if !state.is_null() { statusMsg += &format!("更新ID: #{}\n", state["updateId"].as_i64().unwrap_or(0)); statusMsg += &format!("时间: {}\n", _D(state["timestamp"].as_i64().unwrap_or(0))); statusMsg += &format!("交易对: {}\n", state["symbol"].as_str().unwrap_or("")); statusMsg += &format!("最新价: ${:.2}\n", state["lastPrice"].as_f64().unwrap_or(0.0)); statusMsg += &format!("成交量: {:.4}\n", state["volume"].as_f64().unwrap_or(0.0)); } else { statusMsg += "状态: 等待中... (首次调用返回 null)\n"; } LogStatus!(statusMsg); Sleep(5000); // 每 5 秒订阅一次频道 } }
    c++
  • 跨平台订阅示例 - 使用 UUID 订阅外部系统发送的数据

    javascript
    function main() { // 使用 32 位 UUID 作为频道标识符 let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while (true) { // 订阅 UUID 频道的数据 let data = GetChannelData(uuid) if (data !== null) { Log("Received cross-platform data:", data) } else { Log("Waiting for data... (first call returns null)") } Sleep(10000) // 每 10 秒检查一次 } }
    python
    def main(): # 使用 32 位 UUID 作为频道标识符 uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while True: # 订阅 UUID 频道的数据 data = GetChannelData(uuid) if data is not None: Log("Received cross-platform data:", data) else: Log("Waiting for data... (first call returns None)") Sleep(10000) # 每 10 秒检查一次
    rust
    fn main() { // Rust 的 GetChannelData() 函数不接受频道 ID 参数,无法使用 32 位 UUID 订阅跨平台数据, // 只能读取当前实盘自身频道(即本实盘通过 SetChannelData() 发布)的最新数据 loop { // 订阅频道的数据 let data = GetChannelData(); if !data.is_null() { Log!("Received cross-platform data:", data); } else { Log!("Waiting for data... (first call returns null)"); } Sleep(10000); // 每 10 秒检查一次 } }
    c++

返回值

类型描述

object / array / string / number / bool / 空值

返回所订阅频道的最新状态数据。首次调用时返回null,需要重试。数据结构由广播端发布的数据决定。

参数

名称类型必填描述

channelId

string / number

频道标识符,支持以下两种类型:

  1. 实盘ID:用于订阅其他实盘的频道数据(即实盘间通信),可通过_G()函数获取实盘ID。

  2. 32位UUID:用于订阅跨平台发送的数据(即外部系统通过HTTP API向FMZ平台发送的数据)。

参考

备注

GetChannelData()函数为非阻塞调用,调用后立即返回,不会等待数据接收完成。

首次调用GetChannelData()函数时会返回null,需要重试并等待频道数据同步完成。

每次调用获取的均为频道上的最新状态数据,而非历史消息队列。

一个实盘可同时订阅多个不同实盘的频道,只需多次调用GetChannelData()并分别传入不同的实盘ID即可。

当前实盘也可以订阅自身的频道,即robotId参数可以是当前实盘的ID。

频道数据可跨实盘、跨托管者、跨服务器进行传输。

广播端使用SetChannelData()函数发布频道数据。

频道通信适用于实盘环境,在回测系统中该功能可能受限。

GetChannelData()函数支持跨平台订阅功能。当使用32位UUID作为频道标识符时,可接收来自FMZ平台外部系统通过HTTP API发送的数据。外部系统需同时指定实盘ID和UUID才能发送数据;同一托管者下的所有实盘均可订阅该UUID频道的数据,而不同托管者的实盘则无法订阅。

Log()函数用于输出日志。

Log(...msgs)

示例

  • 可以传入多个msg参数:

    javascript
    function main() { Log("msg1", "msg2", "msg3") }
    python
    def main(): Log("msg1", "msg2", "msg3")
    rust
    fn main() { Log!("msg1", "msg2", "msg3"); }
    c++
    void main() { Log("msg1", "msg2", "msg3"); }
  • 支持设置输出消息的颜色。若需同时设置颜色和推送,需先设置颜色,最后再使用@字符设置推送。

    javascript
    function main() { Log("Hello FMZ Quant !@") Sleep(1000 * 5) // 字符串内加入#ff0000,打印日志显示为红色,并且推送消息 Log("Hello, #ff0000@") }
    python
    def main(): Log("Hello FMZ Quant !@") Sleep(1000 * 5) Log("Hello, #ff0000@")
    rust
    fn main() { Log!("Hello FMZ Quant !@"); Sleep(1000 * 5); // 字符串内加入#ff0000,打印日志显示为红色,并且推送消息 Log!("Hello, #ff0000@"); }
    c++
    void main() { Log("Hello FMZ Quant !@"); Sleep(1000 * 5); Log("Hello, #ff0000@"); }
  • Log()函数支持打印base64编码后的图片,内容以`开头,以`结尾,例如:

    javascript
    function main() { Log("`data:image/png;base64,AAAA`") }
    python
    def main(): Log("`data:image/png;base64,AAAA`")
    rust
    fn main() { Log!("`data:image/png;base64,AAAA`"); }
    c++
    void main() { Log("`data:image/png;base64,AAAA`"); }
  • Log()函数支持直接打印Pythonmatplotlib.pyplot对象,只要该对象包含savefig方法,即可直接使用Log函数打印,例如:

    python
    import matplotlib.pyplot as plt def main(): plt.plot([3,6,2,4,7,1]) Log(plt)
  • Log()函数支持语言切换,其输出的文本会根据平台页面的语言设置自动切换为对应的语言,例如:

    javascript
    function main() { Log("[trans]中文|abc[/trans]") }
    python
    def main(): Log("[trans]中文|abc[/trans]")
    rust
    fn main() { Log!("[trans]中文|abc[/trans]"); }
    c++
    void main() { Log("[trans]中文|abc[/trans]"); }

参数

名称类型必填描述

msg

string / number / bool / object / array / any (平台支持的任意类型)

参数msg为需要输出的内容,可传入多个msg参数。

参考

备注

Log()函数会在实盘或回测系统的日志区域输出一条日志信息,实盘运行时日志将保存在实盘的数据库中。若Log()函数输出的内容以@字符结尾,该条日志会进入消息推送队列,并推送至当前发明者量化交易平台账号在推送设置中配置的邮箱、WebHook地址等。调试工具和回测系统不支持消息推送。消息推送存在频率限制,具体规则如下:在实盘的每个20秒周期内,仅保留并推送最后一条推送消息,其余消息将被过滤而不推送(通过 Log 函数输出的推送日志仍会正常打印显示在日志区域)。

Log()函数输出的内容以&字符结尾,该条日志将被标记为私密日志。当实盘公开展示时,该条日志对其他用户隐藏,但在实盘拥有者账户视角下仍然可见。此功能可用于记录API密钥、账户余额等敏感信息。例如:Log("私密信息", "&")

关于WebHook推送,可以使用Golang编写的服务程序:

golang
package main import ( "fmt" "net/http" ) func Handle (w http.ResponseWriter, r *http.Request) { defer func() { fmt.Println("req:", *r) }() } func main () { fmt.Println("listen http://localhost:9090") http.HandleFunc("/data", Handle) http.ListenAndServe(":9090", nil) }

推送设置中设置WebHookhttp://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ,运行编写好的Golang服务程序后,即可开始运行实盘策略。以下为使用JavaScript语言编写的策略,策略运行时会执行Log()函数并推送消息:

javascript
function main() { Log("msg", "@") }

Golang语言编写的服务程序接收到推送后,打印如下信息:

log
listen http://localhost:9090 req: {GET /data?data=Hello_FMZ HTTP/1.1 1 1 map[User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xx.x.xxxx.xxx Safari/537.36] Accept-Encoding:[gzip]] {} <nil> 0 [] false 1XX.XX.X.XX:9090 map[] map[] <nil> map[] XXX.XX.XXX.XX:4xxx2 /data?data=Hello_FMZ <nil> <nil> <nil> 0xc420056300

记录并打印盈亏数值,并根据盈亏数值绘制收益曲线。

LogProfit(profit)
LogProfit(profit, ...args)

示例

调用LogProfit函数时,如果最后一个参数为字符&,则不会将日志写入数据库,仅更新收益图表。使用&参数可以避免频繁的收益记录产生大量日志,从而保持日志整洁。例如:

javascript
function main() { // 在收益图表上打印30个点 for(var i = 0; i < 30; i++) { LogProfit(i, '&') Sleep(500) } }
python
def main(): for i in range(30): LogProfit(i, '&') Sleep(500)
rust
fn main() { // 在收益图表上打印30个点 // Rust 中 LogProfit 只接受收益数值参数,不支持 '&' 等扩展参数 for i in 0..30 { LogProfit(i); Sleep(500); } }
c++
void main() { for(int i = 0; i < 30; i++) { LogProfit(i, '&'); Sleep(500); } }

参数

名称类型必填描述

profit

number

参数profit为收益数据,该数据由策略中设计的算法计算得出。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于向该条收益日志中输出附带信息,arg参数可传入多个。

参考

清空所有收益日志及收益图表。

LogProfitReset()
LogProfitReset(remain)

示例

javascript
function main() { // 在收益图表上打印30个数据点,然后重置,仅保留最后10个数据点 for(var i = 0; i < 30; i++) { LogProfit(i) Sleep(500) } LogProfitReset(10) }
python
def main(): for i in range(30): LogProfit(i) Sleep(500) LogProfitReset(10)
rust
fn main() { // 在收益图表上打印30个数据点,然后重置,仅保留最后10个数据点 for i in 0..30 { LogProfit(i); Sleep(500); } LogProfitReset(10); }
c++
void main() { for(int i = 0; i < 30; i++) { LogProfit(i); Sleep(500); } LogProfitReset(10); }

参数

名称类型必填描述

remain

number

remain参数用于指定需要保留的日志条数(整数)。

参考

在回测系统或实盘页面的状态栏中输出信息。

LogStatus(...msgs)

示例

  • 支持设置输出内容的颜色:

    javascript
    function main() { LogStatus('This is a normal status message') LogStatus('This is a red font status message#ff0000') LogStatus('This is a multi-line status message\nI am the second line') }
    python
    def main(): LogStatus('This is a normal status message') LogStatus('This is a red font status message#ff0000') LogStatus('This is a multi-line status message\nI am the second line')
    rust
    fn main() { LogStatus!("This is a normal status message"); LogStatus!("This is a red font status message#ff0000"); LogStatus!("This is a multi-line status message\nI am the second line"); }
    c++
    void main() { LogStatus("This is a normal status message"); LogStatus("This is a red font status message#ff0000"); LogStatus("This is a multi-line status message\nI am the second line"); }
  • 状态栏中的数据输出示例:

    javascript
    function main() { var table = {type: 'table', title: 'Position Info', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} // JSON 序列化后,在字符串两端添加 ` 字符,即可将其识别为复杂消息格式(当前支持表格) LogStatus('`' + JSON.stringify(table) + '`') // 表格信息也可以显示在多行文本中 LogStatus('First line message\n`' + JSON.stringify(table) + '`\nThird line message') // 支持同时显示多个表格,将以标签页(TAB)形式归为一组显示 LogStatus('`' + JSON.stringify([table, table]) + '`') // 也可以在表格中构造按钮,策略通过 GetCommand 接收 cmd 属性的内容 var table = { type: 'table', title: 'Position Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close All'}] ] } LogStatus('`' + JSON.stringify(table) + '`') // 或者构造一个单独的按钮 LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'Close All'}) + '`') // 可以自定义按钮样式(bootstrap 的按钮属性) LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'Close All'}) + '`') }
    python
    import json def main(): table = {"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]} LogStatus('`' + json.dumps(table) + '`') LogStatus('First line message\n`' + json.dumps(table) + '`\nThird line message') LogStatus('`' + json.dumps([table, table]) + '`') table = { "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus('`' + json.dumps(table) + '`') LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "Close All"}) + '`') LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close All"}) + '`')
    rust
    fn main() { let table = r#"{"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; // 在 JSON 字符串两端添加 ` 字符,即可将其识别为复杂消息格式(当前支持表格) LogStatus!(format!("`{}`", table)); // 表格信息也可以显示在多行文本中 LogStatus!(format!("First line message\n`{}`\nThird line message", table)); // 支持同时显示多个表格,将以标签页(TAB)形式归为一组显示 LogStatus!(format!("`[{},{}]`", table, table)); // 也可以在表格中构造按钮,策略通过 GetCommand 接收 cmd 属性的内容 let table = String::from(r#"{"type": "table", "title": "Position Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}]"# + r#"]}"#; LogStatus!(format!("`{}`", table)); // 或者构造一个单独的按钮 LogStatus!(format!("`{}`", r#"{"type": "button", "cmd": "coverAll", "name": "Close All"}"#)); // 可以自定义按钮样式(bootstrap 的按钮属性) LogStatus!(format!("`{}`", r#"{"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close All"}"#)); }
    c++
    void main() { json table = R"({"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; LogStatus("`" + table.dump() + "`"); LogStatus("First line message\n`" + table.dump() + "`\nThird line message"); json arr = R"([])"_json; arr.push_back(table); arr.push_back(table); LogStatus("`" + arr.dump() + "`"); table = R"({ "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] })"_json; LogStatus("`" + table.dump() + "`"); LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "Close All"})"_json.dump() + "`"); LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close All"})"_json.dump() + "`"); }
  • 支持在状态栏中设计按钮控件(旧版按钮结构):

    javascript
    function main() { var table = { type: "table", title: "Status Bar Button Styles", cols: ["Default", "Primary", "Success", "Info", "Warning", "Danger"], rows: [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] } LogStatus("`" + JSON.stringify(table) + "`") }
    python
    import json def main(): table = { "type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] } LogStatus("`" + json.dumps(table) + "`")
    rust
    fn main() { let table = String::from(r#"{"type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [["#) + r#"{"type": "button", "class": "btn btn-xs btn-default", "name": "Default"},"# + r#"{"type": "button", "class": "btn btn-xs btn-primary", "name": "Primary"},"# + r#"{"type": "button", "class": "btn btn-xs btn-success", "name": "Success"},"# + r#"{"type": "button", "class": "btn btn-xs btn-info", "name": "Info"},"# + r#"{"type": "button", "class": "btn btn-xs btn-warning", "name": "Warning"},"# + r#"{"type": "button", "class": "btn btn-xs btn-danger", "name": "Danger"}"# + r#"]]}"#; LogStatus!(format!("`{}`", table)); }
    c++
    void main() { json table = R"({ "type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] })"_json; LogStatus("`" + table.dump() + "`"); }
  • 设置状态栏按钮的禁用与描述功能(旧版按钮结构):

    javascript
    function main() { var table = { type: "table", title: "Status Bar Button Disable and Description Test", cols: ["Column 1", "Column 2", "Column 3"], rows: [] } var button1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} var button2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true} var button3 = {"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false} table.rows.push([button1, button2, button3]) LogStatus("`" + JSON.stringify(table) + "`") }
    python
    import json def main(): table = { "type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [] } button1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} button2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": True} button3 = {"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": False} table["rows"].append([button1, button2, button3]) LogStatus("`" + json.dumps(table) + "`")
    rust
    fn main() { let button1 = r#"{"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"}"#; let button2 = r#"{"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true}"#; let button3 = r#"{"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false}"#; let table = format!( r#"{{"type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [[{}, {}, {}]]}}"#, button1, button2, button3 ); LogStatus!(format!("`{}`", table)); }
    c++
    void main() { json table = R"({ "type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [] })"_json; json button1 = R"({"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"})"_json; json button2 = R"({"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true})"_json; json button3 = R"({"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false})"_json; json arr = R"([])"_json; arr.push_back(button1); arr.push_back(button2); arr.push_back(button3); table["rows"].push_back(arr); LogStatus("`" + table.dump() + "`"); }
  • 结合 GetCommand() 函数,构建状态栏按钮的交互功能(旧版按钮结构):

    javascript
    function test1() { Log("Calling custom function") } function main() { while (true) { var table = { type: 'table', title: 'Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['a', '1', { 'type': 'button', 'cmd': "CoverAll", 'name': 'Close All' }], ['b', '1', { 'type': 'button', 'cmd': 10, 'name': 'Send Number' }], ['c', '1', { 'type': 'button', 'cmd': _D(), 'name': 'Call Function' }], ['d', '1', { 'type': 'button', 'cmd': 'test1', 'name': 'Call Custom Function' }] ] } LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`') var str_cmd = GetCommand() if (str_cmd) { Log("Received interaction data str_cmd:", "Type:", typeof(str_cmd), "Value:", str_cmd) if(str_cmd == "test1") { test1() } } Sleep(500) } }
    python
    import json def test1(): Log("Calling custom function") def main(): while True: table = { "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": [ ["a", "1", { "type": "button", "cmd": "CoverAll", "name": "Close All" }], ["b", "1", { "type": "button", "cmd": 10, "name": "Send Number" }], ["c", "1", { "type": "button", "cmd": _D(), "name": "Call Function" }], ["d", "1", { "type": "button", "cmd": "test1", "name": "Call Custom Function" }] ] } LogStatus(_D(), "\n", "`" + json.dumps(table) + "`") str_cmd = GetCommand() if str_cmd: Log("Received interaction data str_cmd", "Type:", type(str_cmd), "Value:", str_cmd) if str_cmd == "test1": test1() Sleep(500)
    rust
    fn test1() { Log!("Calling custom function"); } fn main() { loop { let table = String::from(r#"{"type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["a", "1", {"type": "button", "cmd": "CoverAll", "name": "Close All"}],"# + r#"["b", "1", {"type": "button", "cmd": 10, "name": "Send Number"}],"# + &format!(r#"["c", "1", {{"type": "button", "cmd": "{}", "name": "Call Function"}}],"#, _D(None)) + r#"["d", "1", {"type": "button", "cmd": "test1", "name": "Call Custom Function"}]"# + r#"]}"#; LogStatus!(_D(None), "\n", format!("`{}`", table)); if let Some(str_cmd) = GetCommand(0) { Log!("Received interaction data str_cmd:", "Type:", "String", "Value:", &str_cmd); if str_cmd == "test1" { test1(); } } Sleep(500); } }
    c++
    void test1() { Log("Calling custom function"); } void main() { while(true) { json table = R"({ "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": [ ["a", "1", { "type": "button", "cmd": "CoverAll", "name": "Close All" }], ["b", "1", { "type": "button", "cmd": 10, "name": "Send Number" }], ["c", "1", { "type": "button", "cmd": "", "name": "Call Function" }], ["d", "1", { "type": "button", "cmd": "test1", "name": "Call Custom Function" }] ] })"_json; table["rows"][2][2]["cmd"] = _D(); LogStatus(_D(), "\n", "`" + table.dump() + "`"); auto str_cmd = GetCommand(); if(str_cmd != "") { Log("Received interaction data str_cmd", "Type:", typeid(str_cmd).name(), "Value:", str_cmd); if(str_cmd == "test1") { test1(); } } Sleep(500); } }
  • 在构造状态栏按钮进行交互时,同样支持输入数据,交互指令最终由GetCommand()函数捕获。

    在状态栏按钮控件的数据结构中增加input项(旧版按钮结构),例如为{"type": "button", "cmd": "open", "name": "Open"}添加"input": {"name": "Quantity", "type": "number", "defValue": 1},即可使按钮在被点击时弹出一个带输入框控件的弹窗(输入框中的默认值为1,即defValue所设置的数据),从而可以输入一个数据并与按钮命令一起发送。例如运行以下测试代码时,点击「开仓」按钮后会弹出一个带输入框的弹窗,在输入框中输入111并点击「确定」,GetCommand()函数便会捕获消息:open:111

    javascript
    function main() { var tbl = { type: "table", title: "Operation", cols: ["Column 1", "Column 2"], rows: [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`") while (true) { var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) } Sleep(1000) } }
    python
    import json def main(): tbl = { "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`") while True: cmd = GetCommand() if cmd: Log("cmd:", cmd) Sleep(1000)
    rust
    fn main() { let tbl = String::from(r#"{"type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": ["#) + r#"["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}],"# + r#"["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}]"# + r#"]}"#; LogStatus!(_D(None), "\n", format!("`{}`", tbl)); loop { if let Some(cmd) = GetCommand(0) { Log!("cmd:", cmd); } Sleep(1000); } }
    c++
    void main() { json tbl = R"({ "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] })"_json; LogStatus(_D(), "\n", "`" + tbl.dump() + "`"); while(true) { auto cmd = GetCommand(); if(cmd != "") { Log("cmd:", cmd); } Sleep(1000); } }
  • 支持分组按钮控件(旧版按钮结构),其功能与支持输入数据的状态栏按钮(通过"input"字段设置)一致,交互指令最终均由GetCommand()函数捕获。区别在于分组按钮通过"group"字段设置:当点击按钮触发交互时,页面弹出的对话框中会显示预先设置好的一组输入控件,可一次性输入一组数据。
    关于状态栏按钮控件和分组按钮控件结构中的"group"字段,需要注意以下几点:

    • group中type属性仅支持以下4种类型,defValue属性用于设置默认值。
      "selected":下拉框控件,设置下拉框中的各个选项时使用|符号分隔。
      "number":数值输入框控件。
      "string":字符串输入框控件。
      "boolean":勾选框控件,勾选表示(布尔值)真,不勾选表示(布尔值)假。
    • 交互输入时的控件支持依赖设置:
      例如以下例子中的"name": "tradePrice@orderType==1"设置,使交易价格tradePrice)输入控件仅在下单方式(orderType)下拉框控件选择为挂单时可用。
    • 交互输入时的控件名称支持双语设置。
      例如以下例子中的"description": "下单方式|order type"设置,使用|符号分隔中英文描述内容。
    • group中的namedescription与按钮结构中的namedescription虽然字段名一致,但定义并不相同。
      group中的name与input中的name定义也不相同。
    • 分组按钮控件触发后,发送的交互内容格式为:按钮的cmd字段值加group字段相关数据。例如以下例子测试时Log("cmd:", cmd)语句输出的内容为:
      cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true},即发生交互操作时GetCommand()函数返回的内容:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
    • 按钮控件的type属性仅支持"button"
      支持输入数据的按钮控件,即设置了input属性的控件,其input字段配置信息中的type属性支持多种控件类型。

    参考以下例子:

    javascript
    function main() { var tbl = { type: "table", title: "Group Button Control Demo", cols: ["Operation"], rows: [] } // 创建分组按钮控件结构 var groupBtn = { 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} ] } // 测试按钮1 var testBtn1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} var testBtn2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}} // 在tbl中添加groupBtn tbl.rows.push([groupBtn]) // 支持状态栏表格的一个单元格内设置多个按钮,即一个单元格内的数据为一个按钮结构数组:[testBtn1, testBtn2] tbl.rows.push([[testBtn1, testBtn2]]) while (true) { LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + JSON.stringify(groupBtn) + "`") var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) } Sleep(5000) } }
    python
    import json def main(): tbl = { "type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [] } groupBtn = { "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} ] } testBtn1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} testBtn2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}} tbl["rows"].append([groupBtn]) tbl["rows"].append([[testBtn1, testBtn2]]) while True: LogStatus("`" + json.dumps(tbl) + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + json.dumps(groupBtn) + "`") cmd = GetCommand() if cmd: Log("cmd:", cmd) Sleep(5000)
    rust
    fn main() { // 创建分组按钮控件结构 let group_btn = String::from(r#"{"type": "button", "cmd": "open", "name": "Open", "group": ["#) + r#"{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"},"# + r#"{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},"# + r#"{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},"# + r#"{"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true}"# + r#"]}"#; // 测试按钮1、测试按钮2 let test_btn1 = r#"{"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"}"#; let test_btn2 = r#"{"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}}"#; // 在tbl中添加groupBtn;支持状态栏表格的一个单元格内设置多个按钮,即一个单元格内的数据为一个按钮结构数组:[testBtn1, testBtn2] let tbl = format!( r#"{{"type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [[{}], [[{}, {}]]]}}"#, group_btn, test_btn1, test_btn2 ); loop { LogStatus!(format!("`{}`", tbl), "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", format!("`{}`", group_btn)); if let Some(cmd) = GetCommand(0) { Log!("cmd:", cmd); } Sleep(5000); } }
    c++
    void main() { json tbl = R"({ "type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [] })"_json; json groupBtn = R"({ "type": "button", "name": "Open", "cmd": "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; json testBtn1 = R"({"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"})"_json; json testBtn2 = R"({"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}})"_json; tbl["rows"].push_back({groupBtn}); tbl["rows"].push_back({{testBtn1, testBtn2}}); while(true) { LogStatus("`" + tbl.dump() + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + groupBtn.dump() + "`"); auto cmd = GetCommand(); if(cmd != "") { Log("cmd:", cmd); } Sleep(5000); } }
  • 当状态栏分组按钮控件(通过设置group字段实现)与状态栏按钮控件(通过设置input字段实现)被点击触发交互时(旧版按钮结构),页面弹出的对话框中的下拉框控件同样支持多选。以下示例演示如何设计包含多选选项的下拉框控件:

    javascript
    function main() { // 状态栏按钮控件(通过设置input字段实现)testBtn1按钮所触发的页面中,下拉框控件使用options字段设置选项,并使用defValue字段设置默认选项。区别于本章其它示例中直接使用defValue设置选项的方式。 var testBtn1 = { type: "button", name: "testBtn1", cmd: "cmdTestBtn1", input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1} } /* 状态栏按钮控件(通过设置input字段实现)testBtn2按钮所触发的页面中,下拉框控件使用options字段设置选项。options字段中的选项不仅支持字符串, 也支持使用```{text: "描述", value: "值"}```结构。使用defValue字段设置默认选项,默认选项支持多选(通过数组结构实现)。多选时需额外设置multiple字段为真值(true)。 */ var testBtn2 = { type: "button", name: "testBtn2", cmd: "cmdTestBtn2", input: { name: "testBtn2MultiComboBox", type: "selected", description: "Implement multi-select dropdown", options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}], defValue: ["A", "C"], multiple: true } } // 状态栏分组按钮控件(通过设置group字段实现)testBtn3按钮所触发的页面中,下拉框控件使用options字段设置选项,也支持直接使用defValue设置选项。 var testBtn3 = { type: "button", name: "testBtn3", cmd: "cmdTestBtn3", group: [ {name: "comboBox1", label: "labelComboBox1", description: "Dropdown 1", type: "selected", defValue: 1, options: ["A", "B"]}, {name: "comboBox2", label: "labelComboBox2", description: "下拉框2", type: "selected", defValue: "A|B"}, {name: "comboBox3", label: "labelComboBox3", description: "Dropdown 3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]}, { name: "comboBox4", label: "labelComboBox4", description: "Dropdown 4", type: "selected", defValue: ["A", "C"], multiple: true, options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}, {text: "Option D", value: "D"}] } ] } while (true) { LogStatus("`" + JSON.stringify(testBtn1) + "`\n", "`" + JSON.stringify(testBtn2) + "`\n", "`" + JSON.stringify(testBtn3) + "`\n") var cmd = GetCommand() if (cmd) { Log(cmd) } Sleep(5000) } }
    python
    import json def main(): testBtn1 = { "type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1} } testBtn2 = { "type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": { "name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown", "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}], "defValue": ["A", "C"], "multiple": True } } testBtn3 = { "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown 2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "Dropdown 4", "type": "selected", "defValue": ["A", "C"], "multiple": True, "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}] } ] } while True: LogStatus("`" + json.dumps(testBtn1) + "`\n", "`" + json.dumps(testBtn2) + "`\n", "`" + json.dumps(testBtn3) + "`\n") cmd = GetCommand() if cmd: Log(cmd) Sleep(5000)
    rust
    fn main() { // 状态栏按钮控件(通过设置input字段实现)testBtn1按钮所触发的页面中,下拉框控件使用options字段设置选项,并使用defValue字段设置默认选项。区别于本章其它示例中直接使用defValue设置选项的方式。 let test_btn1 = r#"{"type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}}"#; /* 状态栏按钮控件(通过设置input字段实现)testBtn2按钮所触发的页面中,下拉框控件使用options字段设置选项。options字段中的选项不仅支持字符串, 也支持使用{"text": "描述", "value": "值"}结构。使用defValue字段设置默认选项,默认选项支持多选(通过数组结构实现)。多选时需额外设置multiple字段为真值(true)。 */ let test_btn2 = String::from(r#"{"type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": {"#) + r#""name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown","# + r#""options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],"# + r#""defValue": ["A", "C"], "multiple": true}}"#; // 状态栏分组按钮控件(通过设置group字段实现)testBtn3按钮所触发的页面中,下拉框控件使用options字段设置选项,也支持直接使用defValue设置选项。 let test_btn3 = String::from(r#"{"type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": ["#) + r#"{"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},"# + r#"{"name": "comboBox2", "label": "labelComboBox2", "description": "下拉框2", "type": "selected", "defValue": "A|B"},"# + r#"{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]},"# + r#"{"name": "comboBox4", "label": "labelComboBox4", "description": "Dropdown 4", "type": "selected", "defValue": ["A", "C"], "multiple": true, "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}]}"# + r#"]}"#; loop { LogStatus!(format!("`{}`\n", test_btn1), format!("`{}`\n", test_btn2), format!("`{}`\n", test_btn3)); if let Some(cmd) = GetCommand(0) { Log!(cmd); } Sleep(5000); } }
    c++
    void main() { json testBtn1 = R"({ "type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1} })"_json; json testBtn2 = R"({ "type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": { "name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown", "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}], "defValue": ["A", "C"], "multiple": true } })"_json; json testBtn3 = R"({ "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown 2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "Dropdown 4", "type": "selected", "defValue": ["A", "C"], "multiple": true, "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}] } ] })"_json; while (true) { LogStatus("`" + testBtn1.dump() + "`\n", "`" + testBtn2.dump() + "`\n", "`" + testBtn3.dump() + "`\n"); auto cmd = GetCommand(); if (cmd != "") { Log(cmd); } Sleep(5000); } }
  • 基于当前最新的按钮结构,构造状态栏表格中的按钮;点击按钮触发交互时,弹出一个包含多个控件的弹窗。

    详细内容可参考:用户指南-状态栏中的交互控件

    javascript
    var symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"] function createBtn(tmp, group) { var btn = JSON.parse(JSON.stringify(tmp)) _.each(group, function(eleByGroup) { btn["group"].unshift(eleByGroup) }) return btn } function main() { var arrManager = [] _.each(symbols, function(symbol) { arrManager.push({ "symbol": symbol, }) }) // Btn var tmpBtnOpen = { "type": "button", "cmd": "open", "name": "Open Position", "group": [{ "type": "selected", "name": "tradeType", "label": "Order Type", "description": "Market order, Limit order", "default": 0, "group": "Trade Settings", "settings": { "options": ["Market Order", "Limit Order"], "required": true, } }, { "type": "selected", "name": "direction", "label": "Trade Direction", "description": "Buy, Sell", "default": "buy", "group": "Trade Settings", "settings": { "render": "segment", "required": true, "options": [{"name": "Buy", "value": "buy"}, {"name": "Sell", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": { "required": true, } }, { "type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": { "required": true, } }], } while (true) { var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []} _.each(arrManager, function(m) { var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Symbol", "default": m["symbol"], "settings": {"required": true}}]) tbl["rows"].push([m["symbol"], btnOpen]) }) var cmd = GetCommand() if (cmd) { Log("Received interaction:", cmd) // 解析交互消息: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111} // 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息 var arrCmd = cmd.split(":", 2) if (arrCmd[0] == "open") { var msg = JSON.parse(cmd.slice(5)) Log("Symbol:", msg["symbol"], ", Direction:", msg["direction"], ", Order type:", msg["tradeType"] == 0 ? "Market order" : "Limit order", msg["tradeType"] == 0 ? ", Price: Current market price" : ", Price:" + msg["price"], ", Amount:", msg["amount"]) } } LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`") Sleep(1000) } }
    python
    import json symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"] def createBtn(tmp, group): btn = json.loads(json.dumps(tmp)) for eleByGroup in group: btn["group"].insert(0, eleByGroup) return btn def main(): arrManager = [] for symbol in symbols: arrManager.append({"symbol": symbol}) # Btn tmpBtnOpen = { "type": "button", "cmd": "open", "name": "Open Position", "group": [{ "type": "selected", "name": "tradeType", "label": "Order Type", "description": "Market order, Limit order", "default": 0, "group": "Trade Settings", "settings": { "options": ["Market Order", "Limit Order"], "required": True, } }, { "type": "selected", "name": "direction", "label": "Trade Direction", "description": "Buy, Sell", "default": "buy", "group": "Trade Settings", "settings": { "render": "segment", "required": True, "options": [{"name": "Buy", "value": "buy"}, {"name": "Sell", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": { "required": True, } }, { "type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": { "required": True, } }], } while True: tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []} for m in arrManager: btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Symbol", "default": m["symbol"], "settings": {"required": True}}]) tbl["rows"].append([m["symbol"], btnOpen]) cmd = GetCommand() if cmd != "" and cmd != None: Log("Received interaction:", cmd) # 解析交互消息: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111} # 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息 arrCmd = cmd.split(":") if arrCmd[0] == "open": msg = json.loads(cmd[5:]) Log("Symbol:", msg["symbol"], ", Direction:", msg["direction"], ", Order type:", "Market order" if msg["tradeType"] == 0 else "Limit order", ", Price: Current market price" if msg["tradeType"] == 0 else ", Price:" + str(msg["price"]), ", Amount:", msg["amount"]) # 输出状态栏信息 LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`") Sleep(1000)
    rust
    fn main() { let symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]; // Btn:按钮模板,"group"的第一个元素为交易品种控件,__SYMBOL__为占位符,构造按钮时替换 let tmp_btn_open = String::from(r#"{"type": "button", "cmd": "open", "name": "Open Position", "group": ["#) + r#"{"type": "string", "name": "symbol", "label": "Symbol", "default": "__SYMBOL__", "settings": {"required": true}},"# + r#"{"type": "selected", "name": "tradeType", "label": "Order Type", "description": "Market order, Limit order", "default": 0, "group": "Trade Settings", "settings": {"options": ["Market Order", "Limit Order"], "required": true}},"# + r#"{"type": "selected", "name": "direction", "label": "Trade Direction", "description": "Buy, Sell", "default": "buy", "group": "Trade Settings", "settings": {"render": "segment", "required": true, "options": [{"name": "Buy", "value": "buy"}, {"name": "Sell", "value": "sell"}]}},"# + r#"{"type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": {"required": true}},"# + r#"{"type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": {"required": true}}"# + r#"]}"#; loop { let mut rows: Vec<String> = Vec::new(); for symbol in &symbols { let btn_open = tmp_btn_open.replace("__SYMBOL__", symbol); rows.push(format!(r#"["{}", {}]"#, symbol, btn_open)); } let tbl = format!(r#"{{"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": [{}]}}"#, rows.join(",")); if let Some(cmd) = GetCommand(0) { Log!("Received interaction:", &cmd); // 解析交互消息: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111} // 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息 if cmd.starts_with("open:") { let msg = JSONParse(&cmd[5..]).unwrap(); let trade_type = msg["tradeType"].as_i64().unwrap_or(0); Log!("Symbol:", msg["symbol"].as_str().unwrap_or(""), ", Direction:", msg["direction"].as_str().unwrap_or(""), ", Order type:", if trade_type == 0 { "Market order" } else { "Limit order" }, if trade_type == 0 { ", Price: Current market price".to_string() } else { format!(", Price:{}", msg["price"].as_f64().unwrap_or(0.0)) }, ", Amount:", msg["amount"].as_f64().unwrap_or(0.0)); } } LogStatus!(_D(None), "\n", format!("`{}`", tbl)); Sleep(1000); } }
    c++
    // 略...
  • 横向合并LogStatus()函数绘制的表格中的单元格:

    javascript
    function main() { var table = { type: 'table', title: 'Position Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close'}] ] } var ticker = exchange.GetTicker() // 添加一行数据,将第一个和第二个单元格合并,并在合并后的单元格内输出 ticker 变量 table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}] ] } ticker = exchange.GetTicker() table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"]) LogStatus("`" + json.dumps(table) + "`")
    rust
    fn main() { let table_tpl = String::from(r#"{"type": "table", "title": "Position Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}],"# + r#"__ROW2__"# + r#"]}"#; let ticker = exchange.GetTicker(None).unwrap(); let json_ticker = format!( r#"{{"Buy": {}, "Sell": {}, "High": {}, "Low": {}, "Volume": {}, "Last": {}, "Time": {}}}"#, ticker.Buy, ticker.Sell, ticker.High, ticker.Low, ticker.Volume, ticker.Last, ticker.Time ); // 添加一行数据,将第一个和第二个单元格合并,并在合并后的单元格内输出 ticker 数据 // body 为字符串(对应 JS 的 JSON.stringify(ticker)),内部引号需转义后嵌入 JSON let row2 = format!(r#"[{{"body": "{}", "colspan": 2}}, "abc"]"#, json_ticker.replace('"', "\\\"")); let table = table_tpl.replace("__ROW2__", &row2); LogStatus!(format!("`{}`", table)); }
    c++
    void main() { json table = R"({ "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}] ] })"_json; auto ticker = exchange.GetTicker(); json jsonTicker = R"({"Buy": 0, "Sell": 0, "High": 0, "Low": 0, "Volume": 0, "Last": 0, "Time": 0})"_json; jsonTicker["Buy"] = ticker.Buy; jsonTicker["Sell"] = ticker.Sell; jsonTicker["Last"] = ticker.Last; jsonTicker["Volume"] = ticker.Volume; jsonTicker["Time"] = ticker.Time; jsonTicker["High"] = ticker.High; jsonTicker["Low"] = ticker.Low; json arr = R"([{"body": {}, "colspan": 2}, "abc"])"_json; arr[0]["body"] = jsonTicker; table["rows"].push_back(arr); LogStatus("`" + table.dump() + "`"); }
  • 纵向合并 LogStatus() 函数绘制的表格中的单元格:

    javascript
    function main() { var table = { type: 'table', title: 'Table Demo', cols: ['Column A', 'Column B', 'Column C'], rows: [ ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}] ] } var ticker = exchange.GetTicker() var name = exchange.GetName() table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"]) table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"]) // A3 被上一行的第一个单元格合并 table.rows.push(["B4", "C4"]) // A2 被上一行的第一个单元格合并 table.rows.push(["B5", "C5"]) table.rows.push(["A6", "B6", "C6"]) LogStatus('`' + JSON.stringify(table) + '`') }
    python
    import json def main(): table = { "type" : "table", "title" : "Table Demo", "cols" : ["Column A", "Column B", "Column C"], "rows" : [ ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}] ] } ticker = exchange.GetTicker() name = exchange.GetName() table["rows"].append([{"body": "A2 + B2:" + json.dumps(ticker), "colspan": 2}, "C2"]) table["rows"].append([{"body": "A3 + A4 + A5:" + name, "rowspan": 3}, "B3", "C3"]) table["rows"].append(["B4", "C4"]) table["rows"].append(["B5", "C5"]) table["rows"].append(["A6", "B6", "C6"]) LogStatus("`" + json.dumps(table) + "`")
    rust
    fn main() { // 为便于测试,此处使用构造的数据以保持代码简短易读 let json_ticker = r#"{"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0}"#; let name = exchange.GetName(); let mut rows: Vec<String> = Vec::new(); rows.push(String::from(r#"["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]"#)); // body 为字符串,其内部的引号需要转义后才能嵌入 JSON let body = format!("A2 + B2:{}", json_ticker).replace('"', "\\\""); rows.push(format!(r#"[{{"body": "{}", "colspan": 2}}, "C2"]"#, body)); rows.push(format!(r#"[{{"body": "A3 + A4 + A5:{}", "rowspan": 3}}, "B3", "C3"]"#, name)); // A3 被上一行的第一个单元格合并 rows.push(String::from(r#"["B4", "C4"]"#)); // A2 被上一行的第一个单元格合并 rows.push(String::from(r#"["B5", "C5"]"#)); rows.push(String::from(r#"["A6", "B6", "C6"]"#)); let table = format!(r#"{{"type": "table", "title": "Table Demo", "cols": ["Column A", "Column B", "Column C"], "rows": [{}]}}"#, rows.join(",")); LogStatus!(format!("`{}`", table)); }
    c++
    void main() { json table = R"({ "type" : "table", "title" : "Table Demo", "cols" : ["Column A", "Column B", "Column C"], "rows" : [ ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}] ] })"_json; // 为便于测试,此处使用构造的数据以保持代码简短易读 json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json; auto name = exchange.GetName(); json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json; arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump(); json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json; arr2[0]["body"] = "A3 + A4 + A5:" + name; table["rows"].push_back(arr1); table["rows"].push_back(arr2); table["rows"].push_back(R"(["B4", "C4"])"_json); table["rows"].push_back(R"(["B5", "C5"])"_json); table["rows"].push_back(R"(["A6", "B6", "C6"])"_json); LogStatus("`" + table.dump() + "`"); }
  • 状态栏中分页显示表格:

    javascript
    function main() { var table1 = {type: 'table', title: 'table1', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} var table2 = {type: 'table', title: 'table2', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} LogStatus('`' + JSON.stringify([table1, table2]) + '`') }
    python
    import json def main(): table1 = {"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} table2 = {"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} LogStatus("`" + json.dumps([table1, table2]) + "`")
    rust
    fn main() { let table1 = r#"{"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; let table2 = r#"{"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; LogStatus!(format!("`[{},{}]`", table1, table2)); }
    c++
    void main() { json table1 = R"({"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; json table2 = R"({"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; json arr = R"([])"_json; arr.push_back(table1); arr.push_back(table2); LogStatus("`" + arr.dump() + "`"); }
  • 除了可以分页显示表格之外,还可以将多个表格自上而下排列显示:

    javascript
    function main(){ var tab1 = { type : "table", title : "Table 1", cols : ["1", "2"], rows : [] } var tab2 = { type : "table", title : "Table 2", cols : ["1", "2", "3"], rows : [] } var tab3 = { type : "table", title : "Table 3", cols : ["A", "B", "C"], rows : [] } tab1.rows.push(["jack", "lucy"]) tab2.rows.push(["A", "B", "C"]) tab3.rows.push(["A", "B", "C"]) LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n' + '`' + JSON.stringify(tab3) + '`') Log("exit") }
    python
    import json def main(): tab1 = { "type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [] } tab2 = { "type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [] } tab3 = { "type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [] } tab1["rows"].append(["jack", "lucy"]) tab2["rows"].append(["A", "B", "C"]) tab3["rows"].append(["A", "B", "C"]) LogStatus("`" + json.dumps(tab1) + "`\n" + "`" + json.dumps(tab2) + "`\n" + "`" + json.dumps(tab3) + "`")
    rust
    fn main() { // Rust 中直接把行数据写入JSON字符串中 let tab1 = r#"{"type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [["jack", "lucy"]]}"#; let tab2 = r#"{"type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [["A", "B", "C"]]}"#; let tab3 = r#"{"type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [["A", "B", "C"]]}"#; LogStatus!(format!("`{}`\n`{}`\n`{}`", tab1, tab2, tab3)); Log!("exit"); }
    c++
    void main() { json tab1 = R"({ "type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [] })"_json; json tab2 = R"({ "type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [] })"_json; json tab3 = R"({ "type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [] })"_json; tab1["rows"].push_back(R"(["jack", "lucy"])"_json); tab2["rows"].push_back(R"(["A", "B", "C"])"_json); tab3["rows"].push_back(R"(["A", "B", "C"])"_json); LogStatus("`" + tab1.dump() + "`\n" + "`" + tab2.dump() + "`\n" + "`" + tab3.dump() + "`"); }
  • 支持设置状态栏表格的横向和纵向滚动模式。将scroll属性设置为"auto"后,当状态栏表格的纵向行数超过 20 行时,内容将自动滚动显示;当横向列数超出页面显示范围时,则进行横向滚动显示。使用scroll属性可以缓解实盘运行时因状态栏写入大量数据而导致的卡顿问题。

    参考以下测试例子:

    javascript
    function main() { var tbl = { type : "table", title : "test scroll", scroll : "auto", cols : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], rows : [] } for (var i = 1 ; i < 100 ; i++) { tbl.rows.push([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i]) } LogStatus("`" + JSON.stringify(tbl) + "`") }
    python
    import json def main(): tbl = { "type" : "table", "title" : "test scroll", "scroll" : "auto", "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], "rows" : [] } for index in range(1, 100): i = str(index) tbl["rows"].append([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i]) LogStatus("`" + json.dumps(tbl) + "`")
    rust
    fn main() { let tbl_tpl = String::from(r#"{"type": "table", "title": "test scroll", "scroll": "auto", "cols": ["#) + r#""col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10","# + r#""col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20""# + r#"], "rows": [__ROWS__]}"#; let mut rows: Vec<String> = Vec::new(); for index in 1..100 { let i = index.to_string(); rows.push(format!( r#"[{}, "1,{}", "2,{}", "3,{}", "4,{}", "5,{}", "6,{}", "7,{}", "8,{}", "9,{}", "10,{}", "11,{}", "12,{}", "13,{}", "14,{}", "15,{}", "16,{}", "17,{}", "18,{}", "19,{}", "20,{}"]"#, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i )); } let tbl = tbl_tpl.replace("__ROWS__", &rows.join(",")); LogStatus!(format!("`{}`", tbl)); }
    c++
    void main() { json table = R"({ "type" : "table", "title" : "test scroll", "scroll" : "auto", "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], "rows" : [] })"_json; for (int index = 1; index < 100; ++index) { std::string i = std::to_string(index); table["rows"].push_back({i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i}); } LogStatus("`" + table.dump() + "`"); }

参数

名称类型必填描述

msg

string / number / bool / object / array / any (平台支持的任意类型)

参数msg为要输出的内容,可传入多个msg参数。

参考

备注

实盘运行时,LogStatus()函数输出的信息不会保存到实盘数据库,仅更新当前实盘的状态栏内容。

LogStatus()函数支持打印base64编码后的图片,图片字符串以`开头,以`结尾。例如: LogStatus("`data:image/png;base64,AAAA`")

LogStatus()函数支持直接传入Pythonmatplotlib.pyplot对象。只要对象包含savefig方法,即可作为参数传入LogStatus()函数,例如:

python
import matplotlib.pyplot as plt def main(): plt.plot([3,6,2,4,7,1]) LogStatus(plt)

策略实盘运行时,在实盘页面翻看历史记录时,状态栏会进入休眠状态,停止更新;只有当日志处于第一页时,状态栏数据才会刷新。状态栏支持输出base64编码后的图片,也支持在状态栏显示的表格中输出base64编码后的图片。由于编码后的图片字符串数据通常很长,因此此处不再展示示例代码。

启用或禁用订单信息的日志记录。

EnableLog(enable)

示例

javascript
function main() { EnableLog(false) }
python
def main(): EnableLog(False)
rust
fn main() { EnableLog(false); }
c++
void main() { EnableLog(false); }

参数

名称类型必填描述

enable

bool

enable参数设置为假值(例如false)时,将不打印订单日志(即exchange.Buy()等函数产生的日志),也不会写入实盘的数据库。

参考

自定义图表绘图函数。

Chart(options)

示例

  • 多图表绘制配置说明:

    • extension.layout 属性
      当此属性设置为 "single" 时,该图表不会与其他图表叠加显示(即不以分页标签方式呈现),而是单独平铺显示。
    • extension.height 属性
      此属性用于设置图表的高度,取值可以为数值类型,也可以采用 "300px" 的形式设置。
    • extension.col 属性
      此属性用于设置图表的宽度。页面宽度共划分为 12 个单元,设置为 8 即表示该图表占用 8 个单元的宽度。
    javascript
    function main() { var cfgA = { extension: { layout: 'single', // 不参与分组,单独显示,默认为分组 'group' height: 300, // 指定高度 }, title: { text: 'Order Book Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Bid 1', data: [], }, { name: 'Ask 1', data: [], }] } var cfgB = { title: { text: 'Spread Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Spread', type: 'column', data: [], }] } var cfgC = { __isStock: false, title: { text: 'Pie Chart' }, series: [{ type: 'pie', name: 'one', data: [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] // 指定初始数据后无需使用 add 函数更新,直接修改图表配置即可更新数据序列。 }] }; var cfgD = { extension: { layout: 'single', col: 8, // 指定宽度所占的单元数,总单元数为 12 height: '300px', }, title: { text: 'Order Book Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Bid 1', data: [], }, { name: 'Ask 1', data: [], }] } var cfgE = { __isStock: false, extension: { layout: 'single', col: 4, height: '300px', }, title: { text: 'Pie Chart 2' }, series: [{ type: 'pie', name: 'one', data: [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] }] }; var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]); chart.reset() // 为饼图追加一个数据点,add 只能更新通过 add 方式添加的数据点,内置的数据点无法在后期更新 chart.add(3, { name: "ZZ", y: Math.random() * 100 }); while (true) { Sleep(1000) var ticker = exchange.GetTicker() if (!ticker) { continue; } var diff = ticker.Sell - ticker.Buy cfgA.subtitle = { text: 'Bid ' + ticker.Buy + ', Ask ' + ticker.Sell, }; cfgB.subtitle = { text: 'Spread ' + diff, }; chart.add([0, [new Date().getTime(), ticker.Buy]]); chart.add([1, [new Date().getTime(), ticker.Sell]]); // 相当于更新第二个图表的第一个数据序列 chart.add([2, [new Date().getTime(), diff]]); chart.add(4, [new Date().getTime(), ticker.Buy]); chart.add(5, [new Date().getTime(), ticker.Buy]); cfgC.series[0].data[0][1] = Math.random() * 100; cfgE.series[0].data[0][1] = Math.random() * 100; // update 实际上等同于重置图表的配置 chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]); } }
    python
    import random import time def main(): cfgA = { "extension" : { "layout" : "single", "height" : 300, "col" : 8 }, "title" : { "text" : "Order Book Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] } cfgB = { "title" : { "text" : "Spread Chart" }, "xAxis" : { "type" : "datetime", }, "series" : [{ "name" : "Spread", "type" : "column", "data" : [] }] } cfgC = { "__isStock" : False, "title" : { "text" : "Pie Chart" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] }] } cfgD = { "extension" : { "layout" : "single", "col" : 8, "height" : "300px" }, "title" : { "text" : "Order Book Chart" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] } cfgE = { "__isStock" : False, "extension" : { "layout" : "single", "col" : 4, "height" : "300px" }, "title" : { "text" : "Pie Chart 2" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] } chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]) chart.reset() chart.add(3, { "name" : "ZZ", "y" : random.random() * 100 }) while True: Sleep(1000) ticker = exchange.GetTicker() if not ticker : continue diff = ticker["Sell"] - ticker["Buy"] cfgA["subtitle"] = { "text" : "Bid " + str(ticker["Buy"]) + " Ask " + str(ticker["Sell"]) } cfgB["subtitle"] = { "text" : "Spread " + str(diff) } chart.add(0, [time.time() * 1000, ticker["Buy"]]) chart.add(1, [time.time() * 1000, ticker["Sell"]]) chart.add(2, [time.time() * 1000, diff]) chart.add(4, [time.time() * 1000, ticker["Buy"]]) chart.add(5, [time.time() * 1000, ticker["Buy"]]) cfgC["series"][0]["data"][0][1] = random.random() * 100 cfgE["series"][0]["data"][0][1] = random.random() * 100
    rust
    fn main() { // Rust 中图表配置为 JSON 字符串,可变部分使用占位符表示,更新时替换占位符以重新构建配置 let cfg_a_tpl = r#"{ "extension": { "layout": "single", "height": 300 }, "title": {"text": "Order Book Chart"}, "subtitle": {"text": "__SUBTITLE__"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Bid 1", "data": []}, {"name": "Ask 1", "data": []}] }"#; let cfg_b_tpl = r#"{ "title": {"text": "Spread Chart"}, "subtitle": {"text": "__SUBTITLE__"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Spread", "type": "column", "data": []}] }"#; let cfg_c_tpl = r#"{ "__isStock": false, "title": {"text": "Pie Chart"}, "series": [{ "type": "pie", "name": "one", "data": [["A", __Y__], ["B", 25], ["C", 25], ["D", 25]] }] }"#; let cfg_d = r#"{ "extension": { "layout": "single", "col": 8, "height": "300px" }, "title": {"text": "Order Book Chart"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Bid 1", "data": []}, {"name": "Ask 1", "data": []}] }"#; let cfg_e_tpl = r#"{ "__isStock": false, "extension": { "layout": "single", "col": 4, "height": "300px" }, "title": {"text": "Pie Chart 2"}, "series": [{ "type": "pie", "name": "one", "data": [["A", __Y__], ["B", 25], ["C", 25], ["D", 25]] }] }"#; let cfg_a = cfg_a_tpl.replace("__SUBTITLE__", ""); let cfg_b = cfg_b_tpl.replace("__SUBTITLE__", ""); let cfg_c = cfg_c_tpl.replace("__Y__", "25"); let cfg_e = cfg_e_tpl.replace("__Y__", "25"); let chart = Chart::new(&format!("[{},{},{},{},{}]", cfg_a, cfg_b, cfg_c, cfg_d, cfg_e)); chart.reset(0); // 为饼图追加一个数据点,add 只能更新通过 add 方式添加的数据点,内置的数据点无法在后期更新 let y = (UnixNano() % 100) as f64; // 用时间戳模拟随机数 chart.add(3, &format!(r#"{{"name": "ZZ", "y": {}}}"#, y), -1); loop { Sleep(1000); let ticker = match exchange.GetTicker(None) { Ok(t) => t, Err(_) => continue, }; let diff = ticker.Sell - ticker.Buy; let cfg_a = cfg_a_tpl.replace("__SUBTITLE__", &format!("Bid {}, Ask {}", ticker.Buy, ticker.Sell)); let cfg_b = cfg_b_tpl.replace("__SUBTITLE__", &format!("Spread {}", diff)); let now = Unix() * 1000; chart.add(0, &format!("[{}, {}]", now, ticker.Buy), -1); chart.add(1, &format!("[{}, {}]", now, ticker.Sell), -1); // 相当于更新第二个图表的第一个数据序列 chart.add(2, &format!("[{}, {}]", now, diff), -1); chart.add(4, &format!("[{}, {}]", now, ticker.Buy), -1); chart.add(5, &format!("[{}, {}]", now, ticker.Buy), -1); let cfg_c = cfg_c_tpl.replace("__Y__", &format!("{}", (UnixNano() % 100) as f64)); let cfg_e = cfg_e_tpl.replace("__Y__", &format!("{}", (UnixNano() % 100) as f64)); // update 实际上等同于重置图表的配置 chart.update(&format!("[{},{},{},{},{}]", cfg_a, cfg_b, cfg_c, cfg_d, cfg_e)); } }
    c++
    void main() { json cfgA = R"({ "extension" : { "layout" : "single", "height" : 300, "col" : 8 }, "title" : { "text" : "Order Book Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] })"_json; json cfgB = R"({ "title" : { "text" : "Spread Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Spread", "type" : "column", "data" : [] }] })"_json; json cfgC = R"({ "__isStock" : false, "title" : { "text" : "Pie Chart" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] })"_json; json cfgD = R"({ "extension" : { "layout" : "single", "col" : 8, "height" : "300px" }, "title" : { "text" : "Order Book Chart" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] })"_json; json cfgE = R"({ "__isStock" : false, "extension" : { "layout" : "single", "col" : 4, "height" : "300px" }, "title" : { "text" : "Pie Chart 2" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] })"_json; auto chart = Chart({cfgA, cfgB, cfgC, cfgD, cfgE}); chart.reset(); json zz = R"({ "name" : "ZZ", "y" : 0 })"_json; zz["y"] = rand() % 100; chart.add(3, zz); while(true) { Sleep(1000); auto ticker = exchange.GetTicker(); if(!ticker.Valid) { continue; } auto diff = ticker.Sell - ticker.Buy; json cfgASubTitle = R"({"text" : ""})"_json; cfgASubTitle["text"] = str_format("买一 %f , 卖一 %f", ticker.Buy, ticker.Sell); cfgA["subtitle"] = cfgASubTitle; json cfgBSubTitle = R"({"text" : ""})"_json; cfgBSubTitle["text"] = str_format("价差 %f", diff); cfgB["subtitle"] = cfgBSubTitle; chart.add(0, {Unix() * 1000, ticker.Buy}); chart.add(1, {Unix() * 1000, ticker.Sell}); chart.add(2, {Unix() * 1000, diff}); chart.add(4, {Unix() * 1000, ticker.Buy}); chart.add(5, {Unix() * 1000, ticker.Buy}); cfgC["series"][0]["data"][0][1] = rand() % 100; cfgE["series"][0]["data"][0][1] = rand() % 100; chart.update({cfgA, cfgB, cfgC, cfgD, cfgE}); } }
  • 简单的绘图示例:

    javascript
    // 在 JavaScript 中,chart 是一个对象;在调用 Chart 函数之前,我们需要先声明一个用于配置图表的对象变量 chart var chart = { // 该字段用于标记图表是否为普通图表,感兴趣的读者可以改为 false 运行查看效果 __isStock: true, // 提示框 tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // 标题 title : { text : '差价分析图'}, // 选择范围 rangeSelector: { buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}], selected: 0, inputEnabled: false }, // 横轴(即 x 轴),当前设置的类型为:时间 xAxis: { type: 'datetime'}, // 纵轴(即 y 轴),默认数值随数据大小自动调整 yAxis : { // 标题 title: {text: '差价'}, // 是否启用右侧纵轴 opposite: false }, // 数据系列,该属性保存各个数据系列(折线、K 线图、标签等……) series : [ // 索引为 0,data 数组中存放的是该索引系列的数据 {name : "line1", id : "Line 1,buy1Price", data : []}, // 索引为 1,设置了 dashStyle: 'shortdash',即将其设置为虚线 {name : "line2", id : "Line 2,lastPrice", dashStyle : 'shortdash', data : []} ] } function main(){ // 调用 Chart 函数,初始化图表 var ObjChart = Chart(chart) // 清空 ObjChart.reset() while(true){ // 获取本次轮询的时间戳(即毫秒级时间戳),用于确定写入图表的 X 轴位置 var nowTime = new Date().getTime() // 获取行情数据 var ticker = _C(exchange.GetTicker) // 从行情数据的返回值中取得买一价 var buy1Price = ticker.Buy // 取得最新成交价,为避免两条线相互重合,此处将其加 1 var lastPrice = ticker.Last + 1 // 以时间戳作为 X 值、买一价作为 Y 值,传入索引 0 的数据序列 ObjChart.add(0, [nowTime, buy1Price]) // 同上 ObjChart.add(1, [nowTime, lastPrice]) Sleep(2000) } }
    python
    import time chart = { "__isStock" : True, "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"}, "title" : {"text" : "Spread Analysis Chart"}, "rangeSelector" : { "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], "selected": 0, "inputEnabled": False }, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "Spread"}, "opposite": False }, "series": [{ "name": "line1", "id": "Line 1,buy1Price", "data": [] }, { "name": "line2", "id": "Line 2,lastPrice", "dashStyle": "shortdash", "data": [] }] } def main(): ObjChart = Chart(chart) ObjChart.reset() while True: nowTime = time.time() * 1000 ticker = exchange.GetTicker() buy1Price = ticker["Buy"] lastPrice = ticker["Last"] + 1 ObjChart.add(0, [nowTime, buy1Price]) ObjChart.add(1, [nowTime, lastPrice]) Sleep(2000)
    rust
    fn main() { // 在 Rust 中,图表配置为 JSON 字符串;在调用 Chart::new 函数之前,先定义图表配置 let chart = r#"{ "__isStock": true, "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"}, "title": {"text": "差价分析图"}, "rangeSelector": { "buttons": [{"type": "hour", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], "selected": 0, "inputEnabled": false }, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "差价"}, "opposite": false }, "series": [ {"name": "line1", "id": "Line 1,buy1Price", "data": []}, {"name": "line2", "id": "Line 2,lastPrice", "dashStyle": "shortdash", "data": []} ] }"#; // 调用 Chart::new 函数,初始化图表 let obj_chart = Chart::new(chart); // 清空 obj_chart.reset(0); loop { // 获取本次轮询的时间戳(即毫秒级时间戳),用于确定写入图表的 X 轴位置 let now_time = Unix() * 1000; // 获取行情数据 let ticker = _C!(exchange.GetTicker(None)); // 从行情数据的返回值中取得买一价 let buy1_price = ticker.Buy; // 取得最新成交价,为避免两条线相互重合,此处将其加 1 let last_price = ticker.Last + 1.0; // 以时间戳作为 X 值、买一价作为 Y 值,传入索引 0 的数据序列 obj_chart.add(0, &format!("[{}, {}]", now_time, buy1_price), -1); // 同上 obj_chart.add(1, &format!("[{}, {}]", now_time, last_price), -1); Sleep(2000); } }
    c++
    void main() { // 使用 C++ 编写策略时,尽量不要声明非基础类型的全局变量,因此将图表配置对象声明在 main 函数内 json chart = R"({ "__isStock" : true, "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"}, "title" : {"text" : "Spread Analysis Chart"}, "rangeSelector" : { "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], "selected": 0, "inputEnabled": false }, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "Spread"}, "opposite": false }, "series": [{ "name": "line1", "id": "Line 1,buy1Price", "data": [] }, { "name": "line2", "id": "Line 2,lastPrice", "dashStyle": "shortdash", "data": [] }] })"_json; auto ObjChart = Chart(chart); ObjChart.reset(); while(true) { auto nowTime = Unix() * 1000; auto ticker = exchange.GetTicker(); auto buy1Price = ticker.Buy; auto lastPrice = ticker.Last + 1.0; ObjChart.add(0, {nowTime, buy1Price}); ObjChart.add(1, {nowTime, lastPrice}); Sleep(2000); } }
  • 绘制三角函数曲线的示例:

    javascript
    // 用于初始化图表的配置对象 var chart = { // 图表标题 title: {text: "Line value triggers plotLines value"}, // Y 轴相关设置 yAxis: { // 垂直于 Y 轴的水平线,用作触发线;这是一个结构体数组,可设置多条触发线 plotLines: [{ // 触发线的值,该线将显示在对应的数值位置 value: 0, // 设置触发线的颜色 color: 'red', // 线宽 width: 2, // 显示的标签 label: { // 标签文本 text: 'Trigger Value', // 标签居中对齐 align: 'center' } }] }, // X 轴相关设置,此处将类型设置为时间轴 xAxis: {type: "datetime"}, series: [ {name: "sin", type: "spline", data: []}, // 数据系列,可设置多个,并通过数组索引进行控制 {name: "cos", type: "spline", data: []} ] } function main(){ // 圆周率 var pi = 3.1415926535897 // 用于记录时间戳的变量 var time = 0 // 角度 var angle = 0 // 坐标 y 值,用于接收正弦值或余弦值 var y = 0 // 调用 API 接口,使用 chart 对象初始化图表 var objChart = Chart(chart) // 初始化时清空图表 objChart.reset() // 将触发线的值设置为 1 chart.yAxis.plotLines[0].value = 1 // 循环 while(true){ // 获取当前时刻的时间戳 time = new Date().getTime() // 每 500ms 将角度 angle 增加 5 度,并计算正弦值 y = Math.sin(angle * 2 * pi / 360) // 将计算得到的 y 值写入图表对应索引的数据系列,add 函数的第一个参数为指定的数据系列索引 objChart.add(0, [time, y]) // 计算余弦值 y = Math.cos(angle * 2 * pi / 360) objChart.add(1, [time, y]) // 增加 5 度 angle += 5 // 暂停 5 秒,避免绘图过于频繁、数据增长过快 Sleep(5000) } }
    python
    import math import time chart = { "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 0, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] } def main(): pi = 3.1415926535897 ts = 0 angle = 0 y = 0 objChart = Chart(chart) objChart.reset() chart["yAxis"]["plotLines"][0]["value"] = 1 while True: ts = time.time() * 1000 y = math.sin(angle * 2 * pi / 360) objChart.add(0, [ts, y]) y = math.cos(angle * 2 * pi / 360) objChart.add(1, [ts, y]) angle += 5 Sleep(5000)
    rust
    fn main() { // 用于初始化图表的 JSON 配置字符串,触发线的值在配置中直接设置为 1 let chart = r#"{ "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 1, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] }"#; // 圆周率 let pi = 3.1415926535897_f64; // 角度 let mut angle = 0.0_f64; // 调用 API 接口,使用 chart 配置初始化图表 let obj_chart = Chart::new(chart); // 初始化时清空图表 obj_chart.reset(0); // 循环 loop { // 获取当前时刻的毫秒时间戳 let ts = Unix() * 1000; // 将角度 angle 增加 5 度,并计算正弦值 let mut y = (angle * 2.0 * pi / 360.0).sin(); // 将计算得到的 y 值写入图表对应索引的数据系列,add 函数的第一个参数为指定的数据系列索引 obj_chart.add(0, &format!("[{}, {}]", ts, y), -1); // 计算余弦值 y = (angle * 2.0 * pi / 360.0).cos(); obj_chart.add(1, &format!("[{}, {}]", ts, y), -1); // 增加 5 度 angle += 5.0; // 暂停 5 秒,避免绘图过于频繁、数据增长过快 Sleep(5000); } }
    c++
    void main() { json chart = R"({ "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 0, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] })"_json; auto pi = 3.1415926535897; auto ts = 0; auto angle = 0.0; auto y = 0.0; auto objChart = Chart(chart); objChart.reset(); chart["yAxis"]["plotLines"][0]["value"] = 1; while(true) { ts = Unix() * 1000; y = sin(angle * 2 * pi / 360); objChart.add(0, {ts, y}); y = cos(angle * 2 * pi / 360); objChart.add(1, {ts, y}); angle += 5; Sleep(5000); } }
  • 使用混合图表的复杂示例:

    javascript
    /*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ var chartCfg = { subtitle: { text: "subtitle", }, yAxis: [{ height: "40%", lineWidth: 2, title: { text: 'PnL', }, tickPixelInterval: 20, minorGridLineWidth: 1, minorTickWidth: 0, opposite: true, labels: { align: "right", x: -3, } }, { title: { text: 'Profit', }, top: "42%", height: "18%", offset: 0, lineWidth: 2 }, { title: { text: 'Vol', }, top: '62%', height: '18%', offset: 0, lineWidth: 2 }, { title: { text: 'Asset', }, top: '82%', height: '18%', offset: 0, lineWidth: 2 }], series: [{ name: 'PnL', data: [], id: 'primary', tooltip: { xDateFormat: '%Y-%m-%d %H:%M:%S' }, yAxis: 0 }, { type: 'column', lineWidth: 2, name: 'Profit', data: [], yAxis: 1, }, { type: 'column', name: 'Trade', data: [], yAxis: 2 }, { type: 'area', step: true, lineWidth: 0, name: 'Long', data: [], yAxis: 2 }, { type: 'area', step: true, lineWidth: 0, name: 'Short', data: [], yAxis: 2 }, { type: 'line', step: true, color: '#5b4b00', name: 'Asset', data: [], yAxis: 3 }, { type: 'pie', innerSize: '70%', name: 'Random', data: [], center: ['3%', '6%'], size: '15%', dataLabels: { enabled: false }, startAngle: -90, endAngle: 90, }], }; function main() { let c = Chart(chartCfg); let preTicker = null; while (true) { let t = exchange.GetTicker(); c.add(0, [t.Time, t.Last]); // PnL c.add(1, [t.Time, preTicker ? t.Last - preTicker.Last : 0]); // profit let r = Math.random(); var pos = parseInt(t.Time/86400); c.add(2, [t.Time, pos/2]); // Vol c.add(3, [t.Time, r > 0.8 ? pos : null]); // Long c.add(4, [t.Time, r < 0.8 ? -pos : null]); // Short c.add(5, [t.Time, Math.random() * 100]); // Asset // update pie chartCfg.series[chartCfg.series.length-1].data = [ ["A", Math.random()*100], ["B", Math.random()*100], ]; c.update(chartCfg) preTicker = t; } }
    python
    '''backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' import random chartCfg = { "subtitle": { "text": "subtitle" }, "yAxis": [{ "height": "40%", "lineWidth": 2, "title": { "text": 'PnL' }, "tickPixelInterval": 20, "minorGridLineWidth": 1, "minorTickWidth": 0, "opposite": True, "labels": { "align": "right", "x": -3 } }, { "title": { "text": 'Profit' }, "top": "42%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": 'Vol' }, "top": '62%', "height": '18%', "offset": 0, "lineWidth": 2 }, { "title": { "text": 'Asset' }, "top": '82%', "height": '18%', "offset": 0, "lineWidth": 2 }], "series": [{ "name": 'PnL', "data": [], "id": 'primary', "tooltip": { "xDateFormat": '%Y-%m-%d %H:%M:%S' }, "yAxis": 0 }, { "type": 'column', "lineWidth": 2, "name": 'Profit', "data": [], "yAxis": 1 }, { "type": 'column', "name": 'Trade', "data": [], "yAxis": 2 }, { "type": 'area', "step": True, "lineWidth": 0, "name": 'Long', "data": [], "yAxis": 2 }, { "type": 'area', "step": True, "lineWidth": 0, "name": 'Short', "data": [], "yAxis": 2 }, { "type": 'line', "step": True, "color": '#5b4b00', "name": 'Asset', "data": [], "yAxis": 3 }, { "type": 'pie', "innerSize": '70%', "name": 'Random', "data": [], "center": ['3%', '6%'], "size": '15%', "dataLabels": { "enabled": False }, "startAngle": -90, "endAngle": 90 }] } def main(): c = Chart(chartCfg) preTicker = None while True: t = exchange.GetTicker() c.add(0, [t["Time"], t["Last"]]) profit = t["Last"] - preTicker["Last"] if preTicker else 0 c.add(1, [t["Time"], profit]) r = random.random() pos = t["Time"] / 86400 c.add(2, [t["Time"], pos / 2]) long = pos if r > 0.8 else None c.add(3, [t["Time"], long]) short = -pos if r < 0.8 else None c.add(4, [t["Time"], short]) c.add(5, [t["Time"], random.random() * 100]) # update pie chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [ ["A", random.random() * 100], ["B", random.random() * 100] ] c.update(chartCfg) preTicker = t
    rust
    /*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ fn main() { // 在 Rust 中,图表配置以 JSON 字符串形式表示;饼图数据使用占位符 __PIE_DATA__ 标记,更新时替换该占位符后重建配置 let chart_cfg_tpl = r##"{ "subtitle": {"text": "subtitle"}, "yAxis": [{ "height": "40%", "lineWidth": 2, "title": {"text": "PnL"}, "tickPixelInterval": 20, "minorGridLineWidth": 1, "minorTickWidth": 0, "opposite": true, "labels": {"align": "right", "x": -3} }, { "title": {"text": "Profit"}, "top": "42%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": {"text": "Vol"}, "top": "62%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": {"text": "Asset"}, "top": "82%", "height": "18%", "offset": 0, "lineWidth": 2 }], "series": [{ "name": "PnL", "data": [], "id": "primary", "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S"}, "yAxis": 0 }, { "type": "column", "lineWidth": 2, "name": "Profit", "data": [], "yAxis": 1 }, { "type": "column", "name": "Trade", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Long", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Short", "data": [], "yAxis": 2 }, { "type": "line", "step": true, "color": "#5b4b00", "name": "Asset", "data": [], "yAxis": 3 }, { "type": "pie", "innerSize": "70%", "name": "Random", "data": __PIE_DATA__, "center": ["3%", "6%"], "size": "15%", "dataLabels": {"enabled": false}, "startAngle": -90, "endAngle": 90 }] }"##; let c = Chart::new(&chart_cfg_tpl.replace("__PIE_DATA__", "[]")); let mut pre_ticker: Option<Ticker> = None; loop { let t = exchange.GetTicker(None).unwrap(); c.add(0, &format!("[{}, {}]", t.Time, t.Last), -1); // PnL let profit = if let Some(p) = &pre_ticker { t.Last - p.Last } else { 0.0 }; c.add(1, &format!("[{}, {}]", t.Time, profit), -1); // profit let r = (UnixNano() % 100) as f64 / 100.0; // 使用时间戳模拟随机数 let pos = (t.Time / 86400) as f64; c.add(2, &format!("[{}, {}]", t.Time, pos / 2.0), -1); // Vol c.add(3, &format!("[{}, {}]", t.Time, if r > 0.8 { pos.to_string() } else { "null".to_string() }), -1); // Long c.add(4, &format!("[{}, {}]", t.Time, if r < 0.8 { (-pos).to_string() } else { "null".to_string() }), -1); // Short c.add(5, &format!("[{}, {}]", t.Time, (UnixNano() % 10000) as f64 / 100.0), -1); // Asset // update pie let pie = format!(r#"[["A", {}], ["B", {}]]"#, (UnixNano() % 100) as f64, (UnixNano() % 100) as f64); c.update(&chart_cfg_tpl.replace("__PIE_DATA__", &pie)); pre_ticker = Some(t); } }
    c++
    /*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { json chartCfg = R"({ "subtitle": { "text": "subtitle" }, "yAxis": [{ "height": "40%", "lineWidth": 2, "title": { "text": "PnL" }, "tickPixelInterval": 20, "minorGridLineWidth": 1, "minorTickWidth": 0, "opposite": true, "labels": { "align": "right", "x": -3 } }, { "title": { "text": "Profit" }, "top": "42%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": "Vol" }, "top": "62%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": "Asset" }, "top": "82%", "height": "18%", "offset": 0, "lineWidth": 2 }], "series": [{ "name": "PnL", "data": [], "id": "primary", "tooltip": { "xDateFormat": "%Y-%m-%d %H:%M:%S" }, "yAxis": 0 }, { "type": "column", "lineWidth": 2, "name": "Profit", "data": [], "yAxis": 1 }, { "type": "column", "name": "Trade", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Long", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Short", "data": [], "yAxis": 2 }, { "type": "line", "step": true, "color": "#5b4b00", "name": "Asset", "data": [], "yAxis": 3 }, { "type": "pie", "innerSize": "70%", "name": "Random", "data": [], "center": ["3%", "6%"], "size": "15%", "dataLabels": { "enabled": false }, "startAngle": -90, "endAngle": 90 }] })"_json; Chart c = Chart(chartCfg); Ticker preTicker; while(true) { auto t = exchange.GetTicker(); c.add(0, {t.Time, t.Last}); auto profit = preTicker.Valid ? t.Last - preTicker.Last : 0; c.add(1, {t.Time, profit}); auto r = rand() % 100; auto pos = t.Time / 86400.0; c.add(2, {t.Time, pos / 2.0}); auto longPos = r > 0.8 ? pos : NULL; c.add(3, {t.Time, longPos}); auto shortPos = r < 0.8 ? -pos : NULL; c.add(4, {t.Time, shortPos}); c.add(5, {t.Time, rand() % 100}); // update pie json pie = R"([["A", 0], ["B", 0]])"_json; pie[0][1] = rand() % 100; pie[1][1] = rand() % 100; chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie; c.update(chartCfg); preTicker = t; } }
  • 图表中pie类型的图表没有时间轴,因此在更新数据时需要直接更新图表配置。例如,在上述范例的代码中,更新数据后调用c.update(chartCfg)即可刷新图表,如下所示:

    javascript
    // update pie chartCfg.series[chartCfg.series.length-1].data = [ ["A", Math.random()*100], ["B", Math.random()*100], ]; c.update(chartCfg)
    python
    # update pie chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [ ["A", random.random() * 100], ["B", random.random() * 100] ] c.update(chartCfg)
    rust
    // update pie // Rust 中图表配置为 JSON 字符串,重建包含新数据的配置后调用 update 更新图表 let pie = format!(r#"[["A", {}], ["B", {}]]"#, (UnixNano() % 100) as f64, (UnixNano() % 100) as f64); c.update(&chart_cfg_tpl.replace("__PIE_DATA__", &pie));
    c++
    // update pie json pie = R"([["A", 0], ["B", 0]])"_json; pie[0][1] = rand() % 100; pie[1][1] = rand() % 100; chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie; c.update(chartCfg);

返回值

类型描述

object

图表对象。

参数

名称类型必填描述

options

object / object数组

options参数为图表配置。Chart()函数的参数options是可以进行JSON序列化的HighStocksHighcharts.StockChart参数,相比原生参数增加了一个__isStock属性。如果将__isStock属性设置为假值(例如false),则显示为普通图表,即使用Highcharts图表;如果将__isStock属性设置为真值(例如true),则使用Highstocks图表(默认__isStock为真值,例如true)。详情可查询HighStocks图表库

参考

备注

Chart()函数返回一个图表对象,该对象包含4个方法:add()reset()update()del()

  • 1、update()方法:
    update()方法用于更新图表的配置信息,其参数为Chart图表配置对象(JSON)。
  • 2、del()方法:
    del()方法根据传入的series参数,删除指定索引的数据系列。
  • 3、add()方法:
    add()方法用于向图表中写入数据,参数依次为:
    • series:用于设置数据系列的索引,为整数。
    • data:用于设置写入的具体数据,为一个数组。
    • index(可选):用于设置数据索引,为整数,指定要修改数据的具体索引位置,支持使用负数表示,设置为-1表示数据集的最后一个数据。
      例如画线时,修改线上最后一个点的数据:chart.add(0, [1574993606000, 13.5], -1),即更改图表series[0].data中倒数第一个点的数据。不设置index参数时,表示向当前数据系列(series)末尾添加数据。
  • 4、reset()方法:
    reset()方法用于清空图表数据,可带一个参数remain,用于指定保留数据的条数。不传入参数remain时,表示清除全部数据。

该函数用于采用类似Pine语言的绘图方式,在策略运行时进行自定义绘图。

KLineChart(options)

示例

  • 如果需要在策略自定义画图区域进行画图,必须先创建图表控制对象,使用KLineChart()函数即可创建该对象。KLineChart()函数的参数为一个图表配置结构,参考代码中使用的图表配置结构非常简单:{overlay: true}

    该图表配置结构仅设置将画图内容输出在图表主图上。如果overlay设置为假值(例如false),则图表内容将全部输出在副图上;如果需要指定某个画图函数在主图上绘制,也可以在具体的函数调用中将参数overlay指定为真值(例如true)。

    javascript
    function main() { // 调用KLineChart函数创建图表控制对象c let c = KLineChart({ overlay: true }) // 使用现货交易所对象测试,获取K线数据。如果使用期货交易所对象测试,需要先设置合约 let bars = exchange.GetRecords() if (!bars) { return } // 遍历K线数据执行画图操作,每次画图操作必须以```c.begin(bar)```函数调用作为起始,以```c.close(bar)```函数调用作为结束。 bars.forEach(function(bar, index) { c.begin(bar) c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') if (bar.Close > bar.Open) { c.bgcolor('rgba(0, 255, 0, 0.5)') } let h = c.plot(bar.High, 'high') let l = c.plot(bar.Low, 'low') c.fill(h, l, { color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)' }) c.hline(bar.High) c.plotarrow(bar.Close - bar.Open) c.plotshape(bar.Low, { style: 'diamond' }) c.plotchar(bar.Close, { char: 'X' }) c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9) if (bar.Close > bar.Open) { // long/short/closelong/closeshort c.signal("long", bar.High, 1.5) } else if (bar.Close < bar.Open) { c.signal("closelong", bar.Low, 1.5) } c.close(bar) }) }
    python
    def main(): # 调用KLineChart函数创建图表控制对象c c = KLineChart({ "overlay": True }) # 使用现货交易所对象测试,获取K线数据。如果使用期货交易所对象测试,需要先设置合约 bars = exchange.GetRecords() if not bars: return for bar in bars: c.begin(bar) c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)') if bar.Close > bar.Open: c.bgcolor('rgba(0, 255, 0, 0.5)') h = c.plot(bar.High, 'high') l = c.plot(bar.Low, 'low') c.fill(h, l, 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)') c.hline(bar.High) c.plotarrow(bar.Close - bar.Open) c.plotshape(bar.Low, style = 'diamond') c.plotchar(bar.Close, char = 'X') c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9) if bar.Close > bar.Open: # long/short/closelong/closeshort c.signal("long", bar.High, 1.5) elif bar.Close < bar.Open: c.signal("closelong", bar.Low, 1.5) c.close(bar)
    rust
    fn main() { // 调用KLineChart::new创建图表控制对象c let mut c = KLineChart::new(r#"{"overlay": true}"#); // 使用现货交易所对象测试,获取K线数据。如果使用期货交易所对象测试,需要先设置合约 let bars = exchange.GetRecords(None, None, None).unwrap(); // 遍历K线数据执行画图操作,每次画图操作必须以c.begin(bar)函数调用作为起始,以c.close()函数调用作为结束。 for bar in &bars { c.begin(bar); c.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "rgba(0, 0, 0, 0.2)" }, "{}"); if bar.Close > bar.Open { c.bgcolor("rgba(0, 255, 0, 0.5)", "{}"); } let h = c.plot(bar.High, r#"{"title": "high"}"#); let l = c.plot(bar.Low, r#"{"title": "low"}"#); c.fill(h, l, if bar.Close > bar.Open { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# } else { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# }); c.hline(bar.High, "{}"); c.plotarrow(bar.Close - bar.Open, "{}"); c.plotshape(bar.Low > 0.0, r#"{"style": "diamond"}"#); c.plotchar(bar.Close > 0.0, r#"{"char": "X"}"#); c.plotcandle(bar.Open * 0.9, bar.High * 0.9, bar.Low * 0.9, bar.Close * 0.9, "{}"); if bar.Close > bar.Open { // long/short/closelong/closeshort c.signal("long", bar.High, 1.5, "long"); } else if bar.Close < bar.Open { c.signal("closelong", bar.Low, 1.5, "closelong"); } c.close(); } }
    c++
    // 暂不支持
  • 使用 pricePrecisionvolumePrecision 参数控制图表数据的显示精度。可根据实际需求设置价格与成交量的显示精度,例如对于价格波动较大的品种,可将精度设置为 0 以显示整数;对于价格较为精细的品种,可设置为 2 或更高精度。

    javascript
    function main() { // 创建图表控制对象,将价格精度与成交量精度均设置为 0(即显示整数) let c = KLineChart({ overlay: true, pricePrecision: 0, // 价格数据精度,设置为 2 即保留 2 位小数 volumePrecision: 0 // 成交量数据精度 }) // 根据交易所类型选择合适的交易对 let symbol = exchange.GetName().includes("Futures_") ? "ETH_USDT.swap" : "ETH_USDT" Log("Test symbol:", symbol) // 获取 K 线数据 let bars = exchange.GetRecords(symbol) if (!bars) { return } // 遍历 K 线数据并绘制图表 bars.forEach(function(bar, index) { c.begin(bar) c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') c.plot(bar.High, 'high') c.plot(bar.Low, 'low') c.close(bar) }) }
    python
    def main(): # 创建图表控制对象,将价格精度与成交量精度均设置为 0(即显示整数) c = KLineChart({ "overlay": True, "pricePrecision": 0, # 价格数据精度,设置为 2 即保留 2 位小数 "volumePrecision": 0 # 成交量数据精度 }) # 根据交易所类型选择合适的交易对 exName = exchange.GetName() symbol = "ETH_USDT.swap" if "Futures_" in exName else "ETH_USDT" Log("Test symbol:", symbol) # 获取 K 线数据 bars = exchange.GetRecords(symbol) if not bars: return # 遍历 K 线数据并绘制图表 for bar in bars: c.begin(bar) c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)') c.plot(bar.High, 'high') c.plot(bar.Low, 'low') c.close(bar)
    rust
    fn main() { // 创建图表控制对象,将价格精度与成交量精度均设置为 0(即显示整数) // pricePrecision 为价格数据精度,设置为 2 即保留 2 位小数;volumePrecision 为成交量数据精度 let mut c = KLineChart::new(r#"{"overlay": true, "pricePrecision": 0, "volumePrecision": 0}"#); // 根据交易所类型选择合适的交易对 let symbol = if exchange.GetName().contains("Futures_") { "ETH_USDT.swap" } else { "ETH_USDT" }; Log!("Test symbol:", symbol); // 获取 K 线数据 let bars = exchange.GetRecords(symbol, None, None).unwrap(); // 遍历 K 线数据并绘制图表 for bar in &bars { c.begin(bar); c.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "rgba(0, 0, 0, 0.2)" }, "{}"); c.plot(bar.High, r#"{"title": "high"}"#); c.plot(bar.Low, r#"{"title": "low"}"#); c.close(); } }
    c++
    // 暂不支持
  • 绘图操作中支持的Pine语言绘图接口函数如下:

    barcolor:设置K线颜色。

    barcolor(color, offset, editable, show_last, title, display)

    display参数的可选值为:"none", "all"

    javascript
    c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') // 用法同上例中的参考代码,此处不再赘述
    python
    c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
    rust
    c.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "rgba(0, 0, 0, 0.2)" }, "{}"); // 用法同上例中的参考代码,此处不再赘述
    c++
    // 暂不支持
  • bgcolor:使用指定颜色填充K线背景。

    bgcolor(color, offset, editable, show_last, title, display, overlay)

    display参数的可选值为:"none", "all"

    javascript
    c.bgcolor('rgba(0, 255, 0, 0.5)')
    python
    c.bgcolor('rgba(0, 255, 0, 0.5)')
    rust
    c.bgcolor("rgba(0, 255, 0, 0.5)", "{}");
    c++
    // 暂不支持
  • plot:在图表上绘制一系列数据。

    plot(series, title, color, linewidth, style, trackprice, histbase, offset, join, editable, show_last, display)

    style参数的可选值为:"stepline_diamond", "stepline", "cross", "areabr", "area", "circles", "columns", "histogram", "linebr", "line"

    display参数的可选值为:"none", "all"

    javascript
    c.plot(bar.High, 'high') c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"}) // 支持绘制不连续的数据线
    python
    h = c.plot(bar.High, 'high') h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr") # 支持绘制不连续的数据线
    rust
    let h = c.plot(bar.High, r#"{"title": "high"}"#); c.plot(if bar.Open < bar.Close { f64::NAN } else { bar.Close }, r#"{"title": "Close", "style": "linebr"}"#); // 支持绘制不连续的数据线
    c++
    // 暂不支持
  • fill,使用指定的颜色填充两个绘图或hline之间的背景区域。 > fill(hline1, hline2, color, title, editable, fillgaps, display) > display参数可选:"none", "all"

    由于JavaScript语言无法根据函数形参名称指定传入参数,为解决此问题,可以使用{key: value}结构为指定的形参名称传入参数。例如,参考代码中使用{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'}fill函数的color参数赋值。

    如需连续为多个形参名称指定参数,可以使用{key1: value1, key2: value2, key3: value3}

    例如,本示例中额外指定了一个title参数:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)', title: 'fill'}

    颜色值既可以使用'rgba(255, 0, 0, 0.2)'方式设置,也可以使用'#FF0000'方式设置。

    javascript
    let h = c.plot(bar.High, 'high') let l = c.plot(bar.Low, 'low') c.fill(h, l, {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'})
    python
    h = c.plot(bar.High, 'high') l = c.plot(bar.Low, 'low') c.fill(h, l, color = 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)')
    rust
    let h = c.plot(bar.High, r#"{"title": "high"}"#); let l = c.plot(bar.Low, r#"{"title": "low"}"#); c.fill(h, l, if bar.Close > bar.Open { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# } else { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# });
    c++
    // 暂不支持
  • hline,在给定的固定价格水平上绘制水平线。

    hline(price, title, color, linestyle, linewidth, editable, display)

    linestyle参数可选:"dashed", "dotted", "solid"

    display参数可选:"none", "all"

    javascript
    c.hline(bar.High)
    python
    c.hline(bar.High)
    rust
    c.hline(bar.High, "{}");
    c++
    // 暂不支持
  • plotarrow,在图表上绘制向上和向下的箭头。

    plotarrow(series, title, colorup, colordown, offset, minheight, maxheight, editable, show_last, display)

    display参数可选:"none", "all"

    javascript
    c.plotarrow(bar.Close - bar.Open)
    python
    c.plotarrow(bar.Close - bar.Open)
    rust
    c.plotarrow(bar.Close - bar.Open, "{}");
    c++
    // 暂不支持
  • plotshape,在图表上绘制可视化形状。

    plotshape(series, title, style, location, color, offset, text, textcolor, editable, size, show_last, display)
    style参数可选:"diamond", "square", "label_down", "label_up", "arrow_down", "arrow_up", "circle", "flag", "triangle_down", "triangle_up", "cross", "xcross"
    location参数可选:"abovebar", "belowbar", "top", "bottom", "absolute"
    size参数可选:"10px", "14px", "20px", "40px", "80px",分别对应Pine语言中的size.tiny、size.small、size.normal、size.large、size.huge
    size.auto等同于size.small。
    display参数可选:"none", "all"

    javascript
    c.plotshape(bar.Low, {style: 'diamond'})
    python
    c.plotshape(bar.Low, style = 'diamond')
    rust
    c.plotshape(bar.Low > 0.0, r#"{"style": "diamond"}"#);
    c++
    // 暂不支持
  • plotchar,在图表上使用任意给定的Unicode字符绘制可视化形状。

    plotchar(series, title, char, location, color, offset, text, textcolor, editable, size, show_last, display)
    location参数可选:"abovebar", "belowbar", "top", "bottom", "absolute"
    size参数可选:"10px", "14px", "20px", "40px", "80px",分别对应Pine语言中的size.tiny、size.small、size.normal、size.large、size.huge
    size.auto等同于size.small。
    display参数可选:"none", "all"

    javascript
    c.plotchar(bar.Close, {char: 'X'})
    python
    c.plotchar(bar.Close, char = 'X')
    rust
    c.plotchar(bar.Close > 0.0, r#"{"char": "X"}"#);
    c++
    // 暂不支持
  • plotcandle,在图表上绘制K线图。

    plotcandle(open, high, low, close, title, color, wickcolor, editable, show_last, bordercolor, display)
    display参数可选:"none", "all"

    javascript
    c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
    python
    c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
    rust
    c.plotcandle(bar.Open * 0.9, bar.High * 0.9, bar.Low * 0.9, bar.Close * 0.9, "{}");
    c++
    // 暂不支持
  • signal,此为Pine语言中不存在的函数,此处用于绘制买卖信号。

    signal(direction, price, qty, id)

    传入的参数"long"表示交易方向,可选"long"、"closelong"、"short"、"closeshort"。传入的参数bar.High表示标记信号在Y轴上的位置。
    传入的参数1.5表示信号的交易数量。可传入第四个参数以替换默认绘制的文本内容;信号标记的默认文本为交易方向,例如:"closelong"。

    javascript
    c.signal("long", bar.High, 1.5)
    python
    c.signal("long", bar.High, 1.5)
    rust
    c.signal("long", bar.High, 1.5, "long");
    c++
    // 暂不支持
  • reset,此为Pine语言中不存在的函数,用于清空图表数据。

    reset(remain)

    reset()方法可接受一个参数remain,用于指定保留数据的条数。若不传入remain参数,则表示清除全部数据。

    javascript
    c.reset()
    python
    c.reset()
    rust
    c.reset(0);
    c++
    // 暂不支持

返回值

类型描述

object

图表对象。

KLineChart()函数返回的图表对象包含多个方法,其中需要特别注意begin(bar)close(bar)。在遍历K线数据执行绘图操作时,绘图操作必须以begin(bar)函数调用作为起始,并以close(bar)函数调用作为结束。

参数

名称类型必填描述

options

object / object数组

options参数为图表配置对象,支持以下属性:

  • overlay:布尔值,用于设置绘图内容是否叠加输出到主图。设置为true时在主图显示,设置为false时在副图显示。

  • pricePrecision:数字,价格数据精度,用于控制图表中价格数据的小数位数。例如,设置为2表示保留2位小数,设置为0表示不保留小数(四舍五入为整数)。

  • volumePrecision:数字,成交量数据精度,用于控制图表中成交量数据的小数位数。例如,设置为2表示保留2位小数,设置为0表示不保留小数(四舍五入为整数)。

参考

备注

策略自定义绘图只能选用KLineChart()函数或Chart()函数两种方式中的一种。有关KLineChart()函数调用时所涉及的颜色、样式等设置,请参阅使用KLineChart函数绘图的专题文章

pricePrecisionvolumePrecision参数用于控制图表中数据的显示精度。当未设置这些参数时,图表将使用默认精度显示数据。设置精度参数后,图表中的价格和成交量数据将按照指定的小数位数进行四舍五入显示,这有助于简化图表显示、提升可读性。

清除日志。

LogReset(remain)

示例

javascript
function main() { // 保留最近10条日志,清除其余日志 LogReset(10) }
python
def main(): LogReset(10)
rust
fn main() { // 保留最近10条日志,清除其余日志 LogReset(10); }
c++
void main() { LogReset(10); }

参数

名称类型必填描述

remain

number

remain 参数用于设置需要保留的最近日志条数。

参考

备注

策略实盘每次启动时的启动日志会计为一条,因此如果不传入参数,且策略启动时没有任何日志输出,日志将完全不予显示,需等待托管者回传日志(此为正常现象,并非异常情况)。

用于在调用 LogReset() 函数清除日志后,回收 SQLite 删除数据时所占用的存储空间。

LogVacuum()

示例

javascript
function main() { LogReset() LogVacuum() }
python
def main(): LogReset() LogVacuum()
rust
fn main() { LogReset(0); LogVacuum(); }
c++
void main() { LogReset(); LogVacuum(); }

参考

备注

原因在于 SQLite 删除数据时并不会立即回收所占用的存储空间,需要执行 VACUUM 命令清理数据表以释放空间。该函数在调用时会触发文件移动操作,延迟较大,建议按合适的时间间隔调用。

用于在实盘页面的「调试信息」栏中输出调试信息。例如,实盘ID为123456时,console.log函数在实盘页面输出调试信息的同时,会在实盘所属托管者目录/logs/storage/123456/下创建一个扩展名为.log的日志文件并写入调试信息,文件名前缀为stdout_

console.log(...msgs)

示例

javascript
function main() { console.log("test console.log") }
python
# 不支持
c++
// 不支持

参数

名称类型必填描述

msg

string / number / bool / object / array / any (平台支持的任意类型)

参数msg为输出的内容,可以传递多个参数。

参考

备注

注意事项:

  • JavaScript语言支持此函数。
  • 仅实盘环境支持此函数,「调试工具」和「回测系统」均不支持。
  • 输出对象时会被转换为字符串[object Object],因此建议输出可读的信息。

用于在实盘页面的「调试信息」栏中输出错误信息。例如,实盘ID为123456时,console.error函数在实盘页面输出错误信息的同时,会在实盘所属托管者目录/logs/storage/123456/下创建一个以stderr_为前缀、.log为扩展名的日志文件,并将错误信息写入该文件。

console.error(...msgs)

示例

javascript
function main() { console.error("test console.error") }
python
# 不支持
c++
// 不支持

参数

名称类型必填描述

msg

string / number / bool / object / array / any (平台支持的任意类型)

参数msg为需要输出的内容,可以传入多个参数。

参考

备注

注意事项:

  • JavaScript语言支持此函数。
  • 仅实盘环境支持此函数,「调试工具」和「回测系统」不支持。
  • 输出对象时会被转换为字符串[object Object],建议输出可读性强的信息。

获取当前设置的交易对、合约代码所对应现货或合约的Ticker结构,即行情数据。GetTicker()函数是交易所对象exchange的成员函数,exchange对象的成员函数(方法)的用途仅与exchange相关,后续文档中不再赘述。

exchange.GetTicker()
exchange.GetTicker(symbol)

示例

  • 对于期货交易所对象(即exchangeexchanges[0]),在调用行情函数前需要先使用exchange.SetContractType()函数设置合约代码,后续文档中不再赘述。

    javascript
    function main(){ // 如果是期货交易所对象,先设置合约代码,例如设置为永续合约 // exchange.SetContractType("swap") var ticker = exchange.GetTicker() /* 可能由于网络原因,访问不到交易所接口(即使托管者程序所在设备能打开交易所网站,但是API接口也可能访问不通) 此时ticker为null,当访问ticker.High时,会导致错误,所以在测试该代码时,确保可以访问到交易所接口 */ Log("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume) }
    python
    def main(): ticker = exchange.GetTicker() Log("Symbol:", ticker["Symbol"], "High:", ticker["High"], "Low:", ticker["Low"], "Sell:", ticker["Sell"], "Buy:", ticker["Buy"], "Last:", ticker["Last"], "Open:", ticker["Open"], "Volume:", ticker["Volume"])
    rust
    fn main() { // 如果是期货交易所对象,先设置合约代码,例如设置为永续合约 // exchange.SetContractType("swap").unwrap(); let ticker = exchange.GetTicker(None).unwrap(); Log!("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume); }
    c++
    void main() { auto ticker = exchange.GetTicker(); Log("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume); }
  • 使用symbol参数请求具体品种(现货品种)的行情数据。

    javascript
    function main() { var ticker = exchange.GetTicker("BTC_USDT") Log(ticker) }
    python
    def main(): ticker = exchange.GetTicker("BTC_USDT") Log(ticker)
    rust
    fn main() { let ticker = exchange.GetTicker("BTC_USDT").unwrap(); Log!(ticker); }
    c++
    void main() { auto ticker = exchange.GetTicker("BTC_USDT"); Log(ticker); }

返回值

类型描述

Ticker / 空值

exchange.GetTicker()函数请求数据成功时返回Ticker结构,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所请求的Ticker数据对应的具体交易对、合约代码。若不传该参数,则默认请求当前设置的交易对、合约代码的行情数据。

当调用exchange.GetTicker(symbol)函数且exchange为现货交易所对象时,若需请求计价币种为USDT、交易币种为BTC的行情数据,则参数symbol为:"BTC_USDT",其格式为FMZ平台定义的交易对格式。

当调用exchange.GetTicker(symbol)函数且exchange为期货交易所对象时,若需请求BTC的U本位永续合约的行情数据,则参数symbol为:"BTC_USDT.swap",其格式为FMZ平台定义的交易对合约代码的组合,两者之间以字符"."分隔。

当调用exchange.GetTicker(symbol)函数且exchange为期货交易所对象时,若需请求BTC的U本位期权合约的行情数据,则参数symbol为:"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码的组合,两者之间以字符"."分隔。

参考

备注

在回测系统中,exchange.GetTicker()函数返回的Ticker数据中,HighLow为模拟值,取自当时盘口的卖一价和买一价。

在实盘中,exchange.GetTicker()函数返回的Ticker数据中,HighLow的值根据所封装的交易所Tick接口返回的数据确定,这些数据包含一定周期内(通常为24小时周期)的最高价和最低价。

不支持exchange.GetTicker()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetTicker--Futures_Aevo

获取当前设置的交易对、合约代码所对应的现货或合约的Depth结构,即订单簿数据。

exchange.GetDepth()
exchange.GetDepth(symbol)

示例

  • 测试exchange.GetDepth()函数:

    javascript
    function main(){ var depth = exchange.GetDepth() /* 可能由于网络原因,访问不到交易所接口(即使托管者程序所在设备能打开交易所网站,但是API接口也可能访问不通) 此时depth为null,当访问depth.Asks[1].Price时,会导致错误,所以在测试该代码时,确保可以访问到交易所接口 */ var price = depth.Asks[1].Price Log("Second ask price:", price) }
    python
    def main(): depth = exchange.GetDepth() price = depth["Asks"][1]["Price"] Log("Second ask price:", price)
    rust
    fn main() { let depth = exchange.GetDepth(None).unwrap(); let price = depth.Asks[1].Price; Log!("Second ask price:", price); }
    c++
    void main() { auto depth = exchange.GetDepth(); auto price = depth.Asks[1].Price; Log("Second ask price:", price); }
  • 当配置的exchange对象为期货交易所对象时,使用symbol参数请求指定品种(期货品种)的订单簿数据。

    javascript
    function main() { // BTC的U本位永续合约 var depth = exchange.GetDepth("BTC_USDT.swap") Log(depth) }
    python
    def main(): depth = exchange.GetDepth("BTC_USDT.swap") Log(depth)
    rust
    fn main() { // BTC的U本位永续合约 let depth = exchange.GetDepth("BTC_USDT.swap").unwrap(); Log!(depth); }
    c++
    void main() { auto depth = exchange.GetDepth("BTC_USDT.swap"); Log(depth); }

返回值

类型描述

Depth / 空值

exchange.GetDepth()函数在请求数据成功时返回Depth结构,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所请求的Depth数据对应的具体交易对或合约代码。若不传该参数,则默认请求当前设置的交易对、合约代码的订单簿数据。

当调用exchange.GetDepth(symbol)函数时,若exchange为现货交易所对象,且需要请求计价币种为USDT、交易币种为BTC的订单簿数据,则参数symbol应为"BTC_USDT",其格式为FMZ平台定义的交易对格式。

当调用exchange.GetDepth(symbol)函数时,若exchange为期货交易所对象,且需要请求BTC的U本位永续合约的订单簿数据,则参数symbol应为"BTC_USDT.swap",其格式为FMZ平台定义的交易对合约代码的组合,并以字符"."间隔。

当调用exchange.GetDepth(symbol)函数时,若exchange为期货交易所对象,且需要请求BTC的U本位期权合约的订单簿数据,则参数symbol应为"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码的组合,并以字符"."间隔。

参考

备注

回测系统中,使用模拟级 Tick回测时,exchange.GetDepth()函数返回数据的各档位均为模拟值。

回测系统中,使用实盘级 Tick回测时,exchange.GetDepth()函数返回的数据为秒级别的深度快照。

获取当前设置的交易对、合约代码所对应的现货或合约的Trade结构数组,即市场的成交数据。

exchange.GetTrades()
exchange.GetTrades(symbol)

示例

  • 测试exchange.GetTrades()函数:

    javascript
    function main(){ var trades = exchange.GetTrades() /* 可能由于网络原因,访问不到交易所接口(即使托管者程序所在设备能打开交易所网站,但是API接口也可能访问不通) 此时trades为null,当访问trades[0].Id时,会导致错误,所以在测试该代码时,确保可以访问到交易所接口 */ Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type) }
    python
    def main(): trades = exchange.GetTrades() Log("id:", trades[0]["Id"], "time:", trades[0]["Time"], "Price:", trades[0]["Price"], "Amount:", trades[0]["Amount"], "type:", trades[0]["Type"])
    rust
    fn main() { let trades = exchange.GetTrades(None).unwrap(); Log!("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type); }
    c++
    void main() { auto trades = exchange.GetTrades(); Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type); }
  • 当配置的exchange对象为期货交易所对象时,使用symbol参数请求具体品种(期货品种)的市场成交记录数据。

    javascript
    function main() { // BTC的U本位永续合约 var trades = exchange.GetTrades("BTC_USDT.swap") Log(trades) }
    python
    def main(): trades = exchange.GetTrades("BTC_USDT.swap") Log(trades)
    rust
    fn main() { // BTC的U本位永续合约 let trades = exchange.GetTrades("BTC_USDT.swap").unwrap(); Log!(trades); }
    c++
    void main() { auto trades = exchange.GetTrades("BTC_USDT.swap"); Log(trades); }

返回值

类型描述

Trade数组 / 空值

exchange.GetTrades()函数在请求数据成功时返回Trade结构数组,在请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所请求的Trade数组数据对应的具体交易对、合约代码。若不传该参数,则默认请求当前设置的交易对、合约代码的最近成交记录数据。

当调用exchange.GetTrades(symbol)函数时,若exchange为现货交易所对象,需要请求计价币种为USDT、交易币种为BTC的成交数据,则参数symbol为:"BTC_USDT",其格式为FMZ平台定义的交易对格式。

当调用exchange.GetTrades(symbol)函数时,若exchange为期货交易所对象,需要请求BTC的U本位永续合约的成交数据,则参数symbol为:"BTC_USDT.swap",其格式为FMZ平台定义的交易对合约代码组合,并以字符"."间隔。

当调用exchange.GetTrades(symbol)函数时,若exchange为期货交易所对象,需要请求BTC的U本位期权合约的成交数据,则参数symbol为:"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码组合,并以字符"."间隔。

参考

备注

exchange.GetTrades()函数用于获取当前交易对、合约所对应市场的成交历史(非自身成交)。部分交易所不支持该函数,且具体返回的成交记录范围因交易所而异,需要根据实际情况处理。返回数据为一个数组,其中每个元素的时间顺序与exchange.GetRecords()函数的返回数据顺序一致,即数组的最后一个元素为距离当前时间最近的数据。

在回测系统中,使用模拟级 Tick回测时,exchange.GetTrades()函数返回空数组。

在回测系统中,使用**实盘级 Tick**回测时,exchange.GetTrades()函数返回的数据为订单流快照数据,即Trade结构数组。

不支持exchange.GetTrades()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetTradesHyperliquidFutures_BitMart / Futures_Bibox / Futures_Hyperliquid / Futures_edgeX

获取当前设置的交易对、合约代码所对应的现货或合约的Record结构数组,即K线数据。

exchange.GetRecords()
exchange.GetRecords(symbol)
exchange.GetRecords(symbol, period)
exchange.GetRecords(symbol, period, limit)
exchange.GetRecords(period)
exchange.GetRecords(period, limit)

示例

  • 获取自定义周期的 K 线数据。

    javascript
    function main() { // 打印 K 线周期为 120 秒(2 分钟)的 K 线数据 Log(exchange.GetRecords(60 * 2)) // 打印 K 线周期为 5 分钟的 K 线数据 Log(exchange.GetRecords(PERIOD_M5)) }
    python
    def main(): Log(exchange.GetRecords(60 * 2)) Log(exchange.GetRecords(PERIOD_M5))
    rust
    fn main() { // 打印 K 线周期为 120 秒(2 分钟)的 K 线数据 Log!(exchange.GetRecords(None, 60 * 2, None)); // 打印 K 线周期为 5 分钟的 K 线数据 Log!(exchange.GetRecords(None, PERIOD_M5, None)); }
    c++
    void main() { Log(exchange.GetRecords(60 * 2)[0]); Log(exchange.GetRecords(PERIOD_M5)[0]); }
  • 输出 K 线柱数据:

    javascript
    function main() { var records = exchange.GetRecords(PERIOD_H1) /* 可能由于网络原因,无法访问交易所接口(即使托管者程序所在设备能够打开交易所网站,API 接口仍可能无法访问) 此时 records 为 null,访问 records[0].Time 时会导致错误。因此在测试该代码时,请确保能够正常访问交易所接口 */ Log("First K-line data: Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High) Log("Second K-line data: Time:", records[1].Time ,"Close:", records[1].Close) Log("Current K-line (latest)", records[records.length-1], "Previous K-line", records[records.length-2]) }
    python
    def main(): records = exchange.GetRecords(PERIOD_H1) Log("First K-line data: Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"]) Log("Second K-line data: Time:", records[1]["Time"], "Close:", records[1]["Close"]) Log("Current K-line (latest)", records[-1], "Previous K-line", records[-2])
    rust
    fn main() { let records = exchange.GetRecords(None, PERIOD_H1, None).unwrap(); Log!("First K-line data: Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High); Log!("Second K-line data: Time:", records[1].Time, "Close:", records[1].Close); Log!("Current K-line (latest)", records[records.len() - 1], "Previous K-line", records[records.len() - 2]); }
    c++
    void main() { auto records = exchange.GetRecords(PERIOD_H1); Log("First K-line data: Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High); Log("Second K-line data: Time:", records[1].Time, "Close:", records[1].Close); Log("Current K-line (latest)", records[records.size() - 1], "Previous K-line", records[records.size() - 2]); }
  • 当配置的exchange对象为期货交易所对象时,可使用symbolperiodlimit参数请求指定品种(期货品种)的K线数据。

    javascript
    function main() { var records = exchange.GetRecords("BTC_USDT.swap", 60, 100) Log(records) }
    python
    def main(): records = exchange.GetRecords("BTC_USDT.swap", 60, 100) Log(records)
    rust
    fn main() { let records = exchange.GetRecords("BTC_USDT.swap", 60, 100).unwrap(); Log!(records); }
    c++
    void main() { auto records = exchange.GetRecords("BTC_USDT.swap", 60, 100); Log(records); }

返回值

类型描述

Record数组 / 空值

exchange.GetRecords()函数请求数据成功时返回Record结构数组,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所请求的Record数组数据对应的具体交易对、合约代码。若不传该参数,则默认请求当前设置的交易对、合约代码的K线数据。

当调用exchange.GetRecords(symbol)函数时,若exchange为现货交易所对象,需要请求计价币种为USDT、交易币种为BTC的K线数据,则参数symbol为:"BTC_USDT",其格式为FMZ平台定义的交易对格式。

当调用exchange.GetRecords(symbol)函数时,若exchange为期货交易所对象,需要请求BTC的U本位永续合约K线数据,则参数symbol为:"BTC_USDT.swap",其格式为FMZ平台定义的交易对合约代码组合,并以字符"."间隔。

当调用exchange.GetRecords(symbol)函数时,若exchange为期货交易所对象,需要请求BTC的U本位期权合约K线数据,则参数symbol为:"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码组合,并以字符"."间隔。

period

number

参数period用于指定所请求K线数据的周期,例如:PERIOD_M1PERIOD_M5PERIOD_M15等;参数period除了可以传入已定义的标准周期外,还可以传入整数数值,单位为秒。若不传该参数,则默认请求的K线数据周期为当前策略实盘/回测所配置的默认K线周期。

limit

number

参数limit用于指定所请求K线数据的长度,若不传该参数,则默认请求长度为交易所K线接口单次最大请求的K线柱数量;该参数可能会触发对交易所K线数据的分页查询,分页查询时该函数的调用耗时会相应增加。

参考

备注

默认K线周期可在回测、实盘页面进行设置。调用exchange.GetRecords()函数时,如果指定了参数,则获取该参数所指定周期的K线数据;如果未指定参数,则返回回测、实盘参数中所设置周期的K线数据。

返回值为Record结构数组。返回的K线数据会随时间不断累积,累积的K线柱数量上限受exchange.SetMaxBarLen()函数设置的影响,未设置时默认上限为5000个K线柱。当K线数据达到累积上限后,每新增一根K线柱的同时会删除时间最早的一根K线柱(类似队列的先进先出)。部分交易所未提供K线接口,此时由托管者实时收集市场成交记录数据(Trade结构数组)来合成K线。

如果交易所的K线接口支持分页查询,当调用exchange.SetMaxBarLen()函数设置较大的K线长度时,系统会发起多次API请求。

初始调用exchange.GetRecords()函数时,所获取的K线柱数量在回测和实盘环境下有所不同:

  • 回测系统会预先获取回测时间范围起始时刻之前一定数量的K线柱(默认为5000个,回测系统的相关设置及数据量会影响最终返回的数量),作为初始K线数据。

  • 实盘时具体获取的K线柱数量取决于交易所K线接口所能提供的最大数据量。

period参数设置为5,即表示请求获取以5秒为周期的K线数据。如果period参数不能被60整除(即所代表的周期无法以分钟为单位表示),系统底层会使用exchange.GetTrades()的相关接口获取成交记录数据,以合成所需的K线数据;如果period参数能被60整除,则最小使用1分钟K线数据(并尽可能使用较大的周期)来合成所需的K线数据。

在回测系统的模拟级别回测中,由于需要设置底层K线周期(模拟级别回测时,系统会根据设置的底层K线周期,使用对应的K线数据生成Tick数据),因此需要注意:策略中获取的K线数据周期不能小于底层K线周期。这是因为在模拟级别回测中,各个周期的K线数据均由底层K线周期对应的K线数据合成而来。

C++语言中如果需要自行构造K线数据,可参考以下代码范例:

c++
#include <sstream> void main() { Records r; r.Valid = true; for (auto i = 0; i < 10; i++) { Record ele; ele.Time = i * 100000; ele.High = i * 10000; ele.Low = i * 1000; ele.Close = i * 100; ele.Open = i * 10; ele.Volume = i * 1; r.push_back(ele); } // 输出显示:Records[10] Log(r); auto ma = TA.MA(r,10); // 输出显示:[nan,nan,nan,nan,nan,nan,nan,nan,nan,450] Log(ma); }

不支持exchange.GetRecords()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetRecordsZaif / Coincheck / BitFlyerFutures_Aevo

获取回测或实盘运行策略时,在发明者量化交易平台网站页面上所设置的 K 线周期,即调用 exchange.GetRecords() 函数且不传入参数时使用的默认 K 线周期。

exchange.GetPeriod()

示例

javascript
function main() { // 例如,回测或实盘时在发明者量化交易平台网站页面上设置的 K 线周期为 1 小时 var period = exchange.GetPeriod() Log("K-line period:", period / (60 * 60), "hours") }
python
def main(): period = exchange.GetPeriod() Log("K-line period:", period / (60 * 60), "hours")
rust
fn main() { // 例如,回测或实盘时在发明者量化交易平台网站页面上设置的 K 线周期为 1 小时 let period = exchange.GetPeriod(); Log!("K-line period:", period as f64 / (60.0 * 60.0), "hours"); }
c++
void main() { auto period = exchange.GetPeriod(); Log("K-line period:", period / (60 * 60.0), "hours"); }

返回值

类型描述

number

K 线周期的秒数,为整数数值,单位为秒。

参考

设置K线的最大长度。

exchange.SetMaxBarLen(len)

示例

javascript
function main() { exchange.SetMaxBarLen(50) var records = exchange.GetRecords() Log(records.length, records) }
python
def main(): exchange.SetMaxBarLen(50) r = exchange.GetRecords() Log(len(r), r)
rust
fn main() { exchange.SetMaxBarLen(50); let records = exchange.GetRecords(None, None, None).unwrap(); Log!(records.len(), records); }
c++
void main() { exchange.SetMaxBarLen(50); auto r = exchange.GetRecords(); Log(r.size(), r[0]); }

参数

名称类型必填描述

len

number

参数len用于指定K线的最大长度。

参考

备注

exchange.SetMaxBarLen()函数在加密货币策略运行时会影响以下两个方面:

  • 影响首次调用时获取的K线线柱(Bar)数量。

  • 影响K线线柱(Bar)数量的上限。

获取当前交易所对象(exchangeexchanges)最近一次rest请求返回的原始内容。

exchange.GetRawJSON()

示例

javascript
function main(){ exchange.GetAccount(); var obj = JSON.parse(exchange.GetRawJSON()); Log(obj); }
python
import json def main(): exchange.GetAccount() obj = json.loads(exchange.GetRawJSON()) Log(obj)
c++
void main() { auto obj = exchange.GetAccount(); // C++ 不支持GetRawJSON函数 Log(obj); }

返回值

类型描述

string

rest请求的响应数据。

参考

备注

exchange.GetRawJSON()函数仅支持实盘交易。C++语言的策略不支持此函数。

获取交易所对象当前设置的汇率。

exchange.GetRate()

示例

javascript
function main(){ Log(exchange.GetTicker()) // 设置汇率转换 exchange.SetRate(7) Log(exchange.GetTicker()) Log("Current rate:", exchange.GetRate()) }
python
def main(): Log(exchange.GetTicker()) exchange.SetRate(7) Log(exchange.GetTicker()) Log("Current rate:", exchange.GetRate())
rust
fn main() { Log!(exchange.GetTicker(None)); // 设置汇率转换 exchange.SetRate(7); Log!(exchange.GetTicker(None)); Log!("Current rate:", exchange.GetRate()); }
c++
void main() { Log(exchange.GetTicker()); exchange.SetRate(7); Log(exchange.GetTicker()); Log("Current rate:", exchange.GetRate()); }

返回值

类型描述

number

交易所对象当前的汇率值。

参考

备注

如果未调用exchange.SetRate()设置过转换汇率,exchange.GetRate()函数将返回默认汇率值1,即当前显示的计价货币(quoteCurrency)相关数据未经过汇率转换。

如果已使用exchange.SetRate()设置过汇率值,例如exchange.SetRate(7),那么通过exchange交易所对象获取的行情、深度、下单价格等所有价格信息,都会乘以所设置的汇率7进行转换。

如果exchange对应的是以美元为计价货币的交易所,在调用exchange.SetRate(7)后,实盘中的所有价格都会乘以7,转换为接近人民币(CNY)的价格。此时通过exchange.GetRate()获取的汇率值即为7

exchange.SetData()函数用于设置策略运行时所加载的数据。

exchange.SetData(key, value)

示例

参数value所要求的数据格式如同以下例子中的data变量。可以看到,时间戳1579622400000对应的时间为2020-01-22 00:00:00。当策略程序运行时刻超过该时间之后、且在下一条数据的时间戳1579708800000(即时间2020-01-23 00:00:00)之前,调用exchange.GetData()函数获取到的均为[1579622400000, 123]这条数据的内容。随着程序继续运行、时间推移,以此类推即可逐条获取数据。

在以下例子中,运行时(回测或实盘)当前时刻到达或超过1579795200000这个时间戳时,调用exchange.GetData()函数,返回值为:{"Time":1579795200000,"Data":["abc",123,{"price":123}]}。其中"Time":1579795200000对应数据[1579795200000, ["abc", 123, {"price": 123}]]中的1579795200000"Data":["abc",123,{"price":123}]对应数据[1579795200000, ["abc", 123, {"price": 123}]]中的["abc", 123, {"price": 123}]

javascript
/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ function main() { var data = [ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] exchange.SetData("test", data) while(true) { Log(exchange.GetData("test")) Sleep(1000) } }
python
'''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' def main(): data = [ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] exchange.SetData("test", data) while True: Log(exchange.GetData("test")) Sleep(1000)
rust
/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ fn main() { // Rust SDK 中SetData的数据参数为JSON字符串 let data = r#"[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ]"#; exchange.SetData("test", data); loop { Log!(exchange.GetData("test")); Sleep(1000); } }
c++
/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { json data = R"([ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ])"_json; exchange.SetData("test", data); while(true) { Log(exchange.GetData("test")); Sleep(1000); } }

返回值

类型描述

number

参数value经JSON编码后的字符串长度。

参数

名称类型必填描述

key

string

数据集合的名称。

value

array

exchange.SetData()函数所要加载的数据,其数据结构为数组。该数据结构与exchange.GetData()函数请求外部数据时所要求的格式相同,即:"schema": ["time", "data"]

参考

备注

加载的数据可以是任何经济指标、行业数据、相关指数等,用于在策略中量化评估各类可量化的信息。

exchange.GetData()函数用于获取由exchange.SetData()函数加载的数据,或外部链接提供的数据。

exchange.GetData(key)
exchange.GetData(key, timeout)

示例

  • 获取直接写入数据的调用方式。

    javascript
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ function main() { exchange.SetData("test", [[1579536000000, _D(1579536000000)], [1579622400000, _D(1579622400000)], [1579708800000, _D(1579708800000)]]) while(true) { Log(exchange.GetData("test")) Sleep(1000 * 60 * 60 * 24) } }
    python
    '''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' def main(): exchange.SetData("test", [[1579536000000, _D(1579536000000/1000)], [1579622400000, _D(1579622400000/1000)], [1579708800000, _D(1579708800000/1000)]]) while True: Log(exchange.GetData("test")) Sleep(1000 * 60 * 60 * 24)
    rust
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ fn main() { // Rust SDK 中SetData的数据参数为JSON字符串,使用format!拼接数据 let data = format!(r#"[[1579536000000, "{}"], [1579622400000, "{}"], [1579708800000, "{}"]]"#, _D(1579536000000), _D(1579622400000), _D(1579708800000)); exchange.SetData("test", &data); loop { Log!(exchange.GetData("test")); Sleep(1000 * 60 * 60 * 24); } }
    c++
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { json arr = R"([[1579536000000, ""], [1579622400000, ""], [1579708800000, ""]])"_json; arr[0][1] = _D(1579536000000); arr[1][1] = _D(1579622400000); arr[2][1] = _D(1579708800000); exchange.SetData("test", arr); while(true) { Log(exchange.GetData("test")); Sleep(1000 * 60 * 60 * 24); } }
  • 支持通过外部链接请求数据,请求返回的数据格式如下:

    json
    { "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }

    其中schema定义了数据主体中每条记录的数据格式,该格式固定为["time","data"],与data属性中逐条数据的格式一一对应。data属性用于存储数据主体,每条数据由毫秒级时间戳和数据内容构成(数据内容可以是任何可JSON编码的数据)。

    以下是使用Go语言编写的测试服务程序:

    golang
    package main import ( "fmt" "net/http" "encoding/json" ) func Handle (w http.ResponseWriter, r *http.Request) { defer func() { fmt.Println("req:", *r) ret := map[string]interface{}{ "schema": []string{"time","data"}, "data": []interface{}{ []interface{}{1579536000000, "abc"}, []interface{}{1579622400000, 123}, []interface{}{1579708800000, map[string]interface{}{"price":123}}, []interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}}, }, } b, _ := json.Marshal(ret) w.Write(b) }() } func main () { fmt.Println("listen http://localhost:9090") http.HandleFunc("/data", Handle) http.ListenAndServe(":9090", nil) }

    程序接收到请求后返回的应答数据:

    json
    { "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }

    测试策略代码如下:

    javascript
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ function main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000) } }
    python
    '''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' def main(): while True: Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000)
    rust
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ fn main() { loop { Log!(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Sleep(1000); } }
    c++
    /*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Sleep(1000); } }
  • 获取外部链接数据的调用方式。

    javascript
    function main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json")) }
    python
    def main(): Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
    rust
    fn main() { Log!(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Log!(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json")); }
    c++
    void main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json")); }
  • 请求在datadata平台上创建的查询数据,应答的数据格式需满足以下要求(schema中必须描述time和data字段):

    json
    { "data": [], "schema": ["time", "data"] }

    其中"data"字段为所需的数据内容,且"data"字段中的数据须与"schema"中约定的字段一致。调用exchange.GetData()函数时,将返回一个JSON对象,例如:{"Time":1579795200000, "Data":"..."}

    javascript
    function main() { Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")) // 链接中xxx部分为查询数据的编码,此处xxx仅为示例 }
    python
    def main(): Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data"))
    rust
    fn main() { Log!(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")); // 链接中xxx部分为查询数据的编码,此处xxx仅为示例 }
    c++
    void main() { Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")); }

返回值

类型描述

object / 空值

数据集合中的记录,或请求返回的数据。

参数

名称类型必填描述

key

string

数据集合的名称,或数据请求链接。

timeout

number

用于设置缓存超时时间,单位为毫秒。实盘时默认缓存超时时间为一分钟。

参考

备注

回测时一次性获取数据,实盘时缓存一分钟的数据。在回测系统中,当使用访问接口请求数据的方式时,回测系统会自动为请求添加from(时间戳,单位秒)、to(时间戳,单位秒)、period(底层K线周期,时间戳,单位毫秒)等参数,用于确定要获取数据的时间范围。

exchange.GetMarkets()函数用于获取交易所的市场信息。

exchange.GetMarkets()

示例

  • 期货交易所对象的调用示例:

    javascript
    function main() { var markets = exchange.GetMarkets() var currency = exchange.GetCurrency() // 获取当前合约代码也可以使用exchange.GetContractType()函数 var ct = "swap" var key = currency + "." + ct Log(key, ":", markets[key]) }
    python
    def main(): markets = exchange.GetMarkets() currency = exchange.GetCurrency() ct = "swap" key = currency + "." + ct Log(key, ":", markets[key])
    rust
    fn main() { let markets = exchange.GetMarkets(); let currency = exchange.GetCurrency(); // 获取当前合约代码也可以使用exchange.GetContractType()函数 let ct = "swap"; let key = format!("{}.{}", currency, ct); Log!(key, ":", format!("{:?}", markets.get(&key))); }
    c++
    void main() { auto markets = exchange.GetMarkets(); auto currency = exchange.GetCurrency(); auto ct = "swap"; auto key = currency + "." + ct; Log(key, ":", markets[key]); }
  • 在回测系统中,使用期货交易所对象调用exchange.GetMarkets()函数。在调用任何行情函数之前,GetMarkets仅返回当前默认交易对的market数据;在调用行情函数之后,则会返回所有已请求过品种的market数据。可参考以下测试示例:

    javascript
    /*backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] var tbl1 = { type: "table", title: "markets1", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: [] } var markets1 = exchange.GetMarkets() for (var key in markets1) { var market = markets1[key] tbl1.rows.push([key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal]) } for (var symbol of arrSymbol) { exchange.GetTicker(symbol) } var tbl2 = { type: "table", title: "markets2", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: [] } var markets2 = exchange.GetMarkets() for (var key in markets2) { var market = markets2[key] tbl2.rows.push([key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal]) } LogStatus("`" + JSON.stringify([tbl1, tbl2]) + "`") }
    python
    '''backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] tbl1 = { "type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] } markets1 = exchange.GetMarkets() for key in markets1: market = markets1[key] tbl1["rows"].append([key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]]) for symbol in arrSymbol: exchange.GetTicker(symbol) tbl2 = { "type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] } markets2 = exchange.GetMarkets() for key in markets2: market = markets2[key] tbl2["rows"].append([key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]]) LogStatus("`" + json.dumps([tbl1, tbl2]) + "`")
    rust
    /*backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ fn marketToJson(key: &str, market: &Market) -> String { format!(r#"["{}", "{}", "{}", "{}", {}, {}, {}, {}, {}, {}, {}, {}, {}]"#, key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal) } fn main() { let arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]; // Rust SDK 没有JSON序列化功能,此处使用format!拼接表格的JSON文本 let markets1 = exchange.GetMarkets(); let mut rows1: Vec<String> = Vec::new(); for (key, market) in &markets1 { rows1.push(marketToJson(key, market)); } let tbl1 = format!(r#"{{"type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [{}]}}"#, rows1.join(",")); for symbol in arrSymbol { exchange.GetTicker(symbol); } let markets2 = exchange.GetMarkets(); let mut rows2: Vec<String> = Vec::new(); for (key, market) in &markets2 { rows2.push(marketToJson(key, market)); } let tbl2 = format!(r#"{{"type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [{}]}}"#, rows2.join(",")); LogStatus!(format!("`[{},{}]`", tbl1, tbl2)); }
    c++
    /*backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"}; json tbl1 = R"({ "type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] })"_json; auto markets1 = exchange.GetMarkets(); for (auto& [key, market] : markets1.items()) { json arrJson = {key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]}; tbl1["rows"].push_back(arrJson); } for (const auto& symbol : arrSymbol) { exchange.GetTicker(symbol); } json tbl2 = R"({ "type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] })"_json; auto markets2 = exchange.GetMarkets(); for (auto& [key, market] : markets2.items()) { json arrJson = {key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]}; tbl2["rows"].push_back(arrJson); } json tbls = R"([])"_json; tbls.push_back(tbl1); tbls.push_back(tbl2); LogStatus("`" + tbls.dump() + "`"); }

返回值

类型描述

object / 空值

包含Market结构体的字典。

参考

备注

exchange.GetMarkets()函数的返回值为一个字典。对于现货交易所,键名为交易品种名称,格式固定为交易对,例如:

json
{ "BTC_USDT" : {...}, // 键值为Market结构 "LTC_USDT" : {...}, ... }

对于期货合约交易所而言,由于同一品种可能存在多个合约,例如BTC_USDT交易对包含永续合约、季度合约等,因此exchange.GetMarkets()函数返回的字典中,键名为交易对与合约代码的组合,例如:

json
{ "BTC_USDT.swap" : {...}, // 键值为Market结构 "BTC_USDT.quarter" : {...}, "LTC_USDT.swap" : {...}, ... }

  • exchange.GetMarkets()函数支持实盘与回测系统。
  • exchange.GetMarkets()函数仅返回交易所已上线交易品种的市场信息。
  • exchange.GetMarkets()函数不支持期权合约。

不支持exchange.GetMarkets()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetMarketsCoincheck / Bithumb / BitFlyer--

exchange.GetTickers()函数用于获取交易所的聚合行情数据(Ticker结构的数组)。当exchange为现货交易所对象时,返回所有交易对的 ticker 行情数据;当exchange为期货交易所对象时,返回所有合约的 ticker 行情数据。

exchange.GetTickers()

示例

  • 调用 exchange.GetTickers() 函数,获取聚合行情数据。

    javascript
    function main() { var tickers = exchange.GetTickers() if (tickers && tickers.length > 0) { Log("Number of tradable symbols:", tickers.length) } }
    python
    def main(): tickers = exchange.GetTickers() if tickers and len(tickers) > 0: Log("Number of tradable symbols:", len(tickers))
    rust
    fn main() { if let Ok(tickers) = exchange.GetTickers() { if tickers.len() > 0 { Log!("Number of tradable symbols:", tickers.len()); } } }
    c++
    void main() { auto tickers = exchange.GetTickers(); if (tickers.Valid && tickers.size() > 0) { Log("Number of tradable symbols:", tickers.size()); } }
  • 使用现货交易所对象,在回测系统中调用exchange.GetTickers()函数。在调用任何行情函数之前,GetTickers仅返回当前默认交易对的ticker数据;在调用行情函数之后,则会返回所有已请求过的交易对的ticker数据。可参考以下测试示例:

    javascript
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"] // 请求其它交易对行情数据之前,调用GetTickers var tickers1 = exchange.GetTickers() var tbl1 = {type: "table", title: "tickers1", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []} for (var ticker of tickers1) { tbl1.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume]) } // 请求其它交易对行情数据 for (var symbol of arrSymbol) { exchange.GetTicker(symbol) } // 再次调用GetTickers var tickers2 = exchange.GetTickers() var tbl2 = {type: "table", title: "tickers2", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []} for (var ticker of tickers2) { tbl2.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume]) } LogStatus("`" + JSON.stringify([tbl1, tbl2]) + "`") }
    python
    '''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"] tickers1 = exchange.GetTickers() tbl1 = {"type": "table", "title": "tickers1", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": []} for ticker in tickers1: tbl1["rows"].append([ticker["Symbol"], ticker["High"], ticker["Open"], ticker["Low"], ticker["Last"], ticker["Buy"], ticker["Sell"], ticker["Time"], ticker["Volume"]]) for symbol in arrSymbol: exchange.GetTicker(symbol) tickers2 = exchange.GetTickers() tbl2 = {"type": "table", "title": "tickers2", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": []} for ticker in tickers2: tbl2["rows"].append([ticker["Symbol"], ticker["High"], ticker["Open"], ticker["Low"], ticker["Last"], ticker["Buy"], ticker["Sell"], ticker["Time"], ticker["Volume"]]) LogStatus("`" + json.dumps([tbl1, tbl2]) + "`")
    rust
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ fn tickerToJson(ticker: &Ticker) -> String { format!(r#"["{}", {}, {}, {}, {}, {}, {}, {}, {}]"#, ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume) } fn main() { let arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"]; // 请求其它交易对行情数据之前,调用GetTickers // Rust SDK 没有JSON序列化,使用format!拼接表格的JSON文本 let tickers1 = exchange.GetTickers().unwrap(); let rows1 = tickers1.iter().map(tickerToJson).collect::<Vec<String>>().join(","); let tbl1 = format!(r#"{{"type": "table", "title": "tickers1", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [{}]}}"#, rows1); // 请求其它交易对行情数据 for symbol in arrSymbol { exchange.GetTicker(symbol); } // 再次调用GetTickers let tickers2 = exchange.GetTickers().unwrap(); let rows2 = tickers2.iter().map(tickerToJson).collect::<Vec<String>>().join(","); let tbl2 = format!(r#"{{"type": "table", "title": "tickers2", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [{}]}}"#, rows2); LogStatus!(format!("`[{},{}]`", tbl1, tbl2)); }
    c++
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ json tickerToJson(const Ticker& ticker) { json arrJson; arrJson.push_back(ticker.Symbol); arrJson.push_back(ticker.High); arrJson.push_back(ticker.Open); arrJson.push_back(ticker.Low); arrJson.push_back(ticker.Last); arrJson.push_back(ticker.Buy); arrJson.push_back(ticker.Sell); arrJson.push_back(ticker.Time); arrJson.push_back(ticker.Volume); return arrJson; } void main() { std::string arrSymbol[] = {"ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"}; auto tickers1 = exchange.GetTickers(); json tbl1 = R"({ "type": "table", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [] })"_json; tbl1["title"] = "tickers1"; for (const auto& ticker : tickers1) { json arrJson = tickerToJson(ticker); tbl1["rows"].push_back(arrJson); } for (const std::string& symbol : arrSymbol) { exchange.GetTicker(symbol); } auto tickers2 = exchange.GetTickers(); json tbl2 = R"({ "type": "table", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [] })"_json; tbl2["title"] = "tickers2"; for (const auto& ticker : tickers2) { json arrJson = tickerToJson(ticker); tbl2["rows"].push_back(arrJson); } json tbls = R"([])"_json; tbls.push_back(tbl1); tbls.push_back(tbl2); LogStatus("`" + tbls.dump() + "`"); }

返回值

类型描述

Ticker数组 / 空值

exchange.GetTickers()函数在请求数据成功时返回Ticker结构数组,请求数据失败时返回空值。

参考

备注

注意事项:

  • 该函数请求交易所的聚合行情接口,调用前无需设置交易对或合约代码,且仅返回交易所已上线交易品种的行情数据。

  • 回测系统支持该函数。

  • 未提供聚合行情接口的交易所对象不支持该函数。

  • 该函数不支持期权合约。

不支持exchange.GetTickers()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetTickersZaif / WOO / Gemini / Coincheck / BitFlyer / BiboxFutures_WOO / Futures_dYdX / Futures_Deribit / Futures_Bibox / Futures_Aevo / Futures_edgeX

exchange.Buy()函数用于下买单。Buy()函数是交易所对象exchange的成员函数。Buy()函数操作交易所对象exchange所绑定的交易所账户。exchange对象的成员函数(方法)的用途仅与exchange相关,本文档后续不再赘述。

exchange.Buy(price, amount)
exchange.Buy(price, amount, ...args)

示例

  • exchange.Buy()返回的订单编号,可用于查询订单信息和取消订单。

    javascript
    function main() { var id = exchange.Buy(100, 1); Log("id:", id); }
    python
    def main(): id = exchange.Buy(100, 1) Log("id:", id)
    rust
    fn main() { let id = exchange.Buy(100, 1).unwrap(); Log!("id:", id); }
    c++
    void main() { auto id = exchange.Buy(100, 1); Log("id:", id); }
  • 加密货币期货合约下单时必须注意交易方向是否设置正确,如果交易方向与交易函数不匹配将会报错:

    ```log

    direction is sell, invalid order type Buy

    direction is buy, invalid order type Sell

    direction is closebuy, invalid order type Buy

    direction is closesell, invalid order type Sell

    ```

    javascript
    // 以下为错误调用 function main() { exchange.SetContractType("quarter") // 设置做空方向 exchange.SetDirection("sell") // 下买单,会报错,做空只能卖出 var id = exchange.Buy(50, 1) // 设置做多方向 exchange.SetDirection("buy") // 下卖单,会报错,做多只能买入 var id2 = exchange.Sell(60, 1) // 设置平多方向 exchange.SetDirection("closebuy") // 下买单,会报错,平多只能卖出 var id3 = exchange.Buy(-1, 1) // 设置平空方向 exchange.SetDirection("closesell") // 下卖单,会报错,平空只能买入 var id4 = exchange.Sell(-1, 1) }
    python
    # 以下为错误调用 def main(): exchange.SetContractType("quarter") exchange.SetDirection("sell") id = exchange.Buy(50, 1) exchange.SetDirection("buy") id2 = exchange.Sell(60, 1) exchange.SetDirection("closebuy") id3 = exchange.Buy(-1, 1) exchange.SetDirection("closesell") id4 = exchange.Sell(-1, 1)
    rust
    // 以下为错误调用 fn main() { let _ = exchange.SetContractType("quarter"); // 设置做空方向 let _ = exchange.SetDirection("sell"); // 下买单,会报错,做空只能卖出 let id = exchange.Buy(50, 1); // 设置做多方向 let _ = exchange.SetDirection("buy"); // 下卖单,会报错,做多只能买入 let id2 = exchange.Sell(60, 1); // 设置平多方向 let _ = exchange.SetDirection("closebuy"); // 下买单,会报错,平多只能卖出 let id3 = exchange.Buy(-1, 1); // 设置平空方向 let _ = exchange.SetDirection("closesell"); // 下卖单,会报错,平空只能买入 let id4 = exchange.Sell(-1, 1); }
    c++
    // 以下为错误调用 void main() { exchange.SetContractType("quarter"); exchange.SetDirection("sell"); auto id = exchange.Buy(50, 1); exchange.SetDirection("buy"); auto id2 = exchange.Sell(60, 1); exchange.SetDirection("closebuy"); auto id3 = exchange.Buy(-1, 1); exchange.SetDirection("closesell"); auto id4 = exchange.Sell(-1, 1); }
  • 现货市价单。

    javascript
    // 例如交易对:ETH_BTC ,市价单买入 function main() { // 下市价单买入,买入0.1个BTC(计价币)金额的ETH币 exchange.Buy(-1, 0.1) }
    python
    def main(): exchange.Buy(-1, 0.1)
    rust
    // 例如交易对:ETH_BTC ,市价单买入 fn main() { // 下市价单买入,买入0.1个BTC(计价币)金额的ETH币 let _ = exchange.Buy(-1, 0.1); }
    c++
    void main() { exchange.Buy(-1, 0.1); }

返回值

类型描述

string / 空值

下单成功返回订单Id,下单失败返回空值。FMZ平台的订单Order结构的属性Id由交易所品种代码和交易所原始订单Id组成,以英文逗号分隔。例如OKX交易所现货交易对ETH_USDT订单的属性Id格式为:ETH-USDT,1547130415509278720。调用exchange.Buy()函数下单时,返回值订单Id与订单Order结构的Id属性一致。

参数

名称类型必填描述

price

number

price参数用于设置订单价格。

amount

number

amount参数用于设置订单量。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于将附带信息输出到该条下单日志中,arg参数可传入多个。

参考

exchange.Sell exchange.SetContractType exchange.SetDirection exchange.IO(API限流控制,Buy函数受CreateOrder限流设置影响)

备注

期货合约下单时必须注意交易方向是否设置正确,如果交易方向与交易函数不匹配将会报错。加密货币期货合约交易所的下单量如无特殊说明,则以合约张数为单位。

参数price设置为-1时用于下市价单,此功能需要交易所的下单接口支持市价单。以市价单方式对加密货币现货下买单时,下单量参数amount为以计价币计价的金额数量。以市价单方式对加密货币期货合约下单时,下单量参数amount的单位为合约张数。实盘时,有少数加密货币交易所不支持市价单接口。个别现货交易所市价单买单的下单量为交易币数量,具体请查看「用户指南」中的交易所特殊说明

如使用较旧版本的托管者,exchange.Buy()函数返回的订单Id可能与当前文档中描述的返回值订单Id有所差别。

需要注意,以下三家交易所的下单接口较为特殊。对于现货市价单的买单,其下单量为币数,而非金额。

  • AscendEx

  • BitMEX

  • Bitfinex

exchange.Sell()函数用于下达卖单。

exchange.Sell(price, amount)
exchange.Sell(price, amount, ...args)

示例

  • exchange.Sell()返回的订单编号,可用于查询订单信息和取消订单。

    javascript
    function main(){ var id = exchange.Sell(100, 1) Log("id:", id) }
    python
    def main(): id = exchange.Sell(100, 1) Log("id:", id)
    rust
    fn main() { let id = exchange.Sell(100, 1).unwrap(); Log!("id:", id); }
    c++
    void main() { auto id = exchange.Sell(100, 1); Log("id:", id); }
  • 加密货币期货合约下单时必须注意交易方向是否设置正确,如果交易方向与交易函数不匹配将会报错:

    log
    direction is sell, invalid order type Buy direction is buy, invalid order type Sell direction is closebuy, invalid order type Buy direction is closesell, invalid order type Sell
    javascript
    // 以下为错误调用 function main() { exchange.SetContractType("quarter") // 设置做空方向 exchange.SetDirection("sell") // 下买单,会报错,做空只能卖出 var id = exchange.Buy(50, 1) // 设置做多方向 exchange.SetDirection("buy") // 下卖单,会报错,做多只能买入 var id2 = exchange.Sell(60, 1) // 设置平多方向 exchange.SetDirection("closebuy") // 下买单,会报错,平多只能卖出 var id3 = exchange.Buy(-1, 1) // 设置平空方向 exchange.SetDirection("closesell") // 下卖单,会报错,平空只能买入 var id4 = exchange.Sell(-1, 1) }
    python
    # 以下为错误调用 def main(): exchange.SetContractType("quarter") exchange.SetDirection("sell") id = exchange.Buy(50, 1) exchange.SetDirection("buy") id2 = exchange.Sell(60, 1) exchange.SetDirection("closebuy") id3 = exchange.Buy(-1, 1) exchange.SetDirection("closesell") id4 = exchange.Sell(-1, 1)
    rust
    // 以下为错误调用 fn main() { let _ = exchange.SetContractType("quarter"); // 设置做空方向 let _ = exchange.SetDirection("sell"); // 下买单,会报错,做空只能卖出 let id = exchange.Buy(50, 1); // 设置做多方向 let _ = exchange.SetDirection("buy"); // 下卖单,会报错,做多只能买入 let id2 = exchange.Sell(60, 1); // 设置平多方向 let _ = exchange.SetDirection("closebuy"); // 下买单,会报错,平多只能卖出 let id3 = exchange.Buy(-1, 1); // 设置平空方向 let _ = exchange.SetDirection("closesell"); // 下卖单,会报错,平空只能买入 let id4 = exchange.Sell(-1, 1); }
    c++
    // 以下为错误调用 void main() { exchange.SetContractType("quarter"); exchange.SetDirection("sell"); auto id = exchange.Buy(50, 1); exchange.SetDirection("buy"); auto id2 = exchange.Sell(60, 1); exchange.SetDirection("closebuy"); auto id3 = exchange.Buy(-1, 1); exchange.SetDirection("closesell"); auto id4 = exchange.Sell(-1, 1); }
  • 现货市价单。

    javascript
    // 例如交易对:ETH_BTC,市价单卖出 function main() { // 注意:下市价单卖出,卖出0.2个ETH exchange.Sell(-1, 0.2) }
    python
    def main(): exchange.Sell(-1, 0.2)
    rust
    // 例如交易对:ETH_BTC,市价单卖出 fn main() { // 注意:下市价单卖出,卖出0.2个ETH let _ = exchange.Sell(-1, 0.2); }
    c++
    void main() { exchange.Sell(-1, 0.2); }

返回值

类型描述

string / 空值

下单成功时返回订单Id,下单失败时返回空值。FMZ平台的订单Order结构的属性Id由交易所品种代码和交易所原始订单Id组成,两者以英文逗号间隔。例如OKX交易所现货交易对ETH_USDT订单的属性Id格式为:ETH-USDT,1547130415509278720。调用exchange.Sell()函数下单时,返回值订单Id与订单Order结构的Id属性一致。

参数

名称类型必填描述

price

number

price参数用于设置订单价格。

amount

number

amount参数用于设置下单量。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于向这条下单日志中输出附带信息,arg参数可以传入多个。

参考

exchange.Buy exchange.SetContractType exchange.SetDirection exchange.IO(API限流控制,Sell函数受CreateOrder限流设置影响)

备注

期货合约下单时必须注意交易方向是否设置正确,如果交易方向与交易函数不匹配将会报错。加密货币期货合约交易所的下单量如无特殊说明则以合约张数为单位。

参数price设置为-1时用于下达市价单,需要交易所的下单接口支持市价单。以市价单方式交易加密货币现货时,下卖单时,下单量参数amount以交易币为单位。以市价单方式交易加密货币期货合约时,下单量参数amount以合约张数为单位。实盘时,有少数加密货币交易所不支持市价单接口。

如使用较旧版本的托管者,exchange.Sell()函数返回的订单Id可能与当前文档中描述的返回值订单Id有所差别。

exchange.CreateOrder()函数用于下单。

exchange.CreateOrder(symbol, side, price, amount)
exchange.CreateOrder(symbol, side, price, amount, ...args)

示例

  • 现货交易所对象与期货交易所对象均通过调用exchange.CreateOrder()函数进行下单。

    javascript
    function main() { var id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) // 现货交易所对象下单,交易BTC_USDT币币交易对 // var id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) // 期货交易所对象下单,交易BTC的U本位永续合约 Log("Order Id:", id) }
    python
    def main(): id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) # 现货交易所对象下单,交易BTC_USDT币币交易对 # id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) # 期货交易所对象下单,交易BTC的U本位永续合约 Log("Order Id:", id)
    rust
    fn main() { let id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01); // 现货交易所对象下单,交易BTC_USDT币币交易对 // let id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // 期货交易所对象下单,交易BTC的U本位永续合约 Log!("Order Id:", id); }
    c++
    void main() { auto id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01); // 现货交易所对象下单,交易BTC_USDT币币交易对 // auto id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // 期货交易所对象下单,交易BTC的U本位永续合约 Log("Order Id:", id); }
  • 通过附加参数(option)下单,用于传递交易所的特定参数。

    javascript
    function main() { // 使用JSON格式传递option参数 var option = { "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" } var sideWithOption = "buy;" + JSON.stringify(option) var id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1) Log("Order Id:", id) Sleep(2000) Log(exchange.GetOrder(id)) }
    python
    import json def main(): # 使用JSON格式传递option参数 option = { "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" } sideWithOption = "buy;" + json.dumps(option) id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1) Log("Order Id:", id) Sleep(2000) Log(exchange.GetOrder(id))
    rust
    fn main() { // 使用JSON格式传递option参数(Rust不支持JSON.stringify,直接使用原始字符串构造JSON文本) let option = r#"{"type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1"}"#; let sideWithOption = format!("buy;{}", option); let id = exchange.CreateOrder("SOL_USDT.swap", &sideWithOption, -1, 1).unwrap(); Log!("Order Id:", id); Sleep(2000); Log!(exchange.GetOrder(&id)); }
    c++
    void main() { // 使用JSON格式传递option参数 json option = R"({ "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" })"_json; string sideWithOption = "buy;" + option.dump(); auto id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1); Log("Order Id:", id); Sleep(2000); Log(exchange.GetOrder(id)); }

返回值

类型描述

string / 空值

下单成功时返回订单Id,下单失败时返回空值。FMZ平台的订单Order结构的属性Id由交易所品种代码和交易所原始订单Id组成,两者以英文逗号分隔。例如OKX交易所现货交易对ETH_USDT订单的属性Id格式为:ETH-USDT,1547130415509278720

调用exchange.CreateOrder(symbol, side, price, amount)函数下单时,返回值订单Id与订单Order结构的Id属性一致。

参数

名称类型必填描述

symbol

string

参数symbol用于指定订单对应的交易对、合约代码。

当调用exchange.CreateOrder(symbol, side, price, amount)函数下单时,若exchange为现货交易所对象,且订单的计价币种为USDT、交易币种为BTC,则参数symbol为:"BTC_USDT",采用FMZ平台定义的交易对格式。

当调用exchange.CreateOrder(symbol, side, price, amount)函数下单时,若exchange为期货交易所对象,且订单为BTC的U本位永续合约订单,则参数symbol为:"BTC_USDT.swap",采用FMZ平台定义的交易对合约代码组合的格式,两者之间以字符"."分隔。

当调用exchange.CreateOrder(symbol, side, price, amount)函数下单时,若exchange为期货交易所对象,且订单为BTC的U本位期权合约订单,则参数symbol为:"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),采用FMZ平台定义的交易对与交易所定义的具体期权合约代码组合的格式,两者之间以字符"."分隔。

side

string

参数side用于指定订单的交易方向。

对于现货交易所对象,side参数的可选值为:buysell。其中buy表示买入,sell表示卖出。

对于期货交易所对象,side参数的可选值为:buyclosebuysellclosesell。其中buy表示开多仓,closebuy表示平多仓,sell表示开空仓,closesell表示平空仓。

支持附加参数(option):可以通过side参数传递附加参数,格式为:"side;{JSON对象}""side;key=value&key=value"

例如:'buy;{"type":"TRAILING_STOP_MARKET","activationPrice":"2300"}'"buy;type=TRAILING_STOP_MARKET&activationPrice=2300"

附加参数用于传递交易所特定的参数(如订单类型、生效规则等),具体支持的参数取决于交易所API。

price

number

参数price用于设置订单的价格。当价格为-1时,表示该订单为市价单。

amount

number

参数amount用于设置订单的下单量。需要注意,当订单为现货市价买单时,下单量表示买入金额;个别现货交易所的市价买单下单量为交易币数量,具体请查看「用户指南」中的交易所特殊说明。对于期货交易所对象,使用CreateOrder()/Buy()/Sell()函数下单时,如无特殊说明,下单量参数amount均以合约张数为单位。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于将附带信息输出到本次下单日志中,arg参数可以传入多个。

参考

备注

支持通过side参数传递附加参数(option),用于指定交易所特定的参数。附加参数需与side参数合并传入,格式为"side;{JSON对象}"(推荐)或"side;key=value&key=value"(URL编码格式)。例如:"buy;{\"type\":\"TRAILING_STOP_MARKET\"}"

不同交易所支持的option参数各不相同,具体支持的参数以交易所API文档为准。常见参数包括:订单类型(type)、生效规则(timeInForce)、触发价格(activationPrice)、回调比率(callbackRate)等。

使用option参数时,仍需提供priceamount参数。若某些参数已通过option传递,则这些基础参数可能会被option中的对应参数覆盖,具体行为取决于交易所API的实现。

exchange.CancelOrder()函数用于取消订单。FMZ平台的订单Order结构中,属性Id由交易所品种代码和交易所原始订单Id组成,两者之间以英文逗号分隔。例如,OKX交易所现货交易对ETH_USDT的订单,其属性Id的格式为:ETH-USDT,1547130415509278720

调用exchange.CancelOrder()函数撤销订单时,传入的参数orderId与订单Order结构的Id属性一致。

exchange.CancelOrder(orderId)
exchange.CancelOrder(orderId, ...args)

示例

  • 撤销订单。

    javascript
    function main(){ var id = exchange.Sell(99999, 1) exchange.CancelOrder(id) }
    python
    def main(): id = exchange.Sell(99999, 1) exchange.CancelOrder(id)
    rust
    fn main() { let id = exchange.Sell(99999, 1).unwrap(); let _ = exchange.CancelOrder(&id); }
    c++
    void main() { auto id = exchange.Sell(99999, 1); exchange.CancelOrder(id); }
  • FMZ的API函数中,能够产生日志输出的函数(例如Log()exchange.Buy()exchange.CancelOrder()等)都可以在必要参数之后附带一些输出参数。

    例如:exchange.CancelOrder(orders[i].Id, orders[i]),即在取消Id为orders[i].Id的订单时,附带输出该订单的信息,也就是orders[i]这个Order结构。

    javascript
    function main() { if (exchange.GetName().includes("Futures_")) { Log("Set contract to: perpetual swap, set direction to: open long.") exchange.SetContractType("swap") exchange.SetDirection("buy") } var ticker = exchange.GetTicker() exchange.Buy(ticker.Last * 0.5, 0.1) var orders = exchange.GetOrders() for (var i = 0 ; i < orders.length ; i++) { exchange.CancelOrder(orders[i].Id, "Canceled order:", orders[i]) Sleep(500) } }
    python
    def main(): if exchange.GetName().find("Futures_") != -1: Log("Set contract to: perpetual swap, set direction to: open long.") exchange.SetContractType("swap") exchange.SetDirection("buy") ticker = exchange.GetTicker() exchange.Buy(ticker["Last"] * 0.5, 0.1) orders = exchange.GetOrders() for i in range(len(orders)): exchange.CancelOrder(orders[i]["Id"], "Canceled order:", orders[i]) Sleep(500)
    rust
    fn main() { if exchange.GetName().contains("Futures_") { Log!("Set contract to: perpetual swap, set direction to: open long."); let _ = exchange.SetContractType("swap"); let _ = exchange.SetDirection("buy"); } let ticker = exchange.GetTicker(None).unwrap(); let _ = exchange.Buy(ticker.Last * 0.5, 0.1); let orders = exchange.GetOrders(None).unwrap(); for i in 0..orders.len() { // Rust不支持在CancelOrder的必要参数后附带输出参数,撤单后单独调用Log!宏输出附带信息 let _ = exchange.CancelOrder(&orders[i].Id); Log!("Canceled order:", orders[i]); Sleep(500); } }
    c++
    void main() { if (exchange.GetName().find("Futures_") != std::string::npos) { Log("Set contract to: perpetual swap, set direction to: open long."); exchange.SetContractType("swap"); exchange.SetDirection("buy"); } auto ticker = exchange.GetTicker(); exchange.Buy(ticker.Last * 0.5, 0.1); auto orders = exchange.GetOrders(); for (int i = 0 ; i < orders.size() ; i++) { exchange.CancelOrder(orders[i].Id, "Canceled order:", orders[i]); Sleep(500); } }

返回值

类型描述

bool

exchange.CancelOrder()函数返回真值(例如true)表示取消订单请求发送成功,返回假值(例如false)表示取消订单请求发送失败。返回值仅代表请求发送成功或失败;若要判断交易所是否已取消订单,可以调用exchange.GetOrders()进行判断。

参数

名称类型必填描述

orderId

string

参数orderId用于指定所要取消的订单。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于将附带信息输出到本条撤单日志中;arg参数可以传入多个。

参考

备注

如果使用较旧版本的托管者,exchange.CancelOrder()函数的参数orderId可能与当前文档中描述的orderId有所差别。

exchange.GetOrder()函数用于获取订单信息。

exchange.GetOrder(orderId)

示例

javascript
function main(){ var id = exchange.Sell(1000, 1) // 参数id为订单号码,需填入你想要查询的订单的号码 var order = exchange.GetOrder(id) Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type) }
python
def main(): id = exchange.Sell(1000, 1) order = exchange.GetOrder(id) Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:", order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
rust
fn main() { let id = exchange.Sell(1000, 1).unwrap(); // 参数id为订单号码,需填入你想要查询的订单的号码 let order = exchange.GetOrder(&id).unwrap(); Log!("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type); }
c++
void main() { auto id = exchange.Sell(1000, 1); auto order = exchange.GetOrder(id); Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", order.DealAmount, "Status:", order.Status, "Type:", order.Type); }

返回值

类型描述

Order / 空值

根据订单号查询订单详情,查询成功时返回Order结构,查询失败时返回空值。

参数

名称类型必填描述

orderId

string

orderId参数用于指定要查询的订单。FMZ平台订单Order结构的Id属性由交易所品种代码和交易所原始订单Id组成,以英文逗号分隔。例如,OKX交易所现货交易对ETH_USDT订单的Id属性格式为:ETH-USDT,1547130415509278720

调用exchange.GetOrder()函数查询订单时,传入的参数orderId与订单Order结构的Id属性一致。

参考

备注

部分交易所不支持exchange.GetOrder()函数。返回值Order结构中的AvgPrice属性为成交均价,部分交易所不支持该字段,若不支持则将其设置为0。

如果使用较旧版本的托管者,exchange.GetOrder()函数的参数orderId可能与当前文档中描述的orderId存在差异。

不支持exchange.GetOrder()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetOrderZaif / Coincheck / Bitstamp--

exchange.GetOrders()函数用于获取当前未完成的订单。

exchange.GetOrders()
exchange.GetOrders(symbol)

示例

  • 使用现货交易所对象,针对多个不同的交易对,以当前价格的一半作为下单价格挂出买单,随后查询未成交订单的信息。

    javascript
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"] for (var symbol of arrSymbol) { var t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t.Last / 2, 0.01) } var spotOrders = exchange.GetOrders() var tbls = [] for (var orders of [spotOrders]) { var tbl = {type: "table", title: "test GetOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []} for (var order of orders) { tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) } tbls.push(tbl) } LogStatus("`" + JSON.stringify(tbls) + "`") // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return }
    python
    '''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"] for symbol in arrSymbol: t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t["Last"] / 2, 0.01) spotOrders = exchange.GetOrders() tbls = [] for orders in [spotOrders]: tbl = {"type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": []} for order in orders: tbl["rows"].append([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) tbls.append(tbl) LogStatus("`" + json.dumps(tbls) + "`") return
    rust
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ fn main() { let arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"]; for symbol in arrSymbol { let t = exchange.GetTicker(symbol).unwrap(); let _ = exchange.CreateOrder(symbol, "buy", t.Last / 2.0, 0.01); } let spotOrders = exchange.GetOrders(None).unwrap(); // Rust不支持JSON.stringify,使用format!拼接表格的JSON文本 let mut tbls = Vec::new(); for orders in [&spotOrders] { let mut rows = Vec::new(); for order in orders { rows.push(format!(r#"["{}", "{}", {}, {}, {}, {}, {}, {}, {}, "{}"]"#, order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType)); } let tbl = format!(r#"{{"type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [{}]}}"#, rows.join(",")); tbls.push(tbl); } LogStatus!(format!("`[{}]`", tbls.join(","))); // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return; }
    c++
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"}; for (const auto& symbol : arrSymbol) { auto t = exchange.GetTicker(symbol); exchange.CreateOrder(symbol, "buy", t.Last / 2, 0.01); } auto spotOrders = exchange.GetOrders(); json tbls = R"([])"_json; std::vector<std::vector<Order>> arr = {spotOrders}; for (const auto& orders : arr) { json tbl = R"({ "type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [] })"_json; for (const auto& order : orders) { json arrJson = R"([])"_json; arrJson.push_back("Symbol"); arrJson.push_back("Id"); arrJson.push_back(order.Price); arrJson.push_back(order.Amount); arrJson.push_back(order.DealAmount); arrJson.push_back(order.AvgPrice); arrJson.push_back(order.Status); arrJson.push_back(order.Type); arrJson.push_back(order.Offset); arrJson.push_back(order.ContractType); tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); } LogStatus(_D(), "\n", "`" + tbls.dump() + "`"); return; }
  • 使用期货交易所对象,对多个不同交易对、不同合约代码的品种进行下单。下单价格远离盘口对手价,使订单保持未成交状态,并按多种方式查询订单。

    javascript
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for (var symbol of arrSymbol) { var t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t.Last / 2, 1) exchange.CreateOrder(symbol, "sell", t.Last * 2, 1) } var defaultOrders = exchange.GetOrders() var swapOrders = exchange.GetOrders("USDT.swap") var futuresOrders = exchange.GetOrders("USDT.futures") var btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap") var tbls = [] var arr = [defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders] var tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"] for (var index in arr) { var orders = arr[index] var tbl = {type: "table", title: tblDesc[index], cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []} for (var order of orders) { tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) } tbls.push(tbl) } LogStatus("`" + JSON.stringify(tbls) + "`") // 打印输出一次信息后立即返回,防止后续回测过程中订单成交而影响数据观察 return }
    python
    '''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for symbol in arrSymbol: t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t["Last"] / 2, 1) exchange.CreateOrder(symbol, "sell", t["Last"] * 2, 1) defaultOrders = exchange.GetOrders() swapOrders = exchange.GetOrders("USDT.swap") futuresOrders = exchange.GetOrders("USDT.futures") btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap") tbls = [] arr = [defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders] tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"] for index in range(len(arr)): orders = arr[index] tbl = {"type": "table", "title": tblDesc[index], "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": []} for order in orders: tbl["rows"].append([order["Symbol"], order["Id"], order["Price"], order["Amount"], order["DealAmount"], order["AvgPrice"], order["Status"], order["Type"], order["Offset"], order["ContractType"]]) tbls.append(tbl) LogStatus("`" + json.dumps(tbls) + "`") return
    rust
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ fn main() { let arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]; for symbol in arrSymbol { let t = exchange.GetTicker(symbol).unwrap(); let _ = exchange.CreateOrder(symbol, "buy", t.Last / 2.0, 1); let _ = exchange.CreateOrder(symbol, "sell", t.Last * 2.0, 1); } let defaultOrders = exchange.GetOrders(None).unwrap(); let swapOrders = exchange.GetOrders("USDT.swap").unwrap(); let futuresOrders = exchange.GetOrders("USDT.futures").unwrap(); let btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap").unwrap(); // Rust 不支持 JSON.stringify,此处使用 format! 拼接表格的 JSON 文本 let mut tbls = Vec::new(); let arr = [&defaultOrders, &swapOrders, &futuresOrders, &btcUsdtSwapOrders]; let tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"]; for index in 0..arr.len() { let orders = arr[index]; let mut rows = Vec::new(); for order in orders { rows.push(format!(r#"["{}", "{}", {}, {}, {}, {}, {}, {}, {}, "{}"]"#, order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType)); } let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [{}]}}"#, tblDesc[index], rows.join(",")); tbls.push(tbl); } LogStatus!(format!("`[{}]`", tbls.join(","))); // 打印输出一次信息后立即返回,防止后续回测过程中订单成交而影响数据观察 return; }
    c++
    /*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"}; for (const auto& symbol : arrSymbol) { auto t = exchange.GetTicker(symbol); exchange.CreateOrder(symbol, "buy", t.Last / 2, 1); exchange.CreateOrder(symbol, "sell", t.Last * 2, 1); } auto defaultOrders = exchange.GetOrders(); auto swapOrders = exchange.GetOrders("USDT.swap"); auto futuresOrders = exchange.GetOrders("USDT.futures"); auto btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap"); json tbls = R"([])"_json; std::vector<std::vector<Order>> arr = {defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders}; std::string tblDesc[] = {"defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"}; for (int index = 0; index < arr.size(); index++) { auto orders = arr[index]; json tbl = R"({ "type": "table", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [] })"_json; tbl["title"] = tblDesc[index]; for (const auto& order : orders) { json arrJson = R"([])"_json; arrJson.push_back(order.Symbol); arrJson.push_back(to_string(order.Id)); // Order 订单结构中的 Id 属性类型为 TId,此处使用 FMZ 平台内置的 C++ 函数 to_string 进行编码 arrJson.push_back(order.Price); arrJson.push_back(order.Amount); arrJson.push_back(order.DealAmount); arrJson.push_back(order.AvgPrice); arrJson.push_back(order.Status); arrJson.push_back(order.Type); arrJson.push_back(order.Offset); arrJson.push_back(order.ContractType); tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); } LogStatus(_D(), "\n", "`" + tbls.dump() + "`"); return; }
  • 调用exchange.GetOrders()函数时,可传入Symbol参数以指定请求特定交易对或合约代码的订单数据。

    javascript
    function main() { var orders = exchange.GetOrders("BTC_USDT") // 现货品种示例 // var orders = exchange.GetOrders("BTC_USDT.swap") // 期货品种示例 Log("orders:", orders) }
    python
    def main(): orders = exchange.GetOrders("BTC_USDT") # 现货品种示例 # orders = exchange.GetOrders("BTC_USDT.swap") # 期货品种示例 Log("orders:", orders)
    rust
    fn main() { let orders = exchange.GetOrders("BTC_USDT"); // 现货品种示例 // let orders = exchange.GetOrders("BTC_USDT.swap"); // 期货品种示例 Log!("orders:", orders); }
    c++
    void main() { auto orders = exchange.GetOrders("BTC_USDT"); // 现货品种示例 // auto orders = exchange.GetOrders("BTC_USDT.swap"); // 期货品种示例 Log("orders:", orders); }

返回值

类型描述

Order数组 / 空值

exchange.GetOrders()函数请求数据成功时返回Order结构数组,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所要查询的交易品种交易品种范围

对于现货交易所对象,若不传入symbol参数,则请求所有现货品种的未完成订单数据。

对于期货交易所对象,若不传入symbol参数,则默认以当前交易对、合约代码所在的维度范围,请求该范围内所有品种的未完成订单数据。

参考

备注

GetOrders函数中,symbol参数的使用场景归纳如下:

交易所对象分类symbol参数查询范围备注
现货不传symbol参数查询所有现货交易对适用于所有调用场景;若交易所接口不支持,则报错返回空值,以下不再赘述
现货指定交易品种,symbol参数为:"BTC_USDT"查询指定的BTC_USDT交易对对于现货交易所对象,参数symbol的格式为:"BTC_USDT"
期货不传symbol参数查询当前交易对、合约代码维度范围内的所有交易品种假如当前交易对为BTC_USDT,合约代码为swap,即查询所有USDT本位永续合约。等价于调用GetOrders("USDT.swap")
期货指定交易品种,symbol参数为:"BTC_USDT.swap"查询指定的BTC的USDT本位永续合约对于期货交易所对象,参数symbol的格式为:FMZ平台定义的交易对合约代码的组合,以字符"."间隔。
期货指定交易品种范围,symbol参数为:"USDT.swap"查询所有USDT本位永续合约-
支持期权的期货交易所不传symbol参数查询当前交易对维度范围内的所有期权合约假如当前交易对为BTC_USDT,且合约设置为期权合约,例如币安期权合约:BTC-240108-40000-C
支持期权的期货交易所指定具体交易品种查询指定的期权合约例如对于币安期货交易所,symbol参数为:BTC_USDT.BTC-240108-40000-C
支持期权的期货交易所指定交易品种范围,symbol参数为:"USDT.option"查询所有USDT本位期权合约-

GetOrders函数中,期货交易所对象的查询维度范围归纳如下:

symbol参数请求范围定义备注
USDT.swapUSDT本位永续合约范围。对于交易所API接口不支持的维度,调用时会报错返回空值。
USDT.futuresUSDT本位交割合约范围。-
USD.swap币本位永续合约范围。-
USD.futures币本位交割合约范围。-
USDT.optionUSDT本位期权合约范围。-
USD.option币本位期权合约范围。-
USDT.futures_combo差价组合合约范围。Futures_Deribit交易所
USD.futures_ff混合保证金交割合约范围。Futures_Kraken交易所
USD.swap_pf混合保证金永续合约范围。Futures_Kraken交易所

当交易所对象exchange所代表的账户在查询范围内指定的交易品种上没有挂单(即处于未成交状态的活动订单)时,调用该函数将返回空数组,即:[]

以下交易所查询当前未完成订单的接口必须传入品种参数。使用这些交易所调用GetOrders函数时,若未传入symbol参数,则仅请求当前品种的未完成订单,而非所有品种的未完成订单(因为交易所接口不支持)。

Zaif、MEXC、LBank、Korbit、Coinw、BitMart、Bithumb、BitFlyer、BigONE。

不支持exchange.GetOrders()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetOrders--Futures_Bibox

exchange.GetHistoryOrders()函数用于获取当前交易对、合约的历史订单,并支持指定具体的交易品种。

exchange.GetHistoryOrders()
exchange.GetHistoryOrders(symbol)
exchange.GetHistoryOrders(symbol, since)
exchange.GetHistoryOrders(symbol, since, limit)
exchange.GetHistoryOrders(since)
exchange.GetHistoryOrders(since, limit)

示例

javascript
function main() { var historyOrders = exchange.GetHistoryOrders() Log(historyOrders) }
python
def main(): historyOrders = exchange.GetHistoryOrders() Log(historyOrders)
rust
fn main() { let historyOrders = exchange.GetHistoryOrders(None, None, None); Log!(historyOrders); }
c++
void main() { auto historyOrders = exchange.GetHistoryOrders(); Log(historyOrders); }

返回值

类型描述

Order数组 / 空值

exchange.GetHistoryOrders()函数在请求数据成功时返回Order结构数组,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

symbol参数用于指定交易品种。以BTC_USDT交易对为例:当exchange为现货交易所对象时,symbol参数格式为BTC_USDT;当exchange为期货交易所对象时,以永续合约为例,symbol参数格式为BTC_USDT.swap

如果查询的是期权合约的订单数据,参数symbol需设置为"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码的组合,两者之间以字符"."间隔。若不传该参数,则默认请求当前设置的交易对、合约代码的订单数据。

since

number

since参数用于指定查询的起始时间戳,单位为毫秒。

limit

number

limit参数用于指定查询的订单数量。

参考

备注

  • 未指定symbolsincelimit参数时,默认查询当前交易对、合约的历史订单,即查询距当前时间最近的一定范围内的历史订单,具体查询范围取决于交易所接口的单次查询范围。

  • 指定symbol参数时,查询所设置交易品种的历史订单。

  • 指定since参数时,以since时间戳为起始时间,向当前时间方向查询。

  • 指定limit参数时,查询到足够条数后返回。

  • 该函数仅支持提供历史订单查询接口的交易所。

不支持exchange.GetHistoryOrders()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetHistoryOrdersZaif / Upbit / Coincheck / Bitstamp / Bithumb / BitFlyer / BigONEFutures_Bibox / Futures_ApolloX

exchange.CreateConditionOrder()函数用于创建条件单。条件单是一种在满足特定触发条件时自动执行的订单类型。

exchange.CreateConditionOrder(symbol, side, amount, condition)
exchange.CreateConditionOrder(symbol, side, amount, condition, ...args)

示例

  • 创建止盈单(TP):当价格上涨至目标价位时自动卖出。

    javascript
    function main() { // 创建止盈单:当BTC_USDT价格上涨至65000时,以65000的价格卖出0.01个BTC var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, // 止盈单 TpTriggerPrice: 65000, // 触发价格 TpOrderPrice: 65000 // 执行价格,也可设置为-1表示市价单 } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id) }
    python
    def main(): # 创建止盈单:当BTC_USDT价格上涨至65000时,以65000的价格卖出0.01个BTC condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, # 止盈单 "TpTriggerPrice": 65000, # 触发价格 "TpOrderPrice": 65000 # 执行价格,也可设置为-1表示市价单 } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id)
    rust
    fn main() { // 创建止盈单:当BTC_USDT价格上涨至65000时,以65000的价格卖出0.01个BTC let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, // 止盈单 TpTriggerPrice: 65000.0, // 触发价格 TpOrderPrice: 65000.0, // 执行价格,也可设置为-1表示市价单 ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("TP order Id:", id); }
    c++
    void main() { // 创建止盈单:当BTC_USDT价格上涨至65000时,以65000的价格卖出0.01个BTC OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("TP order Id:", id); }
  • 创建止损单(SL):当价格下跌至止损触发价位时,自动以设定方式卖出。

    javascript
    function main() { // 创建止损单:当BTC_USDT价格下跌至58000时,以市价卖出0.01个BTC var condition = { ConditionType: ORDER_CONDITION_TYPE_SL, // 止损单 SlTriggerPrice: 58000, // 触发价格 SlOrderPrice: -1 // -1表示市价单 } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id) }
    python
    def main(): # 创建止损单:当BTC_USDT价格下跌至58000时,以市价卖出0.01个BTC condition = { "ConditionType": ORDER_CONDITION_TYPE_SL, # 止损单 "SlTriggerPrice": 58000, # 触发价格 "SlOrderPrice": -1 # -1表示市价单 } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id)
    rust
    fn main() { // 创建止损单:当BTC_USDT价格下跌至58000时,以市价卖出0.01个BTC let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, // 止损单 SlTriggerPrice: 58000.0, // 触发价格 SlOrderPrice: -1.0, // -1表示市价单 ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("SL order Id:", id); }
    c++
    void main() { // 创建止损单:当BTC_USDT价格下跌至58000时,以市价卖出0.01个BTC OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = -1}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("SL order Id:", id); }
  • 创建 OCO 订单:同时设置止盈和止损,任意一个触发后,另一个将自动取消。

    javascript
    function main() { // 创建 OCO 订单:止盈价 65000,止损价 58000 var condition = { ConditionType: ORDER_CONDITION_TYPE_OCO, // OCO 订单 TpTriggerPrice: 65000, // 止盈触发价格 TpOrderPrice: 65000, // 止盈执行价格 SlTriggerPrice: 58000, // 止损触发价格 SlOrderPrice: 58000 // 止损执行价格 } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("OCO order Id:", id) }
    python
    def main(): # 创建 OCO 订单:止盈价 65000,止损价 58000 condition = { "ConditionType": ORDER_CONDITION_TYPE_OCO, # OCO 订单 "TpTriggerPrice": 65000, # 止盈触发价格 "TpOrderPrice": 65000, # 止盈执行价格 "SlTriggerPrice": 58000, # 止损触发价格 "SlOrderPrice": 58000 # 止损执行价格 } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("OCO order Id:", id)
    rust
    fn main() { // 创建 OCO 订单:止盈价 65000,止损价 58000 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_OCO, // OCO 订单 TpTriggerPrice: 65000.0, // 止盈触发价格 TpOrderPrice: 65000.0, // 止盈执行价格 SlTriggerPrice: 58000.0, // 止损触发价格 SlOrderPrice: 58000.0 // 止损执行价格 }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("OCO order Id:", id); }
    c++
    void main() { // 创建 OCO 订单:止盈价 65000,止损价 58000 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_OCO, .TpTriggerPrice = 65000, .TpOrderPrice = 65000, .SlTriggerPrice = 58000, .SlOrderPrice = 58000}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("OCO order Id:", id); }
  • 使用附加参数(option)创建条件单,用于传递交易所特定的参数。

    javascript
    function main() { // 以 JSON 格式传递 option 参数 var option = { "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" } var sideWithOption = "buy;" + JSON.stringify(option) var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 71 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition) Log("Condition Order Id:", id) Sleep(2000) Log(exchange.GetConditionOrder(id)) }
    python
    import json def main(): # 以 JSON 格式传递 option 参数 option = { "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" } sideWithOption = "buy;" + json.dumps(option) condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 71 } id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition) Log("Condition Order Id:", id) Sleep(2000) Log(exchange.GetConditionOrder(id))
    rust
    fn main() { // 以 JSON 格式传递 option 参数(Rust 无 JSON 序列化功能,此处直接使用原始字符串构造) let option = r#"{"type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1"}"#; let sideWithOption = format!("buy;{}", option); let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 71.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", &sideWithOption, 1, &condition).unwrap(); Log!("Condition Order Id:", id); Sleep(2000); Log!(exchange.GetConditionOrder(&id)); }
    c++
    void main() { // 以 JSON 格式传递 option 参数 json option = R"({ "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" })"_json; string sideWithOption = "buy;" + option.dump(); OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 71}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition); Log("Condition Order Id:", id); Sleep(2000); Log(exchange.GetConditionOrder(id)); }

返回值

类型描述

string / 空值

创建条件单成功时返回条件单Id,创建失败时返回空值。条件单Id的格式与普通订单Id类似,由交易所品种代码和交易所原始条件单Id组成,两者之间以英文逗号分隔。

参数

名称类型必填描述

symbol

string

参数symbol用于指定条件单对应的交易对或合约代码。

当调用exchange.CreateConditionOrder(symbol, side, amount, condition)函数下条件单时,若exchange为现货交易所对象,且订单的计价币种为USDT、交易币种为BTC,则参数symbol为:"BTC_USDT",其格式为FMZ平台定义的交易对格式。

当调用exchange.CreateConditionOrder(symbol, side, amount, condition)函数下条件单时,若exchange为期货交易所对象,且订单为BTC的U本位永续合约订单,则参数symbol为:"BTC_USDT.swap",其格式为FMZ平台定义的交易对合约代码的组合,两者之间以字符"."分隔。

当调用exchange.CreateConditionOrder(symbol, side, amount, condition)函数下条件单时,若exchange为期货交易所对象,且订单为BTC的U本位期权合约订单,则参数symbol为:"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码的组合,两者之间以字符"."分隔。

side

string

参数side用于指定条件单的交易方向。

对于现货交易所对象,side参数的可选值为:buysellbuy表示买入,sell表示卖出。

对于期货交易所对象,side参数的可选值为:buyclosebuysellclosesell。其中buy表示开多仓,closebuy表示平多仓,sell表示开空仓,closesell表示平空仓。

支持附加参数(option):可以通过side参数传递附加参数,格式为:"side;{JSON对象}""side;key=value&key=value"

例如:"buy;{\"type\":\"TRAILING_STOP_MARKET\",\"activatePrice\":\"300\"}""buy;type=TRAILING_STOP_MARKET&activatePrice=300"

附加参数用于传递交易所特定的参数(如订单类型、生效规则等),具体支持的参数取决于交易所API。

amount

number

参数amount用于设置条件单的下单量。需要注意的是,当订单为现货市价买单时,下单量表示买入金额;个别现货交易所的市价买单下单量为交易币数量,具体请查看「用户指南」中的交易所特殊说明。对于期货交易所对象,下单量参数amount均以合约张数为单位。

condition

object

参数condition是一个对象,用于设置条件单的触发条件和执行价格。该对象的结构参考Condition结构,包含以下属性:

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于将附带信息输出到该条条件单的日志中,arg参数可以传入多个。

参考

备注

条件单功能的支持情况取决于具体交易所,部分交易所可能不支持条件单功能。

条件单在触发前不会占用账户资金,仅在触发后才会实际下单并占用资金。

不同交易所对条件单的支持程度及具体参数可能有所差异,使用前请查阅对应交易所的 API 文档。

支持通过side参数传递附加参数(option),用于传递交易所特定的参数。附加参数需与side参数合并传入,格式为"side;{JSON对象}"(推荐)或"side;key=value&key=value"(URL 编码格式)。例如:"buy;{\"type\":\"TRAILING_STOP_MARKET\"}"

不同交易所支持的 option 参数各不相同,具体支持的参数取决于交易所 API 文档。常见参数包括:订单类型(type)、生效规则(timeInForce)、触发价格(activatePrice)、回调比率(callbackRate)等。

使用 option 参数时,仍需提供amountcondition参数。如果交易所 API 中的某些参数已通过 option 传递,这些基础参数可能会被 option 中的对应参数覆盖,具体行为取决于交易所 API 的实现。

exchange.ModifyOrder()函数用于修改现有的普通订单,可修改订单的价格和数量。该函数支持通过附加参数修改订单的其它属性(具体取决于交易所 API 的支持情况)。

exchange.ModifyOrder(orderId, side, price, amount)

示例

  • 修改普通订单的价格和数量。

    javascript
    function main() { // 创建一个限价买单 var id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1) Log("Original Order ID:", id) Sleep(2000) // 查询原始订单信息 var order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) // 修改订单的价格和数量 var newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) // 查询修改后的订单信息 var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // 取消订单 exchange.CancelOrder(newId) }
    python
    def main(): # 创建一个限价买单 id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1) Log("Original Order ID:", id) Sleep(2000) # 查询原始订单信息 order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) # 修改订单的价格和数量 newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) # 查询修改后的订单信息 newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # 取消订单 exchange.CancelOrder(newId)
    rust
    fn main() { // 创建一个限价买单 let id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1).unwrap(); Log!("Original Order ID:", id); Sleep(2000); // 查询原始订单信息 let order = exchange.GetOrder(&id).unwrap(); Log!("Original Order Info:", order); Sleep(1000); // 修改订单的价格和数量 let newId = exchange.ModifyOrder(&id, "buy", 77, 2).unwrap(); Log!("Modified Order ID:", newId); Sleep(2000); // 查询修改后的订单信息 let newOrder = exchange.GetOrder(&newId).unwrap(); Log!("Modified Order Info:", newOrder); // 取消订单 let _ = exchange.CancelOrder(&newId); }
    c++
    void main() { // 创建一个限价买单 auto id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1); Log("Original Order ID:", id); Sleep(2000); // 查询原始订单信息 auto order = exchange.GetOrder(id); Log("Original Order Info:", order); Sleep(1000); // 修改订单的价格和数量 auto newId = exchange.ModifyOrder(id, "buy", 77, 2); Log("Modified Order ID:", newId); Sleep(2000); // 查询修改后的订单信息 auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // 取消订单 exchange.CancelOrder(newId); }
  • 使用附加参数(option)修改订单的价格匹配模式。

    javascript
    function main() { // 创建一个限价买单 var id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1) Log("Original Order ID:", id) Sleep(2000) // 修改订单,并将价格匹配模式设置为 QUEUE_20 // 通过 side 参数传递附加参数(JSON 格式) var option = {"priceMatch": "QUEUE_20"} var sideWithOption = "buy;" + JSON.stringify(option) var newId = exchange.ModifyOrder(id, sideWithOption, -1, 2) Log("Modified Order ID:", newId) Sleep(2000) // 查询修改后的订单信息 var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // 撤销订单 exchange.CancelOrder(newId) }
    python
    import json def main(): # 创建一个限价买单 id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1) Log("Original Order ID:", id) Sleep(2000) # 修改订单,并将价格匹配模式设置为 QUEUE_20 # 通过 side 参数传递附加参数(JSON 格式) option = {"priceMatch": "QUEUE_20"} sideWithOption = "buy;" + json.dumps(option) newId = exchange.ModifyOrder(id, sideWithOption, -1, 2) Log("Modified Order ID:", newId) Sleep(2000) # 查询修改后的订单信息 newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # 撤销订单 exchange.CancelOrder(newId)
    rust
    fn main() { // 创建一个限价买单 let id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1).unwrap(); Log!("Original Order ID:", id); Sleep(2000); // 修改订单,并将价格匹配模式设置为 QUEUE_20 // 通过 side 参数传递附加参数(JSON 格式);Rust 不支持 JSON.stringify,因此直接使用原始字符串构造 JSON 文本 let option = r#"{"priceMatch": "QUEUE_20"}"#; let sideWithOption = format!("buy;{}", option); let newId = exchange.ModifyOrder(&id, &sideWithOption, -1, 2).unwrap(); Log!("Modified Order ID:", newId); Sleep(2000); // 查询修改后的订单信息 let newOrder = exchange.GetOrder(&newId).unwrap(); Log!("Modified Order Info:", newOrder); // 撤销订单 let _ = exchange.CancelOrder(&newId); }
    c++
    void main() { // 创建一个限价买单 auto id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1); Log("Original Order ID:", id); Sleep(2000); // 修改订单,并将价格匹配模式设置为 QUEUE_20 // 通过 side 参数传递附加参数(JSON 格式) json option = R"({"priceMatch": "QUEUE_20"})"_json; string sideWithOption = "buy;" + option.dump(); auto newId = exchange.ModifyOrder(id, sideWithOption, -1, 2); Log("Modified Order ID:", newId); Sleep(2000); // 查询修改后的订单信息 auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // 撤销订单 exchange.CancelOrder(newId); }

返回值

类型描述

string / 空值

修改订单成功时返回订单 ID,修改失败时返回空值。返回的订单 ID 可能与原订单 ID 相同,也可能不同,这取决于交易所 API 的实现方式。某些交易所在修改订单后会返回新的订单 ID,而有些交易所则保持订单 ID 不变。

参数

名称类型必填描述

orderId

string

参数orderId用于指定待修改的原订单 ID。订单 ID 的格式与exchange.CreateOrder函数返回的订单 ID 一致,由交易所品种代码和交易所原始订单 ID 组成,两者以英文逗号分隔。例如:"ETH-USDT,1547130415509278720"

side

string

参数side用于指定订单的交易方向。

对于现货交易所对象,side参数的可选值为:buysell。其中buy表示买入,sell表示卖出。

对于期货交易所对象,side参数的可选值为:buyclosebuysellclosesell。其中buy表示开多仓,closebuy表示平多仓,sell表示开空仓,closesell表示平空仓。

支持附加参数(option):可通过side参数传递附加参数,格式为"side;{JSON对象}""side;key=value&key=value"

例如:"buy;{\"priceMatch\":\"QUEUE_20\"}""buy;priceMatch=QUEUE_20"

附加参数用于修改订单的其它属性(如价格匹配模式等),具体支持的参数取决于交易所 API。

price

number

参数price用于设置订单的新价格。当价格为 -1 时表示不修改价格,或根据交易所 API 的实现,可能转为市价单。

amount

number

参数amount用于设置订单的新下单量。当数量为 -1 时表示不修改数量。需要注意的是,当订单为现货市价买单时,下单量表示买入金额;个别现货交易所的市价买单,其下单量为交易币的数量。

参考

备注

exchange.ModifyOrder()函数返回的订单 ID 因交易所 API 的实现不同而可能有不同的行为。有些交易所 API 返回的订单 ID 会更新,有些则保持不变。建议使用返回的新订单 ID 进行后续操作。

exchange.ModifyOrder()函数不会依据交易所接口规则校验参数的有效性,而是将参数直接提交给交易所 API。传入无效参数时(如价格或数量为 -1),参数可能会被交易所忽略,订单将保持原有属性不变。

支持通过side参数传递附加参数(option),用于修改订单的其它属性。附加参数需与side参数合并后传入,格式为"side;{JSON对象}"(推荐)或"side;key=value"(URL 编码格式)。例如,修改价格匹配模式:"buy;{\"priceMatch\":\"QUEUE_20\"}"

对于普通订单的市价单修改,需具体查看交易所 API 是否支持。有些交易所不支持对市价单进行修改操作。

修改订单时,订单的其它属性(如订单类型、持仓模式、账户模式、杠杆、订单生效规则等)通常会保留原订单的设置。如需修改这些属性,可通过附加参数(option)传入,前提是交易所 API 支持。

个别交易所 API 在未接收到价格参数时(price 为 -1 或 null),可能会将订单转为市价单。对于现货市价买单,需要注意其下单量单位可能是金额而非币数。

修改订单功能的支持情况取决于具体交易所,部分交易所可能不支持修改订单功能,或仅支持修改部分参数。使用前请查阅对应交易所的 API 文档。

exchange.ModifyConditionOrder()函数用于修改现有的条件单,可修改条件单的下单量、触发条件和执行价格。支持通过附加参数修改条件单的其它属性(具体取决于交易所API的支持情况)。

exchange.ModifyConditionOrder(orderId, side, amount, condition)

示例

  • 修改条件单的数量和触发条件。

    javascript
    function main() { // 创建一个止盈条件单 var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 76 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) // 查询原始条件单信息 var order = exchange.GetConditionOrder(id) Log("Original Condition Order Info:", order) Sleep(1000) // 修改条件单的数量和触发条件 var newCondition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75, TpOrderPrice: 71 } var newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) // 查询修改后的条件单信息 var newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) // 取消条件单 exchange.CancelConditionOrder(newId) }
    python
    def main(): # 创建一个止盈条件单 condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 76 } id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) # 查询原始条件单信息 order = exchange.GetConditionOrder(id) Log("Original Condition Order Info:", order) Sleep(1000) # 修改条件单的数量和触发条件 newCondition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 75, "TpOrderPrice": 71 } newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) # 查询修改后的条件单信息 newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) # 取消条件单 exchange.CancelConditionOrder(newId)
    rust
    fn main() { // 创建一个止盈条件单 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 76.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, &condition).unwrap(); Log!("Original Condition Order ID:", id); Sleep(2000); // 查询原始条件单信息 let order = exchange.GetConditionOrder(&id); Log!("Original Condition Order Info:", order); Sleep(1000); // 修改条件单的数量和触发条件 let newCondition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75.0, TpOrderPrice: 71.0, ..Default::default() }; let newId = exchange.ModifyConditionOrder(&id, "buy", 2, &newCondition).unwrap(); Log!("Modified Condition Order ID:", newId); Sleep(2000); // 查询修改后的条件单信息 let newOrder = exchange.GetConditionOrder(&newId); Log!("Modified Condition Order Info:", newOrder); // 取消条件单 let _ = exchange.CancelConditionOrder(&newId); }
    c++
    void main() { // 创建一个止盈条件单 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 76}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition); Log("Original Condition Order ID:", id); Sleep(2000); // 查询原始条件单信息 auto order = exchange.GetConditionOrder(id); Log("Original Condition Order Info:", order); Sleep(1000); // 修改条件单的数量和触发条件 OrderCondition newCondition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 75, .TpOrderPrice = 71}; auto newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition); Log("Modified Condition Order ID:", newId); Sleep(2000); // 查询修改后的条件单信息 auto newOrder = exchange.GetConditionOrder(newId); Log("Modified Condition Order Info:", newOrder); // 取消条件单 exchange.CancelConditionOrder(newId); }
  • 使用附加参数(option)修改条件单的触发价格类型。

    javascript
    function main() { // 创建一个止盈条件单 var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 76 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) // 修改条件单,并将触发价格类型设置为指数价格(index) // 通过 side 参数传递附加参数(JSON 格式) var option = {"newTpTriggerPxType": "index"} var sideWithOption = "buy;" + JSON.stringify(option) var newCondition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75, TpOrderPrice: 71 } var newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) // 查询修改后的条件单信息 var newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) // 取消条件单 exchange.CancelConditionOrder(newId) }
    python
    import json def main(): # 创建一个止盈条件单 condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 76 } id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) # 修改条件单,并将触发价格类型设置为指数价格(index) # 通过 side 参数传递附加参数(JSON 格式) option = {"newTpTriggerPxType": "index"} sideWithOption = "buy;" + json.dumps(option) newCondition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 75, "TpOrderPrice": 71 } newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) # 查询修改后的条件单信息 newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) # 取消条件单 exchange.CancelConditionOrder(newId)
    rust
    fn main() { // 创建一个止盈条件单 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 76.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, &condition).unwrap(); Log!("Original Condition Order ID:", id); Sleep(2000); // 修改条件单,并将触发价格类型设置为指数价格(index) // 通过 side 参数传递附加参数(JSON 格式;Rust 无 JSON 序列化,故直接使用原始字符串构造) let sideWithOption = r#"buy;{"newTpTriggerPxType": "index"}"#; let newCondition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75.0, TpOrderPrice: 71.0, ..Default::default() }; let newId = exchange.ModifyConditionOrder(&id, sideWithOption, 2, &newCondition).unwrap(); Log!("Modified Condition Order ID:", newId); Sleep(2000); // 查询修改后的条件单信息 let newOrder = exchange.GetConditionOrder(&newId); Log!("Modified Condition Order Info:", newOrder); // 取消条件单 let _ = exchange.CancelConditionOrder(&newId); }
    c++
    void main() { // 创建一个止盈条件单 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 76}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition); Log("Original Condition Order ID:", id); Sleep(2000); // 修改条件单,并将触发价格类型设置为指数价格(index) // 通过 side 参数传递附加参数(JSON 格式) json option = R"({"newTpTriggerPxType": "index"})"_json; string sideWithOption = "buy;" + option.dump(); OrderCondition newCondition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 75, .TpOrderPrice = 71}; auto newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition); Log("Modified Condition Order ID:", newId); Sleep(2000); // 查询修改后的条件单信息 auto newOrder = exchange.GetConditionOrder(newId); Log("Modified Condition Order Info:", newOrder); // 取消条件单 exchange.CancelConditionOrder(newId); }

返回值

类型描述

string / 空值

修改条件单成功时返回条件单ID,修改失败时返回空值。返回的条件单ID可能与原条件单ID相同,也可能不同,这取决于交易所API的具体实现方式。某些交易所在修改条件单后会返回新的条件单ID,而有些交易所则保持条件单ID不变。

参数

名称类型必填描述

orderId

string

参数orderId用于指定待修改的原条件单ID。条件单ID的格式与exchange.CreateConditionOrder函数返回的条件单ID一致,由交易所品种代码和交易所原始条件单ID组成,两者以英文逗号分隔。例如:"SOL-USDT-SWAP,3196255845130256384"

side

string

参数side用于指定条件单的交易方向。
对于现货交易所对象,side参数的可选值为:buysellbuy表示买入,sell表示卖出。
对于期货交易所对象,side参数的可选值为:buyclosebuysellclosesellbuy表示开多仓,closebuy表示平多仓,sell表示开空仓,closesell表示平空仓。

支持附加参数(option):可以通过side参数传递附加参数,格式为:"side;{JSON对象}""side;key=value&key=value"
例如:"buy;{\"newTpTriggerPxType\":\"index\"}""buy;newTpTriggerPxType=index"
附加参数用于修改条件单的其它属性(如触发价格类型等),具体支持的参数取决于交易所API。

amount

number

参数amount用于设置条件单的新下单量。当数量为-1时表示不修改下单量。对于期货交易所对象,下单量参数amount均以合约张数为单位。

condition

object

参数condition是一个对象,用于设置条件单的新触发条件和执行价格。该对象的结构参考Condition结构,包含以下属性:

参考

备注

exchange.ModifyConditionOrder()函数返回的条件单ID因交易所API实现的不同而可能表现出不同行为。有些交易所API返回的条件单ID会更新,有些则保持不变。建议使用返回的新条件单ID进行后续操作。

exchange.ModifyConditionOrder()函数不会依据交易所接口规则校验参数的有效性,而是将参数直接提交给交易所API。传入无效参数时(如数量为-1),该参数可能会被交易所忽略,条件单保持原有属性不变。

支持通过side参数传递附加参数(option),用于修改条件单的其它属性。附加参数需要与side参数合并传入,格式为"side;{JSON对象}"(推荐)或"side;key=value"(URL编码格式)。例如修改触发价格类型:"buy;{\"newTpTriggerPxType\":\"index\"}"

对于条件单的市价单修改,需要具体查看交易所API是否支持。将condition参数中的TpOrderPriceSlOrderPrice设置为-1表示市价单。

修改条件单时,条件单的其它属性(如条件类型、持仓模式、账户模式、杠杆等)通常会保留原条件单的设置。如需修改这些属性,可以通过附加参数(option)传入,前提是交易所API支持。

可以通过附加参数修改触发价格类型,例如将触发价格类型从最新价(last)修改为指数价格(index)或标记价格(mark)。具体的参数名称和支持情况取决于交易所API文档。

修改条件单功能的支持情况取决于具体交易所,部分交易所可能不支持修改条件单功能,或仅支持修改部分参数。使用前请查阅对应交易所的API文档。

exchange.CancelConditionOrder()函数用于取消条件单。条件单Id的格式与普通订单Id类似,由交易所品种代码和交易所原始条件单Id组成,两者以英文逗号分隔。

调用exchange.CancelConditionOrder()函数撤销条件单时,传入的conditionOrderId参数与条件单结构的Id属性一致。

exchange.CancelConditionOrder(conditionOrderId)
exchange.CancelConditionOrder(conditionOrderId, ...args)

示例

  • 撤销条件单。

    javascript
    function main(){ // 创建止损条件单 var condition = { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000, SlOrderPrice: -1 // 市价单 } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) exchange.CancelConditionOrder(id) }
    python
    def main(): # 创建止损条件单 condition = { "ConditionType": ORDER_CONDITION_TYPE_SL, "SlTriggerPrice": 58000, "SlOrderPrice": -1 # 市价单 } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) exchange.CancelConditionOrder(id)
    rust
    fn main() { // 创建止损条件单 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000.0, SlOrderPrice: -1.0, // 市价单 ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition).unwrap(); Sleep(1000); let _ = exchange.CancelConditionOrder(&id); }
    c++
    void main() { // 创建止损条件单 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = -1}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Sleep(1000); exchange.CancelConditionOrder(id); }
  • 批量取消条件单,并附带输出条件单信息。

    javascript
    function main() { // 创建几个条件单 var condition1 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000, TpOrderPrice: 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) var condition2 = { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000, SlOrderPrice: 58000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2) Sleep(1000) var orders = exchange.GetConditionOrders() for (var i = 0 ; i < orders.length ; i++) { exchange.CancelConditionOrder(orders[i].Id, "Canceled condition order:", orders[i]) Sleep(500) } }
    python
    def main(): # 创建几个条件单 condition1 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 65000, "TpOrderPrice": 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) condition2 = { "ConditionType": ORDER_CONDITION_TYPE_SL, "SlTriggerPrice": 58000, "SlOrderPrice": 58000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2) Sleep(1000) orders = exchange.GetConditionOrders() for i in range(len(orders)): exchange.CancelConditionOrder(orders[i]["Id"], "Canceled condition order:", orders[i]) Sleep(500)
    rust
    fn main() { // 创建几个条件单 let condition1 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000.0, TpOrderPrice: 65000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition1); let condition2 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000.0, SlOrderPrice: 58000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition2); Sleep(1000); let orders = exchange.GetConditionOrders(None).unwrap(); for i in 0..orders.len() { // Rust中CancelConditionOrder不支持扩展参数,附带信息用Log输出 let _ = exchange.CancelConditionOrder(&orders[i].Id); Log!("Canceled condition order:", orders[i]); Sleep(500); } }
    c++
    void main() { // 创建几个条件单 OrderCondition condition1 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1); OrderCondition condition2 = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = 58000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2); Sleep(1000); auto orders = exchange.GetConditionOrders(); for (int i = 0 ; i < orders.size() ; i++) { exchange.CancelConditionOrder(orders[i].Id, "Canceled condition order:", orders[i]); Sleep(500); } }

返回值

类型描述

bool

exchange.CancelConditionOrder()函数返回真值(例如true)表示撤销条件单的请求发送成功,返回假值(例如false)表示撤销条件单的请求发送失败。

参数

名称类型必填描述

conditionOrderId

string

conditionOrderId参数用于指定要取消的条件单。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于向该条撤销条件单的日志中输出附带信息,arg参数可以传入多个。

参考

备注

exchange.CancelConditionOrder()函数的返回值仅代表撤销请求发送成功或失败。如需判断交易所是否已取消该条件单,可以调用exchange.GetConditionOrders()函数进行确认。

只有未触发的条件单可以被取消;已经触发并转为普通订单的条件单无法通过此函数取消。

exchange.GetConditionOrder()函数用于获取指定条件单的信息。

exchange.GetConditionOrder(conditionOrderId)

示例

javascript
function main(){ // 创建止盈条件单 var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000, TpOrderPrice: 65000 } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) // 参数id为条件单号码,需填入你想要查询的条件单的号码 var order = exchange.GetConditionOrder(id) Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "Status:", order.Status, "Type:", order.Type, "Condition:", order.Condition) }
python
def main(): # 创建止盈条件单 condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 65000, "TpOrderPrice": 65000 } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) order = exchange.GetConditionOrder(id) Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "Status:", order["Status"], "Type:", order["Type"], "Condition:", order["Condition"])
rust
fn main() { // 创建止盈条件单 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000.0, TpOrderPrice: 65000.0, ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition).unwrap(); Sleep(1000); // 参数id为条件单号码,需填入你想要查询的条件单的号码 let order = exchange.GetConditionOrder(&id).unwrap(); Log!("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "Status:", order.Status, "Type:", order.Type, "Condition:", order.Condition); }
c++
void main() { // 创建止盈条件单 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Sleep(1000); auto order = exchange.GetConditionOrder(id); Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "Status:", order.Status, "Type:", order.Type); }

返回值

类型描述

Order / 空值

根据条件单号查询条件单详情,查询成功时返回Order结构,查询失败时返回空值。

返回的Order结构中包含Condition字段,该字段包含条件单的详细配置信息(触发价格、执行价格、条件类型等)。

参数

名称类型必填描述

conditionOrderId

string

conditionOrderId参数用于指定所要查询的条件单。条件单Id的格式与普通订单Id类似,由交易所品种代码和交易所原始条件单Id组成,两者之间以英文逗号分隔。

调用exchange.GetConditionOrder()函数查询条件单时传入的conditionOrderId参数与条件单结构的Id属性一致。

参考

备注

部分交易所不支持exchange.GetConditionOrder()函数。

返回的条件单结构包含触发条件、触发价格、订单状态等信息。

条件单状态包括:未触发、已触发、已取消等,具体的状态值由交易所而定。

exchange.GetConditionOrders()函数用于获取未完成的条件单(尚未触发或尚未取消的条件单)。

exchange.GetConditionOrders()
exchange.GetConditionOrders(symbol)

示例

  • 使用现货交易所对象创建多个条件单,然后查询未完成的条件单信息。

    javascript
    function main() { // 创建多个条件单 var condition1 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000, TpOrderPrice: 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) var condition2 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 3200, TpOrderPrice: 3200 } exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2) Sleep(1000) // 查询所有未完成条件单 var orders = exchange.GetConditionOrders() Log("Pending condition orders count:", orders.length) for (var i = 0; i < orders.length; i++) { Log("Condition order", i+1, ":", orders[i]) } }
    python
    def main(): # 创建多个条件单 condition1 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 65000, "TpOrderPrice": 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) condition2 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 3200, "TpOrderPrice": 3200 } exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2) Sleep(1000) # 查询所有未完成条件单 orders = exchange.GetConditionOrders() Log("Pending condition orders count:", len(orders)) for i in range(len(orders)): Log("Condition order", i+1, ":", orders[i])
    rust
    fn main() { // 创建多个条件单 let condition1 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000.0, TpOrderPrice: 65000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition1); let condition2 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 3200.0, TpOrderPrice: 3200.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, &condition2); Sleep(1000); // 查询所有未完成条件单 let orders = exchange.GetConditionOrders(None).unwrap(); Log!("Pending condition orders count:", orders.len()); for i in 0..orders.len() { Log!("Condition order", i + 1, ":", orders[i]); } }
    c++
    void main() { // 创建多个条件单 OrderCondition condition1 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1); OrderCondition condition2 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 3200, .TpOrderPrice = 3200}; exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2); Sleep(1000); // 查询所有未完成条件单 auto orders = exchange.GetConditionOrders(); Log("Pending condition orders count:", orders.size()); for (int i = 0; i < orders.size(); i++) { Log("Condition order", i+1, ":", orders[i]); } }
  • 查询指定交易对的未成交条件单。

    javascript
    function main() { // 查询 BTC_USDT 交易对的未成交条件单 var orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders) }
    python
    def main(): # 查询 BTC_USDT 交易对的未成交条件单 orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders)
    rust
    fn main() { // 查询 BTC_USDT 交易对的未成交条件单 let orders = exchange.GetConditionOrders("BTC_USDT"); Log!("BTC_USDT pending condition orders:", orders); }
    c++
    void main() { // 查询 BTC_USDT 交易对的未成交条件单 auto orders = exchange.GetConditionOrders("BTC_USDT"); Log("BTC_USDT pending condition orders:", orders); }

返回值

类型描述

Order数组 / 空值

exchange.GetConditionOrders()函数在请求数据成功时返回Order结构数组,在请求数据失败时返回空值。

返回的Order结构中包含Condition字段,该字段包含条件单的详细配置信息(触发价格、执行价格、条件类型等)。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所要查询的交易品种交易品种范围

对于现货交易所对象,未传入symbol参数时,将请求所有现货品种的未完成条件单数据。

对于期货交易所对象,未传入symbol参数时,默认按当前交易对、合约代码所在的维度范围,请求该范围内所有品种的未完成条件单数据。

参考

备注

GetConditionOrders函数中,symbol参数的使用场景归纳如下:

交易所对象分类symbol参数查询范围备注
现货不传symbol参数查询所有现货交易对适用于所有调用场景;若交易所接口不支持则报错并返回空值,以下不再赘述
现货指定交易品种,symbol参数为:"BTC_USDT"查询指定的BTC_USDT交易对对于现货交易所对象,参数symbol的格式为:"BTC_USDT"
期货不传symbol参数查询当前交易对、合约代码维度范围内的所有交易品种假如当前交易对为BTC_USDT,合约代码为swap,即查询所有USDT本位永续合约。等价于调用GetConditionOrders("USDT.swap")
期货指定交易品种,symbol参数为:"BTC_USDT.swap"查询指定的BTC的USDT本位永续合约对于期货交易所对象,参数symbol的格式为:FMZ平台定义的交易对合约代码组合,两者以字符"."间隔。
期货指定交易品种范围,symbol参数为:"USDT.swap"查询所有USDT本位永续合约-
支持期权的期货交易所不传symbol参数查询当前交易对维度范围内的所有期权合约假如当前交易对为BTC_USDT,且合约设置为期权合约,例如币安期权合约:BTC-240108-40000-C
支持期权的期货交易所指定具体交易品种查询指定的期权合约例如对于币安期货交易所,symbol参数为:BTC_USDT.BTC-240108-40000-C
支持期权的期货交易所指定交易品种范围,symbol参数为:"USDT.option"查询所有USDT本位期权合约-

GetConditionOrders函数中,期货交易所对象的查询维度范围归纳如下:

symbol参数请求范围定义备注
USDT.swapUSDT本位永续合约范围。对于交易所API接口不支持的维度,调用时会报错并返回空值。
USDT.futuresUSDT本位交割合约范围。-
USD.swap币本位永续合约范围。-
USD.futures币本位交割合约范围。-
USDT.optionUSDT本位期权合约范围。-
USD.option币本位期权合约范围。-
USDT.futures_combo差价组合合约范围。Futures_Deribit交易所
USD.futures_ff混合保证金交割合约范围。Futures_Kraken交易所
USD.swap_pf混合保证金永续合约范围。Futures_Kraken交易所

当交易所对象exchange所代表的账户在查询范围内指定的交易品种上没有未完成条件单时,调用该函数将返回空数组,即:[]

条件单功能的支持情况取决于具体交易所,部分交易所可能不支持条件单功能。

exchange.GetHistoryConditionOrders()函数用于获取当前交易对、合约的历史条件单(包括已触发、已取消、已过期的条件单),并支持指定具体的交易品种。

exchange.GetHistoryConditionOrders()
exchange.GetHistoryConditionOrders(symbol)
exchange.GetHistoryConditionOrders(symbol, since)
exchange.GetHistoryConditionOrders(symbol, since, limit)
exchange.GetHistoryConditionOrders(since)
exchange.GetHistoryConditionOrders(since, limit)

示例

  • 查询历史条件单,返回的结果按时间升序排列。

    javascript
    function main() { var historyConditionOrders = exchange.GetHistoryConditionOrders() Log("Historical condition orders count:", historyConditionOrders.length) // 遍历并显示,订单按 Time 属性升序排列 for (var i = 0; i < historyConditionOrders.length; i++) { Log("Order", i+1, "Created at:", historyConditionOrders[i].Time, "ID:", historyConditionOrders[i].Id, "Status:", historyConditionOrders[i].Status) } }
    python
    def main(): historyConditionOrders = exchange.GetHistoryConditionOrders() Log("Historical condition orders count:", len(historyConditionOrders)) # 遍历并显示,订单按 Time 属性升序排列 for i in range(len(historyConditionOrders)): Log("Order", i+1, "Created at:", historyConditionOrders[i]["Time"], "ID:", historyConditionOrders[i]["Id"], "Status:", historyConditionOrders[i]["Status"])
    rust
    fn main() { let historyConditionOrders = exchange.GetHistoryConditionOrders(None, None, None).unwrap(); Log!("Historical condition orders count:", historyConditionOrders.len()); // 遍历并显示,订单按 Time 属性升序排列 for i in 0..historyConditionOrders.len() { Log!("Order", i + 1, "Created at:", historyConditionOrders[i].Time, "ID:", historyConditionOrders[i].Id, "Status:", historyConditionOrders[i].Status); } }
    c++
    void main() { auto historyConditionOrders = exchange.GetHistoryConditionOrders(); Log("Historical condition orders count:", historyConditionOrders.size()); // 遍历并显示,订单按 Time 属性升序排列 for (int i = 0; i < historyConditionOrders.size(); i++) { Log("Order", i+1, "Created at:", historyConditionOrders[i].Time, "ID:", historyConditionOrders[i].Id, "Status:", historyConditionOrders[i].Status); } }
  • 查询指定交易对的历史条件单,并限制返回的数量。

    javascript
    function main() { // 查询BTC_USDT交易对最近的10条历史条件单 var historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders) }
    python
    def main(): # 查询BTC_USDT交易对最近的10条历史条件单 historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders)
    rust
    fn main() { // 查询BTC_USDT交易对最近的10条历史条件单 let historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10); Log!("BTC_USDT historical condition orders:", historyConditionOrders); }
    c++
    void main() { // 查询BTC_USDT交易对最近的10条历史条件单 auto historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10); Log("BTC_USDT historical condition orders:", historyConditionOrders); }
  • 按时间范围查询历史条件单。

    javascript
    function main() { // 查询从指定时间戳开始的历史条件单 var startTime = new Date("2024-01-01").getTime() var historyConditionOrders = exchange.GetHistoryConditionOrders(startTime, 50) Log("Historical condition orders since:", historyConditionOrders) }
    python
    def main(): # 查询从指定时间戳开始的历史条件单 import time startTime = int(time.mktime(time.strptime("2024-01-01", "%Y-%m-%d")) * 1000) historyConditionOrders = exchange.GetHistoryConditionOrders(startTime, 50) Log("Historical condition orders since:", historyConditionOrders)
    rust
    fn main() { // 查询从指定时间戳开始的历史条件单 let startTime: i64 = 1704067200000; // 2024-01-01的时间戳 // Rust中symbol参数传None表示当前交易对 let historyConditionOrders = exchange.GetHistoryConditionOrders(None, startTime, 50); Log!("Historical condition orders since:", historyConditionOrders); }
    c++
    void main() { // 查询从指定时间戳开始的历史条件单 auto startTime = 1704067200000; // 2024-01-01的时间戳 // C++ 中 symbol 参数不可省略,传 "" 表示当前交易对 auto historyConditionOrders = exchange.GetHistoryConditionOrders("", startTime, 50); Log("Historical condition orders since:", historyConditionOrders); }

返回值

类型描述

Order数组 / 空值

exchange.GetHistoryConditionOrders()函数在请求数据成功时返回Order结构数组,在请求数据失败时返回空值。

返回的Order结构中包含Condition字段,该字段包含条件单的详细配置信息(触发价格、执行价格、条件类型等)。

参数

名称类型必填描述

symbol

string

symbol参数用于指定交易品种。以BTC_USDT交易对为例,当exchange为现货交易所对象时,symbol参数的格式为:BTC_USDT;如果为期货交易所对象,以永续合约为例,symbol参数的格式为:BTC_USDT.swap

如果查询的是期权合约的条件单数据,则将symbol参数设置为"BTC_USDT.BTC-240108-40000-C"(以币安期权BTC-240108-40000-C为例),其格式为FMZ平台定义的交易对与交易所定义的具体期权合约代码的组合,两者之间以字符"."间隔。若不传入该参数,则默认请求当前所设置交易对、合约代码的条件单数据。

since

number

since参数用于指定查询的起始时间戳,单位为毫秒。

limit

number

limit参数用于指定查询的条件单数量。

参考

备注

  • 不指定symbolsincelimit参数时,默认查询当前交易对、合约的历史条件单,即查询距离当前时间最近的一定范围内的历史条件单,查询范围取决于交易所接口的单次查询范围。

  • 指定symbol参数时,查询所设置交易品种的历史条件单。

  • 指定since参数时,以since时间戳为起始时间,向当前时间方向查询。

  • 指定limit参数时,在查询到足够条数后返回。

  • 该函数仅支持提供历史条件单查询接口的交易所。

历史条件单包括:已触发(转为普通订单)、已取消、已过期等状态的条件单。

返回的历史条件单数组按订单创建时间(Time属性)升序排列,即时间最早的订单位于数组前面,时间最晚的订单位于数组后面。

对条件单功能的支持情况取决于具体的交易所,部分交易所可能不支持条件单功能或历史条件单查询功能。

exchange.SetPrecision()函数用于设置exchange交易所对象的价格下单量的精度,设置后系统会自动忽略数据中超出精度的多余部分。

exchange.SetPrecision(pricePrecision, amountPrecision)

示例

javascript
function main(){ // 设置价格小数位精度为2位,下单量小数位精度为3位 exchange.SetPrecision(2, 3) }
python
def main(): exchange.SetPrecision(2, 3)
rust
fn main() { // 设置价格小数位精度为2位,下单量小数位精度为3位 exchange.SetPrecision(2, 3); }
c++
void main() { exchange.SetPrecision(2, 3); }

参数

名称类型必填描述

pricePrecision

number

pricePrecision参数用于设置价格数据的精度。

amountPrecision

number

amountPrecision参数用于设置下单量数据的精度。

参考

备注

回测系统不支持该函数,回测系统的数值精度由系统自动处理。

设置交易所对象当前的汇率。

exchange.SetRate(rate)

示例

javascript
function main(){ Log(exchange.GetTicker()) // 设置汇率转换 exchange.SetRate(7) Log(exchange.GetTicker()) // 设置为 1,不转换 exchange.SetRate(1) }
python
def main(): Log(exchange.GetTicker()) exchange.SetRate(7) Log(exchange.GetTicker()) exchange.SetRate(1)
rust
fn main() { Log!(exchange.GetTicker(None)); // 设置汇率转换 exchange.SetRate(7); Log!(exchange.GetTicker(None)); // 设置为 1,不转换 exchange.SetRate(1); }
c++
void main() { Log(exchange.GetTicker()); exchange.SetRate(7); Log(exchange.GetTicker()); exchange.SetRate(1); }

参数

名称类型必填描述

rate

number

rate 参数用于指定转换汇率。

参考

备注

如果使用 exchange.SetRate() 函数设置了汇率值(例如设置为 7),那么当前 exchange 交易所对象所代表交易所的行情、深度、下单价格等所有价格信息,都会被乘以所设置的汇率 7 进行转换。

例如,exchange 是以美元为计价货币的交易所。执行 exchange.SetRate(7) 之后,实盘中的所有价格都会被乘以 7,转换为接近 CNY 计价的价格。

exchange.IO()函数用于调用交易所对象相关的其它接口。

exchange.IO(k, ...args)

示例

  • 使用 "api" 模式调用 OKX 期货批量下单接口,并通过 raw 参数传递 JSON 格式的订单数据:

    javascript
    function main() { var arrOrders = [ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ] // 调用 exchange.IO 直接访问交易所批量下单接口 var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders)) Log(ret) }
    python
    import json def main(): arrOrders = [ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ] ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", json.dumps(arrOrders)) Log(ret)
    rust
    fn main() { // Rust无JSON序列化,直接用原始字符串构造订单数组 let arrOrders = r#"[ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ]"#; // 调用 exchange.IO 直接访问交易所批量下单接口,多参数以元组传入 let ret = exchange.IO(("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders)); Log!(ret); }
    c++
    void main() { json arrOrders = R"([ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ])"_json; auto ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders.dump()); Log(ret); }
  • params参数中的键值为字符串类型时,需要使用单引号将参数值包裹起来:

    javascript
    var amount = 1 var price = 10 var basecurrency = "ltc" function main () { // 注意 amount.toString() 和 price.toString() 左边右边都有一个 ' 字符 var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit" var id = exchange.IO("api", "POST", "/v1/order/new", message) }
    python
    amount = 1 price = 10 basecurrency = "ltc" def main(): message = "symbol=" + basecurrency + "&amount='" + str(amount) + "'&price='" + str(price) + "'&side=buy" + "&type=limit" id = exchange.IO("api", "POST", "/v1/order/new", message)
    rust
    fn main() { let amount = 1; let price = 10; let basecurrency = "ltc"; // 注意 amount 和 price 参数值的左边右边都有一个 ' 字符 let message = format!("symbol={}&amount='{}'&price='{}'&side=buy&type=limit", basecurrency, amount, price); let id = exchange.IO(("api", "POST", "/v1/order/new", message)); }
    c++
    void main() { auto amount = 1.0; auto price = 10.0; auto basecurrency = "ltc"; string message = str_format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price); auto id = exchange.IO("api", "POST", "/v1/order/new", message); }
  • resource参数支持传入完整的URL:

    javascript
    function main() { var ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC") Log(ret) }
    python
    def main(): ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC") Log(ret)
    rust
    fn main() { let ret = exchange.IO(("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC")); Log!(ret); }
    c++
    void main() { auto ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC"); Log(ret); }
  • 不使用raw参数的GET请求:

    javascript
    function main(){ var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT") Log(ret) }
    python
    def main(): ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT") Log(ret)
    rust
    fn main() { let ret = exchange.IO(("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")); Log!(ret); }
    c++
    void main() { auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT"); Log(ret); }
  • 运行时切换交易对:

    javascript
    function main() { // 例如,实盘启动时交易所对象当前的交易对为BTC_USDT,打印当前交易对的行情 Log(exchange.GetTicker()) // 将交易对切换为LTC_BTC exchange.IO("currency", "LTC_BTC") Log(exchange.GetTicker()) }
    python
    def main(): Log(exchange.GetTicker()) exchange.IO("currency", "LTC_BTC") Log(exchange.GetTicker())
    rust
    fn main() { // 例如,实盘启动时交易所对象当前的交易对为BTC_USDT,打印当前交易对的行情 Log!(exchange.GetTicker(None)); // 将交易对切换为LTC_BTC let _ = exchange.IO(("currency", "LTC_BTC")); Log!(exchange.GetTicker(None)); }
    c++
    void main() { Log(exchange.GetTicker()); exchange.IO("currency", "LTC_BTC"); Log(exchange.GetTicker()); }
  • 切换交易所接口基地址:

    javascript
    function main () { // exchanges[0]即实盘创建时添加的第一个交易所对象 exchanges[0].IO("base", "https://api.huobi.pro") }
    python
    def main(): exchanges[0].IO("base", "https://api.huobi.pro")
    rust
    fn main() { // exchanges[0]即实盘创建时添加的第一个交易所对象 let _ = exchanges[0].IO(("base", "https://api.huobi.pro")); }
    c++
    void main() { exchanges[0].IO("base", "https://api.huobi.pro"); }
  • 通过"mbase"切换行情接口基地址(以Bitfinex为例):

    javascript
    function main() { exchange.SetBase("https://api.bitfinex.com") exchange.IO("mbase", "https://api-pub.bitfinex.com") }
    python
    def main(): exchange.SetBase("https://api.bitfinex.com") exchange.IO("mbase", "https://api-pub.bitfinex.com")
    rust
    fn main() { exchange.SetBase("https://api.bitfinex.com"); let _ = exchange.IO(("mbase", "https://api-pub.bitfinex.com")); }
    c++
    void main() { exchange.SetBase("https://api.bitfinex.com"); exchange.IO("mbase", "https://api-pub.bitfinex.com"); }
  • 切换模拟盘/实盘环境(以OKX期货为例):

    javascript
    function main() { exchange.IO("simulate", true) // Switch to demo trading environment // ... trading logic ... exchange.IO("simulate", false) // Switch back to live trading environment }
    python
    def main(): exchange.IO("simulate", True) # ... trading logic ... exchange.IO("simulate", False)
    rust
    fn main() { let _ = exchange.IO(("simulate", true)); // Switch to demo trading environment // ... trading logic ... let _ = exchange.IO(("simulate", false)); // Switch back to live trading environment }
    c++
    void main() { exchange.IO("simulate", true); // ... trading logic ... exchange.IO("simulate", false); }
  • 切换合约保证金模式与持仓模式(以币安期货为例):

    javascript
    function main() { exchange.IO("dual", true) // Switch to hedge mode (dual position) exchange.IO("dual", false) // Switch to one-way mode exchange.SetContractType("swap") exchange.IO("cross", true) // Switch to cross margin exchange.IO("cross", false) // Switch to isolated margin }
    python
    def main(): exchange.IO("dual", True) exchange.IO("dual", False) exchange.SetContractType("swap") exchange.IO("cross", True) exchange.IO("cross", False)
    rust
    fn main() { let _ = exchange.IO(("dual", true)); // Switch to hedge mode (dual position) let _ = exchange.IO(("dual", false)); // Switch to one-way mode let _ = exchange.SetContractType("swap"); let _ = exchange.IO(("cross", true)); // Switch to cross margin let _ = exchange.IO(("cross", false)); // Switch to isolated margin }
    c++
    void main() { exchange.IO("dual", true); exchange.IO("dual", false); exchange.SetContractType("swap"); exchange.IO("cross", true); exchange.IO("cross", false); }
  • 切换统一账户模式(以币安期货为例):

    javascript
    function main() { exchange.IO("unified", true) // Switch to unified account mode exchange.IO("unified", false) // Switch to normal mode }
    python
    def main(): exchange.IO("unified", True) exchange.IO("unified", False)
    rust
    fn main() { let _ = exchange.IO(("unified", true)); // Switch to unified account mode let _ = exchange.IO(("unified", false)); // Switch to normal mode }
    c++
    void main() { exchange.IO("unified", true); exchange.IO("unified", false); }
  • 设置自成交预防模式(以币安为例):

    javascript
    function main() { // "NONE" means disable STP mode, other parameters: "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH" exchange.IO("selfTradePreventionMode", "NONE") }
    python
    def main(): exchange.IO("selfTradePreventionMode", "NONE")
    rust
    fn main() { // "NONE" means disable STP mode, other parameters: "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH" let _ = exchange.IO(("selfTradePreventionMode", "NONE")); }
    c++
    void main() { exchange.IO("selfTradePreventionMode", "NONE"); }
  • Futures_edgeX计算订单Hash并签名:

    javascript
    function main() { var strJson = `{ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 }` var signature = exchange.IO("calcOrderHashAndSign", strJson) Log(signature) }
    python
    import json def main(): params = { "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": True, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 } signature = exchange.IO("calcOrderHashAndSign", json.dumps(params)) Log(signature)
    rust
    fn main() { let strJson = r#"{ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 }"#; let signature = exchange.IO(("calcOrderHashAndSign", strJson)); Log!(signature); }
    c++
    void main() { json params = R"({ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 })"_json; auto signature = exchange.IO("calcOrderHashAndSign", params.dump()); Log(signature); }
  • rate模式限流 - 限制GetTicker每秒最多调用10次,超出限制时返回null:

    javascript
    function main() { exchange.IO("rate", "GetTicker", 10, "1s") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log("Ticker:", ticker.Last) } else { Log("Rate limit exceeded") } } }
    python
    def main(): exchange.IO("rate", "GetTicker", 10, "1s") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log("Ticker:", ticker["Last"]) else: Log("Rate limit exceeded")
    rust
    fn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); for _i in 0..20 { // 超出限制时GetTicker返回Err match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!("Ticker:", ticker.Last), Err(_) => Log!("Rate limit exceeded"), } } }
    c++
    // C++暂不支持
  • rate模式限流 - 使用"delay"参数,超出限制时自动等待而非返回null:

    javascript
    function main() { exchange.IO("rate", "GetTicker", 10, "1s", "delay") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker.Last) } }
    python
    def main(): exchange.IO("rate", "GetTicker", 10, "1s", "delay") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker["Last"])
    rust
    fn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s", "delay")); for i in 0..20 { let ticker = exchange.GetTicker("BTC_USDT").unwrap(); Log!("Call", i + 1, "Ticker:", ticker.Last); } }
    c++
    // C++暂不支持
  • 多个函数共享限流额度:

    javascript
    function main() { // GetTicker 和 GetDepth 共享限流额度,合计每秒最多调用 10 次 exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for (var i = 0; i < 20; i++) { if (i % 2 == 0) { Log("Ticker:", exchange.GetTicker("BTC_USDT")) } else { Log("Depth:", exchange.GetDepth("BTC_USDT")) } } }
    python
    def main(): exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for i in range(20): if i % 2 == 0: Log("Ticker:", exchange.GetTicker("BTC_USDT")) else: Log("Depth:", exchange.GetDepth("BTC_USDT"))
    rust
    fn main() { // GetTicker 和 GetDepth 共享限流额度,合计每秒最多调用 10 次 let _ = exchange.IO(("rate", "GetTicker,GetDepth", 10, "1s")); for i in 0..20 { if i % 2 == 0 { Log!("Ticker:", exchange.GetTicker("BTC_USDT")); } else { Log!("Depth:", exchange.GetDepth("BTC_USDT")); } } }
    c++
    // C++暂不支持
  • 使用通配符统一限制所有 API 的调用频率:

    javascript
    function main() { exchange.IO("rate", "*", 100, "1m") for (var i = 0; i < 10; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000) } }
    python
    def main(): exchange.IO("rate", "*", 100, "1m") for i in range(10): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000)
    rust
    fn main() { let _ = exchange.IO(("rate", "*", 100, "1m")); for i in 0..10 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); let _ = exchange.GetAccount(); Log!("Round", i + 1, "completed"); Sleep(1000); } }
    c++
    // C++暂不支持
  • quota 模式 - 严格按时间窗口对齐限流:

    javascript
    function main() { exchange.IO("quota", "GetTicker", 3, "1s") for (var i = 0; i < 10; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log(_D(), "Ticker:", ticker.Last) } else { Log(_D(), "Quota exceeded, waiting for next window") } Sleep(100) } }
    python
    def main(): exchange.IO("quota", "GetTicker", 3, "1s") for i in range(10): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log(_D(), "Ticker:", ticker["Last"]) else: Log(_D(), "Quota exceeded, waiting for next window") Sleep(100)
    rust
    fn main() { let _ = exchange.IO(("quota", "GetTicker", 3, "1s")); for _i in 0..10 { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!(_D(None), "Ticker:", ticker.Last), Err(_) => Log!(_D(None), "Quota exceeded, waiting for next window"), } Sleep(100); } }
    c++
    // C++暂不支持
  • quota 模式 - 日内配额,每天于指定时间重置:

    javascript
    function main() { exchange.IO("quota", "GetTicker", 1000, "@0815") var count = 0 while (true) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { count++ Log("Call count:", count, "Ticker:", ticker.Last) } else { Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) // Wait 1 minute } Sleep(1000) } }
    python
    def main(): exchange.IO("quota", "GetTicker", 1000, "@0815") count = 0 while True: ticker = exchange.GetTicker("BTC_USDT") if ticker: count += 1 Log("Call count:", count, "Ticker:", ticker["Last"]) else: Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) # Wait 1 minute Sleep(1000)
    rust
    fn main() { let _ = exchange.IO(("quota", "GetTicker", 1000, "@0815")); let mut count = 0; loop { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => { count += 1; Log!("Call count:", count, "Ticker:", ticker.Last); } Err(_) => { Log!("Daily quota exceeded, waiting for reset at 08:15"); Sleep(60000); // Wait 1 minute } } Sleep(1000); } }
    c++
    // C++暂不支持
  • 组合使用多个限流规则:

    javascript
    function main() { exchange.IO("rate", "GetTicker", 10, "1s") // GetTicker 每秒 10 次 exchange.IO("rate", "GetDepth", 5, "1s") // GetDepth 每秒 5 次 exchange.IO("rate", "CreateOrder", 2, "1s") // CreateOrder 每秒 2 次 exchange.IO("quota", "*", 1000, "@0000") // 所有 API 每天 00:00 重置,上限 1000 次 Log("Rate limits configured successfully") for (var i = 0; i < 5; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200) } }
    python
    def main(): exchange.IO("rate", "GetTicker", 10, "1s") # GetTicker 每秒 10 次 exchange.IO("rate", "GetDepth", 5, "1s") # GetDepth 每秒 5 次 exchange.IO("rate", "CreateOrder", 2, "1s") # CreateOrder 每秒 2 次 exchange.IO("quota", "*", 1000, "@0000") # 所有 API 每天 00:00 重置,上限 1000 次 Log("Rate limits configured successfully") for i in range(5): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200)
    rust
    fn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); // GetTicker 每秒 10 次 let _ = exchange.IO(("rate", "GetDepth", 5, "1s")); // GetDepth 每秒 5 次 let _ = exchange.IO(("rate", "CreateOrder", 2, "1s")); // CreateOrder 每秒 2 次 let _ = exchange.IO(("quota", "*", 1000, "@0000")); // 所有 API 每天 00:00 重置,上限 1000 次 Log!("Rate limits configured successfully"); for _i in 0..5 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); Sleep(200); } }
    c++
    // C++ 暂不支持

返回值

类型描述

string / number / bool / object / array / any

exchange.IO()函数用于调用交易所对象的其它相关接口,调用成功时返回请求的应答数据,调用失败时返回空值。

参数

名称类型必填描述

k

string

调用类型标识符,不同的取值对应不同的功能,具体请参见下方各章节的说明。

arg

string / number / bool / object / array / any

扩展参数,根据k值的不同需要传入不同的参数,其个数和类型均不固定。

参考

备注

一、直接调用交易所API("api"模式)

javascript
exchange.IO("api", httpMethod, resource, params, raw)

用于调用交易所未封装的原生API接口。FMZ会自动处理签名验证,您只需填写请求参数即可。

参数类型必填说明
httpMethodstringGETPOST
resourcestring请求路径或完整URL
paramsstringURL编码格式的请求参数
rawstring原始请求体(JSON等)

调用失败时返回空值,且该模式仅支持实盘。

二、运行时切换交易对("currency"模式)

javascript
exchange.IO("currency", "ETH_USDT")

用于在运行时动态切换交易对,交易对格式为大写字母加下划线分隔。此指令等同于exchange.SetCurrency

回测模式下仅支持现货,且只能切换至相同计价币种的交易对。期货切换交易对后,需再次调用exchange.SetContractType()

三、切换基地址("base" / "mbase"模式)

  • "base":切换交易接口的基地址,等同于exchange.SetBase()
  • "mbase":切换行情接口的基地址,适用于行情与交易采用不同域名的交易所。

四、通用交易模式指令

以下指令在多个交易所中通用,各交易所的具体支持情况请参见第五节的说明。

指令参数功能
simulatebool模拟盘(true)/实盘(false)
crossbool全仓(true)/逐仓(false)
dualbool双向持仓(true)/单向持仓(false)
unifiedbool统一账户(true)/普通账户(false)
trade_margin切换至逐仓杠杆模式
trade_super_margin切换至全仓杠杆模式
trade_normal切换回普通现货模式
selfTradePreventionModestring自成交预防(STP)模式

五、各交易所IO指令

所有交易所均支持"api""currency"指令,下方仅列出各交易所的特有指令。


现货交易所

Binance(币安)

指令参数说明
trade_margin切换至逐仓杠杆模式
trade_super_margin切换至全仓杠杆模式
trade_normal切换回普通现货模式
unifiedbool统一账户模式
selfTradePreventionModestring自成交防护,可选:EXPIRE_TAKER/EXPIRE_MAKER/EXPIRE_BOTH/NONE

OKX(欧易)

指令参数说明
simulatebool模拟盘/实盘切换
trade_margin逐仓杠杆(tdMode=isolated)
trade_super_margin全仓杠杆(tdMode=cross)
trade_normal切换回普通现货模式
tdModestring直接设置交易模式,组合保证金模式下须使用全仓

Huobi(火币)

指令参数说明
trade_margin切换至逐仓杠杆模式
trade_super_margin切换至全仓杠杆模式
trade_normal切换回普通现货模式

Bybit

指令参数说明
trade_margin切换至杠杆模式
trade_normal切换回普通现货模式

Gate.io

指令参数说明
trade_margin切换至逐仓杠杆模式
trade_super_margin切换至全仓杠杆模式
trade_normal切换回普通现货模式
unifiedbool统一账户模式

Bitget

指令参数说明
simulatebool模拟盘/实盘切换

CoinEx

指令参数说明
trade_margin切换至杠杆模式
trade_normal切换回普通模式

WOO

指令参数说明
trade_margin切换至杠杆模式
trade_normal切换回普通模式

Crypto.com

指令参数说明
trade_margin切换至杠杆模式
trade_normal切换回普通模式

AscendEx

指令参数说明
trade_margin切换至杠杆模式
trade_normal切换回普通模式

Gemini

指令参数说明
subAccountstring设置子账户名称

Poloniex

指令参数说明
accountIdstring设置账户ID

Bitfinex

指令参数说明
version获取当前API版本号

Backpack

指令参数说明
selfTradePreventionModestring自成交防护,可选:Allow/RejectTaker/RejectMaker/RejectBoth/Ban

Hyperliquid(现货)

指令参数说明
source"a"/"b"切换API数据源
vaultAddressstring设置金库地址,传入空字符串则禁用
walletAddressstring设置钱包地址
expiresAfternumber订单过期时间(毫秒),设为0则禁用

合约交易所

Futures_Binance(币安合约)

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓
unifiedbool统一账户(切换后使用papi.binance.com
selfTradePreventionModestring自成交防护,可选:EXPIRE_TAKER/EXPIRE_MAKER/EXPIRE_BOTH/NONE
extend_keystring设置API响应扩展字段(以逗号分隔)

Futures_OKX(欧易合约)

指令参数说明
simulatebool模拟盘/实盘切换
crossbool全仓/逐仓,默认全仓
dualbool双向(long_short_mode)/单向(net_mode)持仓

Futures_HuobiDM(火币合约)

指令参数说明
crossbool全仓/逐仓,默认逐仓。仅XXX_USDT永续合约(swap)支持
dualbool双向(dual_side)/单向(single_side)持仓
unifiedbool统一账户模式
signHoststring设置API签名Host地址,传入空字符串则禁用

Futures_Bybit

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓

Futures_KuCoin

指令参数说明
crossbool全仓/逐仓

Futures_GateIO

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓
unifiedbool统一账户模式

Futures_Bitget

指令参数说明
simulatebool模拟盘/实盘切换
crossbool全仓(crossed)/逐仓(isolated)
dualbool双向(hedge_mode)/单向(one_way_mode)持仓

Futures_MEXC

指令参数说明
crossbool全仓/逐仓

Futures_BitMEX

指令参数说明
crossbool全仓/逐仓

Futures_CoinEx

指令参数说明
crossbool全仓/逐仓

Futures_WOO

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓

Futures_Kraken

指令参数说明
crossbool全仓/逐仓(仅multi-collateral账户支持)

Futures_Aevo

指令参数说明
signingKeystring设置签名密钥,返回公钥。需从交易所API Key页面获取,请注意其存在时效性

Futures_Hyperliquid

指令参数说明
crossbool全仓/逐仓
source"a"/"b"切换API数据源
vaultAddressstring设置金库地址,传入空字符串则禁用
walletAddressstring设置钱包地址
expiresAfternumber订单过期时间(毫秒),设为0则禁用

Futures_Deepcoin

指令参数说明
crossbool全仓/逐仓
mergebool合并持仓(true)/拆分持仓(false)

Futures_DigiFinex

指令参数说明
simulatebool模拟盘/实盘切换
crossbool全仓/逐仓

Futures_ApolloX

指令参数说明
crossbool全仓/逐仓

Futures_Aster

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓

Futures_CoinW

指令参数说明
crossbool全仓/逐仓

Futures_BitMart

指令参数说明
crossbool全仓/逐仓

Futures_Backpack

指令参数说明
selfTradePreventionModestring自成交防护,可选:Allow/RejectTaker/RejectMaker/RejectBoth/Ban

Futures_Lighter

指令参数说明
crossbool全仓/逐仓
expirynumber订单过期时间戳(毫秒),默认29天,最小4分钟

Futures_Crypto.com

指令参数说明
accountIdstring设置交易账户ID

Futures_Bitfinex

指令参数说明
mbasestring设置行情API基础地址

Futures_edgeX

指令参数说明
calcOrderHashAndSignstring(JSON)计算订单哈希并签名,返回签名字符串

Futures_Bibox

指令参数说明
crossbool全仓/逐仓,默认全仓

Futures_Pionex

指令参数说明
crossbool全仓/逐仓
dualbool双向/单向持仓

Futures_Phemex

指令参数说明
dualbool双向/单向持仓。全仓/逐仓需在交易所网页端设置

Futures_WooFi

仅支持通用指令"api""currency",无特有指令。

六、特殊平台IO指令

Polymarket(预测市场)

指令参数说明
nonce[number]获取或设置订单的 nonce 值。不传参数时返回当前 nonce,传入数值时设置新的 nonce
proxyWalletAddress获取代理钱包地址
redeemsymbol, [wait]赎回已结算头寸(通过 Relayer 免 Gas)。wait 默认为 true,等待交易确认;wait 为 false 时立即返回{"transactionID": "..."}
mergesymbol, [amount], [wait]将 YES+NO 代币合并赎回为 USDC(通过 Relayer 免 Gas)。amount 为 0 或不传时,自动取两个 outcome 中较小的持仓量。wait 默认为 true,等待交易确认
l2_credentials获取 L2 认证信息,返回{"apiKey":"","secret":"","passphrase":""},用于 WebSocket 连接等场景
batchOrdersarray批量下单,参数为订单对象数组,每个对象包含symbolsidepriceamount字段,以及可选的option字段

Web3(区块链)

指令参数说明
abi合约地址, ABI字符串注册合约 ABI
address[私钥]获取钱包地址
encode / pack类型, 数据...ABI 编码数据
encodePacked类型, 数据...ABI 紧密编码数据
hash参数1-4计算哈希值
decode / unpack类型, 数据...ABI 解码数据
keystring切换操作所使用的私钥

IB(盈透证券)

指令参数说明
status获取连接状态
time获取 IB 服务器时间
reqId强制获取新的请求 ID
orderId获取下一个可用的订单 ID
ignorestring(数组)忽略指定的错误码
scanstring(JSON)执行市场扫描器
wait[number]等待行情事件,可设置超时秒数
debugbool调试模式
marketDataTypenumber行情数据类型(1 实时 / 2 冻结 / 3 延迟 / 4 延迟冻结)

Futu(富途证券)

指令参数说明
refreshbool缓存刷新,禁用缓存后频率限制为每 30 秒最多 10 次
accounts获取所有账户列表
status获取连接状态
lock锁定交易
unlock解锁交易
wait等待行情事件

七、API限流控制("rate" / "quota"模式)

javascript
exchange.IO("rate", functionNames, maxCalls, period, [behavior]) exchange.IO("quota", functionNames, maxCalls, period, [behavior])
  • rate:平滑限流,不严格对齐时间窗口。
  • quota:额度限流,严格对齐时间窗口。
参数类型说明
functionNamesstring函数名,多个之间以逗号分隔,*表示全部
maxCallsnumber单个时间周期内的最大调用次数
periodstring时间周期("1s"/"1m"/"1h")或重置时间点("@0815"
behaviorstring可选,"delay"表示超限时等待,默认返回 null

Buy/Sell的限流遵循CreateOrder的设置;Go遵循实际并发函数的设置;IO/api仅对exchange.IO("api", ...)生效。

exchange.Log()函数用于在日志栏区域输出下单、撤单日志。该函数被调用时不会实际下单,仅用于输出并记录交易日志。

exchange.Log(orderType, price, amount)
exchange.Log(orderType, price, amount, ...args)

示例

使用exchange.Log(orderType, price, amount)可以进行实盘跟单测试、模拟下单,也可以辅助记录下单信息。

最常见的使用场景为:通过exchange.IO函数访问交易所的创建条件订单接口,但调用exchange.IO()函数并不会在实盘日志中输出交易日志信息。

此时即可使用exchange.Log()函数补充输出日志,以便记录下单信息,撤单操作亦是如此。

javascript
var id = 123 function main() { // 下单类型买入,价格999,数量 0.1 exchange.Log(LOG_TYPE_BUY, 999, 0.1) // 取消订单 exchange.Log(LOG_TYPE_CANCEL, id) }
python
id = 123 def main(): exchange.Log(LOG_TYPE_BUY, 999, 0.1) exchange.Log(LOG_TYPE_CANCEL, id)
rust
fn main() { let id = 123; // 下单类型买入,价格999,数量 0.1 exchange.Log(LOG_TYPE_BUY, 999, 0.1); // 取消订单,orderType为LOG_TYPE_CANCEL时price参数为撤单的订单Id(Rust中amount参数必传,可传0) exchange.Log(LOG_TYPE_CANCEL, id, 0); }
c++
void main() { auto id = 123; exchange.Log(LOG_TYPE_BUY, 999, 0.1); exchange.Log(LOG_TYPE_CANCEL, id); }

参数

名称类型必填描述

orderType

number

orderType参数用于设置输出的日志类型,可选值为LOG_TYPE_BUYLOG_TYPE_SELLLOG_TYPE_CANCEL

price

number

price参数用于设置日志中显示的价格。

amount

number

amount参数用于设置日志中显示的下单量。

arg

string / number / bool / object / array / any (平台支持的任意类型)

扩展参数,用于向该条日志中输出附带信息,arg参数可以传入多个。

参考

备注

orderType参数为LOG_TYPE_CANCEL时,price参数表示撤单的订单Id,用于在直接调用exchange.IO()函数撤单时打印撤单日志。

exchange.Log()函数是exchange交易所对象的成员函数,区别于全局函数Log

exchange.Encode()函数用于执行签名与加密计算。

exchange.Encode(algo, inputFormat, outputFormat, data)
exchange.Encode(algo, inputFormat, outputFormat, data, keyFormat, key)

示例

BitMEX仓位变化推送(wss协议)示例:

javascript
function main() { var APIKEY = "your Access Key(Bitmex API ID)" var expires = parseInt(Date.now() / 1000) + 10 var signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "hex", "{{secretkey}}") var client = Dial("wss://www.bitmex.com/realtime", 60) var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"}) var pos = 0 client.write(auth) client.write('{"op": "subscribe", "args": "position"}') while (true) { var bitmexData = JSON.parse(client.read()) if(bitmexData.table == 'position' && pos != parseInt(bitmexData.data[0].currentQty)){ Log('position change', pos, parseInt(bitmexData.data[0].currentQty), '@') pos = parseInt(bitmexData.data[0].currentQty) } } }
python
import time def main(): APIKEY = "your Access Key(Bitmex API ID)" expires = int(time.time() + 10) signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "hex", "{{secretkey}}") client = Dial("wss://www.bitmex.com/realtime", 60) auth = json.dumps({"args": [APIKEY, expires, signature], "op": "authKeyExpires"}) pos = 0 client.write(auth) client.write('{"op": "subscribe", "args": "position"}') while True: bitmexData = json.loads(client.read()) if "table" in bitmexData and bitmexData["table"] == "position" and len(bitmexData["data"]) != 0 and pos != bitmexData["data"][0]["currentQty"]: Log("position change", pos, bitmexData["data"][0]["currentQty"], "@") pos = bitmexData["data"][0]["currentQty"]
c++
void main() { auto APIKEY = "your Access Key(Bitmex API ID)"; auto expires = Unix() + 10; auto signature = exchange.Encode("sha256", "string", "hex", str_format("GET/realtime%d", expires), "hex", "{{secretkey}}"); auto client = Dial("wss://www.bitmex.com/realtime", 60); json auth = R"({"args": [], "op": "authKeyExpires"})"_json; auth["args"].push_back(APIKEY); auth["args"].push_back(expires); auth["args"].push_back(signature); auto pos = 0; client.write(auth.dump()); client.write("{\"op\": \"subscribe\", \"args\": \"position\"}"); while(true) { auto bitmexData = json::parse(client.read()); if(bitmexData["table"] == "position" && bitmexData["data"][0].find("currentQty") != bitmexData["data"][0].end() && pos != bitmexData["data"][0]["currentQty"]) { Log("Test"); Log("position change", pos, bitmexData["data"][0]["currentQty"], "@"); pos = bitmexData["data"][0]["currentQty"]; } } }

返回值

类型描述

string

exchange.Encode()函数返回计算得到的哈希值编码。

参数

名称类型必填描述

algo

string

参数algo用于指定编码计算时所使用的算法。
支持设置为:"raw"(不使用算法)、"sign"、"signTx"、"md4"、"md5"、"sha256"、"sha512"、"sha1"、"keccak256"、"sha3.224"、"sha3.256"、"sha3.384"、"sha3.512"、"sha3.keccak256"、"sha3.keccak512"、"sha512.384"、"sha512.256"、"sha512.224"、"ripemd160"、"blake2b.256"、"blake2b.512"、"blake2s.128"、"blake2s.256"。

参数algo还支持:"text.encoder.utf8"、"text.decoder.utf8"、"text.encoder.gbk"、"text.decoder.gbk",用于对字符串进行编码、解码。
参数algo也支持"ed25519"算法,并可搭配不同的哈希算法使用,例如参数algo可写为"ed25519.md5"、"ed25519.sha512"等,同时支持ed25519.seed计算。

inputFormat

string

用于指定data参数的数据格式。inputFormat参数支持设置为:"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

outputFormat

string

用于指定输出的数据格式。outputFormat参数支持设置为:"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

data

string

参数data为所要处理的数据。

keyFormat

string

用于指定key参数的数据格式。keyFormat参数支持设置为:"raw"、"hex"、"base64"、"string"其中之一。"raw"表示原始数据,"hex"表示hex编码数据,"base64"表示base64编码数据,"string"表示字符串数据。

key

string

key参数用于指定签名计算时使用的密钥,可以使用明文字符串,也可以使用"{{accesskey}}""{{secretkey}}"分别代指exchange交易所对象中配置的accessKeysecretKey

参考

备注

仅实盘支持调用exchange.Encode()函数。"{{accesskey}}""{{secretkey}}"的引用方式仅在调用exchange.Encode()函数时有效。

多线程异步支持函数,可将所有受支持函数的操作转换为异步并发执行。

exchange.Go(method)
exchange.Go(method, ...args)

示例

  • exchange.Go()函数的使用范例。判断undefined时需使用typeof(xx) === "undefined",因为null == undefined在 JavaScript 中是成立的。

    javascript
    function main(){ // 以下四种操作为并发多线程异步执行,不会耗时,会立即返回 var a = exchange.Go("GetTicker") var b = exchange.Go("GetDepth") var c = exchange.Go("Buy", 1000, 0.1) var d = exchange.Go("GetRecords", PERIOD_H1) // 调用 wait 方法等待异步获取 ticker 的结果 var ticker = a.wait() // 返回深度数据,如果获取失败也有可能返回 null var depth = b.wait() // 返回订单号,限定 1 秒超时,超时返回 undefined,若上次 wait 超时,此对象可继续调用 wait 等待 var orderId = c.wait(1000) if(typeof(orderId) == "undefined") { // 超时,重新获取 orderId = c.wait() } var records = d.wait() }
    python
    def main(): a = exchange.Go("GetTicker") b = exchange.Go("GetDepth") c = exchange.Go("Buy", 1000, 0.1) d = exchange.Go("GetRecords", PERIOD_H1) ticker, ok = a.wait() depth, ok = b.wait() orderId, ok = c.wait(1000) if ok == False: orderId, ok = c.wait() records, ok = d.wait()
    rust
    fn main() { // Rust 中 exchange.Go 为类型化写法:使用 Go:: 方法 token 指定并发函数,无参数传 (),有参数传元组 // 以下四种操作为并发多线程异步执行,不会耗时,会立即返回 let a = exchange.Go(Go::GetTicker, ()); let b = exchange.Go(Go::GetDepth, ()); // Rust 中没有 Buy 的 token,等价于 CreateOrder,第一个参数 "" 表示当前交易对 let c = exchange.Go(Go::CreateOrder, ("", "buy", 1000, 0.1)); let d = exchange.Go(Go::GetRecords, (PERIOD_H1,)); // 调用 wait 方法等待异步获取 ticker 的结果,wait(0) 会阻塞直到并发线程运行完毕(对应 JS 的无参 wait()) let ticker = a.wait(0); // 返回深度数据,如果获取失败也有可能返回 Err let depth = b.wait(0); // 返回订单号,限定 1 秒超时,超时返回 Err,若上次 wait 超时,此对象可继续调用 wait 等待 // 注意:Err 也可能是下单本身失败(与超时无法区分),此时再次 wait 会返回 Err 并记录出错信息 let mut orderId = c.wait(1000); if orderId.is_err() { // 超时,重新获取 orderId = c.wait(0); } let records = d.wait(0); }
    c++
    void main() { auto a = exchange.Go("GetTicker"); auto b = exchange.Go("GetDepth"); auto c = exchange.Go("Buy", 1000, 0.1); auto d = exchange.Go("GetRecords", PERIOD_H1); Ticker ticker; Depth depth; Records records; TId orderId; a.wait(ticker); b.wait(depth); if(!c.wait(orderId, 300)) { c.wait(orderId); } d.wait(records); }
  • 对已释放的并发对象调用其wait()方法会报错:

    javascript
    function main() { var d = exchange.Go("GetRecords", PERIOD_H1) // 等待 K 线数据返回结果 var records = d.wait() // 此处对已经 wait 过且已结束的异步操作再次调用 wait,将返回 null,并记录错误信息 var ret = d.wait() }
    python
    def main(): d = exchange.Go("GetRecords", PERIOD_H1) records, ok = d.wait() ret, ok = d.wait()
    rust
    fn main() { // Rust 中 exchange.Go 采用类型化写法:通过 Go:: 方法 token 指定并发函数 let d = exchange.Go(Go::GetRecords, (PERIOD_H1,)); // 等待 K 线数据返回结果,wait(0) 会阻塞直到运行完毕(对应 JS 的无参 wait()) let records = d.wait(0); // 此处对已经 wait 过且已结束的异步操作再次调用 wait,将返回 Err,并记录错误信息 let ret = d.wait(0); }
    c++
    void main() { auto d = exchange.Go("GetRecords", PERIOD_H1); Records records; d.wait(records); Records ret; d.wait(ret); }
  • 并发获取多个交易所行情:

    javascript
    function main() { while(true) { var beginTS = new Date().getTime() var arrRoutine = [] var arrTicker = [] var arrName = [] for(var i = 0; i < exchanges.length; i++) { arrRoutine.push(exchanges[i].Go("GetTicker")) arrName.push(exchanges[i].GetName()) } for(var i = 0; i < arrRoutine.length; i++) { arrTicker.push(arrRoutine[i].wait()) } var endTS = new Date().getTime() var tbl = { type: "table", title: "行情", cols: ["索引", "名称", "最新成交价"], rows: [] } for(var i = 0; i < arrTicker.length; i++) { tbl.rows.push([i, arrName[i], arrTicker[i].Last]) } LogStatus(_D(), "Total time for concurrent ticker retrieval:", endTS - beginTS, "ms", "\n", "`" + JSON.stringify(tbl) + "`") Sleep(500) } }
    python
    import time import json def main(): while True: beginTS = time.time() arrRoutine = [] arrTicker = [] arrName = [] for i in range(len(exchanges)): arrRoutine.append(exchanges[i].Go("GetTicker")) arrName.append(exchanges[i].GetName()) for i in range(len(exchanges)): ticker, ok = arrRoutine[i].wait() arrTicker.append(ticker) endTS = time.time() tbl = { "type": "table", "title": "行情", "cols": ["索引", "名称", "最新成交价"], "rows": [] } for i in range(len(arrTicker)): tbl["rows"].append([i, arrName[i], arrTicker[i]["Last"]]) LogStatus(_D(), "Total time for concurrent ticker retrieval:", endTS - beginTS, "seconds", "\n", "`" + json.dumps(tbl) + "`") Sleep(500)
    rust
    fn main() { loop { let beginTS = UnixNano() / 1000000; let mut arrRoutine = Vec::new(); let mut arrTicker = Vec::new(); let mut arrName = Vec::new(); for e in exchanges.iter() { // Rust中exchange.Go为类型化写法,token为Go::GetTicker arrRoutine.push(e.Go(Go::GetTicker, ())); arrName.push(e.GetName()); } // 失败时记None占位,保持与arrName按索引对齐 for r in arrRoutine.iter() { arrTicker.push(r.wait(0).ok()); } let endTS = UnixNano() / 1000000; // Rust无JSON序列化,用format!拼接表格的JSON文本 let mut rows = String::new(); for i in 0..arrTicker.len() { if let Some(ticker) = &arrTicker[i] { if !rows.is_empty() { rows.push(','); } rows += &format!(r#"[{}, "{}", {}]"#, i, arrName[i], ticker.Last); } } let tbl = format!(r#"{{"type": "table", "title": "行情", "cols": ["索引", "名称", "最新成交价"], "rows": [{}]}}"#, rows); LogStatus!(_D(None), "Total time for concurrent ticker retrieval:", endTS - beginTS, "ms", "\n", format!("`{}`", tbl)); Sleep(500); } }
    c++
    void main() { while(true) { int length = exchanges.size(); auto beginTS = UnixNano() / 1000000; vector<Ticker> arrTicker(length); vector<string> arrName(length); // 注意,添加几个交易所对象,这里要执行几次exchanges[n].Go 函数,这个例子是需要添加四个交易所对象,具体可以修改 auto r0 = exchanges[0].Go("GetTicker"); auto r1 = exchanges[1].Go("GetTicker"); auto r2 = exchanges[2].Go("GetTicker"); auto r3 = exchanges[3].Go("GetTicker"); vector<GoObj*> arrRoutine = {&r0, &r1, &r2, &r3}; for(int i = 0; i < length; i++) { arrName[i] = exchanges[i].GetName(); } for(int i = 0; i < length; i++) { Ticker ticker; arrRoutine[i]->wait(ticker); arrTicker[i] = ticker; } auto endTS = UnixNano() / 1000000; json tbl = R"({ "type": "table", "title": "行情", "cols": ["索引", "名称", "最新成交价"], "rows": [] })"_json; for(int i = 0; i < length; i++) { json arr = R"(["", "", ""])"_json; arr[0] = str_format("%d", i); arr[1] = arrName[i]; arr[2] = str_format("%f", arrTicker[i].Last); tbl["rows"].push_back(arr); } LogStatus(_D(), "Total time for concurrent ticker retrieval:", str_format("%d", endTS - beginTS), "ms", "\n", "`" + tbl.dump() + "`"); Sleep(500); } }
  • 并发调用exchange.IO("api", ...)函数:

    javascript
    function main() { /* 测试OKX期货下单接口 POST /api/v5/trade/order */ var beginTS = new Date().getTime() var param = {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"} var ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var id1 = ret1.wait() var id2 = ret2.wait() var id3 = ret3.wait() var endTS = new Date().getTime() Log("id1:", id1) Log("id2:", id2) Log("id3:", id3) Log("Concurrent order time:", endTS - beginTS, "ms") }
    python
    import time import json def main(): beginTS = time.time() param = {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"} ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) id1, ok1 = ret1.wait() id2, ok2 = ret2.wait() id3, ok3 = ret3.wait() endTS = time.time() Log("id1:", id1) Log("id2:", id2) Log("id3:", id3) Log("Concurrent order time:", endTS - beginTS, "seconds")
    rust
    fn main() { /* 测试OKX期货下单接口 POST /api/v5/trade/order */ let beginTS = UnixNano() / 1000000; // Rust不支持JSON序列化,直接使用原始字符串构造参数 let param = r#"{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}"#; // 在Rust中,exchange.Go采用类型化写法,token为Go::IO,参数以元组形式传入 let ret1 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let ret2 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let ret3 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let id1 = ret1.wait(0); let id2 = ret2.wait(0); let id3 = ret3.wait(0); let endTS = UnixNano() / 1000000; Log!("id1:", id1); Log!("id2:", id2); Log!("id3:", id3); Log!("Concurrent order time:", endTS - beginTS, "ms"); }
    c++
    void main() { auto beginTS = UnixNano() / 1000000; json param = R"({"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"})"_json; auto ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); auto ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); auto ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); json id1 = R"({})"_json; json id2 = R"({})"_json; json id3 = R"({})"_json; ret1.wait(id1); ret2.wait(id2); ret3.wait(id3); auto endTS = UnixNano() / 1000000; Log("id1:", id1); Log("id2:", id2); Log("id3:", id3); Log("Concurrent order time:", endTS - beginTS, "ms"); }
  • 自动释放机制的测试

    javascript
    function main() { var counter = 0 var arr = [] // 用于测试持续引用并发对象的相关变量 var symbols = ["BTC_USDT", "ETH_USDT", "SOL_USDT", "LTC_USDT", "EOS_USDT"] while (true) { var arrRoutine = [] for (var symbol of symbols) { var r = exchange.Go("GetTicker", symbol) arrRoutine.push(r) // 记录并发对象,用于调用 r.wait() 函数获取结果,每轮循环都会清空 // arr.push(r) // 若使用这句代码,运行时会持续引用并发对象,导致其无法自动释放;当并发数超过 2000 时,会报错:```InternalError: too many routine wait, max is 2000```。 counter++ } // 遍历 arrRoutine 并调用 r.wait() 获取结果 LogStatus(_D(), "routine number:", counter) Sleep(50) } }
    rust
    fn main() { let mut counter = 0; let mut arr: Vec<TypedRoutine<Go::GetTicker>> = Vec::new(); // 用于测试持续引用并发对象的相关变量 let symbols = ["BTC_USDT", "ETH_USDT", "SOL_USDT", "LTC_USDT", "EOS_USDT"]; loop { let mut arrRoutine = Vec::new(); for symbol in symbols { // Rust 中 exchange.Go 为类型化写法,token 为 Go::GetTicker let r = exchange.Go(Go::GetTicker, (symbol,)); arrRoutine.push(r); // 记录并发对象,用于调用 r.wait(0) 函数获取结果,每轮循环都会清空 // arr.push(r); // 若使用这句代码,运行时会持续引用并发对象,导致其无法自动释放;当并发数超过 2000 时,会报错:InternalError: too many routine wait, max is 2000。 counter += 1; } // 遍历 arrRoutine 并调用 r.wait(0) 获取结果 LogStatus!(_D(None), "routine number:", counter); Sleep(50); } }

返回值

类型描述

object

exchange.Go()函数会立即返回一个并发对象,可使用该并发对象的wait()方法获取并发请求的结果。

参数

名称类型必填描述

method

string

method参数用于指定要并发执行的函数名称,请注意该参数为函数名称字符串,而非函数引用。

arg

string / number / bool / object / array / function / any (平台支持的任意类型)

并发执行函数的参数,参数arg可以有多个。参数arg的类型与数量取决于并发执行函数的参数定义。

参考

Mail_Go HttpQuery_Go EventLoop exchange.IO(API 限流控制)

备注

该函数仅在实盘运行时创建多线程执行任务,回测不支持多线程并发执行任务(回测中可用,但仍为顺序执行)。

exchange.Go()函数返回对象后,可通过该对象调用其wait()函数获取线程返回的数据。当并发的多线程任务执行完毕且相关变量不再被引用时,系统底层会自动处理资源回收。

wait()方法支持超时参数:

1、不设置超时参数,即wait(),或将超时参数设置为0,即wait(0)。此时wait()函数会阻塞等待,直到并发线程运行完毕,并返回并发线程的执行结果。

2、将超时参数设置为-1,即wait(-1)。此时wait()函数会立即返回,不同编程语言的返回值有所不同,具体可参考本小节的调用示例。

3、设置具体的超时参数,即wait(300),此时wait()函数最多等待300毫秒后返回。

虽然系统底层具有自动回收机制,但如果持续引用相关变量,并发线程将不会被释放。当并发线程数量超过2000个时会报错:"too many routine wait, max is 2000"

支持的函数:GetTickerGetDepthGetTradesGetRecordsGetAccountGetOrdersGetOrderCancelOrderBuySellGetPositionsIO等。这些函数并发调用时均基于当前exchange交易所对象执行。

Python语言与JavaScript语言的区别在于,Python语言中并发对象的wait()函数返回两个值,第一个为异步API调用返回的结果,第二个表示异步调用是否完成。

python
def main(): d = exchange.Go("GetRecords", PERIOD_D1) # ok是一定返回True的, 除非策略被停止 ret, ok = d.wait() # 如果等待超时, 或者wait了一个已经结束的实例,ok返回False ret, ok = d.wait(100)

exchange.GetAccount()函数用于请求交易所账户信息。GetAccount()函数是交易所对象exchange的成员函数,exchange对象的成员函数(方法)仅与exchange相关,后续文档不再赘述。

exchange.GetAccount()

示例

设置交易对与合约代码,获取当前账户信息。

javascript
function main(){ // 切换交易对 exchange.IO("currency", "BTC_USDT") // 以OKX期货为例,设置合约为当周合约,当前交易对为BTC_USDT,所以当前合约为BTC的U本位当周合约 exchange.SetContractType("this_week") // 获取当前账户资产数据 var account = exchange.GetAccount() // USDT作为保证金的可用余额 Log(account.Balance) // USDT作为保证金的冻结金额 Log(account.FrozenBalance) // 当前资产权益 Log(account.Equity) // 当前资产作为保证金的所有持仓的未实现盈亏 Log(account.UPnL) }
python
def main(): exchange.IO("currency", "BTC_USDT") exchange.SetContractType("this_week") account = exchange.GetAccount() Log(account["Balance"]) Log(account["FrozenBalance"]) Log(account["Equity"]) Log(account["UPnL"])
rust
fn main() { // 切换交易对 exchange.IO(("currency", "BTC_USDT")).unwrap(); // 以OKX期货为例,设置合约为当周合约,当前交易对为BTC_USDT,所以当前合约为BTC的U本位当周合约 exchange.SetContractType("this_week").unwrap(); // 获取当前账户资产数据 let account = exchange.GetAccount().unwrap(); // USDT作为保证金的可用余额 Log!(account.Balance); // USDT作为保证金的冻结金额 Log!(account.FrozenBalance); // 当前资产权益 Log!(account.Equity); // 当前资产作为保证金的所有持仓的未实现盈亏 Log!(account.UPnL); }
c++
void main() { exchange.IO("currency", "BTC_USDT"); exchange.SetContractType("this_week"); auto account = exchange.GetAccount(); Log(account.Balance); Log(account.FrozenBalance); Log(account.Equity); Log(account.UPnL); }

返回值

类型描述

Account / 空值

查询账户资产信息,查询成功时返回Account结构,查询失败时返回空值。

参考

备注

如果交易所对象设置为加密货币期货合约交易所,并且切换为以USDT作为保证金的合约(切换方法请参阅exchange.SetCurrencyexchange.SetContractType函数),此时资产以USDT作为保证金,记录在Account结构的BalanceFrozenBalance属性中。

如果交易所对象设置为加密货币期货合约交易所,并且切换为币本位合约,此时资产以币作为保证金,记录在Account结构的StocksFrozenStocks属性中。

使用币安期货统一账户时,调用exchange.GetAccount()函数请求账户信息,封装的数据为所有资产折算为**USD**后的金额,显示在Account结构的Balance字段中。如需计算其它资产的折算金额,可将USD折算金额除以(待折算资产的)指数价格,再除以(待折算资产的)质押率即可算出。

exchange.GetAssets函数用于请求交易所账户的资产信息。

exchange.GetAssets()

示例

获取交易所账户的资产信息,exchange.GetAssets()函数返回一个以Asset结构体为元素的数组。

javascript
function main() { // exchange.SetCurrency("BTC_USDT") // 可以设置交易对 // exchange.SetContractType("swap") // 可以设置合约 var assets = exchange.GetAssets() Log(assets) }
python
def main(): # exchange.SetCurrency("BTC_USDT") # 可以设置交易对 # exchange.SetContractType("swap") # 可以设置合约 assets = exchange.GetAssets() Log(assets)
rust
fn main() { // exchange.SetCurrency("BTC_USDT"); // 可以设置交易对 // exchange.SetContractType("swap").unwrap(); // 可以设置合约 let assets = exchange.GetAssets().unwrap(); Log!(assets); }
c++
void main() { // exchange.SetCurrency("BTC_USDT"); // 可以设置交易对 // exchange.SetContractType("swap"); // 可以设置合约 auto assets = exchange.GetAssets(); Log(assets); }

返回值

类型描述

Asset数组 / 空值

exchange.GetAssets()函数请求数据成功时返回Asset结构体数组,请求数据失败时返回空值。

参考

备注

期货交易所对象的GetAssets()函数返回当前交易对(币本位、USDT本位、USDC本位等)下的保证金资产。

exchange.GetName()函数用于获取当前交易所对象所绑定的交易所名称。

exchange.GetName()

示例

javascript
function main() { Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance") }
python
def main(): Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance")
rust
fn main() { Log!("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance"); }
c++
void main() { Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance"); }

返回值

类型描述

string

exchange.GetName()函数返回由FMZ量化交易平台定义的交易所名称。

参考

备注

exchange.GetName()函数通常用于识别策略代码中的exchangeexchanges[1]exchanges[2]等交易所对象。加密货币期货合约交易所的名称带有固定前缀Futures_

exchange.GetLabel()函数用于获取配置交易所对象时设置的自定义标签。

exchange.GetLabel()

示例

javascript
function main() { Log("exchange label:", exchange.GetLabel()) }
python
def main(): Log("exchange label:", exchange.GetLabel())
rust
fn main() { Log!("exchange label:", exchange.GetLabel()); }
c++
void main() { Log("exchange label:", exchange.GetLabel()); }

返回值

类型描述

string

exchange.GetLabel()函数返回配置交易所对象时设置的自定义标签。

参考

备注

通过设置的标签,可在策略代码中识别exchangeexchanges[1]exchanges[2]等交易所对象。

exchange.GetCurrency()函数用于获取当前设置的交易对。

exchange.GetCurrency()

示例

javascript
function main() { Log("Current trading pair:", exchange.GetCurrency()) }
python
def main(): Log("Current trading pair:", exchange.GetCurrency())
rust
fn main() { Log!("Current trading pair:", exchange.GetCurrency()); }
c++
void main() { Log("Current trading pair:", exchange.GetCurrency()); }

返回值

类型描述

string

exchange.GetCurrency()函数返回当前exchange交易所对象所设置的交易对。

参考

备注

交易对格式统一采用大写形式,并使用下划线分隔baseCurrencyquoteCurrency,例如:BTC_USDT

exchange.SetCurrency()函数用于切换交易所对象exchange当前的交易对。

exchange.SetCurrency(currency)

示例

javascript
function main() { var ticker = exchange.GetTicker() Log(ticker) Log(exchange.GetAccount()) // 切换交易对,注意切换后行情数据、账户信息的变化 exchange.SetCurrency("LTC_USDT") Log("Switched to LTC_USDT") ticker = exchange.GetTicker() Log(ticker) Log(exchange.GetAccount()) }
python
def main(): ticker = exchange.GetTicker() Log(ticker) Log(exchange.GetAccount()) exchange.SetCurrency("LTC_USDT") Log("Switched to LTC_USDT") ticker = exchange.GetTicker() Log(ticker) Log(exchange.GetAccount())
rust
fn main() { let ticker = exchange.GetTicker(None).unwrap(); Log!(ticker); Log!(exchange.GetAccount()); // 切换交易对,注意切换后行情数据、账户信息的变化 exchange.SetCurrency("LTC_USDT"); Log!("Switched to LTC_USDT"); let ticker = exchange.GetTicker(None).unwrap(); Log!(ticker); Log!(exchange.GetAccount()); }
c++
void main() { auto ticker = exchange.GetTicker(); Log(ticker); Log(exchange.GetAccount()); exchange.SetCurrency("LTC_USDT"); Log("Switched to LTC_USDT"); ticker = exchange.GetTicker(); Log(ticker); Log(exchange.GetAccount()); }

参数

名称类型必填描述

currency

string

currency参数用于指定要切换的交易对。交易对格式统一为大写,并使用下划线分隔baseCurrencyquoteCurrency,例如:BTC_USDT

参考

备注

1、兼容exchange.IO("currency", "BTC_USDT")的切换方式,详见excahnge.IO

2、支持在回测系统中切换交易对,但回测系统中切换交易对时,计价币的名称不能改变。例如:BTC_USDT可以切换为LTC_USDT,但不能切换为LTC_BTC

3、切换为非回测页面初始设置的交易对后,交易币的数量为0。例如:回测时回测页面上初始设置的交易对为BTC_USDTBTC数量为3个,USDT数量为10000。此时立即切换为LTC_USDT,切换后交易币数量为0,即账户中LTC数量为0;切换后的交易对共享USDT数量,即数量仍为10000。

exchange.GetQuoteCurrency()函数用于获取当前交易对的计价币名称,即quoteCurrency

exchange.GetQuoteCurrency()

示例

javascript
function main() { exchange.SetCurrency("BTC_USDT") Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency()) // exchange.SetCurrency("ETH_BTC") // Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency()) }
python
def main(): exchange.SetCurrency("BTC_USDT") Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency()) # exchange.SetCurrency("ETH_BTC") # Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency())
rust
fn main() { exchange.SetCurrency("BTC_USDT"); Log!("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency()); // exchange.SetCurrency("ETH_BTC"); // Log!("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency()); }
c++
void main() { exchange.SetCurrency("BTC_USDT"); Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency()); // exchange.SetCurrency("ETH_BTC") // Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency()) }

返回值

类型描述

string

exchange.GetQuoteCurrency()函数返回当前交易对的计价币名称。

参考

备注

例如:exchange交易所对象当前的交易对为BTC_USDT时,exchange.GetQuoteCurrency()函数返回USDT;如果当前交易对为ETH_BTC,则exchange.GetQuoteCurrency()函数返回BTC

exchange.GetPositions()函数用于获取持仓信息;GetPositions()函数是交易所对象exchange的成员函数。

GetPositions()函数用于获取交易所对象exchange所绑定的交易所账户的持仓信息。exchange对象的成员函数(方法)的用途仅与exchange相关,本文档之后不再赘述。

exchange.GetPositions()
exchange.GetPositions(symbol)

示例

使用期货交易所对象,对多个不同交易对、不同合约代码的品种下市价单,并通过多种方式查询持仓信息。

javascript
/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for (var symbol of arrSymbol) { exchange.CreateOrder(symbol, "buy", -1, 1) exchange.CreateOrder(symbol, "sell", -1, 1) } var defaultPositions = exchange.GetPositions() var swapPositions = exchange.GetPositions("USDT.swap") var futuresPositions = exchange.GetPositions("USDT.futures") var btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap") var tbls = [] var arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions] var tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"] for (var index in arr) { var positions = arr[index] var tbl = {type: "table", title: tblDesc[index], cols: ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], rows: [] } for (var pos of positions) { tbl.rows.push([pos.Symbol, pos.MarginLevel, pos.Amount, pos.FrozenAmount, pos.Price, pos.Profit, pos.Type, pos.ContractType, pos.Margin]) } tbls.push(tbl) } LogStatus("`" + JSON.stringify(tbls) + "`") // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return }
python
'''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for symbol in arrSymbol: exchange.CreateOrder(symbol, "buy", -1, 1) exchange.CreateOrder(symbol, "sell", -1, 1) defaultPositions = exchange.GetPositions() swapPositions = exchange.GetPositions("USDT.swap") futuresPositions = exchange.GetPositions("USDT.futures") btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap") tbls = [] arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions] tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"] for index in range(len(arr)): positions = arr[index] tbl = {"type": "table", "title": tblDesc[index], "cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], "rows": []} for pos in positions: tbl["rows"].append([pos["Symbol"], pos["MarginLevel"], pos["Amount"], pos["FrozenAmount"], pos["Price"], pos["Profit"], pos["Type"], pos["ContractType"], pos["Margin"]]) tbls.append(tbl) LogStatus("`" + json.dumps(tbls) + "`") return
rust
/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ fn main() { let arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]; for symbol in arrSymbol { exchange.CreateOrder(symbol, "buy", -1, 1); exchange.CreateOrder(symbol, "sell", -1, 1); } let defaultPositions = exchange.GetPositions(None).unwrap(); let swapPositions = exchange.GetPositions("USDT.swap").unwrap(); let futuresPositions = exchange.GetPositions("USDT.futures").unwrap(); let btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap").unwrap(); // Rust SDK 没有JSON序列化,使用format!拼接表格的JSON文本 let mut tbls: Vec<String> = Vec::new(); let arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions]; let tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"]; for (index, positions) in arr.iter().enumerate() { let mut rows: Vec<String> = Vec::new(); for pos in positions { rows.push(format!(r#"["{}", {}, {}, {}, {}, {}, {}, "{}", {}]"#, pos.Symbol, pos.MarginLevel, pos.Amount, pos.FrozenAmount, pos.Price, pos.Profit, pos.Type, pos.ContractType, pos.Margin)); } let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], "rows": [{}]}}"#, tblDesc[index], rows.join(",")); tbls.push(tbl); } LogStatus!(format!("`[{}]`", tbls.join(","))); // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return; }
c++
/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"}; for (const auto& symbol : arrSymbol) { exchange.CreateOrder(symbol, "buy", -1, 1); exchange.CreateOrder(symbol, "sell", -1, 1); } auto defaultPositions = exchange.GetPositions(); auto swapPositions = exchange.GetPositions("USDT.swap"); auto futuresPositions = exchange.GetPositions("USDT.futures"); auto btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap"); json tbls = R"([])"_json; std::vector<std::vector<Position>> arr = {defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions}; std::string tblDesc[] = {"defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"}; for (int index = 0; index < arr.size(); index++) { auto positions = arr[index]; json tbl = R"({ "type": "table", "cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], "rows": [] })"_json; tbl["title"] = tblDesc[index]; for (const auto& pos : positions) { json arrJson = R"([])"_json; arrJson.push_back(pos.Symbol); arrJson.push_back(pos.MarginLevel); arrJson.push_back(pos.Amount); arrJson.push_back(pos.FrozenAmount); arrJson.push_back(pos.Price); arrJson.push_back(pos.Profit); arrJson.push_back(pos.Type); arrJson.push_back(pos.ContractType); arrJson.push_back(pos.Margin); tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); } LogStatus(_D(), "\n", "`" + tbls.dump() + "`"); return; }

返回值

类型描述

Position数组 / 空值

exchange.GetPositions()函数在请求数据成功时返回Position结构数组,在请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所要查询的交易品种交易品种范围

未传入symbol参数时,默认以当前交易对、合约代码所在的维度范围请求所有品种的持仓数据。

参考

备注

加密货币期货合约与加密货币现货不同,现货仅有逻辑上的持仓概念。在FMZ量化交易平台的系统中,加密货币期货合约的具体品种由**交易对**、**合约代码**共同标识。可参阅exchange.SetCurrencyexchange.SetContractType函数。

GetPositions函数中,symbol参数的使用场景归纳如下:

交易所对象分类symbol参数查询范围备注
期货不传symbol参数查询当前交易对、合约代码维度范围内的所有交易品种若当前交易对为BTC_USDT,合约代码为swap,则查询所有USDT本位永续合约。等价于调用GetPositions("USDT.swap")
期货指定交易品种,symbol参数为:"BTC_USDT.swap"查询指定的BTC USDT本位永续合约对于期货交易所对象,symbol参数的格式为:FMZ平台定义的交易对合约代码的组合,以字符"."分隔。
期货指定交易品种范围,symbol参数为:"USDT.swap"查询所有USDT本位永续合约-
支持期权的期货交易所不传symbol参数查询当前交易对维度范围内的所有期权合约若当前交易对为BTC_USDT,且合约设置为期权合约,例如币安期权合约:BTC-240108-40000-C
支持期权的期货交易所指定具体交易品种查询指定的期权合约例如对于币安期货交易所,symbol参数为:BTC_USDT.BTC-240108-40000-C
支持期权的期货交易所指定交易品种范围,symbol参数为:"USDT.option"查询所有USDT本位期权合约-

GetPositions函数中,期货交易所对象的查询维度范围归纳如下:

symbol参数请求范围定义备注
USDT.swapUSDT本位永续合约范围。对于交易所API接口不支持的维度,调用时会报错并返回空值。
USDT.futuresUSDT本位交割合约范围。-
USD.swap币本位永续合约范围。-
USD.futures币本位交割合约范围。-
USDT.optionUSDT本位期权合约范围。-
USD.option币本位期权合约范围。-
USDT.futures_combo差价组合合约范围。Futures_Deribit交易所
USD.futures_ff混合保证金交割合约范围。Futures_Kraken交易所
USD.swap_pf混合保证金永续合约范围。Futures_Kraken交易所

兼容exchange.GetPosition()调用,GetPositionGetPositions的用法完全一致。

当交易所对象exchange所代表的账户在查询范围内指定的交易品种上没有持仓时,exchange.GetPositions()函数返回空数组,例如:[]

exchange.SetMarginLevel()函数用于设置symbol参数所指定的交易对、合约的杠杆值。同时兼容仅传入marginLevel参数的调用方式,用于设置exchange交易所对象当前交易对、合约的杠杆值。

exchange.SetMarginLevel(symbol, marginLevel)
exchange.SetMarginLevel(marginLevel)

示例

javascript
function main() { exchange.SetMarginLevel(10) // 设置BTC的USDT本位永续合约的杠杆为15 exchange.SetMarginLevel("BTC_USDT.swap", 15) }
python
def main(): exchange.SetMarginLevel(10) exchange.SetMarginLevel("BTC_USDT.swap", 15)
rust
fn main() { exchange.SetMarginLevel(10); // Rust SDK 中SetMarginLevel函数不支持symbol参数,仅设置当前交易对、合约的杠杆值 // 如需设置BTC_USDT.swap品种的杠杆为15,需先切换到该交易对、合约后再调用exchange.SetMarginLevel(15) }
c++
void main() { exchange.SetMarginLevel(10); exchange.SetMarginLevel("BTC_USDT.swap", 15); }

参数

名称类型必填描述

symbol

string

symbol参数用于指定需要调整杠杆值的交易对、合约。SetMarginLevel()函数中symbol参数的格式与GetTicker()函数中symbol参数的格式一致。

marginLevel

number

marginLevel参数用于设置杠杆值。交易所的杠杆值通常为整数,部分交易所也支持浮点数形式的杠杆值设置。

参考

备注

exchange.SetMarginLevel()函数仅支持加密货币期货合约交易所对象。回测系统支持调用exchange.SetMarginLevel()函数来设置杠杆值。

对于加密货币期货合约而言,由于各加密货币期货合约交易所的杠杆机制并不统一。

在某些交易所中,期货合约的杠杆值是下单接口中的一个参数,此时调用exchange.SetMarginLevel()函数并不会产生网络请求,仅设置FMZ系统底层中的杠杆变量(用于下单接口传参)。

在另一些交易所中,期货合约的杠杆值是交易所的一项独立设置,需要通过交易所网站页面或API接口进行设置。此时调用exchange.SetMarginLevel()函数则会产生网络请求,并且有可能设置失败。失败原因可能有多种,例如:当前存在持仓或挂单,导致该交易对、合约无法再设置新的杠杆值。

不支持exchange.SetMarginLevel()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
SetMarginLevel--Futures_dYdX / Futures_Deribit / Futures_edgeX

exchange.SetDirection()函数用于设置调用exchange.Buy函数、exchange.Sell函数进行期货合约下单时的订单方向。

exchange.SetDirection(direction)

示例

javascript
function main(){ // 举例设置为OKX期货当周合约 exchange.SetContractType("this_week") // 设置杠杆为5倍 exchange.SetMarginLevel(5) // 设置下单方向为做多 exchange.SetDirection("buy") // 以10000的价格、2张合约数量下单 exchange.Buy(10000, 2) exchange.SetMarginLevel(5) exchange.SetDirection("closebuy") exchange.Sell(1000, 2) }
python
def main(): exchange.SetContractType("this_week") exchange.SetMarginLevel(5) exchange.SetDirection("buy") exchange.Buy(10000, 2) exchange.SetMarginLevel(5) exchange.SetDirection("closebuy") exchange.Sell(1000, 2)
rust
fn main() { // 注意:Rust SDK 中不推荐使用SetDirection、Buy、Sell函数,建议优先使用CreateOrder函数, // CreateOrder可直接指定side参数("buy"、"sell"、"closebuy"、"closesell"),无需先调用SetDirection // 举例设置为OKX期货当周合约 exchange.SetContractType("this_week").unwrap(); // 设置杠杆为5倍 exchange.SetMarginLevel(5); // 设置下单方向为做多 exchange.SetDirection("buy").unwrap(); // 以10000的价格、2张合约数量下单 exchange.Buy(10000, 2).unwrap(); exchange.SetMarginLevel(5); exchange.SetDirection("closebuy").unwrap(); exchange.Sell(1000, 2).unwrap(); }
c++
void main() { exchange.SetContractType("this_week"); exchange.SetMarginLevel(5); exchange.SetDirection("buy"); exchange.Buy(10000, 2); exchange.SetMarginLevel(5); exchange.SetDirection("closebuy"); exchange.Sell(1000, 2); }

参数

名称类型必填描述

direction

string

direction参数用于设置期货合约下单时的方向,可选值为:"buy""closesell""sell""closebuy"

参考

备注

exchange.SetDirection()函数用于设置期货合约交易方向与下单函数之间的对应关系:

下单函数SetDirection函数设置的方向备注
exchange.Buy"buy"买入开多仓
exchange.Buy"closesell"买入平空仓
exchange.Sell"sell"卖出开空仓
exchange.Sell"closebuy"卖出平多仓

exchange.SetContractType()函数用于设置exchange交易所对象当前的合约代码。

exchange.SetContractType(symbol)

示例

  • 将当前合约设置为当周合约:

    javascript
    function main() { // 设置为当周合约 exchange.SetContractType("this_week") }
    python
    def main(): exchange.SetContractType("this_week")
    rust
    fn main() { // 设置为当周合约 exchange.SetContractType("this_week").unwrap(); }
    c++
    void main() { exchange.SetContractType("this_week"); }
  • 在设置以USDT作为保证金的合约时,需要在代码中切换交易对(也可以在添加交易所对象时直接设置交易对):

    javascript
    function main() { // 默认交易对为BTC_USD,设置合约为当周,合约为币本位合约 exchange.SetContractType("this_week") Log("ticker:", exchange.GetTicker()) // 切换交易对,然后设置合约,切换成USDT作为保证金的合约,区别于币本位合约 exchange.IO("currency", "BTC_USDT") exchange.SetContractType("swap") Log("ticker:", exchange.GetTicker()) }
    python
    def main(): exchange.SetContractType("this_week") Log("ticker:", exchange.GetTicker()) exchange.IO("currency", "BTC_USDT") exchange.SetContractType("swap") Log("ticker:", exchange.GetTicker())
    rust
    fn main() { // 默认交易对为BTC_USD,设置合约为当周,合约为币本位合约 exchange.SetContractType("this_week").unwrap(); Log!("ticker:", exchange.GetTicker(None)); // 切换交易对,然后设置合约,切换成USDT作为保证金的合约,区别于币本位合约 exchange.IO(("currency", "BTC_USDT")).unwrap(); exchange.SetContractType("swap").unwrap(); Log!("ticker:", exchange.GetTicker(None)); }
    c++
    void main() { exchange.SetContractType("this_week"); Log("ticker:", exchange.GetTicker()); exchange.IO("currency", "BTC_USDT"); exchange.SetContractType("swap"); Log("ticker:", exchange.GetTicker()); }
  • 打印exchange.SetContractType()函数的返回值:

    javascript
    function main(){ // 设置合约为当周 var ret = exchange.SetContractType("this_week") // 返回当周合约的信息 Log(ret) }
    python
    def main(): ret = exchange.SetContractType("this_week") Log(ret)
    rust
    fn main() { // 设置合约为当周 let ret = exchange.SetContractType("this_week").unwrap(); // 返回当周合约的信息 Log!(ret); }
    c++
    void main() { auto ret = exchange.SetContractType("this_week"); Log(ret); }

返回值

类型描述

object

exchange.SetContractType()函数返回一个结构体,其中包含当前合约代码对应的交易所合约代码。例如,在币安期货合约交易所中,当前合约代码为quarter时,该函数的返回值结构为:{"InstrumentID":"BTCUSD_230630","instrument":"BTCUSD_230630"}

参数

名称类型必填描述

symbol

string

symbol参数用于设置合约代码,可选值为:"this_week""next_week""quarter""next_quarter""swap"等。

加密货币期货合约中的交割合约代码如无特殊说明,一般包括:

  • this_week:当周合约。

  • next_week:次周合约。

  • quarter:当季合约。

  • next_quarter:次季合约。

加密货币期货合约中的永续合约代码如无特殊说明,一般包括:

  • swap:永续合约。

参考

备注

在加密货币期货合约策略中,以切换至BTC_USDT交易对为例:

当使用exchange.SetCurrency("BTC_USDT")exchange.IO("currency", "BTC_USDT")函数切换交易对后,需要再次调用exchange.SetContractType()函数重新设置合约,才能在新的交易对下确定当前需要操作的合约。系统会根据交易对来判定该合约为币本位合约还是USDT本位合约

例如:当交易对设置为BTC_USDT时,使用exchange.SetContractType("swap")函数将合约代码设置为swap,此时即设置为BTCUSDT本位永续合约。若交易对为BTC_USD,使用exchange.SetContractType("swap")函数将合约代码设置为swap,此时则设置为BTC币本位永续合约。

详细介绍平台支持的加密货币期货合约交易所,各交易所的合约命名方式如下:

  • Futures_OKCoin(OKX)
    设置为永续合约:exchange.SetContractType("swap")
    设置为当周合约:exchange.SetContractType("this_week")
    设置为次周合约:exchange.SetContractType("next_week")
    设置为月度合约:exchange.SetContractType("month")
    设置为次月合约:exchange.SetContractType("next_month")
    设置为季度合约:exchange.SetContractType("quarter")
    设置为次季合约:exchange.SetContractType("next_quarter")

    OKX提供盘前交易合约,此类合约的交割日期为固定时间。以交易所定义的合约代码HMSTR-USDT-250207为例,先在发明者平台将交易对设置为HMSTR_USDT,然后使用exchange.SetContractType("HMSTR-USDT-250207")设置该合约。
    对于支持symbol参数的函数(例如exchange.GetTicker()exchange.CreateOrder()等),可以将symbol参数指定为HMSTR_USDT.HMSTR-USDT-250207,以获取该合约的行情数据或进行下单等操作。

  • Futures_HuobiDM(火币期货)
    设置为当周合约:exchange.SetContractType("this_week")
    设置为次周合约:exchange.SetContractType("next_week")
    设置为季度合约:exchange.SetContractType("quarter")
    设置为次季合约:exchange.SetContractType("next_quarter")
    设置为永续合约:exchange.SetContractType("swap")
    支持以USDT作为保证金的合约。以BTC合约为例:调用exchange.IO("currency", "BTC_USDT")即可切换为以USDT作为保证金的合约,
    或在配置实盘参数、添加交易所对象时直接将当前交易对设置为BTC_USDT。切换交易对后需重新调用exchange.SetContractType()函数设置合约。

  • Futures_BitMEX(BitMEX)
    设置为永续合约:exchange.SetContractType("swap")
    Futures_BitMEX交易所的交割合约为月度合约,合约代码如下(一月至十二月):

    code
    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"

    设置交割合约:exchange.SetContractType("December")。例如,将交易对设置为XBT_USDT时,调用exchange.SetContractType("December")函数即可设置BTC的USDT本位十二月交割合约(对应的实际合约代码为XBTUSDTZ23)。

    Futures_BitMEX合约信息汇总

    Futures_BitMEX定义的合约代码在FMZ对应的交易对在FMZ对应的合约代码备注
    DOGEUSDDOGE_USDswap美元计价,XBT结算。XBT即BTC。
    DOGEUSDTDOGE_USDTswapUSDT计价,USDT结算。
    XBTETHXBT_ETHswapETH计价,XBT结算。
    XBTEURXBT_EURswap欧元计价(EUR),XBT结算。
    USDTUSDCUSDT_USDCswapUSDC计价,XBT结算。
    ETHUSD_ETHETH_USD_ETHswap美元计价,ETH结算。
    XBTH24XBT_USDMarch到期日:24年3月,月份代码为H;美元计价,XBT结算。
    ETHUSDZ23ETH_USDDecember到期日:23年12月,月份代码为Z;美元计价,XBT结算。
    XBTUSDTZ23XBT_USDTDecember到期日:23年12月,月份代码为Z;USDT计价,USDT结算。
    ADAZ23ADA_XBTDecember到期日:23年12月,月份代码为Z;XBT计价,XBT结算。
    P_XBTETFX23USDT_XXXP_XBTETFX23到期日:23年11月;以百分比计价,USDT结算。
  • Futures_GateIO
    设置为当周合约:exchange.SetContractType("this_week")
    设置为次周合约:exchange.SetContractType("next_week")
    设置为季度合约:exchange.SetContractType("quarter")
    设置为次季合约:exchange.SetContractType("next_quarter")
    设置为永续合约:exchange.SetContractType("swap")
    支持以USDT作为保证金的合约。以BTC合约为例,调用exchange.IO("currency", "BTC_USDT")即可切换为以USDT作为保证金的合约,
    或在配置实盘参数、添加交易所对象时直接将当前交易对设置为BTC_USDT。切换交易对后需重新调用exchange.SetContractType()函数设置合约。

  • Futures_Deribit
    设置为永续合约:exchange.SetContractType("swap")
    支持Deribit的USDC合约。
    交割合约有:"this_week", "next_week", "month", "quarter", "next_quarter", "third_quarter", "fourth_quarter"
    差价合约(future_combo):"this_week,swap", "next_week,swap", "next_quarter,this_week", "third_quarter,this_week", "month,next_week"等多种组合。
    对于期权合约,需要传入交易所定义的具体期权合约代码,详情请参阅Deribit官网。

  • Futures_KuCoin
    币本位合约:例如将交易对设置为BTC_USD,再设置合约代码,即为币本位合约。
    设置为永续合约:exchange.SetContractType("swap")
    设置为当季合约:exchange.SetContractType("quarter")
    设置为次季合约:exchange.SetContractType("next_quarter")

    以USDT作为保证金的合约:
    例如将交易对设置为BTC_USDT,再设置合约代码,即为以USDT作为保证金的合约。
    设置为永续合约:exchange.SetContractType("swap")

  • Futures_Binance
    币安期货交易所默认为当前交易对的永续合约,合约代码:swap
    设置为永续合约:exchange.SetContractType("swap")。币安的永续合约支持以USDT作为保证金,例如BTCUSDT本位永续合约,需将交易对设置为BTC_USDT;币安也支持以币作为保证金的永续合约,例如BTC的币本位永续合约,需将交易对设置为BTC_USD
    设置为季度合约:exchange.SetContractType("quarter")。交割合约包含币本位合约(即以币作为保证金),例如设置BTC的季度合约时,将交易对设置为BTC_USD,再调用exchange.SetContractType("quarter"),即可设置为BTC的币本位季度合约。
    设置为次季合约:exchange.SetContractType("next_quarter")。例如设置BTC的币本位次季度合约时,将交易对设置为BTC_USD,再调用exchange.SetContractType("next_quarter")
    币安支持部分以USDT作为保证金的交割合约,以BTC为例,将交易对设置为BTC_USDT,再设置合约代码即可。

    支持币安期权合约:
    期权合约代码格式以交易所定义的为准,例如BTC-241227-15000-CXRP-240112-0.5-CBTC-241227-15000-P。以币安期权合约代码BTC-241227-15000-P为例:BTC为期权币种代码,241227为行权日期,15000为行权价格,P表示看跌期权,C表示看涨期权。
    期权的具体类型(欧式期权或美式期权)可查阅交易所期权合约的相关资料。
    交易所可能对期权卖方有所限制,需单独申请资格。币安期权即需要申请卖方资格。

  • Futures_Bibox
    Bibox永续合约的合约代码:swap
    设置为永续合约:exchange.SetContractType("swap")

  • Futures_Bybit
    默认为当前交易对的永续合约,合约代码:swap
    当周合约代码:this_week
    次周合约代码:next_week
    第三周合约代码:third_week
    月度合约代码:month
    次月合约代码:next_month
    季度合约代码:quarter
    次季度合约代码:next_quarter
    第三季度合约代码:third_quarter
    直接使用交易所的合约命名:例如ETHUSDT-04APR25。由于bybit交易所的部分合约品种并无明确的周期性,因此直接使用交易所定义的合约代码进行命名。

  • Futures_Kraken
    默认为当前交易对的永续合约,合约代码:swap
    swap:永续合约。
    month:当月合约。
    quarter:季度合约。
    next_quarter:次季合约。
    third_quarter:第三季度合约。
    swap_pf:混合保证金永续合约。
    quarter_ff:混合保证金季度合约。
    month_ff:混合保证金当月合约。
    next_quarter_ff:混合保证金次季度合约。
    third_quarter_ff:混合保证金第三季度合约。
    直接使用交易所的合约命名:例如FF_ETHUSD_250307。由于Kraken交易所的部分合约品种并无明确的周期性,因此直接使用交易所定义的合约代码进行命名。

  • Futures_Bitfinex
    默认为当前交易对的永续合约,合约代码:swap

  • Futures_Bitget
    默认为当前交易对的永续合约,合约代码:swap
    将交易对设置为BTC_USD即为币本位合约,将交易对设置为BTC_USDT即为USDT结算的合约。模拟合约可将交易对设置为SBTC_USDBTC_SUSDT

  • Futures_dYdX (v4)
    dYdX永续合约的合约代码:swap
    设置为永续合约:exchange.SetContractType("swap")。dYdX仅有USD.swap品种维度,使用的保证金为USDC。

  • Futures_MEXC
    MEXC(抹茶)永续合约的合约代码:swap
    设置为永续合约:exchange.SetContractType("swap")。将交易对设置为BTC_USD即为币本位合约,将交易对设置为BTC_USDT即为USDT结算的合约。

  • Futures_Crypto
    crypto.com交易所账户中的代币可折算为以USD计价的额度,用作合约交易的保证金。
    设置为永续合约:exchange.SetContractType("swap")。例如,将交易对设置为BTC_USD时,调用exchange.SetContractType("swap")函数即可设置BTC的永续合约。
    crypto.com交易所的交割合约为月度合约,合约代码如下(一月至十二月):

    code
    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"

    设置交割合约:exchange.SetContractType("October")。例如,将交易对设置为BTC_USD时,调用exchange.SetContractType("October")函数即可设置BTC的十月交割合约。
    当前时刻对应的合约代码为BTCUSD-231027

  • Futures_WOO
    Futures_WOO交易所支持USDT本位合约,永续合约代码为swap。例如,将交易对设置为BTC_USDT时,调用exchange.SetContractType("swap")函数即可将当前合约设置为BTC的USDT本位永续合约。

  • Futures_Hyperliquid
    Futures_Hyperliquid交易所支持USDC本位合约,永续合约代码为swap。例如,将交易对设置为ETH_USD时,调用exchange.SetContractType("swap")函数即可将当前合约设置为ETH的USDC本位永续合约。
    Futures_Hyperliquid仅有USD.swap品种维度,使用的保证金为USDC。
    Futures_Hyperliquid支持HIP-3品种。

  • Futures_Lighter
    Futures_Lighter交易所支持USDC本位合约,永续合约代码为swap。例如,将交易对设置为BTC_USDC时,调用exchange.SetContractType("swap")函数即可将当前合约设置为BTC的USDC本位永续合约。
    Futures_Lighter仅支持永续合约。

  • Futures_Backpack
    Futures_Backpack交易所支持USDC本位合约,永续合约代码为swap。例如,将交易对设置为ETH_USDC时,调用exchange.SetContractType("swap")函数即可将当前合约设置为ETH的USDC本位永续合约。

  • Futures_edgeX
    Futures_edgeX交易所支持USDT本位合约,永续合约代码为swap。例如,将交易对设置为BTC_USDT时,调用exchange.SetContractType("swap")函数即可将当前合约设置为BTC的USDT本位永续合约。

  • Futures_WOOFI
    Futures_WOOFI交易所支持USDC本位合约,永续合约代码为swap。例如,将交易对设置为ETH_USDC时,调用exchange.SetContractType("swap")函数即可将当前合约设置为ETH的USDC本位永续合约。

  • Futures_Coinw
    Futures_Coinw交易所支持USDT本位合约,永续合约代码为swap。例如,将交易对设置为ETH_USDT时,调用exchange.SetContractType("swap")函数即可将当前合约设置为ETH的USDT本位永续合约。

  • Futures_Aster
    Futures_Aster交易所支持USDT本位合约,永续合约代码为swap。例如,将交易对设置为ETH_USDT时,调用exchange.SetContractType("swap")函数即可将当前合约设置为ETH的USDT本位永续合约。

  • Futures_DeepCoin
    币本位合约:例如将交易对设置为BTC_USD,再设置合约代码,即为币本位合约。
    设置为永续合约:exchange.SetContractType("swap")

    以USDT作为保证金的合约:
    例如将交易对设置为BTC_USDT,再设置合约代码,即为以USDT作为保证金的合约。
    设置为永续合约:exchange.SetContractType("swap")

exchange.GetContractType()函数用于获取exchange交易所对象当前设置的合约代码。

exchange.GetContractType()

示例

javascript
function main () { Log(exchange.SetContractType("this_week")) Log(exchange.GetContractType()) }
python
def main(): Log(exchange.SetContractType("this_week")) Log(exchange.GetContractType())
rust
fn main() { Log!(exchange.SetContractType("this_week")); Log!(exchange.GetContractType()); }
c++
void main() { Log(exchange.SetContractType("this_week")); Log(exchange.GetContractType()); }

返回值

类型描述

string

exchange.GetContractType()函数返回由FMZ平台定义的合约代码,例如:this_weekswap等。

参考

exchange.GetFundings()函数用于获取当前周期的资金费率数据。

exchange.GetFundings()
exchange.GetFundings(symbol)

示例

使用期货交易所对象,在回测系统中调用exchange.GetFundings()函数。在调用任何行情函数之前,GetFundings 仅返回当前默认交易对的 Funding 数据;在调用行情函数之后,则会返回所有已请求过的品种的 Funding 数据。可参考以下测试示例:

javascript
/*backtest start: 2024-10-01 00:00:00 end: 2024-10-23 00:05:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}] */ function main() { // LPT_USDT.swap 4小时周期 var symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"] for (var symbol of symbols) { exchange.GetTicker(symbol) } var arr = [] var arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"] for (var p of arrParams) { if (p == "no param") { arr.push(exchange.GetFundings()) } else { arr.push(exchange.GetFundings(p)) } } var tbls = [] var index = 0 for (var fundings of arr) { var tbl = { "type": "table", "title": arrParams[index], "cols": ["Symbol", "Interval", "Time", "Rate"], "rows": [], } for (var f of fundings) { tbl["rows"].push([f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate * 100 + " %"]) } tbls.push(tbl) index++ } LogStatus(_D(), "\n Requested symbols:", symbols, "\n`" + JSON.stringify(tbls) + "`") }
python
'''backtest start: 2024-10-01 00:00:00 end: 2024-10-23 00:05:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}] ''' import json def main(): # LPT_USDT.swap 4小时周期 symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"] for symbol in symbols: exchange.GetTicker(symbol) arr = [] arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"] for p in arrParams: if p == "no param": arr.append(exchange.GetFundings()) else: arr.append(exchange.GetFundings(p)) tbls = [] index = 0 for fundings in arr: tbl = { "type": "table", "title": arrParams[index], "cols": ["Symbol", "Interval", "Time", "Rate"], "rows": [], } for f in fundings: tbl["rows"].append([f["Symbol"], f["Interval"] / 3600000, _D(f["Time"]), str(f["Rate"] * 100) + " %"]) tbls.append(tbl) index += 1 LogStatus(_D(), "\n Requested symbols:", symbols, "\n`" + json.dumps(tbls) + "`")
rust
/*backtest start: 2024-10-01 00:00:00 end: 2024-10-23 00:05:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}] */ fn main() { // LPT_USDT.swap 4小时周期 let symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"]; for symbol in symbols { exchange.GetTicker(symbol); } let mut arr: Vec<Vec<Funding>> = Vec::new(); let arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"]; for p in arrParams { if p == "no param" { arr.push(exchange.GetFundings(None).unwrap()); } else { arr.push(exchange.GetFundings(p).unwrap()); } } // Rust SDK 没有JSON序列化,使用format!拼接表格的JSON文本 let mut tbls: Vec<String> = Vec::new(); for (index, fundings) in arr.iter().enumerate() { let mut rows: Vec<String> = Vec::new(); for f in fundings { rows.push(format!(r#"["{}", {}, "{}", "{} %"]"#, f.Symbol, f.Interval as f64 / 3600000.0, _D(f.Time), f.Rate * 100.0)); } let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "Interval", "Time", "Rate"], "rows": [{}]}}"#, arrParams[index], rows.join(",")); tbls.push(tbl); } LogStatus!(_D(None), "\n Requested symbols:", format!("{:?}", symbols), format!("\n`[{}]`", tbls.join(","))); }
c++
/*backtest start: 2024-10-01 00:00:00 end: 2024-10-23 00:05:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}] */ void main() { // LPT_USDT.swap 4小时周期 json arrSymbol = R"([])"_json; std::string symbols[] = {"SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"}; for (const std::string& symbol : symbols) { exchange.GetTicker(symbol); arrSymbol.push_back(symbol); } std::vector<std::vector<Funding>> arr = {}; std::string arrParams[] = {"no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"}; for (const std::string& p : arrParams) { if (p == "no param") { arr.push_back(exchange.GetFundings()); } else { arr.push_back(exchange.GetFundings(p)); } } json tbls = R"([])"_json; int index = 0; for (int i = 0; i < arr.size(); i++) { auto fundings = arr[i]; json tbl = R"({ "type": "table", "cols": ["Symbol", "Interval", "Time", "Rate"], "rows": [] })"_json; tbl["title"] = arrParams[index]; for (int j = 0; j < fundings.size(); j++) { auto f = fundings[j]; // json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), string(f.Rate * 100) + " %"}; json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate}; tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); index++; } LogStatus(_D(), "\n Requested symbols:", arrSymbol.dump(), "\n`" + tbls.dump() + "`"); }

返回值

类型描述

Funding数组 / 空值

exchange.GetFundings()函数请求数据成功时返回Funding结构数组,请求数据失败时返回空值。

参数

名称类型必填描述

symbol

string

参数symbol用于指定所要查询的交易品种交易品种范围。若不传入symbol参数,则默认以当前交易对、合约代码所在的维度范围,请求所有品种的当期资金费率数据。

参考

备注

对于不支持批量查询资金费率数据的期货交易所,若将symbol参数指定为查询范围(例如USDT.swap)或不传入symbol参数,接口将会报错。使用这类期货交易所对象调用GetFundings()函数时,必须将symbol参数指定为具体的某个永续合约品种,才能查询到该品种的当期资金费率数据。

exchange.GetFundings()函数支持实盘与回测系统。

不支持批量获取资金费率数据的交易所:Futures_Bitget、Futures_OKX、Futures_MEXC、Futures_Deribit、Futures_Crypto。调用时需传入symbol参数指定具体的品种代码,例如:ETH_USDT.swap

不支持exchange.GetFundings()函数的交易所:

函数名不支持的现货交易所不支持的期货交易所
GetFundings--Futures_DigiFinex

exchange.SetBase()函数用于设置exchange交易所对象所使用的交易所API接口基地址。

exchange.SetBase(s)

示例

javascript
function main() { // 使用默认基地址 Log(exchange.GetTicker()) // 切换为https://aws.okx.com exchange.SetBase("https://aws.okx.com") Log(exchange.GetTicker()) }
python
def main(): Log(exchange.GetTicker()) exchange.SetBase("https://aws.okx.com") Log(exchange.GetTicker())
rust
fn main() { // 使用默认基地址 Log!(exchange.GetTicker(None)); // 切换为https://aws.okx.com exchange.SetBase("https://aws.okx.com"); Log!(exchange.GetTicker(None)); }
c++
void main() { Log(exchange.GetTicker()); exchange.SetBase("https://aws.okx.com"); Log(exchange.GetTicker()); }

参数

名称类型必填描述

s

string

s参数用于指定交易所API接口的基地址。

参考

备注

回测系统不支持切换交易所API接口基地址,因为回测系统是一个沙盒模拟环境,不会真正访问交易所的API接口。

exchange.GetBase() 函数用于获取当前交易所 API 接口的基础地址。

exchange.GetBase()

示例

javascript
function main() { Log(exchange.GetBase()) }
python
def main(): Log(exchange.GetBase())
rust
fn main() { Log!(exchange.GetBase()); }
c++
void main() { Log(exchange.GetBase()); }

返回值

类型描述

string

当前交易所 API 接口的基础地址。

参考

exchange.SetProxy()函数用于设置exchange交易所对象的代理配置。

exchange.SetProxy(proxy)

示例

  • exchange交易所对象配置socks5代理:

    javascript
    function main() { exchange.SetProxy("socks5://192.168.1.10:8080") // 如果无法访问交易所行情接口,设置一个可用的socks5代理即可访问行情接口 Log(exchange.GetTicker()) }
    python
    def main(): exchange.SetProxy("socks5://192.168.1.10:8080") Log(exchange.GetTicker())
    rust
    fn main() { exchange.SetProxy("socks5://192.168.1.10:8080"); // 如果无法访问交易所行情接口,设置一个可用的socks5代理即可访问行情接口 Log!(exchange.GetTicker(None)); }
    c++
    void main() { exchange.SetProxy("socks5://192.168.1.10:8080"); Log(exchange.GetTicker()); }
  • 除了**全局指定**exchange交易所对象发出请求所使用的IP地址外,也支持基于exchange单独指定IP地址:

    javascript
    function main(){ exchange.SetProxy("ip://10.0.3.15") // 发出请求的IP地址为10.0.3.15 exchange.GetTicker() }
    python
    def main(): exchange.SetProxy("ip://10.0.3.15") exchange.GetTicker()
    rust
    fn main() { exchange.SetProxy("ip://10.0.3.15"); // 发出请求的IP地址为10.0.3.15 let _ = exchange.GetTicker(None); }
    c++
    void main() { exchange.SetProxy("ip://10.0.3.15"); exchange.GetTicker(); }

参数

名称类型必填描述

proxy

string

proxy参数用于指定代理配置。

参考

备注

如果代理设置失败,调用exchange.SetProxy()函数时将返回空值。

exchange.SetProxy()函数的代理设置功能仅支持rest协议。每个exchange交易所对象可以设置一个代理,设置代理后,对该exchange交易所对象所绑定交易所接口的访问都会通过该代理进行。

支持设置socks5代理,以第一个添加的交易所对象exchange(即exchanges[0])为例:

  • 设置代理,无用户名、无密码:exchange.SetProxy("socks5://127.0.0.1:8889")

  • 设置代理,指定用户名和密码:exchange.SetProxy("socks5://username:[email protected]:8889"),其中username为用户名,password为密码。

  • 切换为正常模式,不使用代理:exchange.SetProxy("")

支持指定exchange交易所对象发出请求所使用的IP地址,详见全局指定

exchange.SetTimeout()函数用于设置exchange交易所对象rest请求的超时时间。

exchange.SetTimeout(timeout)

示例

javascript
function main() { exchange.SetTimeout(3000) Log(exchange.GetTicker()) }
python
def main(): exchange.SetTimeout(3000) Log(exchange.GetTicker())
rust
fn main() { exchange.SetTimeout(3000); Log!(exchange.GetTicker(None)); }
c++
void main() { exchange.SetTimeout(3000); Log(exchange.GetTicker()); }

参数

名称类型必填描述

timeout

number

timeout参数用于指定超时时间的毫秒数。

参考

备注

参数timeout为毫秒数值,1000毫秒等于1秒。该设置仅适用于rest协议,用于设置rest请求的超时时间,只需设置一次即可生效。例如:exchange.SetTimeout(3000),将exchange交易所对象的rest请求超时时间设置为3秒;调用exchange.GetTicker()等涉及网络请求的函数时,若超过3秒未收到应答则判定为超时,发生超时的函数调用将返回空值。

SetTimeout()不是全局函数,而是exchange交易所对象的方法。

发明者量化交易平台从系统底层真正支持JavaScript语言策略的多线程功能,实现了以下对象:

对象说明备注
threading多线程全局对象成员函数:ThreadgetThreadmainThread等。
Thread线程对象成员函数:peekMessagepostMessagejoin等。
ThreadLock线程锁对象成员函数:acquirerelease。可作为线程执行函数的参数传入线程环境。
ThreadEvent事件对象成员函数:setclearwaitisSet。可作为线程执行函数的参数传入线程环境。
ThreadCondition条件对象成员函数:notifynotifyAllwaitacquirerelease。可作为线程执行函数的参数传入线程环境。
ThreadDict字典对象成员函数:getset。可作为线程执行函数的参数传入线程环境。

threading对象作为全局多线程管理工具,提供了创建并发线程、线程锁、条件变量等功能。本章节介绍threading对象的成员函数。仅JavaScript语言策略支持该对象。

Thread()函数用于创建并发线程。

Thread(func, ...args)
Thread(...items)

示例

  • 同时创建一个自定义函数和一个匿名函数的并发线程。

    javascript
    function test1(a, b, c) { Log("test1:", a, b, c) } function main() { var t1 = threading.Thread(test1, 1, 2, 3) var t2 = threading.Thread(function (msg) { Log("msg:", msg) }, "Hello thread2") t1.join() t2.join() }
  • 使用 Thread(...items) 形式创建并发线程,按顺序执行多个函数。

    javascript
    function test1(msg) { Log("msg:", msg) test2("Hello test2") } function main() { var t1 = threading.Thread( [function(a, b, c) {Log(a, b, c)}, 1, 2, 3], [test1, "Hello test1"], [`function test2(msg) {Log("msg:", msg)}`]) t1.join() }
  • 支持向并发执行函数的参数中传入函数。

    javascript
    function testFunc1(p) { Log("testFunc1 p:", p) } function main() { threading.Thread(function(pfn) { var threadName = threading.currentThread().name() var threadId = threading.currentThread().id() pfn(`in thread threadName: ${threadName}, threadId: ${threadId}`) }, testFunc1).join() }
  • 支持传入函数字符串,可动态导入外部库进行并发计算。

    javascript
    function ml(input) { const net = new brain.NeuralNetwork() net.train([ { input: [0, 0], output: [0] }, { input: [0, 1], output: [1] }, { input: [1, 0], output: [1] }, { input: [1, 1], output: [0] }, ]) return net.run(input) } function main() { var ret = threading.Thread([ml, [1, 0]], [HttpQuery("https://unpkg.com/brain.js")]).join() // ret: {"id":1,"terminated":false,"elapsed":337636000,"ret":{"0":0.9339330196380615}} Log(ret) }

返回值

类型描述

Thread对象

Thread()函数返回一个Thread对象,用于管理创建的并发线程、线程通信等。

参数

名称类型必填描述

func

function

参数func是用于并发执行的函数(通过引用传递),支持传入匿名函数。func可接受多个参数,这些参数将在并发执行时通过...args传入。因此,func的参数列表需要与...args保持一致。

arg

string / number / bool / object / array / function / any (平台支持的任意类型)

参数arg是在回调执行时传递给func(即并发线程执行函数)的实际参数;参数arg可以有多个,func的参数列表需要与...args保持一致。

item

array

参数item是一个数组,包含待并发执行的函数引用及其参数。调用Thread函数时,参数item可以传入多组。

参考

备注

传入Thread()函数用于并发执行的线程函数func运行在隔离环境中,因此无法直接引用线程外部的变量,引用时会导致编译失败。同时,线程内不支持引用其他闭包函数。线程内部可以调用平台提供的所有API,但不能调用用户自定义的其他函数。

当线程执行完毕且没有被持续引用时,系统底层会自动回收线程相关的资源,无需显式调用join()函数来释放资源。如果存在持续引用导致无法释放资源,当并发数量超过2000个时会报错:InternalError: too many routine wait, max is 2000

支持回测系统、实盘环境;所有并发线程相关的函数在回测系统中仅作为代码兼容性支持,实际不会真正执行并发线程,本章不再赘述。

getThread()函数用于根据指定的线程ID获取线程对象。

getThread(threadId)

示例

通过threadId获取指定的线程对象。

javascript
function main() { var t1 = threading.Thread(function () { // Thread 对象有方法:id(),用于获取线程的Id,可以查看文档对应Thread对象的章节 var id = threading.currentThread().id() var thread1 = threading.getThread(id) Log("id:", id, ", thread1.id():", thread1.id()) Log(`id == thread1.id():`, id == thread1.id()) }) t1.join() }

返回值

类型描述

Thread对象

getThread()函数返回由参数threadId指定的Thread对象

参数

名称类型必填描述

threadId

number

参数threadId为线程对象ID,通过指定该参数获取对应的线程对象。

参考

备注

支持回测系统、实盘环境。

如果目标线程已经执行完毕并被释放,则无法通过threading.getThread(threadId)获取该线程的线程对象。

mainThread()函数用于获取主线程的线程对象,即策略中main()函数所在的线程。

mainThread()

示例

  • 获取主线程的Thread对象,输出主线程的threadId

    javascript
    function main() { Log("Main thread ID:", threading.mainThread().id()) }
  • 在并发线程中也可以获取主线程的线程对象。

    javascript
    function test() { Log("Main thread ID output in test function:", threading.mainThread().id()) } function main() { var t1 = threading.Thread(test) t1.join() }

返回值

类型描述

Thread对象

mainThread()函数返回主线程的线程对象。

参考

备注

支持回测系统、实盘环境。

currentThread()函数用于获取当前线程的线程对象。

currentThread()

示例

获取当前线程的Thread对象,输出当前线程的threadId

javascript
function test() { Log("Current thread ID:", threading.currentThread().id()) } function main() { var t1 = threading.Thread(test) t1.join() }

返回值

类型描述

Thread对象

currentThread()函数返回当前线程的线程对象。

参考

备注

支持回测系统、实盘环境。

Lock()函数用于创建线程锁对象。

Lock()

示例

两个并发线程访问共享资源。

javascript
function consumer(productionQuantity, dict, lock) { for (var i = 0; i < productionQuantity; i++) { lock.acquire() var count = dict.get("count") Log("consumer:", count) Sleep(1000) lock.release() } } function producer(productionQuantity, dict, lock) { for (var i = 0; i < productionQuantity; i++) { lock.acquire() dict.set("count", i) Log("producer:", i) Sleep(1000) lock.release() } } function main() { var dict = threading.Dict() dict.set("count", -1) var lock = threading.Lock() var productionQuantity = 10 var producerThread = threading.Thread(producer, productionQuantity, dict, lock) var consumerThread = threading.Thread(consumer, productionQuantity, dict, lock) consumerThread.join() producerThread.join() }

返回值

类型描述

ThreadLock对象

Lock()函数返回一个线程锁对象。

参考

备注

支持回测系统、实盘环境。

Condition()函数用于创建一个条件变量对象,该对象用于在多线程并发环境中实现线程间的同步与通信。通过Condition(),一个线程可以在特定条件未满足时进入等待状态,直到另一个线程发出信号通知条件已满足。

Condition()

示例

两个并发线程访问共享资源。

javascript
function consumer(productionQuantity, dict, condition) { for (var i = 0; i < productionQuantity; i++) { condition.acquire() while (dict.get("array").length == 0) { condition.wait() } var arr = dict.get("array") var count = arr.shift() dict.set("array", arr) Log("consumer:", count, ", array:", arr) condition.release() Sleep(1000) } } function producer(productionQuantity, dict, condition) { for (var i = 0; i < productionQuantity; i++) { condition.acquire() var arr = dict.get("array") arr.push(i) dict.set("array", arr) Log("producer:", i, ", array:", arr) condition.notify() condition.release() Sleep(1000) } } function main() { var dict = threading.Dict() dict.set("array", []) var condition = threading.Condition() var productionQuantity = 10 var producerThread = threading.Thread(producer, productionQuantity, dict, condition) var consumerThread = threading.Thread(consumer, productionQuantity, dict, condition) consumerThread.join() producerThread.join() }

返回值

类型描述

ThreadCondition对象

Condition()函数返回一个ThreadCondition对象。

参考

备注

回测系统暂不支持此功能,仅提供接口定义。

Event()函数用于创建一个线程事件对象,该对象用于线程间的同步,允许一个线程等待另一个线程的通知或信号。

Event()

示例

两个并发线程访问共享资源。

javascript
function consumer(productionQuantity, dict, pEvent, cEvent) { for (var i = 0; i < productionQuantity; i++) { while (dict.get("array").length == 0) { pEvent.wait() } if (pEvent.isSet()) { pEvent.clear() } var arr = dict.get("array") var count = arr.shift() dict.set("array", arr) Log("consumer:", count, ", array:", arr) cEvent.set() Sleep(1000) } } function producer(productionQuantity, dict, pEvent, cEvent) { for (var i = 0; i < productionQuantity; i++) { while (dict.get("array").length != 0) { cEvent.wait() } if (cEvent.isSet()) { cEvent.clear() } var arr = dict.get("array") arr.push(i) dict.set("array", arr) Log("producer:", i, ", array:", arr) pEvent.set() Sleep(1000) } } function main() { var dict = threading.Dict() dict.set("array", []) var pEvent = threading.Event() var cEvent = threading.Event() var productionQuantity = 10 var producerThread = threading.Thread(producer, productionQuantity, dict, pEvent, cEvent) var consumerThread = threading.Thread(consumer, productionQuantity, dict, pEvent, cEvent) consumerThread.join() producerThread.join() }

返回值

类型描述

ThreadEvent对象

Event()函数返回一个ThreadEvent对象。

参考

备注

支持回测系统、实盘环境。

Dict()函数用于创建一个字典对象,用于在并发线程间传递和共享数据。

Dict()

示例

  • 向并发线程执行函数传入普通对象,测试修改对象键值后是否会影响其他线程中的对象键值。

    javascript
    function threadFun1(obj) { obj["age"] = 100 while (true) { Log("threadFun1 obj:", obj) Sleep(5000) } } function threadFun2(obj) { while (true) { Log("threadFun2 obj:", obj) Sleep(5000) } } function main() { var obj = {"age": 10} var t1 = threading.Thread(threadFun1, obj) var t2 = threading.Thread(threadFun2, obj) t1.join() t2.join() }
  • 向并发线程执行函数传入通过Dict()函数创建的ThreadDict对象,测试修改对象键值后是否会影响其他线程中的对象键值。

    javascript
    function threadFun1(threadDict) { threadDict.set("age", 100) while (true) { Log(`threadFun1 threadDict.get("age"):`, threadDict.get("age")) Sleep(5000) } } function threadFun2(threadDict) { while (true) { Log(`threadFun2 threadDict.get("age"):`, threadDict.get("age")) Sleep(5000) } } function main() { var threadDict = threading.Dict() threadDict.set("age", 10) var t1 = threading.Thread(threadFun1, threadDict) var t2 = threading.Thread(threadFun2, threadDict) t1.join() t2.join() }

返回值

类型描述

ThreadDict对象

Dict()函数返回一个ThreadDict对象。

参考

备注

向并发线程函数传入普通对象时采用深拷贝方式传递,在并发线程中修改键值不会影响其他线程中的字典。

支持回测系统、实盘环境。

pending函数用于获取当前策略程序中正在运行的并发线程数量。

pending()

示例

创建两个并发运行的线程,并在不同时间点调用pending()函数。

javascript
function threadFun1() { Log("threadFun1") Sleep(3000) } function threadFun2() { for (var i = 0; i < 3; i++) { LogStatus(_D(), "print from threadFun2") Sleep(3000) } } function main() { Log(`begin -- threading.pending():`, threading.pending()) var t1 = threading.Thread(threadFun1) var t2 = threading.Thread(threadFun2) Log(`after threading.Thread -- threading.pending():`, threading.pending()) t1.join() t2.join() Log(`after thread.join -- threading.pending():`, threading.pending()) }

返回值

类型描述

number

pending()函数返回当前策略程序中正在运行的并发线程数量。

参考

备注

当策略的main()函数开始运行时,直接调用pending()函数将返回1,这是因为main()函数所在的主线程本身也被计入正在运行的线程中。

支持回测系统和实盘环境。

Thread对象可以通过threading.Thread()threading.getThread()threading.mainThread()threading.currentThread()创建或返回。

peekMessage()函数用于从线程接收消息。

peekMessage()
peekMessage(timeout)

示例

并发线程向主线程发送消息。

javascript
function main() { var t1 = threading.Thread(function() { for (var i = 0; i < 10; i++) { Log("thread1 postMessage():", i) threading.mainThread().postMessage(i) Sleep(500) } }) while (true) { var msg = threading.currentThread().peekMessage() Log("main peekMessage():", msg) if (msg == 9) { break } Sleep(1000) } t1.join() }

返回值

类型描述

string / number / bool / object / array / any (平台支持的任意类型)

peekMessage()函数返回当前线程对象关联的线程所接收到的消息。

参数

名称类型必填描述

timeout

number

参数timeout为超时设置,按照该参数设置的毫秒数阻塞等待并返回数据;若无数据且超时则返回空值。如果timeout设置为0或不传timeout参数,则一直阻塞等待,直到接收到通道中的数据。如果timeout设置为-1,则不阻塞并立即返回数据,无数据时返回空值。

参考

备注

编写程序时需注意避免线程死锁问题。

postMessage()函数用于向线程发送消息。

postMessage(msg)

示例

  • 在并发线程中发送消息,使用eventLoop()接收消息通知。

    javascript
    function main() { var t1 = threading.Thread(function() { for (var i = 0; i < 10; i++) { Log("thread1 postMessage():", i) threading.mainThread().postMessage(i) Sleep(500) } }) for (var i = 0; i < 10; i++) { var event = threading.mainThread().eventLoop() Log("main event:", event) Sleep(500) } t1.join() }
  • 支持发送函数。

    javascript
    function main() { threading.mainThread().postMessage(function(msg) { Log("func from mainThread, msg:", msg) }) threading.Thread(function() { var func = threading.mainThread().peekMessage() func("in " + threading.currentThread().name()) }).join() }

参数

名称类型必填描述

msg

string / number / bool / object / array / function / any (平台支持的任意类型)

参数msg为要发送的消息。

参考

备注

当线程的执行函数中调用postMessage()函数发送信号或数据时,会产生消息事件。可以使用eventLoop()函数接收消息通知。

join()函数用于等待线程退出,并回收系统资源。

join()
join(timeout)

示例

测试join()函数超时,输出返回值。

javascript
function main() { var t1 = threading.Thread(function() { Log("Hello thread1") Sleep(5000) }) var ret = t1.join(1000) Log("ret:", ret) // ret: undefined ret = t1.join() Log("ret:", ret) // ret: {"id":1,"terminated":false,"elapsed":5003252000} }

返回值

类型描述

ThreadRet对象

ThreadRet对象包含执行结果的相关数据,包含以下属性:

  • id: 线程ID。
  • terminated: 线程是否被强制终止。
  • elapsed: 线程的运行时间(纳秒)。
  • ret: 线程函数的返回值。

参数

名称类型必填描述

timeout

number

timeout参数用于设置等待线程结束的超时时间,单位为毫秒。当timeout参数设置为0或不设置timeout参数时,join()函数会阻塞,直到线程执行结束。当timeout参数设置为-1时,join()函数会立即返回。

参考

备注

join()函数超时时,返回undefined

terminate()函数用于强制终止线程,释放创建线程时占用的硬件资源。

terminate()

示例

强制终止一个线程的执行。在强制终止线程后,日志中将不再显示该线程输出的内容。

javascript
function main() { var t1 = threading.Thread(function() { for (var i = 0; i < 10; i++) { Log("thread1 i:", i) Sleep(1000) } }) Sleep(3000) t1.terminate() Log("after t1.terminate()") while (true) { LogStatus(_D()) Sleep(1000) } }

参考

备注

对于使用terminate()函数强制终止的线程,无法再使用join()函数等待其结束。

getData()函数用于访问线程环境中记录的变量。数据在线程未执行join()函数(等待退出成功)且未执行terminate()函数(强制终止线程)的情况下有效。

getData()
getData(key)

示例

在并发线程的环境中记录键名为count的值,然后在主线程中读取count的键值。

javascript
function main() { var t1 = threading.Thread(function() { for (var i = 0; i < 5; i++) { threading.currentThread().setData("count", i) Log(`setData("count"):`, i) Sleep(1000) } }) for (var i = 0; i < 5; i++) { var count = threading.getThread(t1.id()).getData("count") Log(`getData("count"):`, count) Sleep(1000) } t1.join() }

返回值

类型描述

string / number / bool / object / array / any (平台支持的任意类型)

getData()函数返回当前线程环境中存储的键值对中key参数对应的键值。

参数

名称类型必填描述

key

string

key参数为存储的键值对的键名。

参考

setData()函数用于在线程环境中存储变量。

setData(key, value)

示例

  • 在并发线程中设置键值对,在主线程中读取该键值对。

    javascript
    function main() { var t1 = threading.Thread(function() { threading.currentThread().setData("data", 100) }) Sleep(1000) Log(`t1.getData("data"):`, t1.getData("data")) t1.join() }
  • 支持将函数作为键值传入。

    javascript
    function main() { threading.mainThread().setData("func2", function(p) { Log("func2 p:", p) }) var t1 = threading.Thread(function() { threading.currentThread().setData("func1", function(p) { Log("func1 p:", p) }) var func2 = threading.mainThread().getData("func2") func2("test2") }) Sleep(1000) var func1 = t1.getData("func1") func1("test1") t1.join() }

参数

名称类型必填描述

key

string

key参数用于指定存储的键值对的键名。

value

string / number / bool / object / array / function / any (平台支持的任意类型)

value参数用于指定存储的键值对的键值。

参考

备注

数据在线程未执行join()函数(等待退出成功)且未执行terminate()函数(强制终止线程)的情况下有效。参数value的值必须是可序列化的变量。

id()函数用于返回当前多线程对象实例的threadId

id()

示例

创建一个并发运行的线程,在主线程中输出该并发线程的threadId

javascript
function main() { var t1 = threading.Thread(function() { threading.currentThread().setData("data", 100) }) Log(`t1.id():`, t1.id()) t1.join() }

返回值

类型描述

number

id()函数返回threadId

参考

name()函数用于返回当前多线程对象实例的名称。

name()

示例

创建一个并发运行的线程,在主线程中输出该并发线程的名称。

javascript
function main() { var t1 = threading.Thread(function() { threading.currentThread().setData("data", 100) }) Log(`t1.name():`, t1.name()) // t1.name(): Thread-1 t1.join() }

返回值

类型描述

string

name()函数返回并发线程的名称。

参考

eventLoop() 函数用于监听当前线程接收到的事件。

eventLoop()
eventLoop(timeout)

示例

并发执行 3 个线程,输出接收到的事件信息;当超时或立即返回时,输出的是空值。

javascript
function main() { var t1 = threading.Thread(function() { while (true) { var eventMsg = threading.currentThread().eventLoop() // 阻塞等待 // 2024-11-14 10:14:18 thread1 eventMsg: {"Seq":1,"Event":"thread","ThreadId":0,"Index":1,"Queue":0,"Nano":1731550458699947000} Log(_D(), "thread1 eventMsg:", eventMsg) } }) var t2 = threading.Thread(function() { while (true) { var eventMsg = threading.currentThread().eventLoop(-1) // 立即返回 Log(_D(), "thread2 eventMsg:", eventMsg) Sleep(5000) } }) var t3 = threading.Thread(function() { while (true) { var eventMsg = threading.currentThread().eventLoop(3000) // 设置3秒超时 Log(_D(), "thread3 eventMsg:", eventMsg) } }) t1.postMessage("Hello " + t1.name()) t2.postMessage("Hello " + t2.name()) t3.postMessage("Hello " + t3.name()) t1.join() t2.join() t3.join() }

返回值

类型描述

object / 空值

eventLoop() 函数返回当前线程接收到的事件信息,详见事件信息结构

参数

名称类型必填描述

timeout

number

参数 timeout 用于设置超时时间,单位为毫秒。若 timeout 设置为 0,则一直阻塞等待,直到有事件发生才返回;若大于 0,则设置事件等待的超时时间;若小于 0,则立即返回最近的事件。

参考

备注

eventLoop() 函数的处理机制与全局函数 EventLoop() 一致。

线程锁对象,用于多线程同步处理。

acquire()函数用于请求线程锁(加锁)。

acquire()

示例

示例请参考threading.Lock()章节的内容。

参考

备注

acquire()函数用于请求线程锁。当线程调用某个线程锁对象的acquire()函数时,它会尝试获取该锁。如果锁当前未被其他线程占用,调用线程将成功获得锁并继续执行。如果锁已被其他线程持有,调用acquire()的线程将被阻塞,直到锁被释放。

release()函数用于释放线程锁(解锁)。

release()

示例

测试死锁场景

javascript
function consumer(productionQuantity, dict, pLock, cLock) { for (var i = 0; i < productionQuantity; i++) { pLock.acquire() cLock.acquire() var arr = dict.get("array") var count = arr.shift() dict.set("array", arr) Log("consumer:", count, ", array:", arr) cLock.release() Sleep(1000) pLock.release() } } function producer(productionQuantity, dict, pLock, cLock) { for (var i = 0; i < productionQuantity; i++) { cLock.acquire() // cLock.acquire() 放在 pLock.acquire() 后不会产生死锁 pLock.acquire() var arr = dict.get("array") arr.push(i) dict.set("array", arr) Log("producer:", i, ", array:", arr) pLock.release() Sleep(1000) cLock.release() } } function main() { var dict = threading.Dict() dict.set("array", []) var pLock = threading.Lock() var cLock = threading.Lock() var productionQuantity = 10 var producerThread = threading.Thread(producer, productionQuantity, dict, pLock, cLock) var consumerThread = threading.Thread(consumer, productionQuantity, dict, pLock, cLock) consumerThread.join() producerThread.join() }

参考

备注

需要注意,线程锁使用不当可能导致死锁。

事件对象,用于多线程间的事件通知和信号传递。

set()函数用于设置事件信号。

set()

示例

请参考threading.Event()章节中的示例。

参考

备注

如果事件已经通过set()设置,则不能重复设置,需要先调用清空操作后才能重新设置信号。

clear()函数用于清除信号。

clear()

示例

请参考threading.Event()章节中的示例。

参考

wait()函数用于设置事件(信号)等待,在事件(信号)被设置之前会阻塞;支持设置超时参数。

wait()
wait(timeout)

示例

测试wait()函数的返回值。

javascript
function main() { var event = threading.Event() var t1 = threading.Thread(function(event) { var ret = event.wait(100) Log(`event.wait(100):`, ret) ret = event.wait() Log(`event.wait():`, ret) }, event) Sleep(1000) event.set() t1.join() }

返回值

类型描述

bool

wait()函数返回是否超时,如果发生超时则返回真值。

参数

名称类型必填描述

timeout

number

参数timeout用于设置等待超时时间,单位为毫秒。

参考

isSet()函数用于判断事件(信号)是否已被设置。

isSet()

示例

请参考threading.Event()章节中的示例。

返回值

类型描述

bool

isSet()函数返回事件(信号)的设置状态;如果事件(信号)已被设置,则返回真值。

参考

条件变量对象,用于实现多线程间的同步与通信。

notify()函数用于唤醒一个正在等待的线程(如果存在)。只有调用了wait()方法的线程才能被唤醒。

notify()

示例

使用notify()函数唤醒等待中的线程。

javascript
function consumer(dict, condition) { while (true) { condition.acquire() while (dict.get("array").length == 0) { Log(threading.currentThread().name(), "wait()...", ", array:", dict.get("array")) condition.wait() } var arr = dict.get("array") var num = arr.shift() Log(threading.currentThread().name(), ", num:", num, ", array:", arr, "#FF0000") dict.set("array", arr) Sleep(1000) condition.release() } } function main() { var condition = threading.Condition() var dict = threading.Dict() dict.set("array", []) var t1 = threading.Thread(consumer, dict, condition) var t2 = threading.Thread(consumer, dict, condition) var t3 = threading.Thread(consumer, dict, condition) Sleep(1000) var i = 0 while (true) { condition.acquire() var msg = "" var arr = dict.get("array") var randomNum = Math.floor(Math.random() * 5) + 1 if (arr.length >= 3) { condition.notifyAll() msg = "notifyAll" } else { arr.push(i) dict.set("array", arr) if (randomNum > 3 && arr.length > 0) { condition.notify() msg = "notify" } else { msg = "pass" } i++ } Log(_D(), "randomNum:", randomNum, ", array:", arr, ", msg:", msg) condition.release() Sleep(1000) } }

参考

备注

notify()函数会唤醒处于等待队列中的一个线程。

notify()函数唤醒线程时,该线程会重新获取线程锁。

notifyAll()函数用于唤醒所有正在等待的线程。

notifyAll()

示例

示例请参考ThreadCondition.notify()章节的内容。

参考

备注

notifyAll()函数会逐个唤醒所有处于等待状态的线程,被唤醒的线程将重新获取线程锁。

wait()函数用于在特定条件下使线程进入等待状态。

wait()

示例

示例请参考ThreadCondition.notify()章节的内容。

参考

备注

wait()函数会释放线程锁,当线程被唤醒时将重新获取线程锁。

acquire()函数用于请求线程锁(加锁)。

acquire()

示例

示例请参考ThreadCondition.notify()章节的内容。

参考

备注

在调用wait()之前必须先请求当前条件对象的线程锁(加锁)。

release()函数用于释放线程锁(解锁)。

release()

示例

示例请参考ThreadCondition.notify()章节的内容。

参考

备注

在调用wait()后需要释放当前条件对象的线程锁(解锁)。

线程安全的字典对象,用于在多线程环境中进行数据共享。

get()函数用于获取字典对象中记录的键值。

get(key)

示例

使用事件对象通知线程读取和修改数据。

javascript
function main() { var event = threading.Event() var dict = threading.Dict() dict.set("data", 100) var t1 = threading.Thread(function(dict, event) { Log(`thread1, dict.get("data"):`, dict.get("data")) event.set() event.clear() event.wait() Log(`after main change data, thread1 dict.get("data"):`, dict.get("data")) dict.set("data", 0) }, dict, event) event.wait() dict.set("data", 99) event.set() event.clear() t1.join() Log(`main thread, dict.get("data"):`, dict.get("data")) }

返回值

类型描述

string / number / bool / object / array / any (平台支持的任意类型)

get()函数返回参数key指定的键对应的值。

参数

名称类型必填描述

key

string

参数key用于指定要获取的键名。

参考

set()函数用于设置键值对。

set(key, value)

示例

支持将函数作为键值传入。

javascript
function main() { var dict1 = threading.Dict() dict1.set("func1", function(p) { Log("func1 p:", p) }) threading.Thread(function(dict1) { var func1 = dict1.get("func1") func1("test") }, dict1).join() }

参数

名称类型必填描述

key

string

参数key用于指定需要设置的键名。

value

string / number / bool / object / array / function / any (平台支持的任意类型)

参数value用于指定需要设置的键值。

参考

在发明者量化交易平台中,主要通过 exchange.IO() 函数实现区块链相关的各种功能调用。以下文档将根据 exchange.IO() 函数的不同功能分别进行描述。exchange.IO("abi", ...) 函数调用方式用于注册 ABI。

  • 支持以太坊(eth)

  • 支持波场(tron)

exchange.IO(k, address, abiContent)

示例

javascript
function main() { // register Uniswap SwapRouter02 abi var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]` // abi 仅使用了局部的 exactOutput 方法内容,完整的 abi 可以在网上搜索 exchange.IO("abi", routerAddress, abi) }

参数

名称类型必填描述

k

string

k 参数用于设置 exchange.IO() 函数的功能,设置为 "abi" 表示该函数用于注册 ABI

address

string

address 参数用于指定智能合约的地址。

abiContent

string

abiContent 参数用于指定智能合约的 ABI

备注

如果调用的智能合约方法是标准 ERC20 方法,则无需注册。

获取合约的 ABI 内容可以通过以下 URL 获取,只需取 result 字段,例如:

url
https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

exchange.IO("api", "eth", ...)函数的调用方式,用于调用以太坊RPC方法(需要在Web3交易所对象配置时选择eth)。

exchange.IO("api", "tron", ...)函数的调用方式,用于调用波场RPC方法(需要在Web3交易所对象配置时选择tron)。

exchange.IO(k, blockChain, rpcMethod)
exchange.IO(k, blockChain, rpcMethod, ...args)

示例

  • 查询钱包中ETH的余额:

    javascript
    function main() { // "owner" 需要替换为具体钱包地址 // "latest"字符串位置的参数标签:'latest'、'earliest'或'pending',参考https://eth.wiki/json-rpc/API#the-default-block-parameter // 返回值 ethBalance 为十六进制字符串:0x9b19ce56113070 var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest") // ETH的精度单位为1e18 var ethDecimal = 18 // 由于JavaScript语言精度原因,需要使用系统底层封装的函数BigInt、BigDecimal处理 // 将ethBalance转换为可读数量,0x9b19ce56113070转换为0.043656995388076145 Log(Number((BigDecimal(BigInt(ethBalance))/BigDecimal(Math.pow(10, ethDecimal))).toString())) }
  • ETH转账,可以根据具体需求设置{gasPrice: 11, gasLimit: 111, nonce: 111}参数,该参数设置在exchange.IO()函数的最后一个参数上。可以省略其中的nonce使用系统默认值,或者不设置gasLimit/gasPrice/nonce,全部使用系统默认值。

    javascript
    function mian() { // ETH的精度单位为1e18 var ethDecimal = 18 // 转账数量,可读的数量例如:0.01个ETH var sendAmount = 0.01 // 由于JavaScript语言精度原因,需要使用系统底层封装的函数BigInt、BigDecimal处理,并且将可读数量转换为链上处理的数据 var toAmount = (BigDecimal(sendAmount)*BigDecimal(Math.pow(10, ethDecimal))).toFixed(0) // "toAddress"为转账时接收方的ETH钱包地址,需要具体填写,toAmount为转账数量 exchange.IO("api", "eth", "send", "toAddress", toAmount) }
  • 查询gasPrice

    javascript
    function toAmount(s, decimals) { return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString()) } function main() { var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) // 5000000000 , in wei (5 gwei) }
  • 查询eth_estimateGas

    javascript
    function toAmount(s, decimals) { // toAmount函数可以将十六进制编码的数值转换为十进制数值 return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString()) } function main() { // 编码approve(授权)方法的调用 var data = exchange.IO("encode", "0x111111111117dC0aa78b770fA6A738034120C302", "approve", "0xe592427a0aece92de3edee1f18e0157c05861564", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") Log("data:", data) var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) var obj = { "from" : "0x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // walletAddress "to" : "0x111111111117dC0aa78b770fA6A738034120C302", "gasPrice" : gasPrice, "value" : "0x0", "data" : "0x" + data, } var gasLimit = exchange.IO("api", "eth", "eth_estimateGas", obj) Log("gasLimit:", toAmount(gasLimit, 0)) Log("gas fee", toAmount(gasLimit, 0) * toAmount(gasPrice, 0) / 1e18) }

返回值

类型描述

string / number / bool / object / array / any (平台支持的任意类型)

exchange.IO("api", "eth", ...)函数返回所调用RPC方法的返回值。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能,设置为"api"表示该函数用于扩展调用请求。

blockChain

string

blockChain参数用于设置exchange.IO()函数的功能,设置为"eth"表示该函数用于调用以太坊网络的RPC方法;设置为"tron"表示该函数用于调用波场网络的RPC方法。

rpcMethod

string

rpcMethod参数用于设置exchange.IO()函数所要调用的RPC方法。

arg

string / number / bool / object / array / function / any (平台支持的任意类型)

arg参数用于指定所要调用的RPC方法的参数。

arg参数可能有多个,arg参数的类型和数量根据rpcMethod参数指定的RPC方法而定。

参考

备注

exchange.IO()函数的第二个参数为"eth"时,可以直接调用以太坊节点服务器可用的RPC方法。

exchange.IO("encode", ...)函数用于数据编码操作。

exchange.IO(k, dataFormat, ...args)
exchange.IO(k, address, dataFormat)
exchange.IO(k, address, dataFormat, ...args)

示例

  • 以编码unwrapWETH9方法调用为例:

    javascript
    function main() { // ContractV3SwapRouterV2 主网地址 : 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 // 调用unwrapWETH9方法需要先注册ABI,此处省略注册 // "owner"代表钱包地址,需要具体填写,1代表解包装数量,把一个WETH解包装为ETH var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner") Log(data) }
  • 等同于Solidityabi.encode的编码示例:

    javascript
    function main() { var x = 10 var address = "0x02a5fBb259d20A3Ad2Fdf9CCADeF86F6C1c1Ccc9" var str = "Hello World" var array = [1, 2, 3] var ret = exchange.IO("encode", "uint256,address,string,uint256[]", x, address, str, array) // uint 即 uint256 , FMZ上需要指定类型长度 Log("ret:", ret) /* 000000000000000000000000000000000000000000000000000000000000000a // x 00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9 // address 0000000000000000000000000000000000000000000000000000000000000080 // str 的偏移 00000000000000000000000000000000000000000000000000000000000000c0 // array 的偏移 000000000000000000000000000000000000000000000000000000000000000b // str 的长度 48656c6c6f20576f726c64000000000000000000000000000000000000000000 // str 数据 0000000000000000000000000000000000000000000000000000000000000003 // array 的长度 0000000000000000000000000000000000000000000000000000000000000001 // array 第一个数据 0000000000000000000000000000000000000000000000000000000000000002 // array 第二个数据 0000000000000000000000000000000000000000000000000000000000000003 // array 第三个数据 */ }
  • 支持对元组(tuple)或包含元组的类型顺序进行编码。此类型顺序由tuplebytes组成,因此在调用exchange.IO()进行encode时需要传入两个对应参数:

    • 1、对应tuple类型的变量:
      { a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }
      传入的参数必须与tuple的结构、类型保持一致,如同types参数中定义的形式:tuple(a uint256,b uint8,c address)
    • 2、对应bytes类型的变量:
      "0011"
    javascript
    function main() { var types = "tuple(a uint256,b uint8,c address),bytes" var ret = exchange.IO("encode", types, { a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }, "0011") Log("encode: ", ret) }
  • 支持对数组或包含数组的类型顺序进行编码:

    javascript
    function main() { var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"] // ETH address, USDT address var ret = exchange.IO("encode", "address[]", path) Log("encode: ", ret) }

返回值

类型描述

string

exchange.IO("encode", ...)函数返回编码后的数据字符串。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能模式,设置为"encode"时表示该函数执行数据编码操作。

address

string

address参数用于指定智能合约地址。当调用exchange.IO("encode", ...)函数时,如果传入address参数,则表示对智能合约方法调用进行编码;如果未传入address参数,则该函数用于按指定类型顺序进行编码,功能等同于Solidity中的abi.encode

dataFormat

string

dataFormat参数用于指定编码数据的方法名称、数据类型及参数顺序。

arg

string / number / tuple / array / any (平台支持的任意类型)

arg参数用于指定与dataFormat参数相匹配的具体数据值。

arg参数可能有多个,其类型和数量根据dataFormat参数的设置而定。

备注

exchange.IO()函数封装了encode方法,可以将函数调用编码并返回为hex字符串格式。具体使用方法可参考平台公开的「Uniswap V3 交易类库」模板

对智能合约方法调用进行编码时,需要先注册相应的ABI。

exchange.IO("encodePacked", ...)函数用于执行encodePacked编码操作。

exchange.IO(k, dataFormat, ...args)

示例

在使用Uniswap V3时需要传入交易路径等参数,此时需要使用encodePacked编码操作:

javascript
function main() { var fee = exchange.IO("encodePacked", "uint24", 3000) var tokenInAddress = "0x111111111117dC0aa78b770fA6A738034120C302" var tokenOutAddress = "0x6b175474e89094c44da98b954eedeac495271d0f" var path = tokenInAddress.slice(2).toLowerCase() path += fee + tokenOutAddress.slice(2).toLowerCase() Log("path:", path) }

返回值

类型描述

string

exchange.IO("encodePacked", ...)函数返回经过encodePacked编码处理后的数据字符串。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能模式,当设置为"encodePacked"时,表示该函数执行数据encodePacked编码操作。

dataFormat

string

dataFormat参数用于指定encodePacked编码时数据的类型格式和排列顺序。

arg

string / number / tuple / array / any (平台支持的任意类型)

arg参数用于指定与dataFormat参数格式相匹配的具体数据值。

arg参数可以有多个,其类型和数量由dataFormat参数的设置决定。

exchange.IO("decode", ...)函数用于数据解码操作。

exchange.IO(k, dataFormat, data)

示例

  • exchange.IO("encode", ...)函数的逆向操作示例:

    javascript
    function main() { var types = "tuple(a uint256,b uint8,c address),bytes" var ret = exchange.IO("encode", types, { a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }, "0011") Log("encode: ", ret) var rawData = exchange.IO("decode", types, ret) Log("decode:", rawData) }
  • 以下示例首先对path参数执行encodePacked操作,因为后续需要编码的exactOutput方法调用需要path作为参数。然后对路由合约的exactOutput方法进行编码,该方法只有一个参数,参数类型为tuple类型。exactOutput方法名编码后的结果为:0x09b81346,使用exchange.IO("decode", ...)方法解码得到decodeRaw,其结果与变量dataTuple保持一致。

    javascript
    function main() { // register SwapRouter02 abi var walletAddress = "0x398a93ca23CBdd2642a07445bCD2b8435e0a373f" var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]` exchange.IO("abi", routerAddress, abi) // abi只使用了局部的exactOutput方法的内容,完整的abi可以在网上搜索 // encode path var fee = exchange.IO("encodePacked", "uint24", 3000) var tokenInAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" var tokenOutAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7" var path = tokenInAddress.slice(2).toLowerCase() path += fee + tokenOutAddress.slice(2).toLowerCase() Log("path:", path) var dataTuple = { "path" : path, "recipient" : walletAddress, "amountOut" : 1000, "amountInMaximum" : 1, } // encode SwapRouter02 exactOutput var rawData = exchange.IO("encode", routerAddress, "exactOutput", dataTuple) Log("method hash:", rawData.slice(0, 8)) // 09b81346 Log("params hash:", rawData.slice(8)) // decode exactOutput params var decodeRaw = exchange.IO("decode", "tuple(path bytes,recipient address,amountOut uint256,amountInMaximum uint256)", rawData.slice(8)) Log("decodeRaw:", decodeRaw) }

返回值

类型描述

array / string

exchange.IO("decode", ...)函数返回解码后的数据。当dataFormat参数指定的数据结构只包含单个字段时,返回字符串类型;当包含多个字段时,返回数组类型。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能模式,设置为"decode"时表示执行数据解码操作。

dataFormat

string

dataFormat参数用于指定待解码数据的格式类型和字段顺序。

data

string

data参数用于传入需要解码的原始数据。

备注

exchange.IO()函数支持数据的双向处理,既可以进行编码(encode)操作,也可以进行解码(decode)操作。

exchange.IO("key", ...)函数用于切换私钥的调用方式。

exchange.IO(k, key)

示例

javascript
function main() { exchange.IO("key", "Private Key") // "Private Key"代表私钥字符串,需要具体填写 }

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能,当设置为"key"时,表示该函数用于切换私钥。

key

string

key参数用于设置私钥字符串。

备注

exchange.IO()函数支持切换私钥功能,可以操作多个钱包地址。也可以添加多个交易所对象(参考:exchanges)来操作多个钱包地址。

对于切换私钥的操作:exchange.IO("key", "xxx"),不能使用并发方式进行切换。

exchange.IO("api", ...)函数用于调用智能合约的方法。

exchange.IO(k, address, method)
exchange.IO(k, address, method, ...args)
exchange.IO(k, address, method, value, ...args)

示例

  • decimals方法是ERC20的一个constant方法,不会产生gas消耗,可以查询某个token的精度数据。

    decimals方法无需参数。返回值:token的精度数据。

    javascript
    function main(){ var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 代币的合约地址,例子中的代币为1INCH Log(exchange.IO("api", tokenAddress, "decimals")) // 查询,打印1INCH代币的精度指数为18 }
  • allowance方法是ERC20的一个constant方法,不会产生gas消耗,可以查询某个token对于某个合约地址的授权额度。

    allowance方法需要传入2个参数,第一个参数为钱包地址,第二个参数为被授权的地址。返回值:token的授权额度。

    owner:钱包地址,例子中以字符串"owner"代替,实际使用需要具体填写地址。

    spender:被授权的合约地址,例子中以字符串"spender"代替,实际使用需要具体填写地址,例如可以是Uniswap V3 router v1地址。

    javascript
    function main(){ // 代币的合约地址,例子中的代币为1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 例如查询得出1000000000000000000,除以该token的精度单位1e18,得出当前交易所对象绑定的钱包给spender地址授权了1个1INCH数量 Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender")) }
  • approve方法是ERC20的一个非constant方法,会产生gas消耗,用于给某个合约地址授权token的操作额度。

    approve方法需要传入2个参数,第一个参数为被授权的地址,第二个参数为授权的额度。返回值:txid。

    spender:被授权的合约地址,例子中以字符串"spender"代替,实际使用需要具体填写地址,例如可以是Uniswap V3 router v1地址。

    0xde0b6b3a7640000:授权数量,这里使用十六进制字符串表示,对应的十进制数值为1e18,除以例子中的token精度单位(即1e18),得出授权了1个token。

    exchange.IO()函数的第三个参数传入方法名approve,也可以写methodId的形式,例如:"0x571ac8b0"。也可以写完整标准方法名,例如:"approve(address,uint256)"。

    javascript
    function main(){ // 代币的合约地址,例子中的代币为1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 授权量的十六进制字符串: 0xde0b6b3a7640000 , 对应的十进制字符串: 1e18 , 1e18除以该token的精度单位,即1个代币数量 , 所以这里指授权一个代币 Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000")) }
  • multicall方法是Uniswap V3的一个非constant方法,会产生gas消耗,用于多路兑换代币。

    multicall方法可能有多种传参方式,具体可以查询包含该方法的ABI,调用该方法之前需要先注册ABI。返回值:txid。

    具体的multicall方法调用示例,可以参考平台公开的「Uniswap V3 交易类库」模板

    这里使用伪代码来描述一些细节:

    exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)

    ContractV3SwapRouterV2:Uniswap V3的router v2地址。

    value:转账的ETH数量,如果兑换操作的tokenIn代币不是ETH,则设置为0。

    deadlinedeadlinemulticall方法的参数,可以设置为(new Date().getTime() / 1000) + 3600,表示一小时内有效。

    datadatamulticall方法的参数,需要执行的打包操作数据。与exchange.IO("api", "eth", "send", "toAddress", toAmount)类似,在调用multicall方法时也可以指定方法调用的gasLimit/gasPrice/nonce设置,同样使用伪代码来描述:

    exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 123456, gasLimit: 21000})

    可以根据具体需求设置{gasPrice: 11, gasLimit: 111, nonce: 111}参数,该参数设置在exchange.IO()函数的最后一个参数上。

    可以省略其中的nonce使用系统默认值,或者不设置gasLimit/gasPrice/nonce,全部使用系统默认值。

    javascript
    function main() { var ContractV3SwapRouterV2 = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" var tokenInName = "ETH" var amountIn = 0.01 var options = {gasPrice: 5000000000, gasLimit: 21000, nonce: 100} // 此处为举例,具体要根据实际场景设置 var data = "" // 编码后的数据,此处为空字符串,具体要根据实际场景设置 var tx = exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", (tokenInName == 'ETH' ? amountIn : 0), (new Date().getTime() / 1000) + 3600, data, options || {}) }

返回值

类型描述

string / number / bool / object / array / any (平台支持的任意类型)

exchange.IO("api", ...)函数返回所调用的智能合约方法的返回值。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能,设置为"api"表示该函数用于扩展API调用请求。

address

string

address参数用于指定智能合约的地址。

method

string

method参数用于指定要调用的智能合约方法。

value

number / string

value参数用于设置发送的ETH数量。当要执行的智能合约方法的stateMutability属性为payable时,需要传入value参数。"stateMutability":"payable"属性可以从ABI中查看,exchange.IO()函数会根据已注册的ABI中的stateMutability属性判断所需参数,如果stateMutability属性为nonpayable则无需传入value参数。

arg

string / number / bool / any (平台支持的任意类型)

arg参数用于指定要调用的智能合约方法的参数。

arg参数可能有多个,arg参数的类型与个数根据要调用的智能合约方法而定。

exchange.IO("address")函数用于获取exchange交易所对象所配置钱包的地址。

exchange.IO(k)

示例

javascript
function main() { Log(exchange.IO("address")) // 打印exchange交易所对象上配置的私钥对应的钱包地址 }

返回值

类型描述

string

exchange.IO("address")函数返回已配置的钱包地址。

参数

名称类型必填描述

k

string

k参数用于设置exchange.IO()函数的功能。当设置为"address"时,表示该函数用于获取已配置的钱包地址。

exchange.IO("base", ...) 函数用于设置 RPC 节点地址。

exchange.IO(k, address)

示例

javascript
function main() { var chainRpc = "https://bsc-dataseed.binance.org" exchange.IO("base", chainRpc) // 切换到 BSC 链 }

参数

名称类型必填描述

k

string

k 参数用于指定 exchange.IO() 函数的功能,设置为 "base" 时表示该函数用于切换 RPC 节点。

address

string

address 参数用于指定 RPC 节点地址。

TA.MACD()函数用于计算指数平滑异同移动平均线(MACD)指标

TA.MACD(inReal)
TA.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)

示例

javascript
function main(){ // 可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1...... var records = exchange.GetRecords(PERIOD_M15) var macd = TA.MACD(records, 12, 26, 9) // 观看日志可得知返回三个数组,分别对应DIF,DEA,MACD Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]) }
python
def main(): r = exchange.GetRecords(PERIOD_M15) macd = TA.MACD(r, 12, 26, 9) Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
rust
fn main() { // 可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1...... let records = exchange.GetRecords(None, PERIOD_M15, None).unwrap(); let macd = TA.MACD(&records, 12, 26, 9); // 观看日志可得知返回三个数组,分别对应DIF,DEA,MACD Log!("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M15); auto macd = TA.MACD(r, 12, 26, 9); Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]); }

返回值

类型描述

array

TA.MACD()函数的返回值为二维数组,其结构为:[DIF, DEA, MACD]

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快线周期。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢线周期。

optInSignalPeriod

number

optInSignalPeriod参数用于设置信号线周期。

参考

备注

发明者量化的TA指标库对常用指标算法进行了优化,支持JavaScriptPythonC++语言策略的调用,详见开源TA库代码

TA.MACD()函数的optInFastPeriodoptInSlowPeriodoptInSignalPeriod参数默认值分别为:12269

TA.KDJ()函数用于计算随机指标(KDJ)

TA.KDJ(inReal)
TA.KDJ(inReal, period, kPeriod, dPeriod)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M15) var kdj = TA.KDJ(records, 9, 3, 3) Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]) }
python
def main(): r = exchange.GetRecords(PERIOD_M15) kdj = TA.KDJ(r, 9, 3, 3) Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M15, None).unwrap(); let kdj = TA.KDJ(&records, 9, 3, 3); Log!("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]); }
c++
void main() { auto r = exchange.GetRecords(); auto kdj = TA.KDJ(r, 9, 3, 3); Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]); }

返回值

类型描述

array

TA.KDJ()函数的返回值为二维数组,其结构为:[K, D, J]

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于传入 K 线数据。

period

number

period参数用于设置计算周期 1。

kPeriod

number

kPeriod参数用于设置计算周期 2。

dPeriod

number

dPeriod参数用于设置计算周期 3。

参考

备注

TA.KDJ()函数的periodkPerioddPeriod参数的默认值分别为:933

TA.RSI()函数用于计算相对强弱指标(RSI)

TA.RSI(inReal)
TA.RSI(inReal, optInTimePeriod)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M30) var rsi = TA.RSI(records, 14) Log(rsi) }
python
def main(): r = exchange.GetRecords(PERIOD_M30) rsi = TA.RSI(r, 14) Log(rsi)
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap(); let rsi = TA.RSI(&records, 14); Log!(rsi); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M30); auto rsi = TA.RSI(r, 14); Log(rsi); }

返回值

类型描述

array

TA.RSI()函数的返回值为一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期。

参考

备注

TA.RSI()函数的optInTimePeriod参数的默认值为:14

TA.ATR()函数用于计算平均真实波幅指标(ATR)

TA.ATR(inPriceHLC)
TA.ATR(inPriceHLC, optInTimePeriod)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M30) var atr = TA.ATR(records, 14) Log(atr) }
python
def main(): r = exchange.GetRecords(PERIOD_M30) atr = TA.ATR(r, 14) Log(atr)
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap(); let atr = TA.ATR(&records, 14); Log!(atr); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M30); auto atr = TA.ATR(r, 14); Log(atr); }

返回值

类型描述

array

TA.ATR()函数的返回值为一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期。

参考

备注

TA.ATR()函数的optInTimePeriod参数默认值为:14

TA.OBV()函数用于计算能量潮指标(OBV)

TA.OBV(inReal)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M30) var obv = TA.OBV(records) Log(obv) }
python
def main(): r = exchange.GetRecords(PERIOD_M30) obv = TA.OBV(r) Log(obv)
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap(); let obv = TA.OBV(&records); Log!(obv); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M30); auto obv = TA.OBV(r); Log(obv); }

返回值

类型描述

array

TA.OBV()函数的返回值为一维数组。

参数

名称类型必填描述

inReal

Record结构数组

inReal参数用于指定K线数据(计算时使用K线数据中的收盘价与成交量)。

参考

TA.MA()函数用于计算移动平均线指标(Moving Average)

TA.MA(inReal)
TA.MA(inReal, optInTimePeriod)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M30) var ma = TA.MA(records, 14) Log(ma) }
python
def main(): r = exchange.GetRecords(PERIOD_M30) ma = TA.MA(r, 14) Log(ma)
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap(); let ma = TA.MA(&records, 14); Log!(ma); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M30); auto ma = TA.MA(r, 14); Log(ma); }

返回值

类型描述

array

TA.MA()函数的返回值为一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期。

参考

备注

TA.MA()函数的optInTimePeriod参数的默认值为:9

TA.EMA()函数用于计算指数移动平均线(EMA)指标

TA.EMA(inReal)
TA.EMA(inReal, optInTimePeriod)

示例

javascript
function main(){ var records = exchange.GetRecords() // 判断K线Bar数量是否满足指标计算所需的周期 if (records && records.length > 9) { var ema = TA.EMA(records, 9) Log(ema) } }
python
def main(): r = exchange.GetRecords() if r and len(r) > 9: ema = TA.EMA(r, 9) Log(ema)
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); // 判断K线Bar数量是否满足指标计算所需的周期 if records.len() > 9 { let ema = TA.EMA(&records, 9); Log!(ema); } }
c++
void main() { auto r = exchange.GetRecords(); if(r.Valid && r.size() > 9) { auto ema = TA.EMA(r, 9); Log(ema); } }

返回值

类型描述

array

TA.EMA()函数的返回值为:一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于传入K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期。

参考

备注

TA.EMA()函数的optInTimePeriod参数的默认值为:9

TA.BOLL()函数用于计算布林带指标

TA.BOLL(inReal)
TA.BOLL(inReal, period, multiplier)

示例

javascript
function main() { var records = exchange.GetRecords() if(records && records.length > 20) { var boll = TA.BOLL(records, 20, 2) var upLine = boll[0] var midLine = boll[1] var downLine = boll[2] Log(upLine) Log(midLine) Log(downLine) } }
python
def main(): r = exchange.GetRecords() if r and len(r) > 20: boll = TA.BOLL(r, 20, 2) upLine = boll[0] midLine = boll[1] downLine = boll[2] Log(upLine) Log(midLine) Log(downLine)
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); if records.len() > 20 { let boll = TA.BOLL(&records, 20, 2.0); let [upLine, midLine, downLine] = boll; Log!(upLine); Log!(midLine); Log!(downLine); } }
c++
void main() { auto r = exchange.GetRecords(); if(r.Valid && r.size() > 20) { auto boll = TA.BOLL(r, 20, 2); auto upLine = boll[0]; auto midLine = boll[1]; auto downLine = boll[2]; Log(upLine); Log(midLine); Log(downLine); } }

返回值

类型描述

array

TA.BOLL()函数的返回值为二维数组,其结构为[upLine, midLine, downLine]

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

period

number

period参数用于设置计算周期。

multiplier

number

multiplier参数用于设置乘数(标准差倍数)。

参考

备注

TA.BOLL()函数的periodmultiplier参数的默认值分别为202

TA.Alligator()函数用于计算鳄鱼线指标(Alligator)

TA.Alligator(inReal)
TA.Alligator(inReal, jawLength, teethLength, lipsLength)

示例

javascript
function main(){ var records = exchange.GetRecords() var alligator = TA.Alligator(records) Log("jawLine:", alligator[0]) Log("teethLine:", alligator[1]) Log("lipsLine:", alligator[2]) }
python
def main(): records = exchange.GetRecords() alligator = TA.Alligator(records) Log("jawLine:", alligator[0]) Log("teethLine:", alligator[1]) Log("lipsLine:", alligator[2])
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); let alligator = TA.Alligator(&records, None, None, None); Log!("jawLine:", alligator[0]); Log!("teethLine:", alligator[1]); Log!("lipsLine:", alligator[2]); }
c++
void main() { auto records = exchange.GetRecords(); auto alligator = TA.Alligator(records); Log("jawLine:", alligator[0]); Log("teethLine:", alligator[1]); Log("lipsLine:", alligator[2]); }

返回值

类型描述

array

TA.Alligator()函数的返回值为二维数组,其结构为:[jawLine, teethLine, lipsLine]

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

jawLength

number

jawLength参数用于设置下颚线(Jaw)的周期。

teethLength

number

teethLength参数用于设置牙齿线(Teeth)的周期。

lipsLength

number

lipsLength参数用于设置上唇线(Lips)的周期。

参考

备注

TA.Alligator()函数的jawLengthteethLengthlipsLength参数默认值分别为:1385

TA.CMF()函数用于计算蔡金资金流量指标(Chaikin Money Flow)

TA.CMF(inReal)
TA.CMF(inReal, periods)

示例

javascript
function main() { var records = exchange.GetRecords() var cmf = TA.CMF(records) Log(cmf) }
python
def main(): records = exchange.GetRecords() cmf = TA.CMF(records) Log(cmf)
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); let cmf = TA.CMF(&records, None); Log!(cmf); }
c++
void main() { auto records = exchange.GetRecords(); auto cmf = TA.CMF(records); Log(cmf); }

返回值

类型描述

array

TA.CMF()函数的返回值为一维数组。

参数

名称类型必填描述

inReal

Record结构数组

inReal参数用于指定K线数据(计算时使用K线数据中的最高价、最低价、收盘价与成交量)。

periods

number

periods参数用于指定计算周期,默认值为20。

参考

TA.Highest()函数用于计算周期内最高价

TA.Highest(inReal)
TA.Highest(inReal, period, attr)

示例

javascript
function main() { var records = exchange.GetRecords() var highestForOpen = TA.Highest(records, 10, "Open") Log(highestForOpen) }
python
def main(): records = exchange.GetRecords() highestForOpen = TA.Highest(records, 10, "Open") Log(highestForOpen)
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); // Rust 的 TA.Highest 无属性名参数,先提取开盘价数值序列再计算(不包含当前Bar) let opens: Vec<f64> = records.iter().map(|r| r.Open).collect(); let highestForOpen = TA.Highest(&opens, 10); Log!(highestForOpen); }
c++
void main() { auto records = exchange.GetRecords(); auto highestForOpen = TA.Highest(records.Open(), 10); Log(highestForOpen); }

返回值

类型描述

number

TA.Highest()函数返回最近指定周期内某个属性的最大值,不包含当前Bar。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

period

number

period参数用于设置计算周期。

attr

string

attr参数用于指定属性,可选值:OpenCloseLowHighVolumeOpenInterest

参考

备注

例如调用TA.Highest(records, 30, "High")函数时,如果周期参数period设置为0,表示计算inReal参数传入的K线数据中的所有Bar;如果不指定属性参数attr,则将inReal参数传入的数据视为普通数组处理。

TA.Lowest()函数用于计算周期最低价

TA.Lowest(inReal)
TA.Lowest(inReal, period, attr)

示例

javascript
function main() { var records = exchange.GetRecords() var lowestForOpen = TA.Lowest(records, 10, "Open") Log(lowestForOpen) }
python
def main(): records = exchange.GetRecords() lowestForOpen = TA.Lowest(records, 10, "Open") Log(lowestForOpen)
rust
fn main() { let records = exchange.GetRecords(None, None, None).unwrap(); // Rust 的 TA.Lowest 无属性名参数,先提取开盘价数值序列再计算(不包含当前Bar) let opens: Vec<f64> = records.iter().map(|r| r.Open).collect(); let lowestForOpen = TA.Lowest(&opens, 10); Log!(lowestForOpen); }
c++
void main() { auto records = exchange.GetRecords(); auto lowestForOpen = TA.Lowest(records.Open(), 10); Log(lowestForOpen); }

返回值

类型描述

number

TA.Lowest()函数返回最近一定周期内某个属性的最小值,不包含当前Bar。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

period

number

period参数用于设置计算周期。

attr

string

attr参数用于设置属性,可选值:OpenCloseLowHighVolumeOpenInterest

参考

备注

例如调用TA.Lowest(records, 30, "Low")函数:如果周期参数period设置为0,则表示计算inReal参数传入的K线数据的所有Bar;如果不指定属性参数attr,则视inReal参数传入的K线数据为普通数组。

C++策略中使用TA.Highest()TA.Lowest()函数时需要注意:Highest()Lowest()函数各自只有2个参数,并且第一个参数传入的不是auto r = exchange.GetRecords()函数调用时获取的K线数据r,而是需要调用r的方法,传入具体的属性数据。例如传入r.Close()收盘价数据。CloseHighLowOpenVolume的调用方式与r.Close()相同。

C++语言策略的测试范例:

c++
void main() { Records r; r.Valid = true; for (auto i = 0; i < 10; i++) { Record ele; ele.Time = i * 100000; ele.High = i * 10000; ele.Low = i * 1000; ele.Close = i * 100; ele.Open = i * 10; ele.Volume = i * 1; r.push_back(ele); } for(int j = 0; j < r.size(); j++){ Log(r[j]); } // 注意:第一个参数传入的不是r,需要调用r.Close() auto highest = TA.Highest(r.Close(), 8); Log(highest); }

TA.SMA()函数用于计算简单移动平均线(SMA)指标

TA.SMA(inReal)
TA.SMA(inReal, optInTimePeriod)

示例

javascript
function main(){ var records = exchange.GetRecords(PERIOD_M30) var sma = TA.SMA(records, 14) Log(sma) }
python
def main(): r = exchange.GetRecords(PERIOD_M30) sma = TA.SMA(r, 14) Log(sma)
rust
fn main() { let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap(); let sma = TA.SMA(&records, 14); Log!(sma); }
c++
void main() { auto r = exchange.GetRecords(PERIOD_M30); auto sma = TA.SMA(r, 14); Log(sma); }

返回值

类型描述

array

TA.SMA()函数的返回值为:一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于传入K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期。

参考

备注

TA.SMA()函数的optInTimePeriod参数默认值为:9

talib.CDL2CROWS()函数用于计算Two Crows(K线形态--两只乌鸦)

talib.CDL2CROWS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL2CROWS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL2CROWS(records); Log(ret); }

返回值

类型描述

array

talib.CDL2CROWS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL2CROWS()函数在talib库文档中的描述为:CDL2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)

对于Python语言中的调用,传参方式有所不同,需要根据上述描述中的:Records[Open,High,Low,Close]进行传参。

例如,将一个变量records(即参数inPriceOHLC,类型为Record结构数组)拆分为:

Open列表:在Python中表示为records.Open

High列表:在Python中表示为records.High

Low列表:在Python中表示为records.Low

Close列表:在Python中表示为records.Close

Python策略代码中的调用方式:

talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)

其他talib指标的调用方式与此类似,不再赘述。

talib.CDL3BLACKCROWS()函数用于计算Three Black Crows(K线图形态--三只黑乌鸦)

talib.CDL3BLACKCROWS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3BLACKCROWS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3BLACKCROWS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3BLACKCROWS(records); Log(ret); }

返回值

类型描述

array

talib.CDL3BLACKCROWS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3BLACKCROWS()函数在talib库文档中的描述为:CDL3BLACKCROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3INSIDE()函数用于计算Three Inside Up/Down(K线形态:三内上下震荡)

talib.CDL3INSIDE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3INSIDE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3INSIDE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3INSIDE(records); Log(ret); }

返回值

类型描述

array

talib.CDL3INSIDE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3INSIDE()函数在talib库文档中的描述为:CDL3INSIDE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3LINESTRIKE()函数用于计算Three-Line Strike(K线图:三线震荡)

talib.CDL3LINESTRIKE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3LINESTRIKE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3LINESTRIKE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3LINESTRIKE(records); Log(ret); }

返回值

类型描述

array

talib.CDL3LINESTRIKE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3LINESTRIKE()函数在talib库文档中的描述为:CDL3LINESTRIKE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3OUTSIDE()函数用于计算Three Outside Up/Down(K线形态:三外包线)

talib.CDL3OUTSIDE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3OUTSIDE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3OUTSIDE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3OUTSIDE(records); Log(ret); }

返回值

类型描述

array

talib.CDL3OUTSIDE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3OUTSIDE()函数在talib库文档中的描述为:CDL3OUTSIDE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3STARSINSOUTH()函数用于计算Three Stars In The South(K线形态:南方三星)

talib.CDL3STARSINSOUTH(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3STARSINSOUTH(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3STARSINSOUTH(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3STARSINSOUTH(records); Log(ret); }

返回值

类型描述

array

talib.CDL3STARSINSOUTH()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3STARSINSOUTH()函数在talib库文档中的描述为:CDL3STARSINSOUTH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3WHITESOLDIERS()函数用于计算Three Advancing White Soldiers(K线形态:三白兵)

talib.CDL3WHITESOLDIERS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDL3WHITESOLDIERS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDL3WHITESOLDIERS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDL3WHITESOLDIERS(records); Log(ret); }

返回值

类型描述

array

talib.CDL3WHITESOLDIERS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDL3WHITESOLDIERS()函数在talib库文档中的描述为:CDL3WHITESOLDIERS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLABANDONEDBABY()函数用于计算弃婴形态(K线图:Abandoned Baby)

talib.CDLABANDONEDBABY(inPriceOHLC)
talib.CDLABANDONEDBABY(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLABANDONEDBABY(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLABANDONEDBABY(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLABANDONEDBABY(records); Log(ret); }

返回值

类型描述

array

talib.CDLABANDONEDBABY()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数用于设置穿透度,默认值为0.3。

备注

CDLABANDONEDBABY()函数在talib库文档中的描述为:CDLABANDONEDBABY(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLADVANCEBLOCK()函数用于计算Advance Block(K线形态:推进阻挡)

talib.CDLADVANCEBLOCK(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLADVANCEBLOCK(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLADVANCEBLOCK(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLADVANCEBLOCK(records); Log(ret); }

返回值

类型描述

array

talib.CDLADVANCEBLOCK()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLADVANCEBLOCK()函数在talib库文档中的描述为:CDLADVANCEBLOCK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLBELTHOLD()函数用于计算Belt-hold(K线形态:腰带线)

talib.CDLBELTHOLD(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLBELTHOLD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLBELTHOLD(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLBELTHOLD(records); Log(ret); }

返回值

类型描述

array

talib.CDLBELTHOLD()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLBELTHOLD()函数在talib库文档中的描述为:CDLBELTHOLD(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLBREAKAWAY()函数用于计算Breakaway(K线形态:分离形态)

talib.CDLBREAKAWAY(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLBREAKAWAY(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLBREAKAWAY(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLBREAKAWAY(records); Log(ret); }

返回值

类型描述

array

talib.CDLBREAKAWAY()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLBREAKAWAY()函数在talib库文档中的描述为:CDLBREAKAWAY(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCLOSINGMARUBOZU()函数用于计算**收盘光头光脚线(Closing Marubozu)**K线形态。

talib.CDLCLOSINGMARUBOZU(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLCLOSINGMARUBOZU(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLCLOSINGMARUBOZU(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLCLOSINGMARUBOZU(records); Log(ret); }

返回值

类型描述

array

talib.CDLCLOSINGMARUBOZU()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLCLOSINGMARUBOZU()函数在talib库文档中的描述为:CDLCLOSINGMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCONCEALBABYSWALL()函数用于计算Concealing Baby Swallow(K线图:藏婴吞没形态)

talib.CDLCONCEALBABYSWALL(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLCONCEALBABYSWALL(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLCONCEALBABYSWALL(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLCONCEALBABYSWALL(records); Log(ret); }

返回值

类型描述

array

talib.CDLCONCEALBABYSWALL()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLCONCEALBABYSWALL()函数在talib库文档中的描述为:CDLCONCEALBABYSWALL(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCOUNTERATTACK()函数用于计算反击线形态(K线图:反击)

talib.CDLCOUNTERATTACK(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLCOUNTERATTACK(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLCOUNTERATTACK(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLCOUNTERATTACK(records); Log(ret); }

返回值

类型描述

array

talib.CDLCOUNTERATTACK()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLCOUNTERATTACK()函数在talib库文档中的描述为:CDLCOUNTERATTACK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDARKCLOUDCOVER()函数用于计算乌云盖顶(Dark Cloud Cover)K线形态

talib.CDLDARKCLOUDCOVER(inPriceOHLC)
talib.CDLDARKCLOUDCOVER(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLDARKCLOUDCOVER(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLDARKCLOUDCOVER(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLDARKCLOUDCOVER(records); Log(ret); }

返回值

类型描述

array

talib.CDLDARKCLOUDCOVER()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数用于设置穿透比例,默认值为0.5。

备注

CDLDARKCLOUDCOVER()函数在talib库文档中的描述为:CDLDARKCLOUDCOVER(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)

talib.CDLDOJI()函数用于计算Doji(K线图:十字星)

talib.CDLDOJI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLDOJI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLDOJI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLDOJI(records); Log(ret); }

返回值

类型描述

array

talib.CDLDOJI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLDOJI()函数在talib库文档中的描述为:CDLDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDOJISTAR()函数用于计算Doji Star(K线图:十字星)

talib.CDLDOJISTAR(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLDOJISTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLDOJISTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLDOJISTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLDOJISTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLDOJISTAR()函数在talib库文档中的描述为:CDLDOJISTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDRAGONFLYDOJI()函数用于计算Dragonfly Doji(K线形态:蜻蜓十字星)

talib.CDLDRAGONFLYDOJI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLDRAGONFLYDOJI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLDRAGONFLYDOJI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLDRAGONFLYDOJI(records); Log(ret); }

返回值

类型描述

array

talib.CDLDRAGONFLYDOJI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLDRAGONFLYDOJI()函数在talib库文档中的描述为:CDLDRAGONFLYDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLENGULFING()函数用于计算吞没形态(Engulfing Pattern)

talib.CDLENGULFING(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLENGULFING(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLENGULFING(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLENGULFING(records); Log(ret); }

返回值

类型描述

array

talib.CDLENGULFING()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLENGULFING()函数在talib库文档中的描述为:CDLENGULFING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLEVENINGDOJISTAR()函数用于计算Evening Doji Star(K线形态:黄昏十字星)

talib.CDLEVENINGDOJISTAR(inPriceOHLC)
talib.CDLEVENINGDOJISTAR(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLEVENINGDOJISTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLEVENINGDOJISTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLEVENINGDOJISTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLEVENINGDOJISTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数用于设置穿透率,默认值为0.3。

备注

CDLEVENINGDOJISTAR()函数在talib库文档中的描述为:CDLEVENINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLEVENINGSTAR()函数用于计算**Evening Star(K线图:黄昏之星)**形态。

talib.CDLEVENINGSTAR(inPriceOHLC)
talib.CDLEVENINGSTAR(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLEVENINGSTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLEVENINGSTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLEVENINGSTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLEVENINGSTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数用于设置穿透度(Penetration),默认值为0.3。

备注

CDLEVENINGSTAR()函数在talib库文档中的描述为:CDLEVENINGSTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLGAPSIDESIDEWHITE()函数用于计算Up/Down-gap side-by-side white lines (K线图:上/下间隙并排白色线条)

talib.CDLGAPSIDESIDEWHITE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLGAPSIDESIDEWHITE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLGAPSIDESIDEWHITE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLGAPSIDESIDEWHITE(records); Log(ret); }

返回值

类型描述

array

talib.CDLGAPSIDESIDEWHITE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLGAPSIDESIDEWHITE()函数在talib库文档中的描述为:CDLGAPSIDESIDEWHITE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLGRAVESTONEDOJI()函数用于计算**墓碑十字线(Gravestone Doji)**K线形态。

talib.CDLGRAVESTONEDOJI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLGRAVESTONEDOJI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLGRAVESTONEDOJI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLGRAVESTONEDOJI(records); Log(ret); }

返回值

类型描述

array

talib.CDLGRAVESTONEDOJI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLGRAVESTONEDOJI()函数在talib库文档中的描述为:CDLGRAVESTONEDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHAMMER()函数用于计算锤子线(K线形态:锤子)

talib.CDLHAMMER(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHAMMER(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHAMMER(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHAMMER(records); Log(ret); }

返回值

类型描述

array

talib.CDLHAMMER()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHAMMER()函数在talib库文档中的描述为:CDLHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHANGINGMAN()函数用于计算Hanging Man(K线形态:吊人线)

talib.CDLHANGINGMAN(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHANGINGMAN(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHANGINGMAN(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHANGINGMAN(records); Log(ret); }

返回值

类型描述

array

talib.CDLHANGINGMAN()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHANGINGMAN()函数在talib库文档中的描述为:CDLHANGINGMAN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHARAMI()函数用于计算Harami Pattern(K线图:阴阳线模式)

talib.CDLHARAMI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHARAMI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHARAMI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHARAMI(records); Log(ret); }

返回值

类型描述

array

talib.CDLHARAMI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHARAMI()函数在talib库文档中的描述为:CDLHARAMI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHARAMICROSS()函数用于计算Harami Cross Pattern(K线图:十字星孕线形态)

talib.CDLHARAMICROSS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHARAMICROSS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHARAMICROSS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHARAMICROSS(records); Log(ret); }

返回值

类型描述

array

talib.CDLHARAMICROSS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHARAMICROSS()函数在talib库文档中的描述为:CDLHARAMICROSS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIGHWAVE()函数用于计算High-Wave Candle(K线图:长脚十字线)

talib.CDLHIGHWAVE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHIGHWAVE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHIGHWAVE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHIGHWAVE(records); Log(ret); }

返回值

类型描述

array

talib.CDLHIGHWAVE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHIGHWAVE()函数在talib库文档中的描述为:CDLHIGHWAVE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIKKAKE()函数用于计算Hikkake Pattern(K线图:陷阱模式)

talib.CDLHIKKAKE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHIKKAKE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHIKKAKE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHIKKAKE(records); Log(ret); }

返回值

类型描述

array

talib.CDLHIKKAKE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHIKKAKE()函数在talib库文档中的描述为:CDLHIKKAKE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIKKAKEMOD()函数用于计算Modified Hikkake Pattern(K线图:改良陷阱模式)

talib.CDLHIKKAKEMOD(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHIKKAKEMOD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHIKKAKEMOD(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHIKKAKEMOD(records); Log(ret); }

返回值

类型描述

array

talib.CDLHIKKAKEMOD()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHIKKAKEMOD()函数在talib库文档中的描述为:CDLHIKKAKEMOD(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHOMINGPIGEON()函数用于计算Homing Pigeon(K线形态:信鸽形态)

talib.CDLHOMINGPIGEON(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLHOMINGPIGEON(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLHOMINGPIGEON(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLHOMINGPIGEON(records); Log(ret); }

返回值

类型描述

array

talib.CDLHOMINGPIGEON()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLHOMINGPIGEON()函数在talib库文档中的描述为:CDLHOMINGPIGEON(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLIDENTICAL3CROWS()函数用于计算Identical Three Crows(K线形态:相同三只乌鸦)

talib.CDLIDENTICAL3CROWS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLIDENTICAL3CROWS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLIDENTICAL3CROWS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLIDENTICAL3CROWS(records); Log(ret); }

返回值

类型描述

array

talib.CDLIDENTICAL3CROWS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLIDENTICAL3CROWS()函数在talib库文档中的描述为:CDLIDENTICAL3CROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLINNECK()函数用于计算颈内线形态(K线图:颈内线)

talib.CDLINNECK(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLINNECK(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLINNECK(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLINNECK(records); Log(ret); }

返回值

类型描述

array

talib.CDLINNECK()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLINNECK()函数在talib库文档中的描述为:CDLINNECK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLINVERTEDHAMMER()函数用于计算倒锤形态(K线图:倒锤)

talib.CDLINVERTEDHAMMER(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLINVERTEDHAMMER(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLINVERTEDHAMMER(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLINVERTEDHAMMER(records); Log(ret); }

返回值

类型描述

array

talib.CDLINVERTEDHAMMER()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLINVERTEDHAMMER()函数在talib库文档中的描述为:CDLINVERTEDHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLKICKING()函数用于计算Kicking(K线形态:踢腿形态)

talib.CDLKICKING(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLKICKING(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLKICKING(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLKICKING(records); Log(ret); }

返回值

类型描述

array

talib.CDLKICKING()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLKICKING()函数在talib库文档中的描述为:CDLKICKING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLKICKINGBYLENGTH()函数用于计算Kicking - bull/bear determined by the longer marubozu (K线图:踢牛/踢熊)

talib.CDLKICKINGBYLENGTH(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLKICKINGBYLENGTH(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLKICKINGBYLENGTH(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLKICKINGBYLENGTH(records); Log(ret); }

返回值

类型描述

array

talib.CDLKICKINGBYLENGTH()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLKICKINGBYLENGTH()函数在talib库文档中的描述为:CDLKICKINGBYLENGTH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLADDERBOTTOM()函数用于计算Ladder Bottom(K线形态:梯底)

talib.CDLLADDERBOTTOM(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLLADDERBOTTOM(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLLADDERBOTTOM(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLLADDERBOTTOM(records); Log(ret); }

返回值

类型描述

array

talib.CDLLADDERBOTTOM()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLLADDERBOTTOM()函数在talib库文档中的描述为:CDLLADDERBOTTOM(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLONGLEGGEDDOJI()函数用于计算长腿十字线(K线形态:Long Legged Doji)

talib.CDLLONGLEGGEDDOJI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLLONGLEGGEDDOJI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLLONGLEGGEDDOJI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLLONGLEGGEDDOJI(records); Log(ret); }

返回值

类型描述

array

talib.CDLLONGLEGGEDDOJI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLLONGLEGGEDDOJI()函数在talib库文档中的描述为:CDLLONGLEGGEDDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLONGLINE()函数用于计算长线蜡烛形态(K线图:长线)

talib.CDLLONGLINE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLLONGLINE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLLONGLINE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLLONGLINE(records); Log(ret); }

返回值

类型描述

array

talib.CDLLONGLINE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLLONGLINE()函数在talib库文档中的描述为:CDLLONGLINE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMARUBOZU()函数用于计算**Marubozu(K线图:光头光脚)**模式。

talib.CDLMARUBOZU(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLMARUBOZU(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLMARUBOZU(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLMARUBOZU(records); Log(ret); }

返回值

类型描述

array

talib.CDLMARUBOZU()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLMARUBOZU()函数在talib库文档中的描述为:CDLMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMATCHINGLOW()函数用于计算Matching Low(K线图:匹配低点)

talib.CDLMATCHINGLOW(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLMATCHINGLOW(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLMATCHINGLOW(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLMATCHINGLOW(records); Log(ret); }

返回值

类型描述

array

talib.CDLMATCHINGLOW()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLMATCHINGLOW()函数在talib库文档中的描述为:CDLMATCHINGLOW(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMATHOLD()函数用于计算Mat Hold(K线形态:垫住)

talib.CDLMATHOLD(inPriceOHLC)
talib.CDLMATHOLD(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLMATHOLD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLMATHOLD(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLMATHOLD(records); Log(ret); }

返回值

类型描述

array

talib.CDLMATHOLD()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数为可选参数,用于指定上升/下降趋势线的穿透比例,默认值为0.5。

备注

CDLMATHOLD()函数在talib库文档中的描述为:CDLMATHOLD(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)

talib.CDLMORNINGDOJISTAR()函数用于计算Morning Doji Star(K线形态:早晨十字星)

talib.CDLMORNINGDOJISTAR(inPriceOHLC)
talib.CDLMORNINGDOJISTAR(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLMORNINGDOJISTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLMORNINGDOJISTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLMORNINGDOJISTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLMORNINGDOJISTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数用于指定验证开盘价与实体部分重合的程度,默认值为0.3。

备注

CDLMORNINGDOJISTAR()函数在talib库文档中的描述为:CDLMORNINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLMORNINGSTAR()函数用于计算Morning Star(K线形态:晨星)

talib.CDLMORNINGSTAR(inPriceOHLC)
talib.CDLMORNINGSTAR(inPriceOHLC, optInPenetration)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLMORNINGSTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLMORNINGSTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLMORNINGSTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLMORNINGSTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

optInPenetration

number

optInPenetration参数为趋势确认所需的价格穿透百分比阈值,取值范围为[0,1],默认值为0.3。

备注

CDLMORNINGSTAR()函数在talib库文档中的描述为:CDLMORNINGSTAR(Records[Open,High,Low,Close],Penetration=0.3) = Array(outInteger)

talib.CDLONNECK()函数用于计算On-Neck Pattern(K线图:颈上线形态)

talib.CDLONNECK(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLONNECK(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLONNECK(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLONNECK(records); Log(ret); }

返回值

类型描述

array

talib.CDLONNECK()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLONNECK()函数在talib库文档中的描述为:CDLONNECK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLPIERCING()函数用于计算Piercing Pattern(K线图:穿透形态)

talib.CDLPIERCING(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLPIERCING(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLPIERCING(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLPIERCING(records); Log(ret); }

返回值

类型描述

array

talib.CDLPIERCING()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLPIERCING()函数在talib库文档中的描述为:CDLPIERCING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLRICKSHAWMAN()函数用于计算Rickshaw Man(K线形态:车夫线)

talib.CDLRICKSHAWMAN(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLRICKSHAWMAN(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLRICKSHAWMAN(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLRICKSHAWMAN(records); Log(ret); }

返回值

类型描述

array

talib.CDLRICKSHAWMAN()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLRICKSHAWMAN()函数在talib库文档中的描述为:CDLRICKSHAWMAN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLRISEFALL3METHODS()函数用于计算Rising/Falling Three Methods(K线形态:上升/下降三法)

talib.CDLRISEFALL3METHODS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLRISEFALL3METHODS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLRISEFALL3METHODS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLRISEFALL3METHODS(records); Log(ret); }

返回值

类型描述

array

talib.CDLRISEFALL3METHODS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLRISEFALL3METHODS()函数在talib库文档中的描述为:CDLRISEFALL3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSEPARATINGLINES()函数用于计算分离线形态(K线图:分离线)

talib.CDLSEPARATINGLINES(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSEPARATINGLINES(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSEPARATINGLINES(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSEPARATINGLINES(records); Log(ret); }

返回值

类型描述

array

talib.CDLSEPARATINGLINES()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLSEPARATINGLINES()函数在talib库文档中的描述为:CDLSEPARATINGLINES(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSHOOTINGSTAR()函数用于计算Shooting Star(K线形态:流星)

talib.CDLSHOOTINGSTAR(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSHOOTINGSTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSHOOTINGSTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSHOOTINGSTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLSHOOTINGSTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLSHOOTINGSTAR()函数在talib库文档中的描述为:CDLSHOOTINGSTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSHORTLINE()函数用于计算短线蜡烛图形态(K线图:短线)

talib.CDLSHORTLINE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSHORTLINE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSHORTLINE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSHORTLINE(records); Log(ret); }

返回值

类型描述

array

talib.CDLSHORTLINE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线价格数据。

备注

CDLSHORTLINE()函数在talib库文档中的描述为:CDLSHORTLINE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSPINNINGTOP()函数用于计算Spinning Top(K线形态:陀螺)

talib.CDLSPINNINGTOP(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSPINNINGTOP(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSPINNINGTOP(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSPINNINGTOP(records); Log(ret); }

返回值

类型描述

array

talib.CDLSPINNINGTOP()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLSPINNINGTOP()函数在talib库文档中的描述为:CDLSPINNINGTOP(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSTALLEDPATTERN()函数用于计算Stalled Pattern(K线图:停滞模式)

talib.CDLSTALLEDPATTERN(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSTALLEDPATTERN(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSTALLEDPATTERN(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSTALLEDPATTERN(records); Log(ret); }

返回值

类型描述

array

talib.CDLSTALLEDPATTERN()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLSTALLEDPATTERN()函数在talib库文档中的描述为:CDLSTALLEDPATTERN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSTICKSANDWICH()函数用于计算Stick Sandwich(K线形态:棍子三明治)

talib.CDLSTICKSANDWICH(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLSTICKSANDWICH(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLSTICKSANDWICH(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLSTICKSANDWICH(records); Log(ret); }

返回值

类型描述

array

talib.CDLSTICKSANDWICH()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLSTICKSANDWICH()函数在talib库文档中的描述为:CDLSTICKSANDWICH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTAKURI()函数用于计算**Takuri (Dragonfly Doji with very long lower shadow) (K线图:托里)**蜡烛图形态。

talib.CDLTAKURI(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLTAKURI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLTAKURI(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLTAKURI(records); Log(ret); }

返回值

类型描述

array

talib.CDLTAKURI()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLTAKURI()函数在talib库文档中的描述为:CDLTAKURI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTASUKIGAP()函数用于计算Tasuki Gap(K线图:翼隙)

talib.CDLTASUKIGAP(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLTASUKIGAP(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLTASUKIGAP(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLTASUKIGAP(records); Log(ret); }

返回值

类型描述

array

talib.CDLTASUKIGAP()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLTASUKIGAP()函数在talib库文档中的描述为:CDLTASUKIGAP(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTHRUSTING()函数用于计算Thrusting Pattern(K线图:推进模式)

talib.CDLTHRUSTING(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLTHRUSTING(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLTHRUSTING(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLTHRUSTING(records); Log(ret); }

返回值

类型描述

array

talib.CDLTHRUSTING()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLTHRUSTING()函数在talib库文档中的描述为:CDLTHRUSTING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTRISTAR()函数用于计算三星形态(K线图:三星模式)

talib.CDLTRISTAR(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLTRISTAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLTRISTAR(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLTRISTAR(records); Log(ret); }

返回值

类型描述

array

talib.CDLTRISTAR()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLTRISTAR()函数在talib库文档中的描述为:CDLTRISTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLUNIQUE3RIVER()函数用于计算Unique 3 River(K线形态:独特三河)

talib.CDLUNIQUE3RIVER(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLUNIQUE3RIVER(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLUNIQUE3RIVER(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLUNIQUE3RIVER(records); Log(ret); }

返回值

类型描述

array

talib.CDLUNIQUE3RIVER()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLUNIQUE3RIVER()函数在talib库文档中的描述为:CDLUNIQUE3RIVER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLUPSIDEGAP2CROWS()函数用于计算向上跳空双乌鸦形态(K线图:双飞乌鸦)

talib.CDLUPSIDEGAP2CROWS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLUPSIDEGAP2CROWS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLUPSIDEGAP2CROWS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLUPSIDEGAP2CROWS(records); Log(ret); }

返回值

类型描述

array

talib.CDLUPSIDEGAP2CROWS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLUPSIDEGAP2CROWS()函数在talib库文档中的描述为:CDLUPSIDEGAP2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLXSIDEGAP3METHODS()函数用于计算上行/下行缺口三方法(K线形态识别)

talib.CDLXSIDEGAP3METHODS(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CDLXSIDEGAP3METHODS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CDLXSIDEGAP3METHODS(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CDLXSIDEGAP3METHODS(records); Log(ret); }

返回值

类型描述

array

talib.CDLXSIDEGAP3METHODS()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

CDLXSIDEGAP3METHODS()函数在talib库文档中的描述为:CDLXSIDEGAP3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.AD()函数用于计算Chaikin A/D Line(累积/派发线指标)

talib.AD(inPriceHLCV)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.AD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.AD(records.High, records.Low, records.Close, records.Volume) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.AD(records); Log(ret); }

返回值

类型描述

array

talib.AD()函数返回一维数组。

参数

名称类型必填描述

inPriceHLCV

Record结构数组

inPriceHLCV参数用于指定K线数据。

备注

AD()函数在talib库文档中的描述为:AD(Records[High,Low,Close,Volume]) = Array(outReal)

talib.ADOSC()函数用于计算Chaikin A/D Oscillator(佳庆指标)

talib.ADOSC(inPriceHLCV)
talib.ADOSC(inPriceHLCV, optInFastPeriod, optInSlowPeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ADOSC(records, 3, 10) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ADOSC(records.High, records.Low, records.Close, records.Volume, 3, 10) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ADOSC(records, 3, 10); Log(ret); }

返回值

类型描述

array

talib.ADOSC()函数返回一维数组。

参数

名称类型必填描述

inPriceHLCV

Record结构数组

inPriceHLCV参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快速周期。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢速周期。

备注

ADOSC()函数在talib库文档中的描述为:ADOSC(Records[High,Low,Close,Volume],Fast Period = 3,Slow Period = 10) = Array(outReal)

talib.OBV()函数用于计算On Balance Volume(能量潮指标)

talib.OBV(inReal)
talib.OBV(inReal, inPriceV)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.OBV(records, records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.OBV(records.Close, records.Volume) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.OBV(records); Log(ret); }

返回值

类型描述

array

talib.OBV()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

inPriceV

Record结构数组

inPriceV参数用于指定K线数据。

备注

OBV()函数在talib库文档中的描述为:OBV(Records[Close],Records[Volume]) = Array(outReal)

talib.ACOS()函数用于计算向量三角反余弦函数(Vector Trigonometric ACos)

talib.ACOS(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.ACOS(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.ACOS(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.ACOS(data); Log(ret); }

返回值

类型描述

array

talib.ACOS()函数返回一维数组,包含计算得出的反余弦值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据。

备注

ACOS()函数在talib库文档中的描述为:ACOS(Records[Close]) = Array(outReal)

talib.ASIN()函数用于计算向量三角反正弦函数(Vector Trigonometric ASin)

talib.ASIN(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.ASIN(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.ASIN(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.ASIN(data); Log(ret); }

返回值

类型描述

array

talib.ASIN()函数返回一维数组,包含计算得出的反正弦值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据。

备注

ASIN()函数在talib库文档中的描述为:ASIN(Records[Close]) = Array(outReal)

talib.ATAN()函数用于计算向量三角反正切函数(Vector Trigonometric ATan)

talib.ATAN(inReal)

示例

javascript
function main() { var data = [-3.14/2, 0, 3.14/2] var ret = talib.ATAN(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-3.14/2, 0, 3.14/2] ret = talib.ATAN(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-3.14/2, 0, 3.14/2}; auto ret = talib.ATAN(data); Log(ret); }

返回值

类型描述

array

talib.ATAN()函数返回一维数组,包含计算得出的反正切值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据。

备注

ATAN()函数在talib库文档中的描述为:ATAN(Records[Close]) = Array(outReal)

talib.CEIL()函数用于计算向上取整(Vector Ceil)

talib.CEIL(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CEIL(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CEIL(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CEIL(records); Log(ret); }

返回值

类型描述

array

talib.CEIL()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

CEIL()函数在talib库文档中的描述为:CEIL(Records[Close]) = Array(outReal)

talib.COS()函数用于计算Vector Trigonometric Cos(向量三角余弦函数)

talib.COS(inReal)

示例

javascript
function main() { var data = [-3.14, 0, 3.14] var ret = talib.COS(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-3.14, 0, 3.14] ret = talib.COS(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-3.14, 0, 3.14}; auto ret = talib.COS(data); Log(ret); }

返回值

类型描述

array

talib.COS()函数返回一个包含余弦计算结果的一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据序列。

备注

COS()函数在talib库文档中的描述为:COS(Records[Close]) = Array(outReal)

talib.COSH()函数用于计算向量三角双曲余弦值(Vector Trigonometric Cosh)

talib.COSH(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.COSH(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.COSH(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.COSH(data); Log(ret); }

返回值

类型描述

array

talib.COSH()函数返回一维数组,包含计算得出的双曲余弦值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

COSH()函数在talib库文档中的描述为:COSH(Records[Close]) = Array(outReal)

talib.EXP()函数用于计算向量算术指数函数(Vector Arithmetic Exp)

talib.EXP(inReal)

示例

javascript
function main() { var data = [0, 1, 2] var ret = talib.EXP(data) // e^0, e^1, e^2 Log(ret) }
python
import talib import numpy as np def main(): data = [0, 1.0, 2.0] ret = talib.EXP(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {0, 1.0, 2.0}; auto ret = talib.EXP(data); Log(ret); }

返回值

类型描述

array

talib.EXP()函数返回一维数组,包含输入数据的指数计算结果。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据。

备注

EXP()函数在talib库文档中的描述为:EXP(Records[Close]) = Array(outReal)

talib.FLOOR()函数用于计算向量向下取整(Vector Floor)

talib.FLOOR(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.FLOOR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.FLOOR(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.FLOOR(records); Log(ret); }

返回值

类型描述

array

talib.FLOOR()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

FLOOR()函数在talib库文档中的描述为:FLOOR(Records[Close]) = Array(outReal)

talib.LN()函数用于计算向量自然对数(Vector Log Natural)

talib.LN(inReal)

示例

javascript
function main() { var data = [1, 2, 3] var ret = talib.LN(data) Log(ret) }
python
import talib import numpy as np def main(): data = [1.0, 2.0, 3.0] ret = talib.LN(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {1, 2, 3}; auto ret = talib.LN(data); Log(ret); }

返回值

类型描述

array

talib.LN()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

LN()函数在talib库文档中的描述为:LN(Records[Close]) = Array(outReal)

talib.LOG10()函数用于计算Vector Log10(对数函数)

talib.LOG10(inReal)

示例

javascript
function main() { var data = [10, 100, 1000] var ret = talib.LOG10(data) Log(ret) }
python
import talib import numpy as np def main(): data = [10.0, 100.0, 1000.0] ret = talib.LOG10(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {10, 100, 1000}; auto ret = talib.LOG10(data); Log(ret); }

返回值

类型描述

array

talib.LOG10()函数的返回值为一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

LOG10()函数在talib库文档中的描述为:LOG10(Records[Close]) = Array(outReal)

talib.SIN()函数用于计算Vector Trigonometric Sin(正弦值)

talib.SIN(inReal)

示例

javascript
function main() { var data = [-3.14/2, 0, 3.14/2] var ret = talib.SIN(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-3.14/2, 0, 3.14/2] ret = talib.SIN(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-3.14/2, 0, 3.14/2}; auto ret = talib.SIN(data); Log(ret); }

返回值

类型描述

array

talib.SIN()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

SIN()函数在talib库文档中的描述为:SIN(Records[Close]) = Array(outReal)

talib.SINH()函数用于计算向量三角双曲正弦函数(Vector Trigonometric Sinh)

talib.SINH(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.SINH(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.SINH(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.SINH(data); Log(ret); }

返回值

类型描述

array

talib.SINH()函数返回一维数组,包含计算得出的双曲正弦值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据。

备注

SINH()函数在talib库文档中的描述为:SINH(Records[Close]) = Array(outReal)

talib.SQRT()函数用于计算向量平方根(Vector Square Root)

talib.SQRT(inReal)

示例

javascript
function main() { var data = [4, 64, 100] var ret = talib.SQRT(data) Log(ret) }
python
import talib import numpy as np def main(): data = [4.0, 64.0, 100.0] ret = talib.SQRT(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {4, 64, 100}; auto ret = talib.SQRT(data); Log(ret); }

返回值

类型描述

array

talib.SQRT()函数返回一维数组,包含输入数据的平方根值。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的数值数据。

备注

SQRT()函数在talib库文档中的描述为:SQRT(Records[Close]) = Array(outReal)

talib.TAN()函数用于计算向量三角正切值(Vector Trigonometric Tan)

talib.TAN(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.TAN(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.TAN(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.TAN(data); Log(ret); }

返回值

类型描述

array

talib.TAN()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

TAN()函数在talib库文档中的描述为:TAN(Records[Close]) = Array(outReal)

talib.TANH()函数用于计算向量三角双曲正切函数(Vector Trigonometric Tanh)

talib.TANH(inReal)

示例

javascript
function main() { var data = [-1, 0, 1] var ret = talib.TANH(data) Log(ret) }
python
import talib import numpy as np def main(): data = [-1.0, 0, 1.0] ret = talib.TANH(np.array(data)) Log(ret)
c++
void main() { std::vector<double> data = {-1, 0, 1}; auto ret = talib.TANH(data); Log(ret); }

返回值

类型描述

array

talib.TANH()函数返回一个包含双曲正切计算结果的一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的实数数据序列。

备注

TANH()函数在talib库文档中的描述为:TANH(Records[Close]) = Array(outReal)

talib.MAX()函数用于计算指定周期内的最大值(Highest value over a specified period)

talib.MAX(inReal)
talib.MAX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MAX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MAX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MAX(records); Log(ret); }

返回值

类型描述

array

talib.MAX()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MAX()函数在talib库文档中的描述为:MAX(Records[Close],Time Period = 30) = Array(outReal)

talib.MAXINDEX()函数用于计算指定周期内最大值的索引位置(Index of highest value over a specified period)

talib.MAXINDEX(inReal)
talib.MAXINDEX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MAXINDEX(records, 5) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MAXINDEX(records.Close, 5) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MAXINDEX(records, 5); Log(ret); }

返回值

类型描述

array

talib.MAXINDEX()函数返回一个一维数组,包含指定周期内最大值的索引位置。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MAXINDEX()函数在talib库文档中的描述为:MAXINDEX(Records[Close],Time Period = 30) = Array(outInteger)

talib.MIN()函数用于计算指定周期内的最小值(Lowest value over a specified period)

talib.MIN(inReal)
talib.MIN(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MIN(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MIN(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MIN(records); Log(ret); }

返回值

类型描述

array

talib.MIN()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MIN()函数在talib库文档中的描述为:MIN(Records[Close],Time Period = 30) = Array(outReal)

talib.MININDEX()函数用于计算指定周期内最小值的索引位置(Index of lowest value over a specified period)

talib.MININDEX(inReal)
talib.MININDEX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MININDEX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MININDEX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MININDEX(records); Log(ret); }

返回值

类型描述

array

talib.MININDEX()函数返回一个一维数组,包含指定周期内最小值的索引位置。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MININDEX()函数在talib库文档中的描述为:MININDEX(Records[Close],Time Period = 30) = Array(outInteger)

talib.MINMAX()函数用于计算指定周期内的最小值和最大值(Lowest and highest values over a specified period)

talib.MINMAX(inReal)
talib.MINMAX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MINMAX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MINMAX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MINMAX(records); Log(ret); }

返回值

类型描述

array

talib.MINMAX()函数返回一个二维数组。该二维数组的第一个元素为最小值数组,第二个元素为最大值数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MINMAX()函数在talib库文档中的描述为:MINMAX(Records[Close],Time Period = 30) = [Array(outMin),Array(outMax)]

talib.MINMAXINDEX()函数用于计算指定周期内最低值和最高值的索引位置(Indexes of lowest and highest values over a specified period)

talib.MINMAXINDEX(inReal)
talib.MINMAXINDEX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MINMAXINDEX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MINMAXINDEX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MINMAXINDEX(records); Log(ret); }

返回值

类型描述

array

talib.MINMAXINDEX()函数返回一个二维数组。该数组的第一个元素为最小值索引数组,第二个元素为最大值索引数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

MINMAXINDEX()函数在talib库文档中的描述为:MINMAXINDEX(Records[Close],Time Period = 30) = [Array(outMinIdx),Array(outMaxIdx)]

talib.SUM()函数用于计算求和(Summation)

talib.SUM(inReal)
talib.SUM(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.SUM(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.SUM(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.SUM(records); Log(ret); }

返回值

类型描述

array

talib.SUM()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

SUM()函数在talib库文档中的描述为:SUM(Records[Close],Time Period = 30) = Array(outReal)

talib.HT_DCPERIOD()函数用于计算Hilbert Transform - Dominant Cycle Period(希尔伯特变换主导周期)

talib.HT_DCPERIOD(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_DCPERIOD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_DCPERIOD(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_DCPERIOD(records); Log(ret); }

返回值

类型描述

array

talib.HT_DCPERIOD()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

HT_DCPERIOD()函数在talib库文档中的描述为:HT_DCPERIOD(Records[Close]) = Array(outReal)

talib.HT_DCPHASE()函数用于计算希尔伯特变换主周期相位(Hilbert Transform - Dominant Cycle Phase)

talib.HT_DCPHASE(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_DCPHASE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_DCPHASE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_DCPHASE(records); Log(ret); }

返回值

类型描述

array

talib.HT_DCPHASE()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

HT_DCPHASE()函数在talib库文档中的描述为:HT_DCPHASE(Records[Close]) = Array(outReal)

talib.HT_PHASOR()函数用于计算Hilbert Transform - Phasor Components(希尔伯特变换-相量分量)

talib.HT_PHASOR(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_PHASOR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_PHASOR(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_PHASOR(records); Log(ret); }

返回值

类型描述

array

talib.HT_PHASOR()函数返回一个二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

备注

HT_PHASOR()函数在talib库文档中的描述为:HT_PHASOR(Records[Close]) = [Array(outInPhase),Array(outQuadrature)]

talib.HT_SINE()函数用于计算Hilbert Transform - SineWave(希尔伯特变换 - 正弦波)

talib.HT_SINE(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_SINE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_SINE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_SINE(records); Log(ret); }

返回值

类型描述

array

talib.HT_SINE()函数返回二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

HT_SINE()函数在talib库文档中的描述为:HT_SINE(Records[Close]) = [Array(outSine),Array(outLeadSine)]

talib.HT_TRENDMODE()函数用于计算Hilbert Transform - Trend vs Cycle Mode(希尔伯特变换 - 趋势与周期模式)

talib.HT_TRENDMODE(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_TRENDMODE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_TRENDMODE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_TRENDMODE(records); Log(ret); }

返回值

类型描述

array

talib.HT_TRENDMODE()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

HT_TRENDMODE()函数在talib库文档中的描述为:HT_TRENDMODE(Records[Close]) = Array(outInteger)

talib.ATR()函数用于计算**Average True Range(平均真实波幅)**指标。

talib.ATR(inPriceHLC)
talib.ATR(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ATR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ATR(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ATR(records); Log(ret); }

返回值

类型描述

array

talib.ATR()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

ATR()函数在talib库文档中的描述为:ATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.NATR()函数用于计算Normalized Average True Range(归一化平均真实范围)

talib.NATR(inPriceHLC)
talib.NATR(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.NATR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.NATR(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.NATR(records); Log(ret); }

返回值

类型描述

array

talib.NATR()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

NATR()函数在talib库文档中的描述为:NATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.TRANGE()函数用于计算**True Range(真实范围)**指标。

talib.TRANGE(inPriceHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TRANGE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TRANGE(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TRANGE(records); Log(ret); }

返回值

类型描述

array

talib.TRANGE()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

备注

TRANGE()函数在talib库文档中的描述为:TRANGE(Records[High,Low,Close]) = Array(outReal)

talib.BBANDS()函数用于计算Bollinger Bands(布林带)

talib.BBANDS(inReal)
talib.BBANDS(inReal, optInTimePeriod)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp, optInNbDevDn)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp, optInNbDevDn, optInMAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.BBANDS(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.BBANDS(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.BBANDS(records); Log(ret); }

返回值

类型描述

array

talib.BBANDS()函数返回一个二维数组,该数组包含三个元素,分别为:上轨数组、中轨数组、下轨数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为5。

optInNbDevUp

number

optInNbDevUp参数用于设置上轨标准差倍数,默认值为2。

optInNbDevDn

number

optInNbDevDn参数用于设置下轨标准差倍数,默认值为2。

optInMAType

number

optInMAType参数用于设置移动平均线类型,默认值为0。

备注

BBANDS()函数在talib库文档中的描述为:BBANDS(Records[Close],Time Period = 5,Deviations up = 2,Deviations down = 2,MA Type = 0) = [Array(outRealUpperBand),Array(outRealMiddleBand),Array(outRealLowerBand)]

talib.DEMA()函数用于计算Double Exponential Moving Average(双指数移动平均线)

talib.DEMA(inReal)
talib.DEMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.DEMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.DEMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.DEMA(records); Log(ret); }

返回值

类型描述

array

talib.DEMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

DEMA()函数在talib库文档中的描述为:DEMA(Records[Close],Time Period = 30) = Array(outReal)

talib.EMA()函数用于计算Exponential Moving Average(指数移动平均线)

talib.EMA(inReal)
talib.EMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.EMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.EMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.EMA(records); Log(ret); }

返回值

类型描述

array

talib.EMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

EMA()函数在talib库文档中的描述为:EMA(Records[Close],Time Period = 30) = Array(outReal)

talib.HT_TRENDLINE()函数用于计算Hilbert Transform - Instantaneous Trendline(希尔伯特变换瞬时趋势线)

talib.HT_TRENDLINE(inReal)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.HT_TRENDLINE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.HT_TRENDLINE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.HT_TRENDLINE(records); Log(ret); }

返回值

类型描述

array

talib.HT_TRENDLINE()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

备注

HT_TRENDLINE()函数在talib库文档中的描述为:HT_TRENDLINE(Records[Close]) = Array(outReal)

talib.KAMA()函数用于计算Kaufman自适应移动平均线(Kaufman Adaptive Moving Average)

talib.KAMA(inReal)
talib.KAMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.KAMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.KAMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.KAMA(records); Log(ret); }

返回值

类型描述

array

talib.KAMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

KAMA()函数在talib库文档中的描述为:KAMA(Records[Close],Time Period = 30) = Array(outReal)

talib.MA()函数用于计算Moving average(移动平均线)

talib.MA(inReal)
talib.MA(inReal, optInTimePeriod)
talib.MA(inReal, optInTimePeriod, optInMAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MA(records); Log(ret); }

返回值

类型描述

array

talib.MA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

optInMAType

number

optInMAType参数用于设置移动平均线类型,默认值为0。

备注

MA()函数在talib库文档中的描述为:MA(Records[Close],Time Period = 30,MA Type = 0) = Array(outReal)

talib.MAMA()函数用于计算MESA自适应移动平均线(MESA Adaptive Moving Average)

talib.MAMA(inReal)
talib.MAMA(inReal, optInFastLimit)
talib.MAMA(inReal, optInFastLimit, optInSlowLimit)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MAMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MAMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MAMA(records); Log(ret); }

返回值

类型描述

array

talib.MAMA()函数返回二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastLimit

number

optInFastLimit参数用于设置快速限制值,默认值为0.5。

optInSlowLimit

number

optInSlowLimit参数用于设置慢速限制值,默认值为0.05。

备注

MAMA()函数在talib库文档中的描述为:MAMA(Records[Close],Fast Limit = 0.5,Slow Limit = 0.05) = [Array(outMAMA),Array(outFAMA)]

talib.MIDPOINT()函数用于计算MidPoint over period(中点价格)

talib.MIDPOINT(inReal)
talib.MIDPOINT(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MIDPOINT(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MIDPOINT(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MIDPOINT(records); Log(ret); }

返回值

类型描述

array

talib.MIDPOINT()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

MIDPOINT()函数在talib库文档中的描述为:MIDPOINT(Records[Close],Time Period = 14) = Array(outReal)

talib.MIDPRICE()函数用于计算Midpoint Price over period(中点价格)

talib.MIDPRICE(inPriceHL)
talib.MIDPRICE(inPriceHL, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MIDPRICE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MIDPRICE(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MIDPRICE(records); Log(ret); }

返回值

类型描述

array

talib.MIDPRICE()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置时间周期,默认值为14。

备注

MIDPRICE()函数在talib库文档中的描述为:MIDPRICE(Records[High,Low],Time Period = 14) = Array(outReal)

talib.SAR()函数用于计算抛物线转向指标(Parabolic SAR)

talib.SAR(inPriceHL)
talib.SAR(inPriceHL, optInAcceleration)
talib.SAR(inPriceHL, optInAcceleration, optInMaximum)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.SAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.SAR(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.SAR(records); Log(ret); }

返回值

类型描述

array

talib.SAR()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInAcceleration

number

optInAcceleration参数用于设置加速因子(Acceleration Factor),默认值为0.02。

optInMaximum

number

optInMaximum参数用于设置加速因子最大值(AF Maximum),默认值为0.2。

备注

SAR()函数在talib库文档中的描述为:SAR(Records[High,Low],Acceleration Factor = 0.02,AF Maximum = 0.2) = Array(outReal)

talib.SAREXT()函数用于计算Parabolic SAR - Extended(增强型抛物线转向指标)

talib.SAREXT(inPriceHL)
talib.SAREXT(inPriceHL, optInStartValue)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort, optInAccelerationShort)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort, optInAccelerationShort, optInAccelerationMaxShort)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.SAREXT(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.SAREXT(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.SAREXT(records); Log(ret); }

返回值

类型描述

array

talib.SAREXT()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInStartValue

number

optInStartValue参数用于设置起始值(Start Value),默认值为0。

optInOffsetOnReverse

number

optInOffsetOnReverse参数用于设置反转偏移量(Offset on Reverse),默认值为0。

optInAccelerationInitLong

number

optInAccelerationInitLong参数用于设置多头初始加速因子(AF Init Long),默认值为0.02。

optInAccelerationLong

number

optInAccelerationLong参数用于设置多头加速因子(AF Long),默认值为0.02。

optInAccelerationMaxLong

number

optInAccelerationMaxLong参数用于设置多头最大加速因子(AF Max Long),默认值为0.2。

optInAccelerationInitShort

number

optInAccelerationInitShort参数用于设置空头初始加速因子(AF Init Short),默认值为0.02。

optInAccelerationShort

number

optInAccelerationShort参数用于设置空头加速因子(AF Short),默认值为0.02。

optInAccelerationMaxShort

number

optInAccelerationMaxShort参数用于设置空头最大加速因子(AF Max Short),默认值为0.2。

备注

SAREXT()函数在talib库文档中的描述为:SAREXT(Records[High,Low],Start Value = 0,Offset on Reverse = 0,AF Init Long = 0.02,AF Long = 0.02,AF Max Long = 0.2,AF Init Short = 0.02,AF Short = 0.02,AF Max Short = 0.2) = Array(outReal)

talib.SMA()函数用于计算Simple Moving Average(简单移动平均线)

talib.SMA(inReal)
talib.SMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.SMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.SMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.SMA(records); Log(ret); }

返回值

类型描述

array

talib.SMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

SMA()函数在talib库文档中的描述为:SMA(Records[Close],Time Period = 30) = Array(outReal)

talib.T3()函数用于计算Triple Exponential Moving Average (T3) (三重指数移动平均)

talib.T3(inReal)
talib.T3(inReal, optInTimePeriod)
talib.T3(inReal, optInTimePeriod, optInVFactor)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.T3(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.T3(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.T3(records); Log(ret); }

返回值

类型描述

array

talib.T3()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为5。

optInVFactor

number

optInVFactor参数用于设置成交量因子,默认值为0.7。

备注

T3()函数在talib库文档中的描述为:T3(Records[Close],Time Period = 5,Volume Factor = 0.7) = Array(outReal)

talib.TEMA()函数用于计算Triple Exponential Moving Average(三重指数移动平均线)

talib.TEMA(inReal)
talib.TEMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TEMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TEMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TEMA(records); Log(ret); }

返回值

类型描述

array

talib.TEMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

TEMA()函数在talib库文档中的描述为:TEMA(Records[Close],Time Period = 30) = Array(outReal)

talib.TRIMA()函数用于计算Triangular Moving Average(三角移动平均线)

talib.TRIMA(inReal)
talib.TRIMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TRIMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TRIMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TRIMA(records); Log(ret); }

返回值

类型描述

array

talib.TRIMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

TRIMA()函数在talib库文档中的描述为:TRIMA(Records[Close],Time Period = 30) = Array(outReal)

talib.WMA()函数用于计算Weighted Moving Average(加权移动平均)

talib.WMA(inReal)
talib.WMA(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.WMA(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.WMA(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.WMA(records); Log(ret); }

返回值

类型描述

array

talib.WMA()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

WMA()函数在talib库文档中的描述为:WMA(Records[Close],Time Period = 30) = Array(outReal)

talib.LINEARREG()函数用于计算**Linear Regression(线性回归)**指标。

talib.LINEARREG(inReal)
talib.LINEARREG(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.LINEARREG(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.LINEARREG(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.LINEARREG(records); Log(ret); }

返回值

类型描述

array

talib.LINEARREG()函数返回一维数组,包含线性回归计算结果。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定输入的K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

LINEARREG()函数在talib库文档中的描述为:LINEARREG(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_ANGLE()函数用于计算Linear Regression Angle(线性回归角度)

talib.LINEARREG_ANGLE(inReal)
talib.LINEARREG_ANGLE(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.LINEARREG_ANGLE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.LINEARREG_ANGLE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.LINEARREG_ANGLE(records); Log(ret); }

返回值

类型描述

array

talib.LINEARREG_ANGLE()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

LINEARREG_ANGLE()函数在talib库文档中的描述为:LINEARREG_ANGLE(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_INTERCEPT()函数用于计算线性回归截距(Linear Regression Intercept)

talib.LINEARREG_INTERCEPT(inReal)
talib.LINEARREG_INTERCEPT(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.LINEARREG_INTERCEPT(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.LINEARREG_INTERCEPT(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.LINEARREG_INTERCEPT(records); Log(ret); }

返回值

类型描述

array

talib.LINEARREG_INTERCEPT()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

LINEARREG_INTERCEPT()函数在talib库文档中的描述为:LINEARREG_INTERCEPT(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_SLOPE()函数用于计算Linear Regression Slope(线性回归斜率)

talib.LINEARREG_SLOPE(inReal)
talib.LINEARREG_SLOPE(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.LINEARREG_SLOPE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.LINEARREG_SLOPE(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.LINEARREG_SLOPE(records); Log(ret); }

返回值

类型描述

array

talib.LINEARREG_SLOPE()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

LINEARREG_SLOPE()函数在talib库文档中的描述为:LINEARREG_SLOPE(Records[Close],Time Period = 14) = Array(outReal)

talib.STDDEV()函数用于计算标准偏差(Standard Deviation)

talib.STDDEV(inReal)
talib.STDDEV(inReal, optInTimePeriod)
talib.STDDEV(inReal, optInTimePeriod, optInNbDev)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.STDDEV(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.STDDEV(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.STDDEV(records); Log(ret); }

返回值

类型描述

array

talib.STDDEV()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为5。

optInNbDev

number

optInNbDev参数用于设置偏差倍数,默认值为1。

备注

STDDEV()函数在talib库文档中的描述为:STDDEV(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)

talib.TSF()函数用于计算Time Series Forecast(时间序列预测)

talib.TSF(inReal)
talib.TSF(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TSF(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TSF(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TSF(records); Log(ret); }

返回值

类型描述

array

talib.TSF()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

TSF()函数在talib库文档中的描述为:TSF(Records[Close],Time Period = 14) = Array(outReal)

talib.VAR()函数用于计算方差(Variance)

talib.VAR(inReal)
talib.VAR(inReal, optInTimePeriod)
talib.VAR(inReal, optInTimePeriod, optInNbDev)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.VAR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.VAR(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.VAR(records); Log(ret); }

返回值

类型描述

array

talib.VAR()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为5。

optInNbDev

number

optInNbDev参数用于设置标准差倍数,默认值为1。

备注

VAR()函数在talib库文档中的描述为:VAR(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)

talib.ADX()函数用于计算Average Directional Movement Index(平均趋向指数)

talib.ADX(inPriceHLC)
talib.ADX(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ADX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ADX(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ADX(records); Log(ret); }

返回值

类型描述

array

talib.ADX()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

ADX()函数在talib库文档中的描述为:ADX(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.ADXR()函数用于计算平均趋向指数评级(Average Directional Movement Index Rating)

talib.ADXR(inPriceHLC)
talib.ADXR(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ADXR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ADXR(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ADXR(records); Log(ret); }

返回值

类型描述

array

talib.ADXR()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

ADXR()函数在talib库文档中的描述为:ADXR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.APO()函数用于计算Absolute Price Oscillator(绝对价格振荡器)

talib.APO(inReal)
talib.APO(inReal, optInFastPeriod)
talib.APO(inReal, optInFastPeriod, optInSlowPeriod)
talib.APO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.APO(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.APO(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.APO(records); Log(ret); }

返回值

类型描述

array

talib.APO()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快速周期,默认值为12。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢速周期,默认值为26。

optInMAType

number

optInMAType参数用于设置移动平均线类型,默认值为0。

备注

APO()函数在talib库文档中的描述为:APO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)

talib.AROON()函数用于计算Aroon(阿隆指标)

talib.AROON(inPriceHL)
talib.AROON(inPriceHL, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.AROON(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.AROON(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.AROON(records); Log(ret); }

返回值

类型描述

array

talib.AROON()函数返回二维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

AROON()函数在talib库文档中的描述为:AROON(Records[High,Low],Time Period = 14) = [Array(outAroonDown),Array(outAroonUp)]

talib.AROONOSC()函数用于计算Aroon Oscillator(阿隆震荡指标)

talib.AROONOSC(inPriceHL)
talib.AROONOSC(inPriceHL, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.AROONOSC(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.AROONOSC(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.AROONOSC(records); Log(ret); }

返回值

类型描述

array

talib.AROONOSC()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

AROONOSC()函数在talib库文档中的描述为:AROONOSC(Records[High,Low],Time Period = 14) = Array(outReal)

talib.BOP()函数用于计算Balance Of Power(均势指标)

talib.BOP(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.BOP(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.BOP(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.BOP(records); Log(ret); }

返回值

类型描述

array

talib.BOP()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

BOP()函数在talib库文档中的描述为:BOP(Records[Open,High,Low,Close]) = Array(outReal)

talib.CCI()函数用于计算Commodity Channel Index(商品通道指数)

talib.CCI(inPriceHLC)
talib.CCI(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CCI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CCI(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CCI(records); Log(ret); }

返回值

类型描述

array

talib.CCI()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

CCI()函数在talib库文档中的描述为:CCI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.CMO()函数用于计算Chande Momentum Oscillator(钱德动量摆动指标)

talib.CMO(inReal)
talib.CMO(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.CMO(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.CMO(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.CMO(records); Log(ret); }

返回值

类型描述

array

talib.CMO()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

CMO()函数在talib库文档中的描述为:CMO(Records[Close],Time Period = 14) = Array(outReal)

talib.DX()函数用于计算Directional Movement Index(动向指数)

talib.DX(inPriceHLC)
talib.DX(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.DX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.DX(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.DX(records); Log(ret); }

返回值

类型描述

array

talib.DX()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

DX()函数在talib库文档中的描述为:DX(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.MACD()函数用于计算Moving Average Convergence/Divergence(移动平均收敛发散指标)

talib.MACD(inReal)
talib.MACD(inReal, optInFastPeriod)
talib.MACD(inReal, optInFastPeriod, optInSlowPeriod)
talib.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MACD(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MACD(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MACD(records); Log(ret); }

返回值

类型描述

array

talib.MACD()函数返回二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快速周期,默认值为12。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢速周期,默认值为26。

optInSignalPeriod

number

optInSignalPeriod参数用于设置信号线周期,默认值为9。

备注

MACD()函数在talib库文档中的描述为:MACD(Records[Close],Fast Period = 12,Slow Period = 26,Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]

talib.MACDEXT()函数用于计算MACD with controllable MA type(可控移动平均类型的MACD)

talib.MACDEXT(inReal)
talib.MACDEXT(inReal, optInFastPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType, optInSignalPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType, optInSignalPeriod, optInSignalMAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MACDEXT(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MACDEXT(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MACDEXT(records); Log(ret); }

返回值

类型描述

array

talib.MACDEXT()函数返回一个二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快速周期,默认值为12。

optInFastMAType

number

optInFastMAType参数用于设置快速移动平均线类型,默认值为0。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢速周期,默认值为26。

optInSlowMAType

number

optInSlowMAType参数用于设置慢速移动平均线类型,默认值为0。

optInSignalPeriod

number

optInSignalPeriod参数用于设置信号线周期,默认值为9。

optInSignalMAType

number

optInSignalMAType参数用于设置信号线移动平均类型,默认值为0。

备注

MACDEXT()函数在talib库文档中的描述为:MACDEXT(Records[Close],Fast Period = 12,Fast MA = 0,Slow Period = 26,Slow MA = 0,Signal Period = 9,Signal MA = 0) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]

talib.MACDFIX()函数用于计算Moving Average Convergence/Divergence Fix 12/26(移动平均收敛/发散固定12/26)

talib.MACDFIX(inReal)
talib.MACDFIX(inReal, optInSignalPeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MACDFIX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MACDFIX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MACDFIX(records); Log(ret); }

返回值

类型描述

array

talib.MACDFIX()函数返回二维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInSignalPeriod

number

optInSignalPeriod参数用于设置信号周期,默认值为9。

备注

MACDFIX()函数在talib库文档中的描述为:MACDFIX(Records[Close],Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]

talib.MFI()函数用于计算Money Flow Index(资金流量指数)

talib.MFI(inPriceHLCV)
talib.MFI(inPriceHLCV, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MFI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MFI(records.High, records.Low, records.Close, records.Volume) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MFI(records); Log(ret); }

返回值

类型描述

array

talib.MFI()函数返回一维数组。

参数

名称类型必填描述

inPriceHLCV

Record结构数组

inPriceHLCV参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

MFI()函数在talib库文档中的描述为:MFI(Records[High,Low,Close,Volume],Time Period = 14) = Array(outReal)

talib.MINUS_DI()函数用于计算负向指标(Minus Directional Indicator)

talib.MINUS_DI(inPriceHLC)
talib.MINUS_DI(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MINUS_DI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MINUS_DI(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MINUS_DI(records); Log(ret); }

返回值

类型描述

array

talib.MINUS_DI()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

MINUS_DI()函数在talib库文档中的描述为:MINUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.MINUS_DM()函数用于计算负向运动指标(Minus Directional Movement)

talib.MINUS_DM(inPriceHL)
talib.MINUS_DM(inPriceHL, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MINUS_DM(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MINUS_DM(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MINUS_DM(records); Log(ret); }

返回值

类型描述

array

talib.MINUS_DM()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

MINUS_DM()函数在talib库文档中的描述为:MINUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)

talib.MOM()函数用于计算Momentum(动量指标)

talib.MOM(inReal)
talib.MOM(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MOM(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MOM(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MOM(records); Log(ret); }

返回值

类型描述

array

talib.MOM()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为10。

备注

MOM()函数在talib库文档中的描述为:MOM(Records[Close],Time Period = 10) = Array(outReal)

talib.PLUS_DI()函数用于计算Plus Directional Indicator(正向指标)

talib.PLUS_DI(inPriceHLC)
talib.PLUS_DI(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.PLUS_DI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.PLUS_DI(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.PLUS_DI(records); Log(ret); }

返回值

类型描述

array

talib.PLUS_DI()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置时间周期,默认值为14。

备注

PLUS_DI()函数在talib库文档中的描述为:PLUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.PLUS_DM()函数用于计算Plus Directional Movement(正向运动指标)

talib.PLUS_DM(inPriceHL)
talib.PLUS_DM(inPriceHL, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.PLUS_DM(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.PLUS_DM(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.PLUS_DM(records); Log(ret); }

返回值

类型描述

array

talib.PLUS_DM()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

PLUS_DM()函数在talib库文档中的描述为:PLUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)

talib.PPO()函数用于计算Percentage Price Oscillator(价格振荡百分比)

talib.PPO(inReal)
talib.PPO(inReal, optInFastPeriod)
talib.PPO(inReal, optInFastPeriod, optInSlowPeriod)
talib.PPO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.PPO(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.PPO(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.PPO(records); Log(ret); }

返回值

类型描述

array

talib.PPO()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInFastPeriod

number

optInFastPeriod参数用于设置快速周期,默认值为12。

optInSlowPeriod

number

optInSlowPeriod参数用于设置慢速周期,默认值为26。

optInMAType

number

optInMAType参数用于设置移动平均线类型,默认值为0。

备注

PPO()函数在talib库文档中的描述为:PPO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)

talib.ROC()函数用于计算*变动率指标(Rate of change):((price/prevPrice)-1)100

talib.ROC(inReal)
talib.ROC(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ROC(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ROC(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ROC(records); Log(ret); }

返回值

类型描述

array

talib.ROC()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为10。

备注

ROC()函数在talib库文档中的描述为:ROC(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCP()函数用于计算价格变化率百分比:(price-prevPrice)/prevPrice

talib.ROCP(inReal)
talib.ROCP(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ROCP(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ROCP(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ROCP(records); Log(ret); }

返回值

类型描述

array

talib.ROCP()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为10。

备注

ROCP()函数在talib库文档中的描述为:ROCP(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCR()函数用于计算价格变化率比值:(price/prevPrice)

talib.ROCR(inReal)
talib.ROCR(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ROCR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ROCR(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ROCR(records); Log(ret); }

返回值

类型描述

array

talib.ROCR()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为10。

备注

ROCR()函数在talib库文档中的描述为:ROCR(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCR100()函数用于计算Rate of change ratio 100 scale: (price/prevPrice)*100(价格变化率比例100倍)

talib.ROCR100(inReal)
talib.ROCR100(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ROCR100(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ROCR100(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ROCR100(records); Log(ret); }

返回值

类型描述

array

talib.ROCR100()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为10。

备注

ROCR100()函数在talib库文档中的描述为:ROCR100(Records[Close],Time Period = 10) = Array(outReal)

talib.RSI()函数用于计算Relative Strength Index(相对强弱指标)

talib.RSI(inReal)
talib.RSI(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.RSI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.RSI(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.RSI(records); Log(ret); }

返回值

类型描述

array

talib.RSI()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

RSI()函数在talib库文档中的描述为:RSI(Records[Close],Time Period = 14) = Array(outReal)

talib.STOCH()函数用于计算随机指标(STOCH指标)

talib.STOCH(inPriceHLC)
talib.STOCH(inPriceHLC, optInFastK_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType, optInSlowD_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType, optInSlowD_Period, optInSlowD_MAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.STOCH(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.STOCH(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.STOCH(records); Log(ret); }

返回值

类型描述

array

talib.STOCH()函数返回二维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInFastK_Period

number

optInFastK_Period参数用于设置快速K值周期,默认值为5。

optInSlowK_Period

number

optInSlowK_Period参数用于设置慢速K值周期,默认值为3。

optInSlowK_MAType

number

optInSlowK_MAType参数用于设置慢速K值移动平均线类型,默认值为0。

optInSlowD_Period

number

optInSlowD_Period参数用于设置慢速D值周期,默认值为3。

optInSlowD_MAType

number

optInSlowD_MAType参数用于设置慢速D值移动平均线类型,默认值为0。

备注

STOCH()函数在talib库文档中的描述为:STOCH(Records[High,Low,Close],Fast-K Period = 5,Slow-K Period = 3,Slow-K MA = 0,Slow-D Period = 3,Slow-D MA = 0) = [Array(outSlowK),Array(outSlowD)]

talib.STOCHF()函数用于计算快速随机指标(Stochastic Fast)

talib.STOCHF(inPriceHLC)
talib.STOCHF(inPriceHLC, optInFastK_Period)
talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period)
talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period, optInFastD_MAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.STOCHF(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.STOCHF(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.STOCHF(records); Log(ret); }

返回值

类型描述

array

talib.STOCHF()函数返回二维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInFastK_Period

number

optInFastK_Period参数用于设置Fast-K周期,默认值为5。

optInFastD_Period

number

optInFastD_Period参数用于设置Fast-D周期,默认值为3。

optInFastD_MAType

number

optInFastD_MAType参数用于设置Fast-D移动平均线类型,默认值为0。

备注

STOCHF()函数在talib库文档中的描述为:STOCHF(Records[High,Low,Close],Fast-K Period = 5,Fast-D Period = 3,Fast-D MA = 0) = [Array(outFastK),Array(outFastD)]

talib.STOCHRSI()函数用于计算随机相对强弱指数(Stochastic Relative Strength Index)

talib.STOCHRSI(inReal)
talib.STOCHRSI(inReal, optInTimePeriod)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period, optInFastD_Period)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period, optInFastD_Period, optInFastD_MAType)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.STOCHRSI(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.STOCHRSI(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.STOCHRSI(records); Log(ret); }

返回值

类型描述

array

talib.STOCHRSI()函数返回二维数组,包含Fast-K和Fast-D两个数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定价格数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

optInFastK_Period

number

optInFastK_Period参数用于设置Fast-K线周期,默认值为5。

optInFastD_Period

number

optInFastD_Period参数用于设置Fast-D线周期,默认值为3。

optInFastD_MAType

number

optInFastD_MAType参数用于设置Fast-D线移动平均类型,默认值为0。

备注

STOCHRSI()函数在talib库文档中的描述为:STOCHRSI(Records[Close],Time Period = 14,Fast-K Period = 5,Fast-D Period = 3,Fast-D MA = 0) = [Array(outFastK),Array(outFastD)]

talib.TRIX()函数用于计算1-day Rate-Of-Change (ROC) of a Triple Smooth EMA(三重指数平滑移动平均线的一日变化率)

talib.TRIX(inReal)
talib.TRIX(inReal, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TRIX(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TRIX(records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TRIX(records); Log(ret); }

返回值

类型描述

array

talib.TRIX()函数返回一维数组。

参数

名称类型必填描述

inReal

Record结构数组 / 数值数组

inReal参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为30。

备注

TRIX()函数在talib库文档中的描述为:TRIX(Records[Close],Time Period = 30) = Array(outReal)

talib.ULTOSC()函数用于计算Ultimate Oscillator(极限振荡器)

talib.ULTOSC(inPriceHLC)
talib.ULTOSC(inPriceHLC, optInTimePeriod1)
talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2)
talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2, optInTimePeriod3)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.ULTOSC(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.ULTOSC(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.ULTOSC(records); Log(ret); }

返回值

类型描述

array

talib.ULTOSC()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod1

number

optInTimePeriod1参数用于设置第一个时间周期,默认值为7。

optInTimePeriod2

number

optInTimePeriod2参数用于设置第二个时间周期,默认值为14。

optInTimePeriod3

number

optInTimePeriod3参数用于设置第三个时间周期,默认值为28。

备注

ULTOSC()函数在talib库文档中的描述为:ULTOSC(Records[High,Low,Close],First Period = 7,Second Period = 14,Third Period = 28) = Array(outReal)

talib.WILLR()函数用于计算Williams' %R(威廉指标)

talib.WILLR(inPriceHLC)
talib.WILLR(inPriceHLC, optInTimePeriod)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.WILLR(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.WILLR(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.WILLR(records); Log(ret); }

返回值

类型描述

array

talib.WILLR()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

optInTimePeriod

number

optInTimePeriod参数用于设置计算周期,默认值为14。

备注

WILLR()函数在talib库文档中的描述为:WILLR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.AVGPRICE()函数用于计算Average Price(平均价格)

talib.AVGPRICE(inPriceOHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.AVGPRICE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.AVGPRICE(records.Open, records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.AVGPRICE(records); Log(ret); }

返回值

类型描述

array

talib.AVGPRICE()函数返回一维数组。

参数

名称类型必填描述

inPriceOHLC

Record结构数组

inPriceOHLC参数用于指定K线数据。

备注

AVGPRICE()函数在talib库文档中的描述为:AVGPRICE(Records[Open,High,Low,Close]) = Array(outReal)

talib.MEDPRICE()函数用于计算Median Price(中位数价格)

talib.MEDPRICE(inPriceHL)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.MEDPRICE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.MEDPRICE(records.High, records.Low) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.MEDPRICE(records); Log(ret); }

返回值

类型描述

array

talib.MEDPRICE()函数返回一维数组。

参数

名称类型必填描述

inPriceHL

Record结构数组

inPriceHL参数用于指定K线数据。

备注

MEDPRICE()函数在talib库文档中的描述为:MEDPRICE(Records[High,Low]) = Array(outReal)

talib.TYPPRICE()函数用于计算典型价格(Typical Price)

talib.TYPPRICE(inPriceHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.TYPPRICE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.TYPPRICE(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.TYPPRICE(records); Log(ret); }

返回值

类型描述

array

talib.TYPPRICE()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

备注

TYPPRICE()函数在talib库文档中的描述为:TYPPRICE(Records[High,Low,Close]) = Array(outReal)

talib.WCLPRICE()函数用于计算Weighted Close Price(加权收盘价)

talib.WCLPRICE(inPriceHLC)

示例

javascript
function main() { var records = exchange.GetRecords() var ret = talib.WCLPRICE(records) Log(ret) }
python
import talib def main(): records = exchange.GetRecords() ret = talib.WCLPRICE(records.High, records.Low, records.Close) Log(ret)
c++
void main() { auto records = exchange.GetRecords(); auto ret = talib.WCLPRICE(records); Log(ret); }

返回值

类型描述

array

talib.WCLPRICE()函数返回一维数组。

参数

名称类型必填描述

inPriceHLC

Record结构数组

inPriceHLC参数用于指定K线数据。

备注

WCLPRICE()函数在talib库文档中的描述为:WCLPRICE(Records[High,Low,Close]) = Array(outReal)

发明者量化交易平台支持文件读写操作,os库提供了完整的文件系统操作接口,帮助用户在策略开发中进行数据持久化、配置管理和日志记录等操作。
需要注意,该功能仅支持JavaScript语言策略。

os库支持:文件对象、文件列表对象、文件信息对象。

对象说明备注
文件对象:File提供文件读写、定位等操作。通过os.open()获取,使用完毕需调用close()释放资源。
文件列表对象:ListFilesResult用于记录目录列表信息。支持通配符匹配模式,由os.listFiles()函数返回。
文件信息对象:FileStat文件统计信息。os.stat()函数返回。

支持实盘、回测系统。

  • 实盘环境:
    实盘默认目录为托管者目录下实盘数据库文件同级目录的files文件夹中,即:/logs/storage/xxx/files,其中xxx为实盘Id,托管者程序(robot)与logs在同一级目录。
  • 回测系统环境:
    回测系统是一个沙盒环境,系统模拟一个文件目录,默认目录为:/logs/storage/1/files
    当回测结束时,创建的文件内容将被清除。

os库为发明者量化交易平台提供完整的文件系统操作接口。

以指定模式打开文件。

open(filename)
open(filename, mode)

示例

创建文件,写入数据后再读取。

javascript
function main() { let fileHandle = os.open("output.txt", "w+") if (!fileHandle) { Log("Failed to open file") return } let bytesWritten = fileHandle.write("Hello FMZ!") Log("Bytes written:", bytesWritten) // Bytes written: 10 fileHandle.seek(0, 0) let fileContent = fileHandle.read() Log("File content read:", fileContent) // File content read: Hello FMZ! fileHandle.close() }

返回值

类型描述

File对象

open()函数返回一个File对象,用于操作文件。

参数

名称类型必填描述

filename

string

文件名称。参数filename是包含文件名的路径。由于托管者与回测系统都支持os操作,需要注意在非回测环境下,文件操作被限制在托管者目录下实盘数据库文件同级目录的files文件夹中,因此不支持使用绝对路径操作任何文件。关于参数filename的这个注意事项后续不再赘述。

mode

string

指定文件的打开模式。

参考

备注

文件打开模式:

  • r : read(只读,文件必须存在)

  • w : write(只写,文件不存在则创建,存在则清空内容)

  • a : append(追加写入,文件不存在则创建,存在则写入到末尾)

  • + : 在 r/w/a 后加 + 表示既可以读也可以写(例如 "r+", "w+", "a+")

  • b : binary(二进制模式,常用于 Windows 区分文本/二进制文件,例如 "rb", "wb")

文件的打开/创建位于实盘数据库文件目录(xxx.db3,其中xxx为实盘Id)下的files文件夹中。

一次性读取整个文件的内容。

fgets(filename)

示例

读取配置文件的内容。

javascript
function main() { // 先创建、写入文件 // let fileHandle = os.open("config.json", "w+") // if (!fileHandle) { // Log("Failed to open file") // return // } // let objJson = {"name": "tom", "age": 18} // fileHandle.write(JSON.stringify(objJson)) // fileHandle.close() let content = os.fgets("config.json") Log("Config content:", content) // Config content: {"name":"tom","age":18} }

返回值

类型描述

string

返回文件的完整内容。

参数

名称类型必填描述

filename

string

文件路径,包含要读取的文件名。

参考

备注

适用于小文件的快速读取,将整个文件内容一次性加载到内存中。

如果文件不存在,fgets()函数会抛出错误:InternalError: failed to open file: openat config.json: no such file or directory at main

向文件写入内容。

fputs(filename, content)
fputs(filename, content, append)

示例

保存策略配置到文件。

javascript
function main() { let config = '{"strategy": "MA", "period": 20}' let bytesWritten = os.fputs("strategy_config.json", config) Log("Bytes written:", bytesWritten) // Bytes written: 32 Log(`os.fgets("strategy_config.json"):`, os.fgets("strategy_config.json")) // os.fgets("strategy_config.json"): {"strategy": "MA", "period": 20} // 追加日志信息 let logInfo = "\n[" + new Date().toISOString() + "] Config saved" os.fputs("strategy_config.json", logInfo, true) Log(`os.fgets("strategy_config.json"):`, os.fgets("strategy_config.json")) // os.fgets("strategy_config.json"): {"strategy": "MA", "period": 20} [2025-09-08T07:20:30.563Z] Config saved }

返回值

类型描述

number

返回实际写入的字节数。

参数

名称类型必填描述

filename

string

文件路径。

content

string

要写入的内容。

append

bool

是否以追加模式写入,默认为 false(覆盖模式)。

参考

备注

便捷的文件写入方法,默认覆盖文件内容。设置 append 为 true 可以追加到文件末尾。

内存映射文件,返回文件的二进制数据。

mmap(filename)

示例

映射文件的二进制数据。

javascript
function ab2str(buf) { let arr = new Uint8Array(buf) return String.fromCharCode.apply(null, arr) } function main() { let buffer = os.mmap("strategyConfig/testData.txt") Log("File size in bytes:", buffer.byteLength) let arr = Array.from(new Uint8Array(buffer)) Log("arr:", arr) // arr: [72,101,108,108,111,32,70,77,90,33] Log("ab2str(buffer):", ab2str(buffer)) // ab2str(buffer): Hello FMZ! }

返回值

类型描述

ArrayBuffer

返回文件内容的二进制数据。

参数

名称类型必填描述

filename

string

文件路径。

参考

备注

适用于大文件的高效读取和处理,将文件映射到内存中并作为 ArrayBuffer 返回。

获取文件操作的根目录路径。

getRootDir()

示例

获取并显示根目录路径。

javascript
function main() { let rootDir = os.getRootDir() Log("Root directory:", rootDir) }

返回值

类型描述

string

返回根目录的路径。

参考

列出指定目录中的文件和子目录。

listFiles()
listFiles(pattern)

示例

列出匹配的文件和目录。

javascript
function main() { // 列出所有json文件 let result = os.listFiles("*.json") Log("result:", result) // 列出所有内容 let allFiles = os.listFiles() Log("allFiles:", allFiles) }

返回值

类型描述

ListFilesResult 对象

返回包含 filesdirs 数组的对象。

  • files:匹配到的文件名数组。

  • dirs:当前目录下的子目录名数组。

参数

名称类型必填描述

pattern

string

可选的匹配模式,支持通配符(如 .txt、data_.json),可以指定目录路径。

参考

备注

不指定 pattern 参数时,列出当前目录(../files)下的所有文件和子目录。

检查指定的文件或目录是否存在。

exists(filename)

示例

检查文件或路径是否存在。

javascript
function main() { Log(`os.exists("./strategyConfig"):`, os.exists("./strategyConfig")) // os.exists("./strategyConfig"): true Log(`os.exists("./strategyConfig/testData.txt"):`, os.exists("./strategyConfig/testData.txt")) // os.exists("./strategyConfig/testData.txt"): true // Log(`os.exists("/strategyConfig"):`, os.exists("/strategyConfig")) // InternalError: invalid filename: path traversal or absolute path not allowed at main Log(`os.exists("test_1.txt"):`, os.exists("test_1.txt")) // os.exists("test_1.txt"): true Log(`os.exists("test_2.txt"):`, os.exists("test_2.txt")) // os.exists("test_2.txt"): false }

返回值

类型描述

bool

如果文件或目录存在则返回 true,否则返回 false。

参数

名称类型必填描述

filename

string

要检查的文件或目录路径。

参考

删除指定文件。

remove(filename)

示例

删除文件示例。

javascript
function main() { let tempFile = "test_1.txt" if (os.exists(tempFile)) { let success = os.remove(tempFile) Log("Temp file deleted:", success) } }

返回值

类型描述

bool

删除成功返回true,失败返回false。

参数

名称类型必填描述

filename

string

要删除的文件路径。

参考

备注

此函数仅用于删除文件,不支持删除目录。如需删除目录,请使用rmdir()函数。

创建目录。

mkdir(dirname)

示例

创建数据存储目录,创建文件并写入数据。

javascript
function main() { let success = os.mkdir("data/backtest/results") Log("Directory created:", success) if (success) { os.fputs("data/backtest/results/summary.txt", "Backtest completed") } }

返回值

类型描述

bool

创建成功返回 true,否则返回 false。

参数

名称类型必填描述

dirname

string

要创建的目录路径。

参考

备注

支持递归创建多级目录。如果父目录不存在,将自动创建。

删除目录及其所有内容。

rmdir(dirname)

示例

删除目录及其所有内容。

javascript
function main() { let tempDir = "data" if (os.exists(tempDir)) { let success = os.rmdir(tempDir) Log("directory removed:", success) } }

返回值

类型描述

bool

删除成功返回 true,失败返回 false。

参数

名称类型必填描述

dirname

string

要删除的目录路径。

参考

备注

此操作将永久删除目录及其所有内容,请谨慎使用。

重命名文件或移动文件。

rename(oldName, newName)

示例

重命名文件并将其移动到其他目录。

javascript
function main() { let oldFileName = "output.txt" let newFileName = "outputFiles/" + new Date().getTime() + "output.txt" // let retRename = os.rename(oldFileName, newFileName) // Log("retRename:", retRename) // InternalError: failed to rename file: renameat output.txt outputFiles/1757322073139output.txt: no such file or directory at main os.mkdir("outputFiles") let retRename = os.rename(oldFileName, newFileName) Log("retRename:", retRename) // retRename: true }

返回值

类型描述

bool

操作成功时返回 true,否则返回 false。

参数

名称类型必填描述

oldName

string

原文件的名称或路径。

newName

string

新文件的名称或路径。

参考

备注

该函数可用于重命名文件,或将文件移动到其他目录。如果新路径所在的目录不存在,操作将会失败。

获取文件的详细统计信息。

stat(filename)

示例

获取文件信息并检查文件大小。

javascript
function main() { if (os.exists("strategyConfig/testData.txt")) { let stat = os.stat("strategyConfig/testData.txt") // stat: {"size":10,"mode":420,"mtime":1757312981796,"atime":1757312981796,"ctime":1757312981796} Log("stat:", stat) } }

返回值

类型描述

FileStat 对象

返回包含文件统计信息的对象。

参数

名称类型必填描述

filename

string

文件路径。

参考

备注

返回的FileStat对象包含以下字段:

  • size: 文件大小。

  • mode: 文件权限。

  • mtime: 最后修改时间。

  • atime: 最后访问时间。

  • ctime: 创建时间。

退出程序。

exit()
exit(status)

示例

检查条件后退出程序。

javascript
function main() { if (!os.exists("required_config.json")) { Log("Required configuration file not found!") os.exit(1) // 异常退出 } Log("Configuration found, continuing...") // 正常的策略逻辑... }

返回值

类型描述

never

此函数不会返回值,程序将直接终止执行。

参数

名称类型必填描述

status

number

可选的退出状态码,默认值为 0。

参考

备注

立即终止程序执行。状态码 0 表示正常退出,非零值表示异常退出(实盘中将显示为错误)。

文件对象,提供文件读写、定位等操作。

关闭文件并释放相关资源。

close()

示例

正确的文件操作流程示例。

javascript
function main() { let file = os.open("data.txt", "w") file.write("Hello FMZ!") file.close() // 必须关闭文件 }

参考

备注

使用完文件对象后必须调用此方法以释放系统资源。

向文件写入一个或多个字符串。

puts(data1, data2, ...dataN)

示例

向文件写入多个字符串。

javascript
function main() { let file = os.open("output.txt", "w+") let bytes = file.puts("Hello", " ", "World", "!") Log("Bytes written:", bytes) // Bytes written: 12 file.seek(0, 0) let data = file.read() Log("data:", data) // If using os.open("output.txt", "w") may result in data being undefined // data: Hello World! // file.puts() // error: puts requires at least 1 argument at main file.puts(", Hello FMZ!") file.seek(0, 0) data = file.read() Log("data:", data) // data: Hello World!, Hello FMZ! file.close() }

返回值

类型描述

number

返回实际写入的字节数。

参数

名称类型必填描述

data

string

要写入的字符串数据,可传入多个参数。

参考

备注

可一次写入多个字符串参数,将按顺序连接后写入。

格式化写入数据到文件。

printf(format)
printf(format, arg1, arg2, ...argN)

示例

格式化写入交易数据。

javascript
function main() { let file = os.open("trade_log.txt", "w+") let price = 100.25 let volume = 1000 let bytes = file.printf("Price: %.2f, Volume: %d\n", price, volume) Log("Formatted bytes written:", bytes) file.seek(0, 0) let data = file.read() Log("data:", data) // data: Price: 100.25, Volume: 1000 // file.printf("| Price: %.2f, Volume: %d\n") // "| Price: %!f(MISSING), Volume: %!d(MISSING)" // file.seek(0, 0) // data = file.read() // Log("data:", data) file.close() }

返回值

类型描述

number

返回实际写入的字节数。

参数

名称类型必填描述

format

string

格式化字符串。

args

any (平台支持的任意类型)

格式化参数。

参考

刷新文件缓冲区,确保数据写入磁盘。

flush()

示例

实时写入重要日志数据。

javascript
function main() { let logFile = os.open("critical.log", "a") logFile.printf("[%s] Critical event occurred\n", new Date().toISOString()) // [2025-09-09T03:15:43.895Z] Critical event occurred logFile.flush() // 立即将数据写入磁盘 // 继续其他操作... logFile.close() }

参考

获取当前文件指针的位置。

tell()

示例

记录文件操作过程中的位置。

javascript
function main() { let file = os.open("data.txt", "r+") Log("Initial position:", file.tell()) // Initial position: 0 file.write("Hello") Log("After write position:", file.tell()) // After write position: 5 file.close() }

返回值

类型描述

number

返回当前文件指针的位置(以字节为单位的偏移量)。

参考

备注

返回当前文件指针相对于文件起始位置的字节偏移量。

将文件指针移动到指定位置。

seek(offset, whence)

示例

倒序读取字符。

javascript
function main() { let str = "Hello FMZ!" let file = os.open("data.txt", "w+") file.write(str) // If i > str.length: will throw InternalError: seek .../xxx/data.txt: invalid argument at main for (let i = 1; i <= str.length; i++) { file.seek(-i, 2) let data = file.read(1) Log("i:", i, ", data:", data) } file.close() }

返回值

类型描述

number

返回新的文件指针位置。

参数

名称类型必填描述

offset

number

偏移量(以字节为单位)。

whence

number

基准位置:0=文件开头,1=当前位置,2=文件末尾。

参考

备注

用于定位文件指针,offset参数可以为负数(表示向前移动)。

检查文件指针是否已到达文件末尾。

eof()

示例

逐行读取文件直至文件结束。

javascript
function main() { let file = os.open("data.txt", "r") let lineCount = 0 while (!file.eof()) { let line = file.getline() if (line) { lineCount++ Log("Line", lineCount + ":", line) } } Log("Total lines:", lineCount) file.close() }

返回值

类型描述

bool

如果已到达文件末尾则返回true,否则返回false。

参考

备注

用于在读取文件时判断是否已读取完所有内容。

从文件中读取数据。

read()
read(size)

示例

分块读取文件内容。

javascript
function main() { let file = os.open("data.txt", "r") // data.txt // This is a test line: Line 1. // This is a test line: Line 2. // ... let chunkSize = 29 let totalBytes = 0 while (!file.eof()) { let chunk = file.read(chunkSize) if (chunk) { totalBytes += chunk.length || chunk.byteLength Log("Read chunk, total bytes so far:", totalBytes, ", chunk:", chunk) } } file.close() }

返回值

类型描述

string / ArrayBuffer / undefined

返回读取的内容。当到达文件末尾时返回undefined

参数

名称类型必填描述

size

number

要读取的字节数。如果不指定,则读取文件中剩余的所有内容。

参考

备注

可以读取指定字节数的内容或文件中剩余的全部内容。返回类型可能是字符串ArrayBuffer

向文件写入字符串数据。

write(data)

示例

写入交易记录

javascript
function main() { let file = os.open("trades.log", "a") let timestamp = new Date().toISOString() let tradeInfo = `${timestamp},BUY,50000,1\n` let bytes = file.write(tradeInfo) Log("Trade record written, bytes:", bytes) file.close() }

返回值

类型描述

number

返回实际写入的字节数。

参数

名称类型必填描述

data

string

要写入的字符串数据。

参考

备注

将字符串数据写入文件的当前位置。

从文件中读取下一行内容。

getline()

示例

逐行读取文件直至结束。

javascript
function main() { let file = os.open("data.txt", "r") let lineCount = 0 while (!file.eof()) { let line = file.getline() if (line) { lineCount++ Log("Line", lineCount + ":", line) } } Log("Total lines:", lineCount) file.close() }

返回值

类型描述

string / undefined

返回下一行内容,到达文件末尾时返回undefined

参考

备注

按行顺序读取文件内容。

获取文件对象的字符串表示形式。

toString()

示例

获取文件对象的描述信息。

javascript
function main() { let file = os.open("data/data.txt", "r") Log("File info:", file.toString()) // File info: File(data/data.txt) file.close() }

返回值

类型描述

string

返回文件对象的字符串描述信息。

参考

备注

返回文件对象的描述信息。

文件列表对象,用于记录目录列表信息。该对象包含两个数组属性:files(文件列表)和dirs(目录列表)。

参考

备注

ListFilesResult对象结构:

javascript
{ files: string[], // 搜索的文件名数组 dirs: string[] // 当前目录下,子目录名数组 }

此对象由os.listFiles()函数返回。

文件统计信息对象。

参考

备注

FileStat对象结构:

javascript
{ size: number, // 文件大小(字节) mode: number, // 文件权限模式 mtime: number, // 修改时间,毫秒时间戳 atime: number, // 访问时间,毫秒时间戳 ctime: number // 创建时间,毫秒时间戳 }

此对象由os.stat()函数返回。