资源加载中... loading...

内置函数

Global

Version

返回系统当前版本号。

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

Version()

function main() {
    Log("version:", Version())
}
def main():
    Log("version:", Version())
void main() {
    Log("version:", Version());
}

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

Sleep

休眠函数,使程序暂停一段时间。

Sleep(millisecond)

millisecond参数用于设置休眠时长,毫秒数。 millisecond true number

function main() {
    Sleep(1000 * 10)   // 等待10秒钟
    Log("等待了10秒钟")
}
def main():
    Sleep(1000 * 10)
    Log("等待了10秒钟")
void main() {
    Sleep(1000 * 10);
    Log("等待了10秒钟");
}

例如执行Sleep(1000)函数时,程序会休眠1秒。 支持休眠时间小于1毫秒的操作,例如设置Sleep(0.1)。 支持最小参数为0.000001,即纳秒级休眠,1纳秒等于1e-6毫秒。 在使用Python语言编写策略时,对于轮询间隔、时间等待的操作应当使用Sleep(millisecond)函数。 不建议使用Pythontime库的time.sleep(second)函数。 因为策略中使用time.sleep(second)函数在回测时会让策略程序实际等待一段时间(并非在回测系统的时间序列上跳过),所以导致策略回测非常慢。

IsVirtual

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

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

IsVirtual()

function main() {
    if (IsVirtual()) {
        Log("当前为回测系统环境。")
    } else {
        Log("当前为实盘环境。")
    }
}
def main():
    if IsVirtual():
        Log("当前为回测系统环境。")
    else:
        Log("当前为实盘环境。")
void main() {
    if (IsVirtual()) {
        Log("当前为回测系统环境。");
    } else {
        Log("当前为实盘环境。");
    }
}

判断当前运行环境是否是回测系统,用来兼容回测与实盘的差异。

Mail

发送邮件。

邮件发送成功返回真值,例如:true,发送失败返回假值,例如:false。 bool

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

用于指定邮件发送方的SMTP服务地址。 smtpServer true string 用于指定邮件发送方的邮箱地址。 smtpUsername true string 邮件发送方邮箱的SMTP密码。 smtpPassword true string 用于指定邮件接收方的邮箱地址。 mailTo true string 邮件标题。 title true string 邮件正文。 body true string

function main(){
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
}
def main():
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
void main() {
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}

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。 回测系统中不起作用。

{@fun/Global/Mail_Go Mail_Go}

Mail_Go

Mail函数的异步版本。

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

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

用于指定邮件发送方的SMTP服务地址。 smtpServer true string 用于指定邮件发送方的邮箱地址。 smtpUsername true string 邮件发送方邮箱的SMTP密码。 smtpPassword true string 用于指定邮件接收方的邮箱地址。 mailTo true string 邮件标题。 title true string 邮件正文。 body true string

function main() {
    var r1 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
    var r2 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
    
    var ret1 = r1.wait()
    var ret2 = r2.wait()
    
    Log("ret1:", ret1)
    Log("ret2:", ret2)
}
# 不支持
// 不支持

回测系统中不起作用。

{@fun/Global/Mail Mail}

SetErrorFilter

过滤错误日志。

SetErrorFilter(filters)

正则表达式字符串。 filters true string

function main() {
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
}
def main():
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
void main() {
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
}

过滤常见错误。

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    
    // 随便查询一个不存在的订单,id为123,故意让接口报错
    var order = exchange.GetOrder("123")
    Log(order)
    // 过滤http502错误、GetOrder接口错误,设置错误过滤之后,第二次调用GetOrder不再报错
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    exchange.SetContractType("rb888")
    
    order = exchange.GetOrder("123")
    Log(order)
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    exchange.SetContractType("rb888");
    
    TId orderId;
    Order order = exchange.GetOrder(orderId);
    Log(order);
    SetErrorFilter("502:|GetOrder");
    order = exchange.GetOrder(orderId);
    Log(order);
}

过滤某个接口错误信息。

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

GetPid

获取实盘进程Id。

返回实盘进程Id。 string

GetPid()

function main(){
    var id = GetPid()
    Log(id)
}
def main():
    id = GetPid()
    Log(id)
void main() {
    auto id = GetPid();
    Log(id);
}

GetLastError

获取最近一次出错信息。

最近一次出错信息。 string

GetLastError()

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    
    exchange.SetContractType("rb888")
    
    // 因为不存在编号为123的订单,所以会出错
    exchange.GetOrder("123")
    var error = GetLastError()
    Log(error)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    exchange.SetContractType("rb888")
    
    exchange.GetOrder("123")
    error = GetLastError()
    Log(error)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    exchange.SetContractType("rb888");
    
    // 订单ID类型:TId,所以不能传入字符串,我们下一个不符合交易所规范的订单来触发
    exchange.GetOrder(exchange.Buy(1, 1));
    auto error = GetLastError();
    Log(error);
}

回测系统中不起作用。

GetCommand

获取策略交互命令。

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

GetCommand()

function main(){
    while(true) { 
        var cmd = GetCommand()
        if (cmd) { 
            Log(cmd)
        }
        Sleep(1000) 
    }
}
def main():
    while True:
        cmd = GetCommand()
        if cmd:
            Log(cmd)
        Sleep(1000)
void main() {
    while(true) {
        auto cmd = GetCommand();
        if(cmd != "") {
            Log(cmd);
        }
        Sleep(1000);
    }
}

检测交互命令并且在检测到交互命令时使用Log函数输出交互命令。

function main() {
    while (true) {
        LogStatus(_D())
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)    
            var arr = cmd.split(":")
            if (arr[0] == "buy") {
                Log("买入,该控件不带数量")
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1])
            } else {
                Log("其它控件触发:", arr)
            }
        }
        Sleep(1000)
    } 
}
def main():
    while True:
        LogStatus(_D())
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
            arr = cmd.split(":")
            if arr[0] == "buy":
                Log("买入,该控件不带数量")
            elif arr[0] == "sell":
                Log("卖出,该控件带数量:", arr[1])
            else:
                Log("其它控件触发:", arr)
        Sleep(1000)
#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("买入,该控件不带数量");
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1]);
            } else {
                Log("其它控件触发:", arr);
            }
        }
        Sleep(1000);
    }
}

例如策略交互控件中添加了一个不带输入框的控件,交互控件命名为:buy,控件描述信息为:买入,这是一个按钮控件。 继续添加一个带输入框的控件,交互控件名为:sell,控件描述信息为:卖出,这是一个由按钮和输入框组合起来的交互控件。 策略中设计交互代码来响应不同交互控件:

回测系统中不起作用。

GetMeta

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

Meta数据。 string

GetMeta()

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
    }
    
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    
    exchange.SetContractType("rb888")
    
    while(true) {
        Sleep(1000)
        var ticker = exchange.GetTicker()
        
        // 检测资产数值
        var acc = exchange.GetAccount()
        if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Balance + acc.FrozenBalance) {
            // 停止执行策略交易逻辑
            LogStatus(_D(), "level:", level, "持仓超过注册码的使用限定,不再执行策略交易逻辑!")
            continue
        }
        
        // 其它交易逻辑
        
        // 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\n", ticker)
    }
}
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 not exchange.IO("status"):
        Sleep(1000)
    
    exchange.SetContractType("rb888")
    
    while True:
        Sleep(1000)
        ticker = exchange.GetTicker()        
        acc = exchange.GetAccount()
        if maxBaseCurrency != -1 and maxBaseCurrency < acc["Balance"] + acc["FrozenBalance"]:
            LogStatus(_D(), "level:", level, "持仓超过注册码的使用限定,不再执行策略交易逻辑!")
            continue        
        
        # 其它交易逻辑
        
        # 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\n", ticker)
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(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    exchange.SetContractType("rb888");
    
    while(true) {
        Sleep(1000);
        auto ticker = exchange.GetTicker();  
        auto acc = exchange.GetAccount();
        if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Balance + acc.FrozenBalance) {
            // 停止执行策略交易逻辑
            LogStatus(_D(), "level:", level, "持仓超过注册码的使用限定,不再执行策略交易逻辑!");
            continue;
        }
        
        // 其它交易逻辑
        
        // 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\n", ticker);
    }
}

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

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

Dial

用于原始的Socket访问,支持tcpudptlsunix协议。 支持4种流行的通信协议:mqttnatsamqpkafka。 支持连接数据库,支持的数据库有:sqlite3mysqlpostgresclickhouse

如果超时Dial()函数返回空值。 正常调用时返回一个连接对象,该对象有三个方法:readwritecloseread方法用于读取数据,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()函数关闭连接,如果设置了自动重连则不用关闭,系统底层会自动重连。

object

Dial(address) Dial(address, timeout)

请求地址。 address true string 超时秒数, timeout false number

function main(){
    // Dial支持tcp://,udp://,tls://,unix://协议,可加一个参数指定超时的秒数
    var client = Dial("tls://www.baidu.com:443")  
    if (client) {
        // write可再跟一个数字参数指定超时,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()
    }
}
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()
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();
    }
}

Dial函数调用例子:

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("执行client.close()")
    client.close()
}
// 不支持
// 不支持

Dial函数连接数据库时返回的连接对象有2个其独有的方法函数:

  • exec(sqlString): 用于执行SQL语句,使用方式类似于DBExec()函数。
  • fd(): fd()函数返回一个句柄(例如:句柄变量为handle),用于其它线程重连(即使Dial创建的对象已经被执行close()函数关闭连接),将句柄传入Dial()函数,例如:Dial(handle)重用连接。 以下是Dial函数连接sqlite3数据库的例子。

address参数的详细说明,在正常的地址:wss://xxx.xxx.xxx:10441/websocket?compress后,以|符号分隔。 如果参数字符串中有|字符,则以||作为分隔符号。之后的部分是一些功能参数设置,各个参数之间用&字符连接。 例如ss5代理和压缩参数一起设置时可以写作: Dial("wss://baidu.com/stream|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

Dial函数的address参数支持的功能 参数说明
WebSocket协议数据压缩相关的参数:compress=参数值 compress为压缩方式,compress参数可选gzip_raw、gzip等。如果gzip方式非标准gzip,可以使用扩展的方式:gzip_raw
WebSocket协议数据压缩相关的参数:mode=参数值 mode为压缩模式,mode参数可选dual,send,recv三种。dual为双向压缩,发送压缩数据,接收压缩数据。send为发送压缩数据。recv为接收压缩数据,本地解压缩。
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:pwd@192.168.0.1:1080,name为ss5服务端用户名,pwd为ss5服务端登录密码,1080为ss5服务的端口。

Dial()函数仅支持实盘。 使用Dial函数连接数据库时,编写的连接字符串参考各数据库的go语言驱动项目。

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

目前仅JavaScript语言支持Dial函数中使用mqttnatsamqpkafka通信协议,以JavaScript语言策略代码为例展示mqttnatsamqpkafka四种协议使用例子:

// 需要先配置、部署完成各个协议的代理服务器
// 为了便于演示,主题test_topic的订阅(read操作)、发布(write操作)都在当前这个策略中进行
var arrConn = []
var arrName = []

function main() {
    LogReset(1)
    conn_nats = Dial("nats://admin@127.0.0.1:4222?topic=test_topic")
    conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
    conn_amqp = Dial("amqp://q:admin@127.0.0.1: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("关闭", arrName[i], "连接")
    }
}

HttpQuery

发送Http请求。

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

HttpQuery(url) HttpQuery(url, options)

Http请求url。 url true string Http请求相关设置,例如可以是以下结构:

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    profile: "chrome_103",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}
  • profile:用来模拟浏览器tls指纹。 支持的设置有以下选项: chrome_:"chrome_103""chrome_104""chrome_105""chrome_106""chrome_107""chrome_108""chrome_109""chrome_110""chrome_111""chrome_112""chrome_117"、 safari_:"safari_15_6_1""safari_16_0""safari_ipad_15_6""safari_ios_15_5""safari_ios_15_6""safari_ios_16_0"、 firefox_:"firefox_102""firefox_104""firefox_105""firefox_106""firefox_108""firefox_110""firefox_117"、 opera_:"opera_89""opera_90""opera_91"、 zalando_:"zalando_android_mobile""zalando_ios_mobile"、 nike_:"nike_ios_mobile""nike_android_mobile"、 cloudscraper:"cloudscraper"、 mms_:"mms_ios"、 mesh_:"mesh_ios""mesh_ios_1""mesh_ios_2""mesh_android""mesh_android_1""mesh_android_2"、 confirmed_:"confirmed_ios""confirmed_android"、 okhttp4_:"okhttp4_android_7""okhttp4_android_8""okhttp4_android_9""okhttp4_android_10""okhttp4_android_11""okhttp4_android_12""okhttp4_android_13"
  • debug:设置为true时,此次HttpQuery函数调用返回完整的应答报文。设置为false时只返回应答报文Body中的数据。
  • timeout:超时设置,设置1000表示1秒钟超时。
  • charset:支持对请求的应答数据进行转码,例如:GB18030。支持常用编码。

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

options false object

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:password@127.0.0.1:8889/http://www.baidu.com/")
}
# HttpQuery不支持Python,可以使用Python的urllib2库
void main() {
    HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
    HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
}

HttpQuery函数使用代理设置。

HttpQuery()函数只支持JavaScriptC++语言,Python语言可以使用urllib库,直接发送Http请求。 回测系统中可以使用HttpQuery()发送请求(只支持GET请求)获取数据。 回测时限制使用20次访问不同的URL,并且HttpQuery()访问会缓存数据, 相同的URL第二次访问时HttpQuery()函数返回缓存数据,不再发生实际网络请求。

{@fun/Global/HttpQuery_Go HttpQuery_Go}

HttpQuery_Go

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

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

HttpQuery_Go(url) HttpQuery_Go(url, options)

Http请求url。 url true string Http请求相关设置,例如可以是以下结构:

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    // profile: "",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}              
  • profile:用来模拟浏览器tls指纹。
  • debug:设置为true时,此次HttpQuery_Go函数调用返回完整的应答报文。设置为false时只返回应答报文Body中的数据。
  • timeout:超时设置,设置1000表示1秒钟超时。

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

options false object

function main() {
    // 创建第一个异步线程
    var r1 = HttpQuery_Go("https://xxx.xxx.xxx")   // https://xxx.xxx.xxx 仅为演示地址,可以是某个数据源
    // 创建第二个异步线程
    var r2 = HttpQuery_Go("https://xxx.xxx.xxx")
    
    // 获取第一个异步线程调用的返回值
    var tickers1 = r1.wait()
    // 获取第二个异步线程调用的返回值
    var tickers2 = r2.wait()
    
    // 打印结果
    Log("tickers1:", tickers1)
    Log("tickers2:", tickers2)
}
# 不支持
// 不支持

HttpQuery_Go()函数使用范例:

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

{@fun/Global/HttpQuery HttpQuery}

Encode

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

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

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

参数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计算。 algo true string 用于指定data参数的数据格式。 inputFormat参数支持设置为:“raw”,“hex”,“base64”,"string"其中之一。 "raw"表示数据为原始数据,"hex"表示数据为hex编码,"base64"表示数据为base64编码,"string"表示数据为字符串。 inputFormat true string 用于指定输出的数据格式。 outputFormat参数支持设置为:“raw”,“hex”,“base64”,"string"其中之一。 "raw"表示数据为原始数据,"hex"表示数据为hex编码,"base64"表示数据为base64编码,"string"表示数据为字符串。 outputFormat true string 参数data为所要处理的数据。 data true string 用于指定key参数的数据格式。 key参数支持设置为:“raw”,“hex”,“base64”,"string"其中之一。 "raw"表示数据为原始数据,"hex"表示数据为hex编码,"base64"表示数据为base64编码,"string"表示数据为字符串。 keyFormat false string 参数keyHMAC加密时使用的秘钥。 参数algo设置为"sign"或者"signTx"时需要参数key。 参数algo设置为"raw"时不会使用key参数进行HMAC加密(因为HMAC加密必须指定算法)。 key false string

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
}
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
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
}

Encode函数调用例子。

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)
}
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)
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);
}

参数algo也支持:“text.encoder.utf8”,“text.decoder.utf8”,“text.encoder.gbk”,“text.decoder.gbk”,对字符串编码、解码。

Encode()函数仅支持实盘。 不传keykeyFormat参数,则不使用key加密。

UnixNano

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

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

UnixNano()

function main() {
    var time = UnixNano() / 1000000
    Log(_N(time, 0))
}
def main():
    time = UnixNano()
    Log(time)
void main() {
    auto time = UnixNano();
    Log(time);
}

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

{@fun/Global/Unix Unix}

Unix

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

返回秒级别时间戳。 number

Unix()

function main() {
    var t = Unix()
    Log(t)
}
def main():
    t = Unix()
    Log(t)
void main() {
    auto t = Unix();
    Log(t);
}

{@fun/Global/UnixNano UnixNano}

GetOS

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

系统信息。 string

GetOS()

function main() {
    Log("GetOS:", GetOS())
}
def main():
    Log("GetOS:", GetOS())
void main() {
    Log("GetOS:", GetOS());
}

例如在Mac OS操作系统下运行的托管者,调用GetOS()函数可能返回:darwin/amd64, 因为苹果电脑有多种硬件架构。darwinMac OS系统的名称。

MD5

计算参数data的MD5哈希值。

MD5哈希值。 string

MD5(data)

需要进行MD5计算的数据。 data true string

function main() {
    Log("MD5", MD5("hello world"))
}
def main():
    Log("MD5", MD5("hello world"))
void main() {
    Log("MD5", MD5("hello world"));
}

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

{@fun/Global/Encode Encode}

DBExec

数据库接口函数。

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

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

object

DBExec(sql)

sql语句字符串。 sql true string

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;"))
}
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;"))
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函数的参数,如果sql语句是以:开头则在内存数据库中操作,不写文件速度更快。 适合不需要持久化保存的数据库操作,例如:

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)
}
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)
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);
}

创建表。

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))
}
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))
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));
}

表中记录的增删查改操作。

函数DBExec()通过传入参数,可以操作实盘数据库(SQLite数据库)。 实现对实盘数据库中数据的增、删、查、改等操作,支持SQLite语法。 实盘数据库中系统保留表:kvdbcfglogprofitchart,切勿对这些表进行操作。 目前不支持事务,不建议执行此类操作,会引起系统中的冲突。 DBExec()函数仅支持实盘。

{@fun/Global/_G _G}

UUID

创建一个UUID。

32位的UUID。 string

UUID()

function main() {
    var uuid1 = UUID()
    var uuid2 = UUID()
    Log(uuid1, uuid2)
}
def main():
    uuid1 = UUID()
    uuid2 = UUID()
    Log(uuid1, uuid2)
void main() {
    auto uuid1 = UUID();
    auto uuid2 = UUID();
    Log(uuid1, uuid2);
}

UUID()函数仅支持实盘。

EventLoop

监听事件,有任意事件发生时返回。

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

{"Seq":10,"Event":"tick","ThreadId":0,"Index":0,"Nano":1689216222796834300,"Symbol":"rb2311","Ticker": {...}}

object

EventLoop() EventLoop(timeout)

参数timeout为超时设置,单位为毫秒。 参数timeout如果设置为0则等待有事件发生才返回,如果大于0就是设置事件等待超时,小于0立即返回最近事件。 timeout false number

function main(){
    while(true){
        // 需要在判断exchange.IO("status")函数返回true,即为真值时才可调用行情、交易等函数
        if(exchange.IO("status")){
            exchange.SetContractType("rb888")            
            LogStatus(_D(), "已经连接CTP !")
            var msg = EventLoop()
            Log(msg)
        } else {
            LogStatus(_D(), "未连接CTP !")
        }
    }
}
# 不支持EventLoop函数
// 不支持EventLoop函数

代码中第一次调用EventLoop()函数才会初始化该监听事件的机制,如果在事件回调之后才开始首次EventLoop()调用,会错过之前的事件。 底层系统封装的队列结构会缓存最大500个事件回调,如果程序执行过程中没有及时调用EventLoop()函数取出,会丢失500个缓存之外较晚的事件回调。 EventLoop()函数的调用不会影响系统底层WebSocket的缓存队列。 对于这些缓存依然需要使用各自的方法取出数据。对于在EventLoop()函数返回之前,已经取出的数据,不会在EventLoop()函数中产生返回事件。 EventLoop()函数的主要用途就是通知策略层,系统底层接收到了新的网络数据。以事件驱动整个策略。当EventLoop()函数返回事件时, 只需遍历所有数据来源。 EventLoop()函数仅支持实盘。 在主函数main()中调用时,监听主线程的事件。 在JavaScript语言编写的策略中,threading.Thread()函数创建的线程,在线程的执行函数中也可以调用,监听当前线程的事件。

{@fun/Global/Dial Dial}

__Serve

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

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

string

__Serve(serveURI, handler) __Serve(serveURI, handler, …args)

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=trueserveURI参数用于Https例如:https://127.0.0.1:6666?tls=true&gzip=true;可以加入cert_pemcert_key_pem参数来加载证书。

serveURI true string handler参数用于传入路由处理函数(Http协议)、消息处理函数(TCP协议)、Stream处理函数(Websocket)。 参数handler传入的回调函数可以定义多个参数,第一个参数为ctx对象(上下文对象)。

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

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

调用__Serve()函数时传入的参数1, 2, 3对应传入回调函数的参数a, b, c

arg false string、number、bool、object、array、function、空值等系统支持的所有类型

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)
    }
}
# 不支持
// 不支持
  • 该函数仅支持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协议,可以使用该方法将编码后的字符串传递给客户端。

{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}

_G

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

持久化保存的k-v键值对中的键值数据。 string、number、bool、object、array、空值

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

参数k为保存的键值对中的键名,不区分大小写。 k false string、空值 参数v为保存的键值对中的键值,可以是任何可以JSON序列化的数据。 v false string、number、bool、object、array、空值

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
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()
}
def main():
    _G("num", 1)     
    _G("num", "ok")    
    _G("num", None)
    Log(_G("num"))
    _G(None)
    robotId = _G()
void main() {
    _G("num", 1);
    _G("num", "ok");
    _G("num", NULL);
    Log(_G("num"));
    _G(NULL);
    // 不支持 auto robotId = _G();
}

每个实盘单独一个数据库,策略重启或者托管者停止运行,_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键值对。

{@fun/Global/DBExec DBExec}

_D

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

时间字符串。 string

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

毫秒时间戳或者Date对象。 timestamp false number、object 格式化字符串,默认格式:yyyy-MM-dd hh:mm:ss。 fmt false string

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main(){
    var time = _D()
    Log(time)
}
def main():
    strTime = _D()
    Log(strTime)
void main() {
    auto strTime = _D();
    Log(strTime);
}

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

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main() {
    Log(_D(1574993606000))
}
def main():
    # 北京时间的服务器上运行:2019-11-29 10:13:26 ,另一台其它地区的服务器上的托管者运行此代码结果则为:2019-11-29 02:13:26
    Log(_D(1574993606))
void main() {
    Log(_D(1574993606000));
}

时间戳为1574993606000,使用代码转换:

function main() {
    Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss"))   // 2019--11--29 10--13--26
}
def main():
    # 1574993606为秒级别时间戳
    Log(_D(1574993606, "%Y--%m--%d %H--%M--%S"))        #  2019--11--29 10--13--26
void main() {
    Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S"));    // 2019--11--29 10--13--26
}

使用参数fmt格式化,JavaScriptPythonC++语言的格式化字符串有所不同,具体参看以下例子:

不传任何参数就返回当前时间字符串。 Python策略中使用_D()函数时,需要注意传入的参数为秒级别时间戳(JavaScript、C++策略中为毫秒级别时间戳,1秒等于1000毫秒)。 在实盘时使用_D()函数解析一个时间戳为可读的时间字符串时,需要注意托管者程序所在的操作系统的时区、时间设置。 _D()函数解析一个时间戳为可读时间字符串是根据托管者系统的时间而定的。

{@fun/Global/UnixNano UnixNano}, {@fun/Global/Unix Unix}

_N

格式化一个浮点数。

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

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

需要格式化的浮点数。 num true number 格式化的精度设置,参数precision为整数,参数precision默认为4。 precision false number

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main() {
    var i = 3.1415
    Log(i)
    var ii = _N(i, 2)
    Log(ii)
}
def main():
    i = 3.1415
    Log(i)
    ii = _N(i, 2)
    Log(ii)
void main() {
    auto i = 3.1415;
    Log(i);
    auto ii = _N(i, 2);
    Log(ii);
}

例如_N(3.1415, 2)将删除3.1415小数点两位以后的值,函数返回3.14

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main() {
    var i = 1300
    Log(i)
    var ii = _N(i, -3)
    // 查看日志得知为1000
    Log(ii)
}
def main():
    i = 1300
    Log(i)
    ii = _N(i, -3)
    Log(ii)
void main() {
    auto i = 1300;
    Log(i);
    auto ii = _N(i, -3);
    Log(ii);
}

如果需要将小数点左边的N个位数都变为0,可以这么写:

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

{@fun/Trade/exchange.SetPrecision exchange.SetPrecision}

_C

重试函数,用于接口容错。

回调函数执行时的返回值。 除了逻辑假值空值以外系统支持的所有类型。

_C(pfn) _C(pfn, …args)

参数pfn为函数引用,是一个回调函数。 pfn true function 回调函数的参数,参数arg可能有多个。参数arg的类型与个数根据回调函数的参数而定。 arg false string、number、bool、object、array、function、空值等系统支持的所有类型

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    
    // 测试代码部分
    // 设置合约为rb888即螺纹钢主力连续合约,或者设置股票代码
    exchange.SetContractType("rb888")
    
    var ticker = _C(exchange.GetTicker)
    // 调整_C()函数重试时间间隔为2秒
    _CDelay(2000)
    var depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
        
    exchange.SetContractType("rb888")
    
    ticker = _C(exchange.GetTicker)
    _CDelay(2000)
    depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    exchange.SetContractType("rb888");
    
    auto ticker = _C(exchange.GetTicker);
    _CDelay(2000);
    auto depth = _C(exchange.GetDepth);
    Log(ticker);
    Log(depth);
}

对于无参数的函数容错:

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    
    // 测试代码部分
    // 设置合约为rb888即螺纹钢主力连续合约,或者设置股票代码
    exchange.SetContractType("rb888")
    
    var records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    exchange.SetContractType("rb888")
    
    records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    exchange.SetContractType("rb888");
    
    auto records = _C(exchange.GetRecords, PERIOD_D1);
    Log(records);
}

对于有参数的函数容错:

var test = function(a, b){
    var time = new Date().getTime() / 1000
    if(time % b == 3){
        Log("符合条件!", "#FF0000")
        return true
    }
    Log("重试!", "#FF0000")
    return false
}

function main(){
    // 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试自定义的函数
    var ret = _C(test, 1, 5)
    Log(ret)
}
import time
def test(a, b):
    ts = time.time()
    if ts % b == 3:
        Log("符合条件!", "#FF0000")
        return True
    Log("重试!", "#FF0000")
    return False

def main():
    ret = _C(test, 1, 5)
    Log(ret)
// C++ 不支持这种方式对于自定义函数容错

也可以用于自定义函数的容错处理:

_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())

_Cross

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

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

_Cross(arr1, arr2)

元素为number类型的数组。 arr1 true array 元素为number类型的数组。 arr2 true array

// 快线指标
var arr1 = [1,2,3,4,5,6,8,8,9]
// 慢线指标
var arr2 = [2,3,4,5,6,7,7,7,7]

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main(){
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
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))
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));
}

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

_Cross()函数的返回值是正数表示上穿的周期,负数表示下穿的周期,0指当前价格一样。 具体使用说明:内置函数_Cross分析及使用说明

JSONParse

函数JSONParse()用于解析JSON字符串。

JSON对象。 object

JSONParse(s)

JSON字符串。 s true string

// 不使用接口获取数据的测试,就无需使用exchange.IO("status")函数判断连接状态,也不用设置合约代码,因为这里仅仅是测试
function main() {
    let s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("JSON.parse:", JSON.parse(s1))    // JSON.parse: {"num":8.754613216564988e+39}
    Log("JSONParse:", JSONParse(s1))      // JSONParse:  {"num":"8754613216564987646512354656874651651358"}
    
    let s2 = '{"num": 123}'
    Log("JSON.parse:", JSON.parse(s2))    // JSON.parse: {"num":123}
    Log("JSONParse:", JSONParse(s2))      // JSONParse:  {"num":123}
}
import json

def main():
    s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("json.loads:", json.loads(s1))    # json.loads: map[num:8.754613216564987e+39]
    Log("JSONParse:", JSONParse(s1))      # JSONParse:  map[num:8754613216564987646512354656874651651358]
    
    s2 = '{"num": 123}'
    Log("json.loads:", json.loads(s2))    # json.loads: map[num:123]
    Log("JSONParse:", JSONParse(s2))      # JSONParse:  map[num:123]
void main() {
    auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
    Log("json::parse:", json::parse(s1));
    // Log("JSONParse:", JSONParse(s1));   // 不支持该函数
    
    auto s2 = "{\"num\":123}";
    Log("json::parse:", json::parse(s2));
    // Log("JSONParse:", JSONParse(s2));   // 不支持该函数
}

可以正确解析包含有较大数值的JSON字符串,会将较大的数值解析为字符串类型。 回测系统中不支持JSONParse()函数。

Log

Log

输出日志。

Log(…msgs)

参数msg为输出的内容,参数msg可以传多个。 msg false string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    Log("msg1", "msg2", "msg3")
}
def main():
    Log("msg1", "msg2", "msg3")
void main() {
    Log("msg1", "msg2", "msg3");
}

可以传多个msg参数:

function main() {
    Log("优宽量化你好 !@")
    Sleep(1000 * 5)
    // 字符串内加入#ff0000,打印日志显示为红色,并且推送消息
    Log("你好, #ff0000@")
}
def main():
    Log("优宽量化你好 !@")
    Sleep(1000 * 5)
    Log("你好, #ff0000@")
void main() {
    Log("优宽量化你好 !@");
    Sleep(1000 * 5);
    Log("你好, #ff0000@");
}

支持设置输出消息的颜色,如果设置颜色和推送同时使用,需要先设置颜色,最后使用@字符设置推送。

function main() {
    Log("`data:image/png;base64,AAAA`")
}
def main():
    Log("`data:image/png;base64,AAAA`")
void main() {
    Log("`data:image/png;base64,AAAA`");
}

Log()函数支持打印base64编码后的图片,以`开头,以`结尾,例如:

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

Log()函数支持直接打印Pythonmatplotlib.pyplot对象, 只要对象包含savefig方法就可以直接使用Log函数打印,例如:

function main() {
    Log("[trans]中文|abc[/trans]")
}
def main():
    Log("[trans]中文|abc[/trans]")
void main() {
    Log("[trans]中文|abc[/trans]");
}

Log()函数支持语言切换,Log()函数输出文本,会根据平台页面上语言设置自动切换为对应的语言,例如:

Log()函数在实盘或者回测系统的日志区域输出一条日志信息,实盘运行时日志会保存在实盘的数据库中。 Log()函数输出的内容以@字符结尾则这条日志会进入消息推送队列。 推送到当前优宽量化交易平台账号推送设置中配置的邮箱、WebHook地址等。 调试工具、回测系统不支持消息推送。 消息推送有频率限制,具体限制规则如下:在一个实盘20秒周期内,只有最后一条推送消息会被保留并进行推送,其它消息将被过滤,不进行推送(通过 Log 函数输出的推送日志会正常打印显示在日志区域)。 关于WebHook推送,可以使用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_youquant, 运行写好的Golang服务程序后,开始实盘运行策略,以下为JavaScript语言编写的策略,策略运行时执行Log()函数并推送消息:

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

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

listen http://localhost:9090
req: {GET /data?data=Hello_youquant 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_youquant <nil> <nil> <nil> 0xc420056300

{@fun/Log/LogReset LogReset}, {@fun/Log/LogVacuum LogVacuum}

LogProfit

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

LogProfit(profit) LogProfit(profit, …args)

参数profit为收益数据,该数据由策略中设计算法、计算给出。 profit true number 扩展参数,可以输出附带信息到这条收益日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    // 在收益图表上打印30个点
    for(var i = 0; i < 30; i++) {
        LogProfit(i, '&')
        Sleep(500)
    }
}
def main():
    for i in range(30):
        LogProfit(i, '&')
        Sleep(500)
void main() {
    for(int i = 0; i < 30; i++) {
        LogProfit(i, '&');
        Sleep(500);
    }
}

LogProfit函数如果以字符&结尾,只绘制收益图表,不打印收益日志。例如:

{@fun/Log/LogProfitReset LogProfitReset}

LogProfitReset

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

LogProfitReset() LogProfitReset(remain)

remain参数用于指定保留的日志条数(整数值)。 remain false number

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

在收益图表上打印30个点,然后重置,只保留最后10个点。

{@fun/Log/LogProfit LogProfit}

LogStatus

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

LogStatus(…msgs)

参数msg为输出的内容,参数msg可以传多个。 msg false string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
}
def main():
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
void main() {
    LogStatus("这是一个普通的状态提示");
    LogStatus("这是一个红色字体的状态提示#ff0000");
    LogStatus("这是一个多行的状态信息\n我是第二行");
}

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

function main() {
    var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    // JSON序列化后两边加上`字符,视为一个复杂消息格式(当前支持表格)
    LogStatus('`' + JSON.stringify(table) + '`')                    
    // 表格信息也可以在多行中出现
    LogStatus('第一行消息\n`' + JSON.stringify(table) + '`\n第三行消息')
    // 支持多个表格同时显示,将以TAB显示到一组里
    LogStatus('`' + JSON.stringify([table, table]) + '`')
    
    // 也可以构造一个按钮在表格中,策略用GetCommand接收cmd属性的内容                                
    var table = { 
        type: 'table', 
        title: '持仓操作', 
        cols: ['列1', '列2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
        ]
    }
    LogStatus('`' + JSON.stringify(table) + '`') 
    // 或者构造一单独的按钮
    LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': '平仓'}) + '`') 
    // 可以自定义按钮风格(bootstrap的按钮属性)
    LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': '平仓'}) + '`')
}
import json
def main():
    table = {"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('第一行消息\n`' + json.dumps(table) + '`\n第三行消息')
    LogStatus('`' + json.dumps([table, table]) + '`')            

    table = {
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    }
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "平仓"}) + '`')
    LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"}) + '`')
void main() {
    json table = R"({"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("第一行消息\n`" + table.dump() + "`\n第三行消息");
    json arr = R"([])"_json;
    arr.push_back(table);
    arr.push_back(table);
    LogStatus("`" + arr.dump() + "`");            

    table = R"({
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    })"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
    LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
}

状态栏中数据输出示例:

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮样式",
        cols: ["默认", "原始", "成功", "信息", "警告", "危险"], 
        rows: [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    })"_json;
    LogStatus("`" + table.dump() + "`");
}

支持状态栏中设计按钮控件(旧版按钮结构):

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮的禁用、描述功能测试",
        cols: ["列1", "列2", "列3"], 
        rows: []
    }
    var button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    var button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true}
    var button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": false}
    table.rows.push([button1, button2, button3])
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    }
    button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": True}
    button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": False}
    table["rows"].append([button1, button2, button3])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    })"_json;
    json button1 = R"({"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"})"_json;
    json button2 = R"({"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true})"_json;
    json button3 = R"({"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "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() + "`");
}

设置状态栏按钮的禁用、描述功能(旧版按钮结构):

function test1() {
    Log("调用自定义函数")
}            

function main() {
    while (true) {
        var table = {
            type: 'table',
            title: '操作',
            cols: ['列1', '列2', 'Action'],
            rows: [
                ['a', '1', {
                    'type': 'button',                       
                    'cmd': "CoverAll",                      
                    'name': '平仓'                           
                }],
                ['b', '1', {
                    'type': 'button',
                    'cmd': 10,                              
                    'name': '发送数值'
                }],
                ['c', '1', {
                    'type': 'button',
                    'cmd': _D(),                          
                    'name': '调用函数'
                }],
                ['d', '1', {
                    'type': 'button',
                    'cmd': 'test1',       
                    'name': '调用自定义函数'
                }]
            ]
        }
        LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')            

        var str_cmd = GetCommand()
        if (str_cmd) {
            Log("接收到的交互数据 str_cmd:", "类型:", typeof(str_cmd), "值:", str_cmd)
            if(str_cmd == "test1") {
                test1()
            }
        }            

        Sleep(500)
    }
}
import json
def test1():
    Log("调用自定义函数")            

def main():
    while True:
        table = {
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": _D(),
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        }            

        LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
        str_cmd = GetCommand()
        if str_cmd:
            Log("接收到的交互数据 str_cmd", "类型:", type(str_cmd), "值:", str_cmd)
            if str_cmd == "test1":
                test1()
        Sleep(500)
void test1() {
    Log("调用自定义函数");
}            

void main() {
    while(true) {
        json table = R"({
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": "",
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        })"_json;
        table["rows"][2][2]["cmd"] = _D();
        LogStatus(_D(), "\n", "`" + table.dump() + "`");
        auto str_cmd = GetCommand();
        if(str_cmd != "") {
            Log("接收到的交互数据 str_cmd", "类型:", typeid(str_cmd).name(), "值:", str_cmd);
            if(str_cmd == "test1") {
                test1();
            }
        }
        Sleep(500);
    }
}

结合GetCommand()函数,构造状态栏按钮交互功能(旧版按钮结构):

function main() {
    var tbl = {
        type: "table",
        title: "操作",
        cols: ["列1", "列2"],
        rows: [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ] 
    }            

    LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)
        }
        Sleep(1000)
    }
}
import json            

def main():
    tbl = {
        "type": "table", 
        "title": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    }            

    LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
    while True:
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
        Sleep(1000)
void main() {
    json tbl = R"({
        "type": "table", 
        "title": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    })"_json;            

    LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
    while(true) {
        auto cmd = GetCommand();
        if(cmd != "") {
            Log("cmd:", cmd);
        }
        Sleep(1000);
    }
}

在构造状态栏按钮进行交互时也支持输入数据,交互指令最终由GetCommand()函数捕获。 给状态栏中的按钮控件的数据结构中增加input项(旧版按钮结构),例如给{"type": "button", "cmd": "open", "name": "开仓"}增加: "input": {"name": "开仓数量", "type": "number", "defValue": 1}, 就可以使按钮在被点击时弹出一个带输入框控件的弹窗(输入框中默认值为1,即defValue设置的数据), 可以输入一个数据和按钮命令一起发送。例如以下测试代码运行时,在点击「开仓」按钮后,弹出一个带输入框的弹窗, 在输入框中输入111后点击「确定」。GetCommand()函数就会捕获消息:open:111

function main() {
    var tbl = {
        type: "table",
        title: "演示分组按钮控件",
        cols: ["操作"],
        rows: []
    }

    // 创建分组按钮控件结构
    var groupBtn = {
        type: "button",
        cmd: "open",
        name: "开仓",
        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": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    var testBtn2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}

    // 在tbl中添加groupBtn
    tbl.rows.push([groupBtn])
    // 支持状态栏表格的一个单元格内设置多个按钮,即一个单元格内的数据为一个按钮结构数组:[testBtn1, testBtn2]
    tbl.rows.push([[testBtn1, testBtn2]])

    while (true) {
        LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + JSON.stringify(groupBtn) + "`")
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)
        }
        Sleep(5000)
    }
}
import json

def main():
    tbl = {
        "type": "table",
        "title": "演示分组按钮控件",
        "cols": ["操作"],
        "rows": []
    }

    groupBtn = {
        "type": "button",
        "cmd": "open",
        "name": "开仓",
        "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": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    testBtn2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}

    tbl["rows"].append([groupBtn])
    tbl["rows"].append([[testBtn1, testBtn2]])

    while True:
        LogStatus("`" + json.dumps(tbl) + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + json.dumps(groupBtn) + "`")
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
        Sleep(5000)
void main() {
    json tbl = R"({
        "type": "table", 
        "title": "演示分组按钮控件", 
        "cols": ["操作"],
        "rows": []
    })"_json;

    json groupBtn = R"({
        "type": "button", 
        "name": "开仓", 
        "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": "按钮1", "cmd": "button1", "description": "这是第一个按钮"})"_json;
    json testBtn2 = R"({"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮", "input": {"name": "开仓数量", "type": "number", "defValue": 1}})"_json;
    
    tbl["rows"].push_back({groupBtn});
    tbl["rows"].push_back({{testBtn1, testBtn2}});
    
    while(true) {
        LogStatus("`" + tbl.dump() + "`", "\n", "分组按钮控件除了设置在状态栏表格中,也可以直接设置在状态栏上:", "`" + groupBtn.dump() + "`");
        auto cmd = GetCommand();
        if(cmd != "") {
            Log("cmd:", cmd);
        }
        Sleep(5000);
    }
}

支持分组按钮控件(旧版按钮结构),功能与支持输入数据的状态栏按钮(使用"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属性支持多种控件类型。 参考以下例子:
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: "实现下拉框多选", 
            options: [{text: "选项A", value: "A"}, {text: "选项B", value: "B"}, {text: "选项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: "下拉框1", type: "selected", defValue: 1, options: ["A", "B"]}, 
            {name: "comboBox2", label: "labelComboBox2", description: "下拉框2", type: "selected", defValue: "A|B"}, 
            {name: "comboBox3", label: "labelComboBox3", description: "下拉框3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]}, 
            {
                name: "comboBox4", 
                label: "labelComboBox4", 
                description: "下拉框4", 
                type: "selected", 
                defValue: ["A", "C"], 
                multiple: true, 
                options: [{text: "选项A", value: "A"}, {text: "选项B", value: "B"}, {text: "选项C", value: "C"}, {text: "选项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)
    }
}
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": "实现下拉框多选", 
            "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}],
            "defValue": ["A", "C"],
            "multiple": True
        }
    }

    testBtn3 = {
        "type": "button",                     
        "name": "testBtn3",
        "cmd": "cmdTestBtn3", 
        "group": [
            {"name": "comboBox1", "label": "labelComboBox1", "description": "下拉框1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, 
            {"name": "comboBox2", "label": "labelComboBox2", "description": "下拉框2", "type": "selected", "defValue": "A|B"}, 
            {"name": "comboBox3", "label": "labelComboBox3", "description": "下拉框3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]}, 
            {
                "name": "comboBox4", 
                "label": "labelComboBox4", 
                "description": "下拉框4", 
                "type": "selected", 
                "defValue": ["A", "C"], 
                "multiple": True, 
                "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}, {"text": "选项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)
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": "实现下拉框多选", 
            "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}],
            "defValue": ["A", "C"],
            "multiple": true
        }
    })"_json;
    
    json testBtn3 = R"({
        "type": "button",                     
        "name": "testBtn3",
        "cmd": "cmdTestBtn3", 
        "group": [
            {"name": "comboBox1", "label": "labelComboBox1", "description": "下拉框1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, 
            {"name": "comboBox2", "label": "labelComboBox2", "description": "下拉框2", "type": "selected", "defValue": "A|B"}, 
            {"name": "comboBox3", "label": "labelComboBox3", "description": "下拉框3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]}, 
            {
                "name": "comboBox4", 
                "label": "labelComboBox4", 
                "description": "下拉框4", 
                "type": "selected", 
                "defValue": ["A", "C"], 
                "multiple": true, 
                "options": [{"text": "选项A", "value": "A"}, {"text": "选项B", "value": "B"}, {"text": "选项C", "value": "C"}, {"text": "选项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);
    }
}

状态栏分组按钮控件(设置group字段实现)与状态栏按钮控件(设置input字段实现)被点击触发交互时(旧版按钮结构),页面弹出的对话框中的下拉框控件也支持多选,以下例子演示如何设计包含多选选项的下拉框控件:

var symbols = ["rb2410", "MA501", "hc2501", "i2501", "TA888"]

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": "开仓下单",
        "group": [{
            "type": "selected",
            "name": "tradeType",
            "label": "下单类型",
            "description": "市价单、限价单",
            "default": 0,
            "group": "交易设置",
            "settings": {
                "options": ["市价单", "限价单"],
                "required": true,
            }
        }, {
            "type": "selected",
            "name": "direction",
            "label": "交易方向",
            "description": "买入、卖出",
            "default": "buy",
            "group": "交易设置",
            "settings": {
                "render": "segment",
                "required": true,
                "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
            }
        }, {
            "type": "number",
            "name": "price",
            "label": "价格",
            "description": "订单的价格",
            "group": "交易设置",
            "filter": "tradeType==1",
            "settings": {
                "required": true,
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "下单量",
            "description": "订单的下单量",
            "group": "交易设置",
            "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": "交易品种", "default": m["symbol"], "settings": {"required": true}}])
            tbl["rows"].push([m["symbol"], btnOpen])
        })

        var cmd = GetCommand()
        if (cmd) {
            Log("收到交互:", 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("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", msg["tradeType"] == 0 ? "市价单" : "限价单", msg["tradeType"] == 0 ? ",订单价格:当前市价" : ",订单价格:" + msg["price"], ",订单数量:", msg["amount"])
            }
        }

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}
import json

symbols = ["rb2410", "MA501", "hc2501", "i2501", "TA888"]

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": "开仓下单",
        "group": [{
            "type": "selected",
            "name": "tradeType",
            "label": "下单类型",
            "description": "市价单、限价单",
            "default": 0,
            "group": "交易设置",
            "settings": {
                "options": ["市价单", "限价单"],
                "required": True,
            }
        }, {
            "type": "selected",
            "name": "direction",
            "label": "交易方向",
            "description": "买入、卖出",
            "default": "buy",
            "group": "交易设置",
            "settings": {
                "render": "segment",
                "required": True,
                "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
            }
        }, {
            "type": "number",
            "name": "price",
            "label": "价格",
            "description": "订单的价格",
            "group": "交易设置",
            "filter": "tradeType==1",
            "settings": {
                "required": True,
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "下单量",
            "description": "订单的下单量",
            "group": "交易设置",
            "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": "交易品种", "default": m["symbol"], "settings": {"required": True}}])
            tbl["rows"].append([m["symbol"], btnOpen])

        cmd = GetCommand()

        if cmd != "" and cmd != None:
            Log("收到交互:", 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("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", "市价单" if msg["tradeType"] == 0 else "限价单", ",订单价格:当前市价" if msg["tradeType"] == 0 else ",订单价格:" + str(msg["price"]), ",订单数量:", msg["amount"])
        
        # 输出状态栏信息
        LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
        Sleep(1000)
// 略...

使用当前最新的按钮结构,构造状态栏表格中的按钮,点击按钮触发交互时弹出一个多控件弹窗。 详细内容可以参考:用户指南-状态栏中的交互控件

function main() {
    var table = { 
        type: 'table', 
        title: '持仓操作', 
        cols: ['列1', '列2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
        ]
    }
    
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    exchange.SetContractType("rb888")

    var ticker = exchange.GetTicker()
    // 添加一行数据,第一个和第二个单元格合并,并且输出ticker变量在合并后的单元格内
    table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"])    
    LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
    table = {
        "type" : "table",
        "title" : "持仓操作",
        "cols" : ["列1", "列2", "Action"],
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ]
    }
    
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    
    ticker = exchange.GetTicker()
    table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type" : "table",
        "title" : "持仓操作",
        "cols" : ["列1", "列2", "Action"],
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ]
    })"_json;            
    
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    
    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()函数画出的表格内的单元格:

function main() {
    var table = { 
        type: 'table', 
        title: '表格演示', 
        cols: ['列A', '列B', '列C'], 
        rows: [ 
            ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}]
        ]
    }

    // 鉴于测试代码,不使用商品期货策略一般架构
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    exchange.SetContractType("rb888")
    
    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) + '`')
}
import json
def main():
    table = {
        "type" : "table", 
        "title" : "表格演示", 
        "cols" : ["列A", "列B", "列C"], 
        "rows" : [
            ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
        ]
    }
    
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    
    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) + "`")
void main() {
    json table = R"({
        "type" : "table", 
        "title" : "表格演示", 
        "cols" : ["列A", "列B", "列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() + "`");
}

纵向合并LogStatus()函数画出的表格内的单元格:

function main() {
    var table1 = {type: 'table', title: 'table1', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    var table2 = {type: 'table', title: 'table2', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    LogStatus('`' + JSON.stringify([table1, table2]) + '`')
}
import json
def main():
    table1 = {"type": "table", "title": "table1", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    table2 = {"type": "table", "title": "table2", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus("`" + json.dumps([table1, table2]) + "`")
void main() {
    json table1 = R"({"type": "table", "title": "table1", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json table2 = R"({"type": "table", "title": "table2", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json arr = R"([])"_json;
    arr.push_back(table1);
    arr.push_back(table2);
    LogStatus("`" + arr.dump() + "`");
}

状态栏表格分页显示:

function main(){
    var tab1 = {
        type : "table",
        title : "表格1",
        cols : ["1", "2"],
        rows : []
    }
    var tab2 = {
        type : "table",
        title : "表格2",
        cols : ["1", "2", "3"],
        rows : []
    }
    var tab3 = {
        type : "table",
        title : "表格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")
}
import json
def main():
    tab1 = {
        "type": "table", 
        "title": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    }
    tab2 = {
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    }
    tab3 = {
        "type": "table", 
        "title": "表格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) + "`")
void main() {
    json tab1 = R"({
        "type": "table", 
        "title": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    })"_json;
    json tab2 = R"({
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    })"_json;
    json tab3 = R"({
        "type": "table", 
        "title": "表格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() + "`");
}

除了可以分页显示表格,也可以多个表格自上而下排列显示:

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) + "`")
}
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) + "`")
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() + "`");
}

支持设置状态栏表格横向、纵向滚动模式。设置scroll属性为"auto",当状态栏表格纵向的行数超过20行时内容进行滚动显示, 当横向的列数超出页面显示范围时进行横向滚动显示,使用scroll属性可以缓解实盘时状态栏中大量写入数据的卡顿问题。参考以下测试例子:

实盘运行时LogStatus()函数输出的信息不保存到实盘数据库,只更新当前实盘的状态栏内容。 LogStatus()函数支持打印base64编码后的图片,以`开头,以`结尾。例如: LogStatus("`data:image/png;base64,AAAA`")LogStatus()函数支持直接传入Pythonmatplotlib.pyplot对象,只要对象包含savefig方法就可以作为参数传入LogStatus()函数,例如:

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

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

{@fun/Global/GetCommand GetCommand}

EnableLog

打开或者关闭订单信息的日志记录。

EnableLog(enable)

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

function main() {
    EnableLog(false)
}
def main():
    EnableLog(False)
void main() {
    EnableLog(false);
}

关闭订单信息的日志记录。

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.CancelOrder exchange.CancelOrder}

Chart

自定义图表画图函数。

图表对象。 object

Chart(options)

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

function main() {
    var cfgA = {
        extension: {
            layout: 'single', // 不参于分组,单独显示, 默认为分组 'group'
            height: 300, // 指定高度
        },
        title: {
            text: '盘口图表'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: '买一',
            data: [],
        }, {
            name: '卖一',
            data: [],
        }]
    }
    var cfgB = {
        title: {
            text: '差价图'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: '差价',
            type: 'column',
            data: [],
        }]
    }            

    var cfgC = {
        __isStock: false,
        title: {
            text: '饼图'
        },
        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: '盘口图表'
        },
        xAxis: {
            type: 'datetime'
        },
        series: [{
            name: '买一',
            data: [],
        }, {
            name: '卖一',
            data: [],
        }]
    }
    var cfgE = {
        __isStock: false,
        extension: {
            layout: 'single',
            col: 4,
            height: '300px',
        },
        title: {
            text: '饼图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)
        exchange.SetContractType("rb888")
        var ticker = exchange.GetTicker()
        if (!ticker) {
            continue;
        }
        var diff = ticker.Sell - ticker.Buy
        cfgA.subtitle = {
            text: '买一 ' + ticker.Buy + ', 卖一 ' + ticker.Sell,
        };
        cfgB.subtitle = {
            text: '价差 ' + 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]);
    }
}            
import random
import time
def main():
    cfgA = {
        "extension" : {
            "layout" : "single", 
            "height" : 300,
            "col" : 8
        }, 
        "title" : {
            "text" : "盘口图表"
        },
        "xAxis" : {
            "type" : "datetime" 
        }, 
        "series" : [{
            "name" : "买一",
            "data" : []
        }, {
            "name" : "卖一", 
            "data" : []
        }]
    }                

    cfgB = {
        "title" : {
            "text" : "差价图"
        }, 
        "xAxis" : {
            "type" : "datetime",
        }, 
        "series" : [{
            "name" : "差价", 
            "type" : "column", 
            "data" : []
        }]
    }                

    cfgC = {
        "__isStock" : False,
        "title" : {
            "text" : "饼图"
        }, 
        "series" : [{
            "type" : "pie", 
            "name" : "one", 
            "data" : [
                ["A", 25],
                ["B", 25],
                ["C", 25],
                ["D", 25],
            ]
        }]
    }                

    cfgD = {
        "extension" : {
            "layout" : "single",
            "col" : 8,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "盘口图表"
        }, 
        "series" : [{
            "name" : "买一", 
            "data" : []
        }, {
            "name" : "卖一",
            "data" : []
        }]
    }                

    cfgE = {
        "__isStock" : False, 
        "extension" : {
            "layout" : "single", 
            "col" : 4,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "饼图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)
        exchange.SetContractType("rb888")
        ticker = exchange.GetTicker()
        if not ticker :
            continue
        diff = ticker["Sell"] - ticker["Buy"]
        cfgA["subtitle"] = {
            "text" : "买一" + str(ticker["Buy"]) + "卖一" + str(ticker["Sell"])
        }
        cfgB["subtitle"] = {
            "text" : "价差 " + 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
void main() {
    json cfgA = R"({
        "extension" : {
            "layout" : "single", 
            "height" : 300,
            "col" : 8
        }, 
        "title" : {
            "text" : "盘口图表"
        },
        "xAxis" : {
            "type" : "datetime" 
        }, 
        "series" : [{
            "name" : "买一",
            "data" : []
        }, {
            "name" : "卖一", 
            "data" : []
        }]
    })"_json;                

    json cfgB = R"({
        "title" : {
            "text" : "差价图"
        }, 
        "xAxis" : {
            "type" : "datetime"
        }, 
        "series" : [{
            "name" : "差价", 
            "type" : "column", 
            "data" : []
        }]
    })"_json;    
    
    json cfgC = R"({
        "__isStock" : false,
        "title" : {
            "text" : "饼图"
        }, 
        "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" : "盘口图表"
        }, 
        "series" : [{
            "name" : "买一", 
            "data" : []
        }, {
            "name" : "卖一",
            "data" : []
        }]
    })"_json;    
    
    json cfgE = R"({
        "__isStock" : false, 
        "extension" : {
            "layout" : "single", 
            "col" : 4,
            "height" : "300px"
        }, 
        "title" : {
            "text" : "饼图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);
        exchange.SetContractType("rb888");
        auto ticker = exchange.GetTicker();
        if(!ticker.Valid) {
            continue;
        }
        auto diff = ticker.Sell - ticker.Buy;
        json cfgASubTitle = R"({"text" : ""})"_json;
        cfgASubTitle["text"] = format("买一 %f , 卖一 %f", ticker.Buy, ticker.Sell);
        cfgA["subtitle"] = cfgASubTitle;
        
        json cfgBSubTitle = R"({"text" : ""})"_json;
        cfgBSubTitle["text"] = 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});
    }
}

多图表画图配置:

  • extension.layout属性 如果设置此属性,值为"single",则图表不会叠加(不会以分页标签方式显示),会单独显示(平铺显示)。
  • extension.height属性 此属性用于设置图表的高度,值可以为数值类型,或以"300px"方式设置。
  • extension.col属性 此属性用于设置图表的宽度,页面宽度一共划分为12个单元,设置8即该图表占用8个单元宽度。
// 这个chart在JavaScript语言中是对象,在使用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 : "线1,buy1Price", data : []},                          
        // 索引为1,设置了dashStyle:'shortdash'即:设置虚线
        {name : "line2", id : "线2,lastPrice", dashStyle : 'shortdash', data : []}  
    ]
}
function main(){
    // 调用Chart函数,初始化图表
    var ObjChart = Chart(chart)         
    // 清空
    ObjChart.reset()                      
    while(true){
        // 判断连接期货公司前置机是否成功。股票证券无需使用exchange.IO("status")判断连接状态
        if (!exchange.IO("status")) {
            Sleep(1000)
            continue
        }
        exchange.SetContractType("rb888")

        // 获取本次轮询的时间戳,即一个毫秒的时间戳。用来确定写入到图表的X轴的位置
        var nowTime = new Date().getTime()
        // 获取行情数据
        var ticker = _C(exchange.GetTicker)
        // 从行情数据的返回值取得买一价
        var buy1Price = ticker.Buy    
        // 取得最后成交价,为了2条线不重合在一起,我们加1
        var lastPrice = ticker.Last + 1
        // 用时间戳作为X值,买一价作为Y值传入索引0的数据序列
        ObjChart.add(0, [nowTime, buy1Price])
        // 同上
        ObjChart.add(1, [nowTime, lastPrice])
        Sleep(2000)
    }
}
import time
chart = {
    "__isStock" : True,
    "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},  
    "title" : {"text" : "差价分析图"}, 
    "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": "差价"},
        "opposite": False
    },
    "series": [{
        "name": "line1", "id": "线1,buy1Price", "data": []
    }, {
        "name": "line2", "id": "线2,lastPrice", "dashStyle": "shortdash", "data": []
    }]
}
def main():
    ObjChart = Chart(chart)
    ObjChart.reset()
    while True:
        if not exchange.IO("status"):
            Sleep(1000)
            continue
        exchange.SetContractType("rb888")
        
        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)
void main() {
    // C++编写策略时,尽量不要声明非基础类型的全局变量,所以图表配置对象声明在main函数内
    json chart = R"({
        "__isStock" : true,
        "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"},  
        "title" : {"text" : "差价分析图"}, 
        "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": "差价"},
            "opposite": false
        },
        "series": [{
            "name": "line1", "id": "线1,buy1Price", "data": []
        }, {
            "name": "line2", "id": "线2,lastPrice", "dashStyle": "shortdash", "data": []
        }]
    })"_json;
    auto ObjChart = Chart(chart);
    ObjChart.reset();
    while(true) {
        if (exchange.IO("status") == 0) {
            Sleep(1000);
            continue;
        }
        exchange.SetContractType("rb888");
        
        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);
    }
}

简单的画图例子:

// 用于初始化图表的对象
var chart = {                                   
    // 图表标题
    title: {text: "line数值触发 plotLines 值"},   
    // Y轴相关设置
    yAxis: {                                    
        // 垂直于Y轴的水平线,用作触发线,是一个结构数组,可以设置多条触发线
        plotLines: [{                           
            // 触发线的值,设置多少这条线就在相应的数值位置显示
            value: 0,                           
            // 设置触发线的颜色
            color: 'red',                       
            // 宽度
            width: 2,                           
            // 显示的标签
            label: {                            
                // 标签文本
                text: '触发值',                  
                // 标签位置居中
                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)     
    }
}
import math
import time
chart = {
    "title": {"text": "line数值触发 plotLines 值"}, 
    "yAxis": {
        "plotLines": [{
            "value": 0,
            "color": "red",
            "width": 2,
            "label": {
                "text": "触发值", 
                "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)
void main() {
    json chart = R"({
        "title": {"text": "line数值触发 plotLines 值"}, 
        "yAxis": {
            "plotLines": [{
                "value": 0,
                "color": "red",
                "width": 2,
                "label": {
                    "text": "触发值", 
                    "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);
    }
}

三角函数曲线画图例子:

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) {
        if (!exchange.IO("status")) {
            Sleep(1000)
            continue
        }
        exchange.SetContractType("rb888")

        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;
    }
}
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:
        if not exchange.IO("status"):
            Sleep(1000)
            continue
        exchange.SetContractType("rb888")

        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
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) {
        if (exchange.IO("status") != 0) {
            Sleep(1000);
            continue;
        }
        exchange.SetContractType("rb888");

        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;
    }
}            

使用混合图表的复杂例子:

// update pie
chartCfg.series[chartCfg.series.length-1].data = [
    ["A", Math.random()*100],
    ["B", Math.random()*100],
];
c.update(chartCfg)
# update pie
chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
    ["A", random.random() * 100], 
    ["B", random.random() * 100]
]
c.update(chartCfg)
// 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);

图表中pie类型的图是没有时间轴的图表,在更新数据时需要直接更新图表配置。 例如以上范例中的代码,更新数据后使用c.update(chartCfg)更新图表,如下所示:

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()方法用于清空图表数据,reset()方法可以带一个参数remain用于指定保留数据的条数。不传参数remain表示清除全部数据。

{@fun/Log/KLineChart KLineChart}

KLineChart

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

图表对象。 KLineChart()函数返回的图表对象有多个方法,其中需要注意begin()close(), 在K线数据上遍历执行画图操作,画图操作中必须以begin()函数调用作为起始,以close()函数调用作为结束。 object

KLineChart(options)

options参数为图表配置。 options true object、object数组

function main() {
    // 调用KLineChart函数创建图表控制对象c
    let c = KLineChart({
        overlay: true
    })

    while(true) {
        if (exchange.IO("status")) {
            break
        }
        Sleep(1000)
    }
    exchange.SetContractType("rb888")

    // 获取K线
    let bars = exchange.GetRecords()
    if (!bars) {
        return
    }

    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()
    })
}
def main():
    # 调用KLineChart函数创建图表控制对象c
    c = KLineChart({
        "overlay": True
    })

    while True:
        if exchange.IO("status"):
            break
        Sleep(1000)
    exchange.SetContractType("rb888")

    # 获取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()
// 暂不支持

如果在策略自定义画图区域画图必须有图表控制对象,使用KLineChart()函数创建该对象。 KLineChart()函数的参数为一个图表配置结构,在参考代码中使用的图表结构很简单:{overlay: true}。 这个图表配置结构仅仅设置了画图内容在图表主图上输出,如果overlay设置为假值,例如:false,则图表上的内容都输出在副图上, 如果需要指定某个画图函数在主图上画出也可以在具体函数调用中指定参数overlay为真值,例如:true

c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)')   // 使用本例中参考代码中的例子说明,不再赘述
c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
//  暂不支持

画图操作中支持的Pine语言的画图接口函数有: barcolor,设置K线颜色。

barcolor(color, offset, editable, show_last, title, display) display参数可选:“none”, “all”

c.bgcolor('rgba(0, 255, 0, 0.5)')
c.bgcolor('rgba(0, 255, 0, 0.5)')
// 暂不支持

bgcolor,用指定颜色填充K线的背景。

bgcolor(color, offset, editable, show_last, title, display, overlay) display参数可选:“none”, “all”

c.plot(bar.High, 'high')
c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"})  // 支持画不连续的数据线
h = c.plot(bar.High, 'high')
h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr")  # 支持画不连续的数据线
// 暂不支持

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”

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)'})
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)')
// 暂不支持

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'方式设置。

c.hline(bar.High)
c.hline(bar.High)
// 暂不支持

hline,在给定的固定价格水平上呈现水平线。

hline(price, title, color, linestyle, linewidth, editable, display) linestyle参数可选:“dashed”, “dotted”, “solid” display参数可选:“none”, “all”

c.plotarrow(bar.Close - bar.Open)
c.plotarrow(bar.Close - bar.Open)
// 暂不支持

plotarrow,在图表上绘制向上和向下箭头。

plotarrow(series, title, colorup, colordown, offset, minheight, maxheight, editable, show_last, display) display参数可选:“none”, “all”

c.plotshape(bar.Low, {style: 'diamond'})
c.plotshape(bar.Low, style = 'diamond')
// 暂不支持

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”

c.plotchar(bar.Close, {char: 'X'})
c.plotchar(bar.Close, char = 'X')
// 暂不支持

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”

c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
// 暂不支持

plotcandle,在图表上绘制K线图。

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

c.signal("long", bar.High, 1.5)
c.signal("long", bar.High, 1.5)
// 暂不支持

signal,Pine语言上没有的函数,这里用来画买卖信号。

signal(direction, price, qty, id) 传入的参数"long"表示交易方向,可选"long"、“closelong”、“short”、“closeshort”。传入的参数bar.High为标记信号的Y轴位置。 传入的参数1.5表示信号的交易数量。可以传入第四个参数用来替换默认画出的文本内容,画出的信号标记默认文本为交易方向,例如:“closelong”。

c.reset()
c.reset()
// 暂不支持

reset,Pine语言上没有的函数,用于清空图表数据。

reset(remain) reset()方法可以带一个参数remain用于指定保留数据的条数。不传参数remain表示清除全部数据。

策略自定义画图只能使用KLineChart()函数的方式或者Chart()函数的方式中的一种。 KLineChart()函数调用时用到的一些颜色、样式等设置,参看使用KLineChart函数画图的专题文章

{@fun/Log/Chart Chart}

LogReset

清除日志。

LogReset(remain)

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

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

使用LogReset()函数清理日志。

策略实盘每次启动的启动日志算一条,所以如果不传入参数并且策略起始时没有日志输出,就会完全不显示日志,等待托管者日志回传(并非异常情况)。

{@fun/Log Log}, {@fun/Log/LogVacuum LogVacuum}

LogVacuum

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

LogVacuum()

function main() {
    LogReset()
    LogVacuum()
}
def main():
    LogReset()
    LogVacuum()
void main() {
    LogReset()
    LogVacuum()
}

测试LogVacuum()函数。

原因是SQLite删除数据时不回收占用的空间,需要执行VACUUM清理表,释放空间。 该函数调用时会发生文件移动操作,延迟较大,建议在合适的时间间隔调用。

{@fun/Log/LogReset LogReset}

console.log

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

console.log(…msgs)

参数msg为输出的内容,参数msg可以传多个。 msg false string、number、bool、object、array、空值等系统支持的任意类型

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

测试console.log()函数。

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

{@fun/Log/console.error console.error}

console.error

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

console.error(…msgs)

参数msg为输出的内容,参数msg可以传多个。 msg false string、number、bool、object、array、空值等系统支持的任意类型

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

测试console.error()函数。

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

{@fun/Log/console.log console.log}

Market

exchange.GetTicker

获取当前设置的交易对、合约代码对应的{@struct/Ticker Ticker}结构,即行情数据。 GetTicker()函数是交易所对象{@var/EXCHANGE exchange}的成员函数,exchange对象的成员函数(方法)的用途只和exchange相关,文档之后不再赘述。

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

exchange.GetTicker() exchange.GetTicker(symbol)

参数symbol用于指定请求的{@struct/Ticker Ticker}数据对应的合约代码。不传该参数时默认请求当前设置的合约代码的行情数据。

symbol false string

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    Log(exchange.SetContractType("rb888"))

    var 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)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    Log(exchange.SetContractType("rb888"))

    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"])
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    Log(exchange.SetContractType("rb888"));

    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);
}

测试exchange.GetTicker()函数:

回测系统中exchange.GetTicker()函数返回的Ticker数据, 其中HighLow为模拟值,取自当时盘口的卖一、买一。 商品期货策略实盘中如果没有行情推送过来时,exchange.GetTicker()函数会阻塞,等待行情推送。 exchange.GetDepth()exchange.GetTrades()exchange.GetRecords()同理。如果不希望阻塞可以使用切换行情模式:

  • exchange.IO("mode", 0) 立即返回模式,如果当前还没有接收到交易所最新的行情数据推送,就立即返回旧的行情数据,如果有新的数据就返回新的数据。
  • exchange.IO("mode", 1) 缓存模式(默认模式),如果当前还没有收到交易所最新的行情数据(同上一次接口获取的数据比较),就等待接收然后再返回,如果调用该函数之前收到了最新的行情数据,就立即返回最新的数据。
  • exchange.IO("mode", 2) 强制更新模式,进入等待一直到接收到交易所下一次的最新推送数据后返回。

实盘时(非回测)exchange.GetTicker()函数的返回值中Info属性储存接口调用时返回的原始数据。

  • 商品期货 返回商品期货CTP协议/易盛协议接口应答数据,以CTP协议为例:

    {
        "BidPrice4": 1.7976931348623157e+308,
        "AskVolume4": 0,
        "AskVolume5": 0,
        "Turnover": 26229625880,
        "OpenInterest": 1364847,                  // 持仓量
        "ClosePrice": 1.7976931348623157e+308,
        "LowerLimitPrice": 3473,
        "BidPrice3": 1.7976931348623157e+308,
        "ExchangeID": "",
        "BidPrice2": 1.7976931348623157e+308,
        "BidPrice5": 1.7976931348623157e+308,
        "AveragePrice": 37323.89130239898,
        "BidVolume4": 0,
        "BidVolume5": 0,
        "ExchangeInstID": "",
        "LowestPrice": 3715,
        "Volume": 702757,
        "BidVolume3": 0,
        "AskPrice3": 1.7976931348623157e+308,
        "AskVolume3": 0,
        "ActionDay": "20200714",
        "PreClosePrice": 3739,
        "SettlementPrice": 1.7976931348623157e+308,
        "UpdateTime": "13:40:01",
        "BidPrice1": 3727,
        "AskPrice2": 1.7976931348623157e+308,
        "UpperLimitPrice": 3996,
        "CurrDelta": 1.7976931348623157e+308,
        "UpdateMillisec": 500,
        "AskVolume1": 154,
        "BidVolume2": 0,
        "PreOpenInterest": 1372843,
        "PreDelta": 0,
        "AskPrice1": 3728,
        "AskVolume2": 0,
        "TradingDay": "20200714",
        "InstrumentID": "rb2010",
        "LastPrice": 3727,
        "HighestPrice": 3749,
        "BidVolume1": 444,
        "PreSettlementPrice": 3735,
        "OpenPrice": 3740,
        "AskPrice4": 1.7976931348623157e+308,
        "AskPrice5": 1.7976931348623157e+308
    }
    

{@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.GetRecords exchange.GetRecords}

exchange.GetDepth

获取当前设置的交易对、合约代码对应的{@struct/Depth Depth}结构,即订单薄数据。 结构体{@struct/Depth Depth}包含两个结构体数组,分别是Asks[]Bids[]AsksBids包含以下结构体变量:

数据类型 变量名 说明
number Price 价格
number Amount 数量

exchange.GetDepth()函数请求数据成功时返回{@struct/Depth Depth}结构,请求数据失败时返回空值。 {@struct/Depth Depth}、空值

exchange.GetDepth() exchange.GetDepth(symbol)

参数symbol用于指定请求的{@struct/Depth Depth}数据对应的合约代码。不传该参数时默认请求当前设置的合约代码的订单薄数据。

symbol false string

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    Log(exchange.SetContractType("rb888"))

    var depth = exchange.GetDepth()
    var price = depth.Asks[0].Price
    Log("卖一价为:", price)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    Log(exchange.SetContractType("rb888"))
    
    depth = exchange.GetDepth()
    price = depth["Asks"][0]["Price"]
    Log("卖一价为:", price)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    Log(exchange.SetContractType("rb888"));
    
    auto depth = exchange.GetDepth();
    auto price = depth.Asks[0].Price;
    Log("卖一价为:", price);
}

测试exchange.GetDepth()函数:

回测系统中,使用模拟级 Tick回测时exchange.GetDepth()函数返回的数据各档位均为模拟值。 回测系统中,使用实盘级 Tick回测时exchange.GetDepth()函数返回的数据为秒级别深度快照。 商品期货实盘时需要注意: 涨停时卖单卖一的价格是涨停价格,订单量是0。跌停时买单买一的价格是跌停价格,订单量是0。通过判断买一、卖一订单数据中的订单量,可以判断出是否涨跌停。

{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.GetRecords exchange.GetRecords}

exchange.GetTrades

获取当前设置的交易对、合约代码对应的{@struct/Trade Trade}结构数组,即市场的成交数据。 商品期货通过算法根据行情数据(Tick数据)推算出市场成交记录。

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

{@struct/Trade Trade}数组、空值

exchange.GetTrades() exchange.GetTrades(symbol)

参数symbol用于指定请求的{@struct/Trade Trade}数组数据对应的合约代码。不传该参数时默认请求当前设置的合约代码的最近成交记录数据。

symbol false string

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    Log(exchange.SetContractType("rb888"))

    var trades = exchange.GetTrades()
    Log(trades)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    Log(exchange.SetContractType("rb888"))
    
    trades = exchange.GetTrades()
    Log(trades)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    Log(exchange.SetContractType("rb888"));
    
    auto trades = exchange.GetTrades();
    Log(trades);
}

测试exchange.GetTrades()函数:

根据Tick数据推算成交记录的策略例子:

{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetRecords exchange.GetRecords}

exchange.GetRecords

获取当前设置的交易对、合约代码对应的{@struct/Record Record}结构数组,即K线数据。

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

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

参数symbol用于指定请求的{@struct/Record Record}数组数据对应的合约代码。不传该参数时默认请求当前设置的合约代码的K线数据。

symbol false string period参数指定请求的K线数据的周期,例如:{@var/PERIOD/PERIOD_M1 PERIOD_M1},{@var/PERIOD/PERIOD_M5 PERIOD_M5},{@var/PERIOD/PERIOD_M15 PERIOD_M15}等。 参数period的值除了可以传定义的标准周期,还可以传入整数数值,单位为秒。 period false number 参数limit用于指定请求的K线数据的长度。

limit false string

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    Log(exchange.SetContractType("rb888"))

    // 打印K线周期为120秒(2分钟)的K线数据
    Log(exchange.GetRecords(60 * 2))
    // 打印K线周期为5分钟的K线数据
    Log(exchange.GetRecords(PERIOD_M5))      
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    Log(exchange.SetContractType("rb888"))
    
    Log(exchange.GetRecords(60 * 2))
    Log(exchange.GetRecords(PERIOD_M5))
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    Log(exchange.SetContractType("rb888"));

    Log(exchange.GetRecords(60 * 2)[0]);
    Log(exchange.GetRecords(PERIOD_M5)[0]);
}

对于exchange.GetRecords(Period)函数来说商品期货的实盘、回测均支持自定义周期,参数Period为秒数。

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    Log(exchange.SetContractType("rb888"))

    var records = exchange.GetRecords(PERIOD_H1)
    Log("第一根k线数据为,Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High)
    Log("第二根k线数据为,Time:", records[1].Time ,"Close:", records[1].Close)
    Log("当前K线(最新)", records[records.length-1], "上一根K线", records[records.length-2])
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    Log(exchange.SetContractType("rb888"))
    
    records = exchange.GetRecords(PERIOD_H1)
    Log("第一根k线数据为,Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"])
    Log("第二根k线数据为,Time:", records[1]["Time"], "Close:", records[1]["Close"])
    Log("当前K线(最新)", records[-1], "上一根K线", records[-2])
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    Log(exchange.SetContractType("rb888"));
    
    auto records = exchange.GetRecords(PERIOD_H1);
    Log("第一根k线数据为,Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High);
    Log("第二根k线数据为,Time:", records[1].Time, "Close:", records[1].Close);
    Log("当前K线(最新)", records[records.size() - 1], "上一根K线", records[records.size() - 2]);
}

输出K线柱数据:

function main() {
    while(!exchange.IO("status")) {
        Sleep(1000)
    }

    var records = exchange.GetRecords("rb888")
    Log("当前K线(最新)", records[records.length - 1])
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    records = exchange.GetRecords("rb888")
    Log("当前K线(最新)", records[-1])
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    auto records = exchange.GetRecords("rb888");
    Log("当前K线(最新)", records[records.size() - 1]);
}

指定具体合约代码请求K线数据:

默认K线周期在回测、实盘页面可以设置,如果在调用exchange.GetRecords()函数时指定了参数,获取的就是该参数周期对应的K线数据。 如果函数调用时没有指定参数,则按照回测、实盘参数上设置的K线周期返回对应的K线数据。 返回值为Record结构数组,返回的K线数据会随时间累积,累积K线柱数量的上限受到exchange.SetMaxBarLen()函数设置的影响, 没有设置时默认上限为5000个K线柱。当K线数据到达K线柱累积上限,之后会更新加入一根K线柱的同时删除一根最早时间的K线柱(如队列进出)。 初始调用GetRecords函数时获取的K线柱数量:

  • 回测系统中会预先取回测周期起始时刻前1000根K线柱,作为初始K线数据。

参数period设置为5,即为请求获取5秒为周期的K线数据。 如果period参数不能被60整除(即代表的周期是不可用分钟为单位的周期),系统底层则使用tick数据合成所需的K线数据。 如果period参数能被60整除,则最小使用1分钟K线数据(尽可能使用较大的周期合成所需K线数据),合成所需的K线数据。
股票证券:

  • 富途证券 在K线周期为日线周期以下时,调用GetRecords()函数返回的数据中数组的每个元素为一个K线柱数据(即Record结构体),每个K线柱数据结构的Time属性是该周期的结束时间(毫秒级时间戳)并非起始时间(毫秒级时间戳)。 在K线周期为日线周期时,Record结构体的Time属性是该周期的起始时间(毫秒级时间戳)。

回测系统中模拟级别回测由于需要设置底层K线周期(回测系统模拟级别回测时,根据设置的底层K线周期使用对应的K线数据生成Tick数据), 需要注意在策略中获取的K线数据的周期不能小于底层K线周期。因为在模拟级别回测中,各个周期的K线数据在回测系统中都是通过底层K线周期对应的K线数据合成的。 C++语言中如果需要自己构造K线数据有以下代码范例:

#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);                     
}

{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.SetMaxBarLen exchange.SetMaxBarLen}

exchange.GetPeriod

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

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

exchange.GetPeriod()

function main() {
    // 例如回测、实盘时优宽量化交易平台网站页面上设置的K线周期为1小时
    var period = exchange.GetPeriod()
    Log("K线周期:", period / (60 * 60), "小时")
}
def main():
    period = exchange.GetPeriod()
    Log("K线周期:", period / (60 * 60), "小时")
void main() {
    auto period = exchange.GetPeriod();
    Log("K线周期:", period / (60 * 60.0), "小时");
}

获取当前默认的K线周期。

{@fun/Market/exchange.GetRecords exchange.GetRecords}

exchange.SetMaxBarLen

设置K线最大长度。

exchange.SetMaxBarLen(n)

参数n用于指定最大K线长度。 n true number

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    exchange.SetMaxBarLen(50)
    Log(exchange.SetContractType("rb888"))
    
    var records = exchange.GetRecords()
    Log(records.length, records)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetMaxBarLen(50)
    Log(exchange.SetContractType("rb888"))
    
    r = exchange.GetRecords()
    Log(len(r), r)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetMaxBarLen(50);
    Log(exchange.SetContractType("rb888"));
    
    auto r = exchange.GetRecords();
    Log(r.size(), r[0]);
}

测试exchange.SetMaxBarLen()函数:

exchange.SetMaxBarLen(Len)函数对于商品期货策略来说,运行时影响K线线柱(BAR)的上限数量。 exchange.SetMaxBarLen函数需要在exchange.SetContractType函数调用之前执行,因为当exchange.SetContractType函数调用时,系统底层已经开始处理K线数据。

{@fun/Market/exchange.GetRecords exchange.GetRecords}

exchange.GetRate

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

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

exchange.GetRate()

function main(){
    Log(exchange.GetTicker())
    // 设置汇率转换
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    Log("当前汇率:", exchange.GetRate())
}
def main():
    Log(exchange.GetTicker())
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    Log("当前汇率:", exchange.GetRate())
void main() {
    Log(exchange.GetTicker());
    exchange.SetRate(7);
    Log(exchange.GetTicker());
    Log("当前汇率:", exchange.GetRate());
}

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

如果没有调用exchange.SetRate()设置过转换汇率,exchange.GetRate()函数返回的默认汇率值为1, 即当前显示的计价货币(quoteCurrency)相关数据没有发生过汇率转换。 如果使用exchange.SetRate()设置过一个汇率值,例如exchange.SetRate(7), 那么通过exchange这个交易所对象获取的行情、深度、下单价格等所有价格信息,都会被乘以设置的汇率7来进行转换。 如果exchange对应的是以美元为计价货币的交易所,调用exchange.SetRate(7)后,实盘所有价格都会被乘7转换成接近CNY的价格。 此时使用exchange.GetRate()获取的汇率值就是7

{@fun/Trade/exchange.SetRate exchange.SetRate}

exchange.SetData

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

参数valueJSON编码后的字符串长度。 number

exchange.SetData(key, value)

数据集合名称。 key true string exchange.SetData()函数所要加载的数据,数据结构为数组。数据结构与exchange.GetData()函数请求外部数据时所要求的数据格式相同,即:"schema": ["time", "data"]。 value true array

/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/
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)
    }
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''  

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)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/  

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);
    }
}

在策略中直接写入数据,要求数据格式如同以下例子中的data变量。以下测试代码运行时,会在对应的时间获取对应的数据。 可以看到时间戳1579622400000对应的时间为2020-01-22 00:00:00,当策略程序运行在这个时间之后, 在下一条数据时间戳1579708800000即时间2020-01-23 00:00:00之前,调用exchange.GetData(Source)函数获取数据。 获取的都是[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}]

加载的数据可以是任何经济指标、行业数据、相关指数等,用于策略量化考核所有可量化的信息。

{@fun/Market/exchange.GetData exchange.GetData}

exchange.GetData

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

数据集合中的记录。 object

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

数据集合名称。 key true string 用于设置缓存超时,单位为毫秒。实盘时默认为一分钟缓存超时。 timeout false number

/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

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)
    }
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''  
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)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/    
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);
    }
}

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

/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/
function main() {
    while(true) {
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
        Sleep(1000)
    }
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''  

def main():
    while True:
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
        Sleep(1000)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/  

void main() {
    while(true) {
        Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
        Sleep(1000);
    }
}

支持通过外部链接请求数据,请求到的数据格式:

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

其中schema为加载数据的主体中的每一条记录的数据格式,该格式固定为["time","data"]对应data属性中的逐条数据的格式。 data属性中储存的为数据主体,每条数据由毫秒级别时间戳和数据内容构成(数据内容可以是任何可JSON编码的数据)。 测试用的服务程序,使用Go语言编写:

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)
}

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

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

测试策略代码:

function main() {
    Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
}
def main():
    Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
void main() {
    Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
}

获取外部链接的数据的调用方式。

function main() {
    // 链接中xxx部分为查询的数据的编码,此处xxx为举例。具体查询链接可以登录datadata.cn平台创建,也可以在优宽量化平台「数据探索」页面创建
    Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data"))   
}
def main():
    Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data"))
void main() {
    Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data"));
}

请求datadata平台上创建的查询数据,要求应答的数据格式为(必须有time、data字段在schema里描述):

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

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

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

{@fun/Market/exchange.SetData exchange.SetData}

exchange.GetMarkets

exchange.GetMarkets()函数用于获取已订阅的交易品种信息。

包含{@struct/Market Market}结构体的字典。
object

exchange.GetMarkets()

/*backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

function main() {
    var arrSymbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"]
    var tbl = {type: "table", title: "test markets", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: []}
    for (var i = 0; i < 10; i++) {
        if (exchange.IO("status")) {
            for (var symbol of arrSymbol) {
                exchange.SetContractType(symbol)
            }
            
            var markets = exchange.GetMarkets()
            for (var symbol in markets) {
                var market = markets[symbol]
                tbl.rows.push([symbol, 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(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
            return   
        }
        
        Sleep(1000)
    }    
}
'''backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

import json

def main():
    arrSymbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"]
    tbl = {"type": "table", "title": "test markets", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": []}
    for i in range(10):
        if exchange.IO("status"):
            for symbol in arrSymbol:
                exchange.SetContractType(symbol)
            
            markets = exchange.GetMarkets()
            for symbol in markets:
                market = markets[symbol]
                tbl["rows"].append([symbol, 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(_D(), "\n", "`" + json.dumps(tbl) + "`")
            return
        
        Sleep(1000)
/*backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

void main() {
    auto arrSymbol = {"rb2501", "MA888", "i2501", "p2501", "TA501"};
    json tbl = R"({
        "type": "table", 
        "title": "test markets", 
        "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"],
        "rows": []
    })"_json;
    for (int i = 0; i < 10; i++) {
        if (exchange.IO("status") == 1) {
            for (const auto& symbol : arrSymbol) {
                exchange.SetContractType(symbol);
            }
            auto markets = exchange.GetMarkets();
            for (auto& [key, market] : markets.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"]};
                tbl["rows"].push_back(arrJson);
            }
            
            LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
            return; 
        }
        
        Sleep(1000);
    }
}

在回测系统中调用exchange.GetMarkets()函数,只返回已经订阅过的合约信息。

exchange.GetMarkets()函数返回值为一个字典。键名为合约代码,例如:

{
    "MA888": {
        "AmountPrecision": 1,
        "AmountSize": 1,
        "BaseAsset": "FUTURES",
        "CtVal": 10,
        "CtValCcy": "FUTURES",
        "MaxNotional": 10000000,
        "MaxQty": 1000,
        "MinNotional": 1,
        "MinQty": 1,
        "PricePrecision": 0,
        "QuoteAsset": "CNY",
        "Symbol": "MA888",
        "TickSize": 1
    }
    // ...
}
  • exchange.GetMarkets()函数支持实盘、回测系统。
  • exchange.GetMarkets()函数只返回已订阅过的品种的相关数据。

{@struct/Market Market}

exchange.GetTickers

exchange.GetTickers()函数用于获取已订阅的交易品种聚合行情数据({@struct/Ticker Ticker}结构的数组)。

exchange.GetTickers()函数请求数据成功时返回{@struct/Ticker Ticker}结构数组,请求数据失败时返回空值。
{@struct/Ticker Ticker}数组、空值

exchange.GetTickers()

/*backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

function main() {
    var arrSymbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"]
    var tbl = {type: "table", title: "test tickers", cols: ["Symbol", "Buy", "Sell", "Open", "Last", "High", "Low", "Volume", "Time", "OpenInterest"], rows: []}
    for (var i = 0; i < 10; i++) {
        if (exchange.IO("status")) {
            for (var symbol of arrSymbol) {
                exchange.SetContractType(symbol)
            }
            
            var tickers = exchange.GetTickers()
            for (var ticker of tickers) {                            
                tbl.rows.push([ticker.Symbol, ticker.Buy, ticker.Sell, ticker.Open, ticker.Last, ticker.High, ticker.Low, ticker.Volume, ticker.Time, ticker.OpenInterest])
            }
            
            LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
            return   
        }
        
        Sleep(1000)
    }
}
'''backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

import json

def main():
    arrSymbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"]
    tbl = {"type": "table", "title": "test tickers", "cols": ["Symbol", "Buy", "Sell", "Open", "Last", "High", "Low", "Volume", "Time", "OpenInterest"], "rows": []}
    for i in range(10):
        if exchange.IO("status"):
            for symbol in arrSymbol:
                exchange.SetContractType(symbol)
            
            tickers = exchange.GetTickers()
            for ticker in tickers:
                tbl["rows"].append([ticker["Symbol"], ticker["Buy"], ticker["Sell"], ticker["Open"], ticker["Last"], ticker["High"], ticker["Low"], ticker["Volume"], ticker["Time"], ticker["OpenInterest"]])
            
            LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
            return
        
        Sleep(1000)
/*backtest
start: 2024-07-01 00:00:00
end: 2024-07-07 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

void main() {
    auto arrSymbol = {"rb2501", "MA888", "i2501", "p2501", "TA501"};
    json tbl = R"({
        "type": "table", 
        "title": "test tickers", 
        "cols": ["Symbol", "Buy", "Sell", "Open", "Last", "High", "Low", "Volume", "Time", "OpenInterest"],
        "rows": []
    })"_json;
    for (int i = 0; i < 10; i++) {
        if (exchange.IO("status") == 1) {
            for (const auto& symbol : arrSymbol) {
                exchange.SetContractType(symbol);
            }
            auto tickers = exchange.GetTickers();
            for (auto& ticker : tickers) {
                json arrJson = {ticker.Symbol, ticker.Buy, ticker.Sell, ticker.Open, ticker.Last, ticker.High, ticker.Low, ticker.Volume, ticker.Time, ticker.OpenInterest};
                tbl["rows"].push_back(arrJson);
            }
            
            LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
            return; 
        }
        
        Sleep(1000);
    }
}

在回测系统中调用exchange.GetTickers()函数,只返回已经订阅过的合约的聚合行情数据。

  • exchange.GetTickers()函数支持实盘、回测系统。
  • exchange.GetTickers()函数只返回已订阅过的品种的相关数据。

{@struct/Ticker Ticker}, {@fun/Market/exchange.GetTicker exchange.GetTicker}

Trade

exchange.Buy

exchange.Buy()函数用于下买单。Buy()函数是交易所对象{@var/EXCHANGE exchange}的成员函数。 Buy()函数操作交易所对象exchange绑定的交易所账户,exchange对象的成员函数(方法)的用途只和exchange相关,文档之后不再赘述。

下单成功返回订单Id,下单失败返回空值。 string、空值

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

price参数用于设置订单价格。 price true number amount参数用于设置订单量。 amount true number 扩展参数,可以输出附带信息到这条下单日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("buy")

    // 注意,这里的下单价格100为举例,具体测试的时候可以自行设置、改动
    var id = exchange.Buy(100, 1)
    Log("id:", id)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("buy")
    
    id = exchange.Buy(100, 1)
    Log("id:", id)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("buy");
    
    auto id = exchange.Buy(100, 1);
    Log("id:", id);
}

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

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("buy")  
    
    // 下单价格参数传-1即为市价单
    var id = exchange.Buy(-1, 1)
    Log("id:", id)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("buy")  
    
    id = exchange.Buy(-1, 1)
    Log("id:", id)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("buy");
    
    auto id = exchange.Buy(-1, 1);
    Log("id:", id);
}

商品期货、股票证券除了使用市价单(价格参数传-1,实际是系统使用了一个较高的买入价或者较低的卖出价来确保成交),还可以用限价单方式下单。 可以使用一个较大的滑价,确保和对手盘成交,参看exchange.Sell中的范例。

期货合约下单时必须注意交易方向是否设置正确,如果交易方向和交易函数不匹配会报错。 参考:{@fun/Futures/exchange.SetDirection exchange.SetDirection} 参数price设置为-1用于下市价单,回测系统、实盘环境均支持市价单。 股票证券下单: 下单量为股票股数,并非股票手数(在股票证券交易所对象中如无特殊说明,相关的量均为股票股数)。下单量需要符合股票信息中的每手股数要求。 例如,02333.HK港股长城汽车,每手500股。下单量必须是500的整倍数。601633.SH为A股长城汽车,每手100股。下单量必须是100的整倍数。 每手股数可以从SetContractType函数返回的数据结构中获取(VolumeMultiple字段)。也可以从GetTicker()函数返回的数据结构中的Info属性中获取(LotSize字段)。

{@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}, {@fun/Futures/exchange.SetDirection exchange.SetDirection}

exchange.Sell

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

下单成功返回订单Id,下单失败返回空值。 参考{@fun/Trade/exchange.Buy exchange.Buy}。 string、空值

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

price参数用于设置订单价格。 price true number amount参数用于设置订单量。 amount true number 扩展参数,可以输出附带信息到这条下单日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("sell")
    
    // 注意,这里的下单价格100为举例,具体测试的时候可以自行设置、改动
    var id = exchange.Sell(100, 1)
    Log("id:", id)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("sell")
    
    id = exchange.Sell(100, 1)
    Log("id:", id)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("sell");
    
    auto id = exchange.Sell(100, 1);
    Log("id:", id);
}

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

function main() {
    while(true) {
        if (exchange.IO("status")) {
            // 设置当前合约为 rb2001 , 测试的时候按回测时间设置合适的合约
            exchange.SetContractType("rb2001")               
            exchange.SetDirection("buy")
            // 获取当前行情
            var ticker = exchange.GetTicker()                
            // 拿到当前卖一价格
            var currSell1Price = ticker.Sell                 
            // 加50元滑价,即为比出价卖出的挂单高50,要求买入1手
            var id = exchange.Buy(currSell1Price + 50, 1)    
            Log(exchange.GetOrder(id))
            break
        } else {
            Log("未连接")
        }
    }
}
def main():
    while True:
        if exchange.IO("status"):
            exchange.SetContractType("rb2001")
            exchange.SetDirection("buy")
            ticker = exchange.GetTicker()
            currSell1Price = ticker["Sell"]
            id = exchange.Buy(currSell1Price + 50, 1)
            Log(exchange.GetOrder(id))
            break
        else :
            Log("未连接")
void main() {
    while(true) {
        if(exchange.IO("status") == 1) {
            exchange.SetContractType("rb2001");
            exchange.SetDirection("buy");
            auto ticker = exchange.GetTicker();
            auto currSell1Price = ticker.Sell;
            auto id = exchange.Buy(currSell1Price + 50, 1);
            Log(exchange.GetOrder(id));
            break;
        } else {
            Log("未连接");
        }
    }
}

商品期货除了使用市价单还可以用限价单方式下单,可以使用一个较大的滑价确保和对手盘成交。

期货合约下单时必须注意交易方向是否设置正确,如果交易方向和交易函数不匹配会报错。 参考:{@fun/Futures/exchange.SetDirection exchange.SetDirection} 参数price设置为-1用于下市价单,回测系统、实盘环境均支持市价单。 下单量为股票股数,并非股票手数(在股票证券交易所对象中如无特殊说明,相关的量均为股票股数)。下单量需要符合股票信息中的每手股数要求。 参考{@fun/Trade/exchange.Buy exchange.Buy}。

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}, {@fun/Futures/exchange.SetDirection exchange.SetDirection}

exchange.CreateOrder

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

下单成功返回订单Id,下单失败返回空值。 string、空值

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

参数symbol用于指定订单的合约代码。传空字符串""时默认以当前设置的合约代码下单。

symbol true string side参数的可选值为:buyclosebuysellclosesellclosesell_todayclosebuy_todaybuy表示开多仓,closebuy表示平多昨仓,sell表示开空仓,closesell表示平空昨仓,closebuy_today表示平多今仓,closesell_today表示平空今仓。

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

price true number amount参数用于设置订单量。

amount true number 扩展参数,可以输出附带信息到这条下单日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    while(!exchange.IO("status")) {
        Sleep(1000)
    }
    // 调用CreateOrder函数下单
    var id = exchange.CreateOrder("rb2410", "buy", 3500, 1)
    Log(id)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    id = exchange.CreateOrder("rb2410", "buy", 3500, 1)
    Log(id)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    auto id = exchange.CreateOrder("rb2410", "buy", 3500, 1);
    Log(id);
}

商品期货交易所对象调用exchange.CreateOrder()函数下单。

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}

exchange.CancelOrder

exchange.CancelOrder()函数用于取消订单。

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

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

orderId参数用于指定所要取消的订单。 orderId true string 扩展参数,可以输出附带信息到这条撤单日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("sell")
    
    // 下单价格只是举例,较大的价格不会成交,订单会处于订单薄中待成交状态,具体测试可以自行调整价格
    var id = exchange.Sell(99999, 1)
    exchange.CancelOrder(id)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("sell")
    
    id = exchange.Sell(99999, 1)
    exchange.CancelOrder(id)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("sell");
    
    auto id = exchange.Sell(99999, 1);
    exchange.CancelOrder(id);
}

撤销订单。

function main() {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("sell")    

    Log("数据1", "数据2", "数据3", "...")
    var data2 = 200
    // 下单价格只是举例,较大的价格不会成交,订单会处于订单薄中待成交状态,具体测试可以自行调整价格
    var id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...")
    exchange.CancelOrder(id, "附带数据1", data2, "...")
    LogProfit(100, "附带数据1", data2, "...")
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("sell")
    
    Log("数据1", "数据2", "数据3", "...")
    data2 = 200
    id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...")
    exchange.CancelOrder(id, "附带数据1", data2, "...")
    LogProfit(100, "附带数据1", data2, "...")
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("sell");
    
    Log("数据1", "数据2", "数据3", "...");
    int data2 = 200;
    auto id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...");
    exchange.CancelOrder(id, "附带数据1", data2, "...");
    LogProfit(100, "附带数据1", data2, "...");
}

优宽量化的API函数中可以产生日志输出的函数例如:Log(...)exchange.Buy(Price, Amount)exchange.CancelOrder(Id)等都可以在必要参数后跟一些附带输出参数。 例如:exchange.CancelOrder(orders[j].Id, orders[j]),这样就是在取消Id为orders[j].Id的这个订单时附带输出这个订单的信息,即orders[j]这个Order结构。

参数orderId的类型为字符串类型。

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}

exchange.GetOrder

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

根据订单号查询订单详情,查询成功返回{@struct/Order Order}结构,查询失败返回空值。 {@struct/Order Order}、空值

exchange.GetOrder(orderId)

orderId参数用于指定所要查询的订单。 orderId true string

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("sell")
    
    // 下单价格只是举例,较大的价格不会成交,订单会处于订单薄中待成交状态,具体测试可以自行调整价格
    var id = exchange.Sell(99999, 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)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("sell")
    
    id = exchange.Sell(99999, 1)
    order = exchange.GetOrder(id)
    Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:", 
        order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("sell");
    
    auto id = exchange.Sell(99999, 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);
}

根据具体订单Id查询订单详细信息。

返回值为{@struct/Order Order}结构。

{@struct/Order Order}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}

exchange.GetOrders

exchange.GetOrders()函数用于获取所有合约的未完成的订单,支持查询指定合约的未完成订单。

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

exchange.GetOrders() exchange.GetOrders(symbol)

参数symbol用于指定所要查询的订单数据的合约代码。不传该参数时默认请求所有合约的当前未完成订单数据。

symbol false string

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    // 设置下单方向
    exchange.SetDirection("sell")
    
    // 下单价格只是举例,较大的价格不会成交,订单会处于订单薄中待成交状态,具体测试可以自行调整价格
    exchange.Sell(99999, 1)
    exchange.Sell(88888, 1)
    var orders = exchange.GetOrders()
    Log("未完成订单一的信息,ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
        "DealAmount:", orders[0].DealAmount, "Type:", orders[0].Type, "Symbol:", orders[0].Symbol)
    Log("未完成订单二的信息,ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
        "DealAmount:", orders[1].DealAmount, "Type:", orders[1].Type, "Symbol:", orders[1].Symbol)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    exchange.SetDirection("sell")
    
    exchange.Sell(99999, 1)
    exchange.Sell(88888, 1)
    orders = exchange.GetOrders()
    Log("未完成订单一的信息,ID:", orders[0]["Id"], "Price:", orders[0]["Price"], "Amount:", orders[0]["Amount"], 
        "DealAmount:", orders[0]["DealAmount"], "Type:", orders[0]["Type"], "Symbol:", orders[0]["Symbol"])
    Log("未完成订单二的信息,ID:", orders[1]["Id"], "Price:", orders[1]["Price"], "Amount:", orders[1]["Amount"],
        "DealAmount:", orders[1]["DealAmount"], "Type:", orders[1]["Type"], "Symbol:", orders[1]["Symbol"])
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    exchange.SetDirection("sell");
    
    exchange.Sell(99999, 1);
    exchange.Sell(88888, 1);
    auto orders = exchange.GetOrders();
    Log("未完成订单一的信息,ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount, 
        "DealAmount:", orders[0].DealAmount, "Type:", orders[0].Type, "Symbol:", orders[0].Symbol);
    Log("未完成订单二的信息,ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
        "DealAmount:", orders[1].DealAmount, "Type:", orders[1].Type, "Symbol:", orders[1].Symbol);
}

以一个很高的价格下单,然后查询未完成订单信息。

/*backtest
start: 2020-06-17 10:00:00
end: 2020-06-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

function main() {
    var contractTypeList = ["MA009", "rb2010", "i2009"]
    while (true) {
        if (exchange.IO("status")) {
            for (var i = 0; i < contractTypeList.length; i++) {
                var ret = exchange.SetContractType(contractTypeList[i])
                var ticker = exchange.GetTicker()
                exchange.SetDirection("sell")
                var id = exchange.Sell(ticker.Sell + 5, 1)
                Log(contractTypeList[i], "开空仓订单ID:", id)
            }
            var orders = exchange.GetOrders()
            for (var j = 0; j < orders.length; j++) {
                Log(orders[j])
            }
            break
        } else {
            LogStatus(_D(), "未连接")
        }
    }
}
'''backtest
start: 2020-06-17 10:00:00
end: 2020-06-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

def main():
    contractTypeList = ["MA009", "rb2010", "i2009"]
    while True:
        if exchange.IO("status"):
            for i in range(len(contractTypeList)):
                ret = exchange.SetContractType(contractTypeList[i])
                ticker = exchange.GetTicker()
                exchange.SetDirection("sell")
                id = exchange.Sell(ticker["Sell"] + 5, 1)
                Log(contractTypeList[i], "开空仓订单ID:", id)
            
            orders = exchange.GetOrders()
            for i in range(len(orders)):
                Log(orders[i])                            
            break
        else:
            LogStatus(_D(), "未连接")
/*backtest
start: 2020-06-17 10:00:00
end: 2020-06-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

void main() {
    vector<string> contractTypeList = {"MA009", "rb2010", "i2009"};
    while (true) {
        if (exchange.IO("status") == 1) {
            for (int i = 0 ; i < contractTypeList.size(); i++) {
                auto ret = exchange.SetContractType(contractTypeList[i]);
                auto ticker = exchange.GetTicker();
                exchange.SetDirection("sell");
                auto id = exchange.Sell(ticker.Sell + 5.0, 1);
                Log(contractTypeList[i], "开空仓订单ID:", id);
            }
            auto orders = exchange.GetOrders();
            for (int j = 0; j < orders.size(); j++) {
                Log(orders[j]);
            }
            break;
        } else {
            LogStatus(_D(), "未完成");
        }
    } 
}

exchange.GetOrders()函数在商品期货、股票证券中获取的是所有未完成订单。 在商品期货中exchange.GetOrders()函数获取的订单与当前设置的合约无关。可以使用以下例子进行回测、模拟盘、实盘测试。

当交易所对象exchange代表的账户没有挂单(处于未成交状态的活动订单)时,调用exchange.GetOrders()函数返回空数组,即:[]exchange.GetOrders()函数不依赖于当前合约代码设置,不传symbol参数时获取所有合约的未完成订单。

{@struct/Order Order}, {@fun/Trade/exchange.GetOrder exchange.GetOrder}

exchange.GetHistoryOrders

exchange.GetHistoryOrders()函数用于获取当前交易日内的所有合约的历史订单,支持查询指定合约的历史订单。

exchange.GetHistoryOrders()函数请求数据成功时返回{@struct/Order Order}结构数组,请求数据失败时返回空值。 {@struct/Order Order}数组、空值

exchange.GetHistoryOrders() exchange.GetHistoryOrders(symbol)

symbol参数用来指定所要获取的历史订单的合约名称。

symbol false string

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    
    var orders = exchange.GetHistoryOrders()
    Log(orders)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    orders = exchange.GetHistoryOrders()
    Log(orders)
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    auto orders = exchange.GetHistoryOrders();
    Log(orders);
}

注意:exchange.GetHistoryOrders()函数不依赖于当前合约代码设置,不传symbol参数时获取当前交易日所有合约的历史订单。传入symbol参数指定获取当前交易日具体合约的历史订单。

{@struct/Order Order}, {@fun/Trade/exchange.GetOrder exchange.GetOrder}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}

exchange.SetPrecision

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

exchange.SetPrecision(pricePrecision, amountPrecision)

pricePrecision参数用来控制价格数据的精度。 pricePrecision true number amountPrecision参数用来控制下单量数据的精度。 amountPrecision true number

function main(){
    // 设置价格小数位精度为2位,品种下单量小数位精度为3位
    exchange.SetPrecision(2, 3)
}
def main():
    exchange.SetPrecision(2, 3)
void main() {
    exchange.SetPrecision(2, 3);
}

设置价格精度、下单量精度。

回测系统不支持该函数,回测系统的数值精度会自动处理。 pricePrecisionamountPrecision都必须是整型的数值。

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}

exchange.SetRate

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

exchange.SetRate(rate)

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

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    // 设置合约代码
    exchange.SetContractType("rb888")
    
    // 设置汇率之前打印行情数据
    Log(exchange.GetTicker())
    // 设置汇率转换
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    // 设置为1,不转换
    exchange.SetRate(1)
    Log(exchange.GetTicker())
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    exchange.SetContractType("rb888")
    
    Log(exchange.GetTicker())
    exchange.SetRate(7)
    Log(exchange.GetTicker())
    exchange.SetRate(1)
    Log(exchange.GetTicker())
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    exchange.SetContractType("rb888");
    
    Log(exchange.GetTicker());
    exchange.SetRate(7);
    Log(exchange.GetTicker());
    exchange.SetRate(1);
    Log(exchange.GetTicker());
}

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

如果使用exchange.SetRate()函数设置过一个汇率值,例如设置为7。 那么当前exchange这个交易所对象代表的交易所的行情、深度、下单价格等所有价格信息,都会被乘以设置的汇率7,进行转换。 例如exchange是以美元为计价货币的交易所。执行exchange.SetRate(7)之后,实盘所有价格都会被乘7转换成接近CNY计价的价格。

{@fun/Market/exchange.GetRate exchange.GetRate}

exchange.IO

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

exchange.IO()函数调用交易所对象相关的其它接口,调用成功时返回请求的应答数据,调用失败时返回空值。 string、number、bool、object、array、空值等系统支持的任意类型

exchange.IO(k, …args)

k参数用于设置调用类型,可选值为"api"wait。 k true string 扩展参数,根据具体调用场景传参,arg参数可以传多个。 由于exchange.IO()函数的多态机制,不同的参数设置对应不同的功能。 exchange.IO()函数的参数个数、类型都是不确定的。 arg true string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    while (!exchange.IO("status")) {
        LogStatus("正在等待与交易服务器连接, " + new Date())
    }
}
def main():
    while not exchange.IO("status"):
        LogStatus("正在等待与交易服务器连接, " + _D())
void main() {
    while(exchange.IO("status") == 0) {
        LogStatus("正在等待与交易服务器连接, " + _D());
    }
}

使用status参数,判断与期货公司前置机连接状态: exchange.IO("status"),返回true证明与CTP服务器行情与数据的两台服务器都连接正常。

function on_tick(symbol, ticker) {
    Log("symbol:", symbol, "update")
    Log("ticker:", ticker)
}

function on_order(order) {
    Log("order update", order)
}

function main() {
    while(!exchange.IO("status")) {
        Sleep(10)
    }
    // 如果在程序中不使用诸如exchange.GetTicker()之类的获取行情的函数,可以不设置exchange.IO("mode", 0)
    exchange.IO("mode", 0)
    _C(exchange.SetContractType, "MA005")
    while(true) {
        var e = exchange.IO("wait")
        if(e) {
            if(e.Event == "tick") {
                on_tick(e.Symbol, e.Ticker)
            } else if(e.Event == "order") {
                on_order(e.Order)
            }
        }
    }
}
def on_tick(symbol, ticker):
    Log("symbol:", symbol, "update")
    # 数据结构:https://www.youquant.com/api#ticker
    Log("ticker:", ticker)              

def on_order(order):
    Log("order update", order)

def main():
    # wait connect trade server
    while not exchange.IO("status"):
        Sleep(10)
    # switch push mode
    exchange.IO("mode", 0)
    # subscribe instrument
    _C(exchange.SetContractType, "MA001")
    while True:
        e = exchange.IO("wait")
        if e:
            if e.Event == "tick":
                on_tick(e['Symbol'], e['Ticker'])
            elif e.Event == "order":
                on_order(e['Order'])
void on_tick(const string &symbol, json &ticker) {
    Log("symbol:", symbol, "update");
    Log("ticker:", ticker);
}

void on_order(json &order) {
    Log("order update", order);
}

void main() {
    while(exchange.IO("status") == 0) {
        Sleep(10);
    }
    exchange.IO("mode", 0);
    _C(exchange.SetContractType, "rb2005");
    while(true) {
        auto e = exchange.IO("wait");
        if(e != false) {
            if(e["Event"] == "tick") {
                on_tick(e["Symbol"], e["Ticker"]);
            }   
            else if(e["Event"] == "order") {
                on_order(e["Order"]);
            }
        }
    }
}

使用wait参数设置阻塞: exchange.IO("wait", Timeout),当前交易所有任何品种更新行情信息或订单成交时才返回,可带第二个参数(毫秒数)指定超时,超时返回空值,正常返回EventTick/OrderEvent结构,结合exchange.IO("mode", 0)函数使用,这样配合使用就可以使程序在有最新行情时进行响应,执行程序逻辑(使用exchange.IO("mode", 0)并不影响exchange.IO("wait"),目的是为了在程序中使用exchange.GetTicker()等函数调用时不阻塞)。如果Timeout参数设置-1该函数设置为立即返回,在没有新事件时返回空值,Timeout参数设置0为阻塞等待最新事件,如同不设置Timeout参数。需要注意的是在使用exchange.IO("wait")时,必须至少已经订阅了一个当前处于交易状态的合约(已经交割的过期合约,不会再有行情数据),否则会阻塞在该函数(由于没有任何行情、订单更新)。只支持商品期货实盘。

EventTick{Event:"tick", Index:交易所索引, Nano:事件纳秒级时间, Symbol:合约名称, Ticker:行情数据}OrderTick{Event:"order", Index:交易所索引, Nano:事件纳秒级时间, Order:订单信息}

简单实现回调机制:

function on_tick(symbol, ticker) {
    Log("symbol:", symbol, "update", "ticker:", ticker)
}  

function main() {
    while(!exchange.IO("status")) {
        Sleep(10)
    }
    
    _C(exchange.SetContractType, "MA101")
    _C(exchange.SetContractType, "rb2101")
    _C(exchange.SetContractType, "i2101")
    while(true) {
        var e = exchange.IO("wait", -1)
        if(e) {
            if(e.Event == "tick") {
                on_tick(e.Symbol, e.Ticker)
            }
        }
        Sleep(10)
    }
}
def on_tick(symbol, ticker):
    Log("symbol:", symbol, "update", "ticker:", ticker)  

def main():
    while not exchange.IO("status"):
        Sleep(10)
    _C(exchange.SetContractType, "MA101")
    _C(exchange.SetContractType, "rb2101")
    _C(exchange.SetContractType, "i2101")
    while True:
        e = exchange.IO("wait", -1)
        if e:
            if e.Event == "tick":
                on_tick(e['Symbol'], e['Ticker'])
        Sleep(10)
void on_tick(const string &symbol, json &ticker) {
    Log("symbol:", symbol, "update", "ticker:", ticker);
}

void main() {
    while(exchange.IO("status") == 0) {
        Sleep(10);
    }
    _C(exchange.SetContractType, "MA101");
    _C(exchange.SetContractType, "rb2101");
    _C(exchange.SetContractType, "i2101");
    while(true) {
        auto e = exchange.IO("wait", -1);
        if(e != false) {
            if(e["Event"] == "tick") {
                on_tick(e["Symbol"], e["Ticker"]);
            }
        }
    }
}

多品种回调例子:

function main() {
    while (!exchange.IO("status")) {
        LogStatus("正在等待与交易服务器连接, " + new Date())
    }

    Log("开始获取所有合约")
    var instruments = _C(exchange.IO, "instruments")
    Log("合约列表获取成功")
    var len = 0
    for (var instrumentId in instruments) {
        len++
    }
    Log("合约列表长度为:",len)
}
def main():
    while not exchange.IO("status"):
        LogStatus("正在等待与交易服务器连接, " + _D())
    
    Log("开始获取所有合约")
    instruments = _C(exchange.IO, "instruments")
    Log("合约列表获取成功")
    length = 0
    for i in range(len(instruments)):
        length += 1
    Log("合约列表长度为:", length)
void main() {
    while(exchange.IO("status") == 0) {
        LogStatus("正在等待与交易服务器连接, " + _D());
    }

    Log("开始获取所有合约");
    auto instruments = _C(exchange.IO, "instruments");
    Log("合约列表获取成功");
    int length = 0;
    for(int i = 0; i < instruments.size(); i++) {
        length++;
    }
    Log("合约列表长度为:", length);
}

使用instruments参数,获取所有合约的列表数据: exchange.IO("instruments"),返回交易所所有合约的列表,只支持实盘。 使用products参数,获取所有产品的列表数据:

exchange.IO("products"),返回交易所所有产品的列表,只支持实盘。

使用subscribed参数,获取已经订阅的合约数据:

exchange.IO("subscribed"),返回已订阅行情的合约,只支持实盘。

使用settlement参数,获取结算单数据:

exchange.IO("settlement"),结算单查询,不加第二个参数默认返回之前一个交易日的数据,加参数如20170317指返回日期为2017-03-17的结算单,只支持实盘。

使用api参数,调用底层接口: 优宽量化的CTP(商品期货)终端提供了完整的全API实现,当发明者平台的API满足不了你需要的功能时可以用exchange.IO函数进行更深层的系统调用,完全兼容官方的Api名称。CTP的IO直接扩展函数调用请求,将会在收到第一个isLast标记为true的响应包后返回。

CTP协议接口:CTP协议接口相关资料

以几个简单的例子做为说明:

function main() {
    while (!exchange.IO("status")) {
        LogStatus("正在等待与交易服务器连接, " + new Date())
    }

    Log(exchange.IO("api", "ReqQryInvestor"))
}
def main():
    while not exchange.IO("status"):
        LogStatus("正在等待与交易服务器连接, " + _D())

    Log(exchange.IO("api", "ReqQryInvestor"))
void main() {
    while(exchange.IO("status") == 0) {
        LogStatus("正在等待与交易服务器连接, " + _D());
    }

    Log(exchange.IO("api", "ReqQryInvestor"));
}

查询投资者信息:

function main() {
    // CTP协议建立连接时需要时间
    Sleep(6000)
    exchange.IO("api", "ReqUserPasswordUpdate", {BrokerID: "9999", UserID: "11111", OldPassword: "oldpass", NewPassword: "newpass"})
}
def main():
    Sleep(6000)
    exchange.IO("api", "ReqUserPasswordUpdate", {"BrokerID": "9999", "UserID": "11111", "OldPassword": "oldpass", "NewPassword": "newpass"})
void main() {
    Sleep(6000);
    exchange.IO("api", "ReqUserPasswordUpdate", R"({"BrokerID": "9999", "UserID": "11111", "OldPassword": "oldpass", "NewPassword": "newpass"})"_json);
}

修改密码:

function main() {
    // CTP协议建立连接时需要时间
    Sleep(6000)
    // 如果再加一个参数值为false表示不等待返回值,只发送请求,第三个参数只需要填充需要的字段,也可省略此参数,如果类型为char,传长度为1的字符串即可
    var r = exchange.IO("api", "ReqQryProduct", {ProductID: "MA"})
    // CTP未登陆的时候会失败
    if (!r) {                                                        
        return
    }
    _.each(r, function(item) {
        // IO请求可能返回多个数据包,所以以数组的形式返回。便历数据包的所有数据类型,一个数据包可能包含多个具体数据,具体数据类型的名称,请参看CTP官方文档http://www.sfit.com.cn/5_2_DocumentDown.htm
        _.each(item, function(f) {                                           
            // 取出来需要的数据,Name为此数据的类型,Value为此数据的值
            if (f.Name == 'CThostFtdcProductField') {                
                // 打印查询的的甲醇的信息
                Log(f.Value)                                         
            }
        })
    });
}
def main():
    Sleep(6000)
    r = exchange.IO("api", "ReqQryProduct", {"ProductID": "MA"})
    if not r:
        return

    for r_index in range(len(r)):
        for f_index in range(len(r[r_index])):
            if r[r_index][f_index]["Name"] == 'CThostFtdcProductField':
                Log(r[r_index][f_index]["Value"])
void main() {
    Sleep(6000);
    auto r = exchange.IO("api", "ReqQryProduct", R"({"ProductID": "MA"})"_json);
    if(r == false) {
        return;
    }

    for(auto& ele1 : r.items()) {
        for(auto& ele2 : ele1.value().items()) {
            if(ele2.value()["Name"] == "CThostFtdcProductField") {
                Log(ele2.value()["Value"]);
            }
        }
    }
}

复杂的例子:

function main() {
    while (!exchange.IO("status")) {
        LogStatus("正在等待与交易服务器连接, " + new Date())
    }
    // 也可不指定日期
    var r = exchange.IO("api", "ReqQrySettlementInfo", {TradingDay: "20190506"})    
    var s = ''
    _.each(r, function(item) {
        _.each(item, function(f) {
            if (f.Name == 'CThostFtdcSettlementInfoField') {
                s += f.Value.Content
            }
        })
    })
    Log(s)
}
def main():
    while not exchange.IO("status"):
        LogStatus("正在等待与交易服务器连接, " + _D())
    r = exchange.IO("api", "ReqQrySettlementInfo", {"TradingDay": "20190506"})
    s = ''
    for i in range(len(r)):
        for ii in range(len(r[i])):
            if r[i][ii]["Name"] == "CThostFtdcSettlementInfoField":
                s += r[i][ii]["Value"]["Content"]
    
    Log(s)
void main() {
    while(exchange.IO("status") == 0) {
        LogStatus("正在等待与交易服务器连接, " + _D());
    }
    auto r = exchange.IO("api", "ReqQrySettlementInfo", R"({"TradingDay": "20200311"})"_json);
    string s = "";
    for(auto& ele1 : r.items()) {
        for(auto& ele2 : ele1.value().items()) {
            if(ele2.value()["Name"] == "CThostFtdcSettlementInfoField") {
                s += std::string(ele2.value()["Value"]["Content"]);
            }
        }
    }
    Log(s);
}

复杂的例子:

使用mode参数,切换行情模式:

  • exchange.IO("mode", 0) 立即返回模式,如果当前还没有接收到交易所最新的行情数据推送,就立即返回旧的行情数据,如果有新的数据就返回新的数据。 商品期货中的应用,可以参考:exchange.IO函数的wait参数的使用例子。

  • exchange.IO("mode", 1) 缓存模式(默认模式),如果当前还没有收到交易所最新的行情数据(同上一次接口获取的数据比较),就等待接收然后再返回,如果调用该函数之前收到了最新的行情数据,就立即返回最新的数据。

  • exchange.IO("mode", 2) 强制更新模式,进入等待一直到接收到交易所下一次的最新推送数据后返回。

{@var EXCHANGE_OP_IO_CONTROL}

exchange.Log

exchange.Log()函数用于在日志栏区域输出下单、撤单日志。调用时不会下单,只输出、记录交易日志。

exchange.Log(orderType, price, amount) exchange.Log(orderType, price, amount, …args)

orderType参数用于设置输出的日志类型,可选值为{@var/LOG_TYPE/LOG_TYPE_BUY LOG_TYPE_BUY},{@var/LOG_TYPE/LOG_TYPE_SELL LOG_TYPE_SELL},{@var/LOG_TYPE/LOG_TYPE_CANCEL LOG_TYPE_CANCEL}。 orderType true number price参数用于设置输出的日志中显示的价格。 price true number amount参数用于设置输出的日志中显示的下单量。 amount true number 扩展参数,可以输出附带信息到这条日志中,arg参数可以传多个。 arg false string、number、bool、object、array、空值等系统支持的任意类型

var id = 123
function main() {
    // 下单类型买入,价格999,数量 0.1
    exchange.Log(LOG_TYPE_BUY, 999, 0.1)      
    // 取消订单
    exchange.Log(LOG_TYPE_CANCEL, id)         
}
id = 123
def main():
    exchange.Log(LOG_TYPE_BUY, 999, 0.1)
    exchange.Log(LOG_TYPE_CANCEL, id)
void main() {
    auto id = 123;
    exchange.Log(LOG_TYPE_BUY, 999, 0.1);
    exchange.Log(LOG_TYPE_CANCEL, id);
}

使用exchange.Log(orderType, price, amount)可以进行实盘跟单测试、模拟下单、可以辅助记录下单。

orderType参数为LOG_TYPE_CANCEL时,price参数为撤单的订单Id,用于直接使用exchange.IO()函数撤单时打印撤单日志。 exchange.Log()函数是{@var/EXCHANGE exchange}交易所对象的成员函数,区别于全局函数{@fun/Log Log}。

{@fun/Log Log}, {@var/EXCHANGE exchange}, {@var/LOG_TYPE/LOG_TYPE_BUY LOG_TYPE_BUY}, {@var/LOG_TYPE/LOG_TYPE_SELL LOG_TYPE_SELL}, {@var/LOG_TYPE/LOG_TYPE_CANCEL LOG_TYPE_CANCEL}

Account

exchange.GetAccount

exchange.GetAccount()函数用于请求交易所账户信息。 GetAccount()函数是交易所对象{@var/EXCHANGE exchange}的成员函数,exchange对象的成员函数(方法)的用途只和exchange相关,文档之后不再赘述。

查询账户资产信息,查询成功返回{@struct/Account Account}结构,查询失败返回空值。 {@struct/Account Account}、空值

exchange.GetAccount()

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while (!exchange.IO("status")) {
        Sleep(1000)
    }
    
    // 获取账户资产信息,可以不用设置合约
    var account = exchange.GetAccount()
    Log("账户信息,Balance:", account.Balance, "FrozenBalance:", account.FrozenBalance, "Equity:", account.Equity, "UPnL:", account.UPnL)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)
    
    account = exchange.GetAccount()
    Log("账户信息,Balance", account["Balance"], "FrozenBalance:", account["FrozenBalance"], "Equity:", account["Equity"], "UPnL:", account["UPnL"])
void main() {
    while (exchange.IO("status") == 0) {
        Sleep(1000);
    }
    
    auto account = exchange.GetAccount();
    Log("账户信息,Balance", account.Balance, "FrozenBalance:", account.FrozenBalance, "Equity:", account.Equity, "UPnL:", account.UPnL);
}

获取当前账户信息。

{@struct/Account Account}

exchange.GetName

exchange.GetName()函数用于获取当前交易所对象绑定的交易所名称。

exchange.GetName()函数返回优宽量化交易平台定义的交易所名称。 string

exchange.GetName()

function main() {
    Log("判断交易所对象exchange为商品期货-CTP协议,判断结果为:", exchange.GetName() == "Futures_CTP")
}
def main():
    Log("判断交易所对象exchange为商品期货-CTP协议,判断结果为:", exchange.GetName() == "Futures_CTP")
void main() {
    Log("判断交易所对象exchange为商品期货-CTP协议,判断结果为:", exchange.GetName() == "Futures_CTP");
}

exchange.GetName()函数一般用来识别策略代码中的exchange或者exchanges[1]exchanges[2]这些交易所对象。

  • 股票证券 实盘:富途证券交易所对象时exchange.GetName()函数返回Futures_Futu。中泰XTP交易所对象时exchange.GetName()函数返回Futures_XTP。 回测系统:回测系统并不区分协议,所以exchange.GetName()函数返回Futures_XTP

  • 商品期货 实盘:CTP协议的交易所对象时exchange.GetName()函数返回Futures_CTP,易盛协议的交易所对象时exchange.GetName()函数返回Futures_Esunny。 回测系统:回测系统并不区分协议,所以exchange.GetName()函数返回Futures_CTP

{@fun/Account/exchange.GetLabel exchange.GetLabel}

exchange.GetLabel

exchange.GetLabel()函数用于获取配置交易所对象时设置的自定义标签。

exchange.GetLabel()函数返回配置交易所对象时设置的自定义标签。 string

exchange.GetLabel()

function main() {
    Log("exchange label:", exchange.GetLabel())
}
def main():
    Log("exchange label:", exchange.GetLabel())
void main() {
    Log("exchange label:", exchange.GetLabel());
}

通过设置的标签来识别策略代码中的exchange或者exchanges[1]exchanges[2]等交易所对象。

{@var/EXCHANGE exchange}

exchange.GetCurrency

exchange.GetCurrency()函数用于获取当前设置的交易对。

exchange.GetCurrency()函数返回当前{@var/EXCHANGE exchange}交易所对象设置的交易对。 string

exchange.GetCurrency()

function main() {
    Log("exchange 当前交易对为:", exchange.GetCurrency())
}
def main():
    Log("exchange 当前交易对为:", exchange.GetCurrency())
void main() {
    Log("exchange 当前交易对为:", exchange.GetCurrency());
}

商品期货、股票证券等返回固定的字符串: - 股票证券 实盘:富途证券交易所对象时exchange.GetCurrency()函数返回STOCK。 回测系统:exchange.GetCurrency()函数返回STOCK_CNY

  • 商品期货 实盘:exchange.GetCurrency()函数返回FUTURES。 回测系统:exchange.GetCurrency()函数返回FUTURES_CNY

{@fun exchange.SetCurrency}

exchange.GetQuoteCurrency

exchange.GetQuoteCurrency()函数用于获取当前交易对的计价币名称,即quoteCurrency

exchange.GetQuoteCurrency()函数返回当前交易对的计价币名称。 string

exchange.GetQuoteCurrency()

例如:国内商品期货的交易所对象返回CNY

{@fun/Account/exchange.GetCurrency exchange.GetCurrency}

Futures

exchange.GetPositions

exchange.GetPositions()函数用于获取所有合约当前持仓信息。GetPositions()函数是交易所对象{@var/EXCHANGE exchange}的成员函数。 GetPositions()函数获取交易所对象exchange绑定的交易所账户的持仓信息,exchange对象的成员函数(方法)的用途只和exchange相关,文档之后不再赘述。

exchange.GetPositions()函数请求数据成功时返回{@struct/Position Position}结构数组,请求数据失败时返回空值。 没有持仓则返回空数组,即[]。 {@struct/Position Position}数组、空值

exchange.GetPositions() exchange.GetPositions(symbol)

参数symbol用于指定请求的持仓数据的合约代码。不传该参数时默认请求所有合约的持仓数据。

symbol false string

/*
    注意:GetPositions函数获取的是所有持仓品种的持仓信息,如果没有持仓则返回空数组,所以使用该接口返回的数据前要先判断返回的数据是否为空数组
*/
function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }

    var info = exchange.SetContractType("rb888")
    var ticker = exchange.GetTicker()
    exchange.SetDirection("buy")
    exchange.Buy(ticker.Last + info.PriceTick * 20, 2)
    var position = exchange.GetPositions()
    if(position.length>0){
        Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
            position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type,
            "ContractType:", position[0].ContractType, "Symbol:", position[0].Symbol)
    }
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)

    info = exchange.SetContractType("rb888")
    ticker = exchange.GetTicker()
    exchange.SetDirection("buy")
    exchange.Buy(ticker["Last"] + info["PriceTick"] * 20, 2)
    position = exchange.GetPositions()
    if len(position) > 0:
        Log("Amount:", position[0]["Amount"], "FrozenAmount:", position[0]["FrozenAmount"], "Price:", 
            position[0]["Price"], "Profit:", position[0]["Profit"], "Type:", position[0]["Type"], 
            "ContractType:", position[0]["ContractType"], "Symbol:", position[0]["Symbol"])
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }

    auto info = exchange.SetContractType("rb888");
    auto ticker = exchange.GetTicker();
    exchange.SetDirection("buy");
    exchange.Buy(ticker.Last + info["PriceTick"].get<double>() * 20, 2);
    auto position = exchange.GetPositions();
    if(position.size() > 0) {
        Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:", 
            position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type, 
            "ContractType:", position[0].ContractType, "Symbol:", position[0].Symbol);
    } 
}

商品期货的持仓需要注意:

  • 回测系统 回测系统不区分今仓、昨仓。GetPositions函数返回的持仓数据{@struct/Position Position}结构数组中,Position结构的Type属性仅为PD_LONG或者PD_SHORT
  • 实盘 有交易所区分今仓、昨仓,例如上期所。 有些交易所虽然也区分,但是不能指定平今还是平昨,有今仓优先平今仓。例如IF等一些品种只能先平今仓,所以今仓、昨仓仓位信息合并为一个并且不予区分。

兼容exchange.GetPosition()调用。

exchange.GetPositions()函数不依赖于当前设置的合约代码,不传symbol参数时获取所有合约当前持仓信息。传入symbol参数时获取指定合约的持仓信息。

{@struct/Position Position}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}

exchange.SetMarginLevel

exchange.SetMarginLevel()函数用于设置{@var/EXCHANGE exchange}交易所对象当前交易对、合约的杠杆值。 商品期货、股票证券不支持。

exchange.SetMarginLevel(marginLevel)

marginLevel参数用于设置杠杆值,交易所的杠杆值通常是整数。 marginLevel true number

{@var/EXCHANGE exchange}

exchange.SetDirection

exchange.SetDirection()函数用于设置{@fun/Trade/exchange.Buy exchange.Buy}函数、{@fun/Trade/exchange.Sell exchange.Sell}函数进行期货合约下单时的订单方向。

exchange.SetDirection(direction) exchange.SetDirection(direction, type)

direction参数用于设置期货合约下单时的方向,可选值为:"buy""closesell""sell""closebuy"closesell_todayclosebuy_today。 其中closebuy_todayclosesell_today指平今仓。closebuy/closesell为平昨仓。 direction true string 对于CTP协议传统期货,可以设置第二个参数type"1"或者"2"或者"3",分别指"投机",“套利”,“套保”,不设置默认为投机。 type false string

function main(){
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }

    // 举例设置为螺纹钢主力合约
    exchange.SetContractType("rb888")    
    // 设置下单类型为做多
    exchange.SetDirection("buy")
    // 以10000的价格,合约数量为2张下单。注意,这里的下单价格为举例,具体测试的时候可以自行设置、改动
    exchange.Buy(10000, 2)
    // 设置下单类型为平多
    exchange.SetDirection("closebuy")
    exchange.Sell(1000, 2)
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)

    exchange.SetContractType("rb888")
    exchange.SetDirection("buy")
    exchange.Buy(10000, 2)
    exchange.SetDirection("closebuy")
    exchange.Sell(1000, 2)
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }

    exchange.SetContractType("rb888");
    exchange.SetDirection("buy");
    exchange.Buy(10000, 2);
    exchange.SetDirection("closebuy");
    exchange.Sell(1000, 2);
}

exchange.SetDirection()函数设置期货合约交易的方向和下单函数之间的对应关系:

下单函数 SetDirection函数的参数设置的方向 备注
exchange.Buy “buy” 买入开多仓
exchange.Buy “closesell” 买入平空仓
exchange.Buy “closesell_today” 买入平空仓(今仓)
exchange.Sell “sell” 卖出开空仓
exchange.Sell “closebuy” 卖出平多仓
exchange.Sell “closebuy_today” 卖出平多仓(今仓)

{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}

exchange.SetContractType

exchange.SetContractType()函数用于设置{@var/EXCHANGE exchange}交易所对象当前的合约代码。 期货支持传统商品期货CTP协议,易盛协议。所有操作前需要先使用exchange.SetContractType()函数设置合约代码。

exchange.SetContractType()函数返回一个结构。该结构中记录合约的详细信息,例如:最小下单合约张数、手续费、交割时间等数据。

打印exchange.SetContractType("MA888")函数返回的数据,即合约详细信息如下:

{
    "InstrumentName": "甲醇连续",
    "MinLimitOrderVolume": 1,
    "OpenDate": "20190116",
    "PositionType": 50,
    "LongMarginRatio": 0.06999999999999999,
    "DeliveryYear": 2020,
    "MaxMarketOrderVolume": 1000,
    "ExpireDate": "20200114",
    "PositionDateType": 50,
    "InstLifePhase": 49,
    "UnderlyingMultiple": 1,
    "CombinationType": 48,
    "InstrumentID": "MA001",
    "ExchangeInstID": "MA001",
    "ProductClass": 49,
    "MinMarketOrderVolume": 1,
    "VolumeMultiple": 10,
    "CreateDate": "20190116",
    "ShortMarginRatio": 0.06999999999999999,
    "UnderlyingInstrID": "",
    "ProductID": "MA",
    "PriceTick": 1,
    "StartDelivDate": "20200114",
    "EndDelivDate": "20200114",
    "ExchangeID": "CZCE",
    "MaxLimitOrderVolume": 1000,
    "MaxMarginSideAlgorithm": 48,
    "DeliveryMonth": 1,
    "IsTrading": 1,
    "StrikePrice": 0,
    "OptionsType": 0
}

object

exchange.SetContractType(symbol)

例如:exchange.SetContractType("rb2310"),作用为设置当前操作的合约为螺纹钢2023年10月交割的合约。 主力连续合约的代码为888,例如MA888,连续指数合约为000,例如MA000888000虚拟合约的交易只支持回测,实盘只支持获取行情。

symbol true string

function main(){
    while(true) {
        if (exchange.IO("status")) {
            var ret = exchange.SetContractType("MA888")
            Log("订阅的合约的详细信息:", ret)
            break
        } else {
            LogStatus(_D(), "未连接")
        }
    }
}
def main():
    while True:
        if exchange.IO("status"):
            ret = exchange.SetContractType("MA888")
            Log("订阅的合约的详细信息:", ret)
            break
        else:
            LogStatus(_D(), "未连接")
void main() {
    while(true) {
        if(exchange.IO("status") == 1) {
            auto ret = exchange.SetContractType("MA888");
            Log("订阅的合约的详细信息:", ret);
            break;
        } else {
            LogStatus(_D(), "未连接");
        }
    }
}

使用exchange.SetContractType()函数设置(订阅)合约。

function main(){
    var n = 0
    while(true){
        // 需要在判断exchange.IO("status")函数返回true,即为真值时才可调用行情、交易等函数
        if(exchange.IO("status")){
            // 设置合约为虚拟合约,MA888,即甲醇主力合约
            var ret = _C(exchange.SetContractType, "MA888")
            var ticker = exchange.GetTicker()
            // 当到达交易条件时
            if(n == 100) {
                exchange.SetContractType(ret.InstrumentID)
                Log("设置映射的实际合约:", ret.InstrumentID)
                exchange.SetDirection("buy")
                var id = exchange.Buy(ticker.Buy - 10, 1)
                Log("id:", id)
                Sleep(1000)
                Log(exchange.GetOrder(id))
                Sleep(1000)
                Log(exchange.GetPositions())
                Sleep(1000)
                exchange.CancelOrder(id)
                Sleep(1000)
                Log(exchange.GetOrders())
            }
            n++
            LogStatus(_D(), "已经连接CTP !")
        } else {
            LogStatus(_D(), "未连接CTP !")
        }
    }
}
def main():
    n = 0
    while True:
        if exchange.IO("status"):
            ret = _C(exchange.SetContractType, "MA888")
            ticker = exchange.GetTicker()
            if n == 100:
                exchange.SetContractType(ret["InstrumentID"])
                Log("设置映射的实际合约:", ret["InstrumentID"])
                exchange.SetDirection("buy")
                id = exchange.Buy(ticker["Buy"] - 10, 1)
                Log("id:", id)
                Sleep(1000)
                Log(exchange.GetOrder(id))
                Sleep(1000)
                Log(exchange.GetPositions())
                Sleep(1000)
                exchange.CancelOrder(id)
                Sleep(1000)
                Log(exchange.GetOrders())
            n += 1
            LogStatus(_D(), "已经连接CTP !")
        else:
            LogStatus(_D(), "未连接CTP !")
void main() {
    int n = 0;
    while(true) {
        if(exchange.IO("status") == 1) {
            auto ret = exchange.SetContractType("MA888");
            auto ticker = exchange.GetTicker();
            if(n == 100) {
                exchange.SetContractType(ret["InstrumentID"]);
                Log("设置映射的实际合约:", ret["InstrumentID"]);
                exchange.SetDirection("buy");
                auto id = exchange.Buy(ticker.Buy - 10, 1);
                Log("id:", id);
                Sleep(1000);
                Log(exchange.GetOrder(id));
                Sleep(1000);
                Log(exchange.GetPositions());
                Sleep(1000);
                exchange.CancelOrder(id);
                Sleep(1000);
                Log(exchange.GetOrders());
            }
            n++;
            LogStatus(_D(), "已经连接CTP !");
        } else {
            LogStatus(_D(), "未连接CTP !");
        }
    }
}

商品期货只有回测支持虚拟合约交易,实盘时虚拟合约只支持获取行情,实盘时我们可以用虚拟合约映射的真实合约下单,例如以下代码:

在商品期货策略中调用exchange.SetContractType(ContractType)函数时,实盘或者simnow模拟盘中是可能订阅失败的,例如连接期货公司前置机失败时或者设置了不存在的合约代码时。 订阅虚拟合约成功以后,返回的字段里面的InstrumentID是主力合约(会在订阅同时获取),方便策略实盘下单交易时做映射使用。 对于商品期货合约代码不太熟悉的用户可以使用如下JavaScript语言的代码查询:

function main(){
    while(true){
        if(exchange.IO("status")){         
            var products_CZCE_Tbl = {
                "type" : "table", 
                "title" : "郑商所 CZCE", 
                "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                "rows" : [] 
            }
            var products_DCE_Tbl = {
                "type" : "table", 
                "title" : "大商所 DCE", 
                "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                "rows" : [] 
            }
            var products_SHFE_Tbl = {
                "type" : "table", 
                "title" : "上期所 SHFE", 
                "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                "rows" : [] 
            }
            var products_other_Tbl = {
                "type" : "table", 
                "title" : "其它", 
                "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                "rows" : [] 
            }
            exchange.IO("products").forEach(function(product) {
                if (product.ExchangeID == "CZCE") {
                    products_CZCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                } else if (product.ExchangeID == "DCE") {
                    products_DCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                } else if (product.ExchangeID == "SHFE") {
                    products_SHFE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                } else {
                    products_other_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                }                
            })
            LogStatus(_D(), "已经连接CTP", "\n`" + JSON.stringify([products_CZCE_Tbl, products_DCE_Tbl, products_SHFE_Tbl, products_other_Tbl]) + "`")  
            Sleep(1000 * 60 * 5)
        } else {
            LogStatus(_D(), "未连接CTP !")
        }
        Sleep(1000)
    }
}

查询结果显示各个交易所的合约信息。

商品期货合约命名规则如下: 前面字母代表品种名(合约代码短名),后面数字代表合约到期日。

交易所 合约命名规则
上期 / 能源所: 小写 + 4个数字
大商所: 小写 + 4个数字
中金所: 大写 + 4个数字
郑商所: 大写 + 3个数字

{@fun/Futures/exchange.GetContractType exchange.GetContractType}

exchange.GetContractType

exchange.GetContractType()函数用于获取{@var/EXCHANGE exchange}交易所对象当前设置的合约代码。

exchange.GetContractType()函数返回交易所对象{@var/EXCHANGE exchange}当前设置的合约代码。 string

exchange.GetContractType()

function main () {
    // 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
    while(!exchange.IO("status")) {
        Sleep(1000)
    }

    Log(exchange.SetContractType("rb888")) 
    Log(exchange.GetContractType())
}
def main():
    while not exchange.IO("status"):
        Sleep(1000)

    Log(exchange.SetContractType("rb888"))
    Log(exchange.GetContractType())
void main() {
    while(exchange.IO("status") == 0) {
        Sleep(1000);
    }

    Log(exchange.SetContractType("rb888"));
    Log(exchange.GetContractType());
}

{@fun/Futures/exchange.SetContractType exchange.SetContractType}

StrDecode

商品期货CTP协议中的汉字是GBK编码可用StrDecode()函数解码。

StrDecode()函数返回GBK编码的字符串解码后的内容。 string

StrDecode(gbkString)

需要解码的字符串。 gbkString true string

{@fun/Global/Encode Encode}

Threads

优宽量化交易平台从系统底层真正支持JavaScript语言策略的多线程功能,实现了以下对象:

对象 说明 备注
threading 多线程全局对象 成员函数:ThreadgetThreadmainThread等。
Thread 线程对象 成员函数:peekMessagepostMessagejoin等。
ThreadLock 线程锁对象 成员函数:acquirerelease。可作为线程执行函数的参数传入线程环境。
ThreadEvent 事件对象 成员函数:setclearwaitisSet。可作为线程执行函数的参数传入线程环境。
ThreadCondition 条件对象 成员函数:notifynotifyAllwaitacquirerelease。可作为线程执行函数的参数传入线程环境。
ThreadDict 字典对象 成员函数:getset。可作为线程执行函数的参数传入线程环境。

threading

threading对象作为全局多线程管理工具,提供了创建并发线程、线程锁、条件对象等功能;本章节介绍threading对象的成员函数;仅JavaScript语言策略支持该对象。

Thread

Thread()函数用于创建并发线程。

Thread()函数返回一个Thread对象,用于管理创建出的并发线程、线程通信等。

Thread对象

Thread(func, …args) Thread(…items)

参数func是用于并发执行的函数(通过引用传递),支持传入匿名函数。func可接受多个参数,这些参数将在并发执行时通过...args传入。因此,func的参数列表需要与...args一致。

func true function 参数arg是在回调执行时传递给func(即并发线程执行函数)的实际参数;参数arg可能有多个,func的参数列表需要与...args一致。

arg false string、number、bool、object、array、function、空值等系统支持的所有类型 参数item是一个数组,包含待并发执行的函数引用及其参数,调用Thread函数时的参数item可以传入多组。

item true array

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()
}

同时创建一个自定义函数和一个匿名函数的并发线程。

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()
}

使用Thread(...items)形式来创建并发线程,顺序执行多个函数。

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()函数用于并发执行的线程函数func运行在隔离环境中,因此无法直接引用线程外部的变量,引用时会编译失败。同时,线程内不支持引用其它闭包函数。线程内部可调用平台提供的所有API,但不能调用用户自定义的其他函数。

支持回测系统、实盘环境;所有并发线程相关的函数,在回测系统中仅作为代码兼容支持,实际不会真正并发线程执行,本章不再赘述。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

getThread

getThread()函数用于根据指定的线程Id获取线程对象。

getThread()函数返回通过参数指定threadId的Thread对象

Thread对象

getThread(threadId)

参数threadId为线程对象Id,通过指定参数获取对应的线程对象。

threadId true number

function main() {
    var t1 = threading.Thread(function () {
        Log("Hello thread1")
    })
    // Thread 对象有方法:id(),用于获取线程的Id,可以查看文档对应Thread对象的章节
    var threadId = t1.id()
    var threadName = t1.name()
    Log("threadId:", threadId, ", threadName:", threadName)
    
    var t2 = threading.getThread(threadId)
    Log(`threadId == t2.id():`, threadId == t2.id(), `, threadName == t2.name():`, threadName == t2.name())
}

通过threadId获取指定的线程对象。

支持回测系统、实盘环境。

如果期望获取的线程已经执行完毕、释放,此时无法通过threading.getThread(threadId)获取该线程的线程对象。

{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

mainThread

mainThread()函数用于获取主线程的线程对象,即策略中main()函数所在的线程。

mainThread()函数返回主线程的线程对象。

Thread对象

mainThread()

function main() {
    Log("主线程的threadId:", threading.mainThread().id())
}

获取主线程的Thread对象,输出主线程的threadId

function test() {
    Log("test函数中输出主线程Id:", threading.mainThread().id())
}

function main() {
    var t1 = threading.Thread(test)
    t1.join()
}

在并发的线程中也可以获取主线程的线程对象。

支持回测系统、实盘环境。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

currentThread

currentThread()函数用于获取当前线程的线程对象。

currentThread()函数返回当前线程的线程对象。

Thread对象

currentThread()

function test() {
    Log("当前线程的Id:", threading.currentThread().id())
}

function main() {
    var t1 = threading.Thread(test)
    t1.join()
}

获取当前线程的Thread对象,输出当前线程的threadId

支持回测系统、实盘环境。

{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

Lock

Lock()函数用于创建线程锁对象。

Lock()函数返回一个线程锁对象。

ThreadLock对象

Lock()

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()
}

两个并发线程访问公共资源。

支持回测系统、实盘环境。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

Condition

Condition()函数用于创建一个条件变量对象,该对象用于在多线程并发环境中实现线程间的同步与通信。通过Condition(),一个线程可以在某些条件未满足时等待,直到另一个线程通知它条件已经满足。

Condition()函数返回一个ThreadCondition对象。

ThreadCondition对象

Condition()

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()
}

两个并发线程访问公共资源。

回测系统没有实现该功能,仅仅是定义。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

Event

Event()函数用于创建一个线程事件对象,该对象用于线程间的同步,允许一个线程等待另一个线程的通知或信号。

Event()函数返回一个ThreadEvent对象。

ThreadEvent对象

Event()

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()
}

两个并发线程访问公共资源。

支持回测系统、实盘环境。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

Dict

Dict()函数用于创建一个字典对象,用于传递到并发的线程中。

Dict()函数返回一个ThreadDict对象。

ThreadDict对象

Dict()

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()    
}

给并发的线程执行函数传入普通的对象,测试修改对象的键值后是否引起其它线程中的对象键值变动。

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()    
}

给并发的线程执行函数传入Dict()函数创建的ThreadDict对象,测试修改对象的键值后是否引起其它线程中的对象键值变动。

线程并发函数传入普通对象时为深拷贝传递,在并发线程中修改键值,并不会影响到其它线程中的字典。

支持回测系统、实盘环境。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}

pending

pending函数用于获取当前策略程序正在运行的并发线程数。

pending()函数返回当前策略程序正在运行的并发线程数。

number

pending()

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())
}

创建两个并发运行的线程,在不同时间节点调用pending()函数。

策略main()函数开始运行时直接调用pending()函数会返回1,因为策略main()函数所在的主线程也是一个pending中的线程。

支持回测系统、实盘环境。

{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/eventLoop eventLoop}

Thread

Thread对象可以由threading.Thread()threading.getThread()threading.mainThread()threading.currentThread()创建或者返回。

peekMessage

peekMessage()函数用于从线程获取消息。

peekMessage()函数返回当前线程对象关联的线程收到的消息。

string、number、bool、object、array、空值等系统支持的所有类型

peekMessage() peekMessage(timeout)

参数timeout为超时设置,会按照该参数设置的毫秒数阻塞等待,返回数据;没有数据并且超时则返回空值。如果timeout设置为0或者不传timeout参数,则表示一直阻塞等待,直到接收到通道中的数据。如果timeout设置为-1,则表示不阻塞并且立即返回数据,没有数据时返回空值。

timeout false number

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()
}

并发线程中向主线程发送消息。

在编写程序时需要注意线程死锁问题。

{@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

postMessage

postMessage()函数用于向线程发送消息。

postMessage(msg)

参数msg为所要发送的消息。

msg true string、number、bool、object、array、空值等系统支持的任意类型

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()
}

在并发的线程中发送消息,使用eventLoop()接收消息通知。

当一个线程的执行函数中调用postMessage()函数发出信号、数据时,也会产生消息事件。 可以用eventLoop()函数收到消息通知。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

join

join()函数用于等待线程退出,并回收系统资源。

ThreadRet对象包含执行结果的相关数据,包含的属性如下:

  • id: 线程Id。
  • terminated: 线程是否被强制结束。
  • elapsed: 线程的运行时间(纳秒)。
  • ret: 线程函数的返回值。

ThreadRet对象

join() join(timeout)

timeout参数用于设置等待线程结束的超时时间,单位为毫秒。timeout参数设置为0或者不设置timeout参数时join()函数会阻塞,等待到线程执行结束。timeout参数设置为-1时,join()函数会立即返回。

timeout false number

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}
}

测试join()函数超时,输出返回值。

join()函数超时,返回undefined

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

terminate

terminate()函数用于强制结束线程,释放创建线程使用的硬件资源。

terminate()

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()函数等待结束。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

getData

getData()函数用于访问线程环境中记录的变量。数据在线程没有被执行join()函数(等待退出成功)并且没有被执行terminate()函数(强制终止线程)的情况下有效。

getData()函数返回当前线程环境中储存的键-值对中key参数对应的键值。

string、number、bool、object、array、空值等系统支持的所有类型

getData() getData(key)

key参数为储存的键-值对的键名。

key true string

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()
}

在并发线程的环境中记录键名为count的值,然后在主线程中读取count的键值。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

setData

setData()函数用于在线程环境储存变量。

setData(key, value)

key参数用于指定储存的键-值对的键名。

key true string value参数用于指定储存的键-值对的键值。

value true string、number、bool、object、array、空值等系统支持的任意类型

function main() {
    var t1 = threading.Thread(function() {
        threading.currentThread().setData("data", 100)
    })
    Sleep(1000)
    Log(`t1.getData("data"):`, t1.getData("data"))
    t1.join()
}

并发的线程中设置键值对,主线程中读取这个键值对。

数据在线程没有被执行join()函数(等待退出成功)并且没有被执行terminate()函数(强制终止线程)的情况下有效。参数value的值必须是可序列化的变量。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

id

id()函数用于返回当前多线程对象实例的threadId

id()函数的返回值为threadId

number

id()

function main() {
    var t1 = threading.Thread(function() {
        threading.currentThread().setData("data", 100)
    })
    Log(`t1.id():`, t1.id())
    t1.join()
}

创建一个并发运行的线程,在主线程输出这个并发线程的threadId

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}

name

name()函数用于返回当前多线程对象实例的名称。

name()函数返回值为并发的线程名称。

string

name()

function main() {
    var t1 = threading.Thread(function() {
        threading.currentThread().setData("data", 100)
    })
    Log(`t1.name():`, t1.name())  // t1.name(): Thread-1
    t1.join()
}

创建一个并发运行的线程,在主线程输出这个并发线程的名称。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/eventLoop eventLoop}

eventLoop

eventLoop()函数用于监听线程收到的事件。

eventLoop()函数返回当前线程收到的事件信息,查看事件信息结构

object、空值

eventLoop() eventLoop(timeout)

参数timeout为超时设置,单位为毫秒。参数timeout如果设置为0则等待有事件发生才返回,如果大于0就是设置事件等待超时,小于0立即返回最近事件。

timeout false number

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()
}

并发执行3个线程,输出接收到的事件信息,超时或者立即返回时输出的是空值。

eventLoop()函数的处理机制与全局函数EventLoop()一致。

{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}

ThreadLock

线程锁对象,用于多线程同步处理。

acquire

acquire()函数用于请求一个线程锁(加锁)。

acquire()

范例可以参考threading.Lock()章节的内容。

acquire()函数用于请求一个线程锁。当一个线程调用某个线程锁对象的acquire()函数时,它会尝试获取锁,如果锁当前没有被其它线程占用,调用线程就会成功获得锁并继续执行。如果锁已经被其它线程持有,调用acquire()的线程会被阻塞,直到锁被释放。

{@fun/Threads/threading/Lock Lock}, {@fun/Threads/ThreadLock/release release}

release

release()函数用于释放一个线程锁(解锁)。

release()

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()
}

测试死锁场景

需要注意,线程锁使用不当可能导致死锁。

{@fun/Threads/threading/Lock Lock}, {@fun/Threads/ThreadLock/acquire acquire}

ThreadEvent

事件对象,用于多线程事件通知、信号。

set

set()函数用于通知事件(设置信号)。

set()

可以参考threading.Event()章节范例。

如果已经set()设置过,不能重复设置,需要清空之后重新设置信号。

{@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/wait wait}, {@fun/Threads/ThreadEvent/isSet isSet}

clear

clear()函数用于清理信号。

clear()

可以参考threading.Event()章节范例。

{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/wait wait}, {@fun/Threads/ThreadEvent/isSet isSet}

wait

wait()函数用于设置事件(信号)等待,在事件(信号)被设置之前会阻塞;支持设置超时参数。

wait()函数返回是否超时,如果超时返回真值。

bool

wait() wait(timeout)

参数timeout用于设置等待超时,单位毫秒。

timeout false number

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()
}

测试wait()函数的返回值。

{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/isSet isSet}

isSet

isSet()函数用于判断是否已经设置了事件(信号)。

isSet()函数返回是否已经设置了事件(信号);如果当前已经设置过事件(信号)则返回真值。

bool

isSet()

可以参考threading.Event()章节范例。

{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/wait wait}

ThreadCondition

条件对象,用于多线程同步。

notify

notify()函数用于唤醒一个正在等待的线程(如果有的话)。只有调用了wait()方法的线程才会被唤醒。

notify()

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()函数会唤醒处于等待队列中的一个线程。

notify()函数唤醒一个线程时,这个线程会重新获取线程锁。

{@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}

notifyAll

notifyAll()函数会唤醒所有正在等待的线程。

notifyAll()

范例可以参考ThreadCondition.notify()章节的内容。

notifyAll()函数逐个唤醒所有等待中的线程,被唤醒的线程重新获取线程锁。

{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}

wait

wait()函数用于在某些设计的条件下让线程等待。

wait()

范例可以参考ThreadCondition.notify()章节的内容。

wait()函数会释放线程锁,当被唤醒时重新获取线程锁。

{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}

acquire

acquire()函数用于请求一个线程锁(加锁)。

acquire()

范例可以参考ThreadCondition.notify()章节的内容。

在使用wait()之前需要请求当前条件对象的线程锁(加锁)。

{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/release release}

release

release()函数用于释放一个线程锁(解锁)。

release()

范例可以参考ThreadCondition.notify()章节的内容。

在使用wait()之后需要释放当前条件对象的线程锁(解锁)。

{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}

ThreadDict

字典对象,用于数据共享。

get

get()函数用于获取字典对象中记录的键值。

get()函数返回通过参数key指定的键值。

string、number、bool、object、array、空值等系统支持的所有类型

get(key)

参数key用于指定要获取的键对应的键名。

key true string

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"))
}

使用事件对象通知线程读取、修改数据。

{@fun/Threads/ThreadDict/set set}

set

set()函数用于设置键值对。

set(key, value)

参数key用于设置需要修改的键名。

key true string 参数value用于设置需要修改的键值。

value true string、number、bool、object、array、空值等系统支持的所有类型

范例可以参考ThreadDict.get()章节的内容。

{@fun/Threads/ThreadDict/get get}

TA

TA.MACD

TA.MACD()函数用于计算指数平滑异同平均线指标

TA.MACD()函数的返回值为二维数组,结构为:[DIF, DEA, MACD]。 array

TA.MACD(inReal) TA.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastPeriod参数用于设置快周期。 optInFastPeriod false number optInSlowPeriod参数用于设置慢周期。 optInSlowPeriod false number optInSignalPeriod参数用于设置信号周期。 optInSignalPeriod false number

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])
}
def main():
    r = exchange.GetRecords(PERIOD_M15)
    macd = TA.MACD(r, 12, 26, 9)
    Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
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]);
}

测试TA.MACD()函数:

优宽量化的TA指标库,优化了常用指标算法。 支持JavaScriptPythonC++语言策略的调用,开源TA库代码TA.MACD()函数的optInFastPeriodoptInSlowPeriodoptInSignalPeriod参数的默认值为:12269

{@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.KDJ

TA.KDJ()函数用于计算随机指标

TA.KDJ()函数的返回值为二维数组,结构为:[K, D, J]。 array

TA.KDJ(inReal) TA.KDJ(inReal, period, kPeriod, dPeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 period参数用于设置周期1。 period false number kPeriod参数用于设置周期2。 kPeriod false number dPeriod参数用于设置周期3。 dPeriod false number

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])
}
def main():
    r = exchange.GetRecords(PERIOD_M15)
    kdj = TA.KDJ(r, 9, 3, 3)
    Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
void main() {
    auto r = exchange.GetRecords();
    auto kdj = TA.KDJ(r, 9, 3, 3);
    Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]);
}

测试TA.KDJ()函数:

TA.KDJ()函数的periodkPerioddPeriod参数的默认值为:933

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.RSI

TA.RSI()函数用于计算强弱指标

TA.RSI()函数的返回值为:一维数组。 array

TA.RSI(inReal) TA.RSI(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期。 optInTimePeriod false number

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var rsi = TA.RSI(records, 14)
    Log(rsi)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    rsi = TA.RSI(r, 14)
    Log(rsi)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto rsi = TA.RSI(r, 14);
    Log(rsi); 
}

测试TA.RSI()函数:

TA.RSI()函数的optInTimePeriod参数的默认值为:14

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.ATR

TA.ATR()函数用于计算平均真实波幅指标

TA.ATR()函数的返回值为:一维数组。 array

TA.ATR(inPriceHLC) TA.ATR(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期。 optInTimePeriod false number

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var atr = TA.ATR(records, 14)
    Log(atr)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    atr = TA.ATR(r, 14)
    Log(atr)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto atr = TA.ATR(r, 14);
    Log(atr);
}

测试TA.ATR()函数:

TA.ATR()函数的optInTimePeriod参数的默认值为:14

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.OBV

TA.OBV()函数用于计算能量潮指标

TA.OBV()函数的返回值为:一维数组。 array

TA.OBV(inReal) TA.OBV(inReal, inPriceV)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 inPriceV参数用于指定成交量数据。 inPriceV false {@struct/Record Record}结构数组

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var obv = TA.OBV(records)
    Log(obv)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    obv = TA.OBV(r)
    Log(obv)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto obv = TA.OBV(r);
    Log(obv);
}

测试TA.OBV()函数:

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.MA

TA.MA()函数用于计算移动平均线指标

TA.MA()函数的返回值为:一维数组。 array

TA.MA(inReal) TA.MA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期。 optInTimePeriod false number

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var ma = TA.MA(records, 14)
    Log(ma)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    ma = TA.MA(r, 14)
    Log(ma)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto ma = TA.MA(r, 14);
    Log(ma);
}

测试TA.MA()函数:

TA.MA()函数的optInTimePeriod参数的默认值为:9

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.EMA

TA.EMA()函数用于计算指数平均数指标

TA.EMA()函数的返回值为:一维数组。 array

TA.EMA(inReal) TA.EMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期。 optInTimePeriod false number

function main(){
    var records = exchange.GetRecords()
    // 判断K线bar数量是否满足指标计算周期
    if (records && records.length > 9) {
        var ema = TA.EMA(records, 9)          
        Log(ema)
    }
}
def main():
    r = exchange.GetRecords()
    if r and len(r) > 9:
        ema = TA.EMA(r, 9)
        Log(ema)
void main() {
    auto r = exchange.GetRecords();
    if(r.Valid && r.size() > 9) {
        auto ema = TA.EMA(r, 9);
        Log(ema);
    }
}

测试TA.EMA()函数:

TA.EMA()函数的optInTimePeriod参数的默认值为:9

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.BOLL

TA.BOLL()函数用于计算布林带指标

TA.BOLL()函数的返回值为二维数组,结构为:[upLine, midLine, downLine]。 array

TA.BOLL(inReal) TA.BOLL(inReal, period, multiplier)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 period参数用于设置周期。 period false number multiplier参数用于设置乘数。 multiplier false number

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)
    }
}
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)
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);
    }
}

测试TA.BOLL()函数:

TA.BOLL()函数的periodmultiplier参数的默认值为:202

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.Alligator

TA.Alligator()函数用于计算鳄鱼线指标

TA.Alligator()函数的返回值为二维数组,结构为:[jawLine, teethLine, lipsLine]。 array

TA.Alligator(inReal) TA.Alligator(inReal, jawLength, teethLength, lipsLength)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 jawLength参数用于设置下颚周期。 jawLength false number teethLength参数用于设置牙齿周期。 teethLength false number lipsLength参数用于设置上唇周期。 lipsLength false number

function main(){
    var records = exchange.GetRecords()
    var alligator = TA.Alligator(records)
    Log("jawLine:", alligator[0])
    Log("teethLine:", alligator[1])
    Log("lipsLine:", alligator[2])
}
def main():
    records = exchange.GetRecords()
    alligator = TA.Alligator(records)
    Log("jawLine:", alligator[0])
    Log("teethLine:", alligator[1])
    Log("lipsLine:", alligator[2])
void main() {
    auto records = exchange.GetRecords();
    auto alligator = TA.Alligator(records);
    Log("jawLine:", alligator[0]);
    Log("teethLine:", alligator[1]);
    Log("lipsLine:", alligator[2]);
}

测试TA.Alligator()函数:

TA.Alligator()函数的jawLengthteethLengthlipsLength参数的默认值为:1385

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.CMF

TA.CMF()函数用于计算蔡金货币流量指标

TA.CMF()函数的返回值为:一维数组。 array

TA.CMF(inReal) TA.CMF(inReal, inPriceV)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 inPriceV参数用于指定成交量数据。 inPriceV false {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var cmf = TA.CMF(records)
    Log(cmf)
}
def main():
    records = exchange.GetRecords()
    cmf = TA.CMF(records)
    Log(cmf)
void main() {
    auto records = exchange.GetRecords();
    auto cmf = TA.CMF(records);
    Log(cmf);
}

测试TA.CMF()函数:

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

TA.Highest

TA.Highest()函数用于计算周期最高价

TA.Highest()函数返回最近一定周期内的某个属性的最大值,不包含当前Bar。 number

TA.Highest(inReal) TA.Highest(inReal, period, attr)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 period参数用于设置周期。 period false number attr参数用于设置属性,可选:OpenCloseLowHighVolumeOpenInterest。 attr false string

function main() {
    var records = exchange.GetRecords()
    var highestForOpen = TA.Highest(records, 10, "Open")
    Log(highestForOpen)
}
def main():
    records = exchange.GetRecords()
    highestForOpen = TA.Highest(records, 10, "Open")
    Log(highestForOpen)
void main() {
    auto records = exchange.GetRecords();
    auto highestForOpen = TA.Highest(records.Open(), 10);
    Log(highestForOpen);
}

测试TA.Highest()函数:

例如调用TA.Highest(records, 30, "High")函数,如果周期参数period设置为0, 指计算inReal参数传入的K线数据的所有Bar;如果属性参数attr不指定,则视为inReal参数传入的K线数据为普通数组。

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Lowest TA.Lowest}

TA.Lowest

TA.Lowest()函数用于计算周期最低价

TA.Lowest()函数返回最近一定周期内的某个属性的最小值,不包含当前Bar。 number

TA.Lowest(inReal) TA.Lowest(inReal, period, attr)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 period参数用于设置周期。 period false number attr参数用于设置属性,可选:OpenCloseLowHighVolumeOpenInterest。 attr false string

function main() {
    var records = exchange.GetRecords()
    var lowestForOpen = TA.Lowest(records, 10, "Open")
    Log(lowestForOpen)
}
def main():
    records = exchange.GetRecords()
    lowestForOpen = TA.Lowest(records, 10, "Open")
    Log(lowestForOpen)
void main() {
    auto records = exchange.GetRecords();
    auto lowestForOpen = TA.Lowest(records.Open(), 10);
    Log(lowestForOpen);
}

测试TA.Lowest()函数:

例如调用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++语言策略的测试范例:

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);                     
}

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}

TA.SMA

TA.SMA()函数用于计算简单移动平均指标

TA.SMA()函数的返回值为:一维数组。 array

TA.SMA(inReal) TA.SMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期。 optInTimePeriod false number

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var sma = TA.SMA(records, 14)
    Log(sma)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    sma = TA.SMA(r, 14)
    Log(sma)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto sma = TA.SMA(r, 14);
    Log(sma);
}

测试TA.SMA()函数:

TA.SMA()函数的optInTimePeriod参数的默认值为:9

{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}

Talib

talib.CDL2CROWS

talib.CDL2CROWS()函数用于计算Two Crows (K线图–两只乌鸦)

talib.CDL2CROWS()函数的返回值为:一维数组。 array

talib.CDL2CROWS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL2CROWS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL2CROWS(records);
    Log(ret);
}

CDL2CROWS()函数在talib库文档中的描述为:CDL2CROWS(Records[Open,High,Low,Close]) = Array(outInteger) 对于Python语言中的调用来说,传参有所不同,需要根据以上描述中的:Records[Open,High,Low,Close]传参。

举例把一个变量records(即参数inPriceOHLC,类型为{@struct/Record Record}结构数组)拆分成: Open列表:在Python中写为records.OpenHigh列表:在Python中写为records.HighLow列表:在Python中写为records.LowClose列表:在Python中写为records.Close

Python策略代码中调用:


talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)

其它talib指标以此类推,不再赘述。

talib.CDL3BLACKCROWS

talib.CDL3BLACKCROWS()函数用于计算Three Black Crows (K线图–3只黑乌鸦)

talib.CDL3BLACKCROWS()函数的返回值为:一维数组。 array

talib.CDL3BLACKCROWS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3BLACKCROWS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3BLACKCROWS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3BLACKCROWS(records);
    Log(ret);
}

CDL3BLACKCROWS()函数在talib库文档中的描述为:CDL3BLACKCROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3INSIDE

talib.CDL3INSIDE()函数用于计算Three Inside Up/Down (K线图:3内上下震荡)

talib.CDL3INSIDE()函数的返回值为:一维数组。 array

talib.CDL3INSIDE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3INSIDE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3INSIDE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3INSIDE(records);
    Log(ret);
}

CDL3INSIDE()函数在talib库文档中的描述为:CDL3INSIDE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3LINESTRIKE

talib.CDL3LINESTRIKE()函数用于计算Three-Line Strike (K线图:3线震荡)

talib.CDL3LINESTRIKE()函数的返回值为:一维数组。 array

talib.CDL3LINESTRIKE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3LINESTRIKE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3LINESTRIKE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3LINESTRIKE(records);
    Log(ret);
}

CDL3LINESTRIKE()函数在talib库文档中的描述为:CDL3LINESTRIKE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3OUTSIDE

talib.CDL3OUTSIDE()函数用于计算Three Outside Up/Down (K线图:3外下震荡)

talib.CDL3OUTSIDE()函数的返回值为:一维数组。 array

talib.CDL3OUTSIDE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3OUTSIDE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3OUTSIDE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3OUTSIDE(records);
    Log(ret);
}

CDL3OUTSIDE()函数在talib库文档中的描述为:CDL3OUTSIDE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3STARSINSOUTH

talib.CDL3STARSINSOUTH()函数用于计算Three Stars In The South (K线图:南方三星)

talib.CDL3STARSINSOUTH()函数的返回值为:一维数组。 array

talib.CDL3STARSINSOUTH(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3STARSINSOUTH(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3STARSINSOUTH(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3STARSINSOUTH(records);
    Log(ret);
}

CDL3STARSINSOUTH()函数在talib库文档中的描述为:CDL3STARSINSOUTH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDL3WHITESOLDIERS

talib.CDL3WHITESOLDIERS()函数用于计算Three Advancing White Soldiers (K线图:三白兵)

talib.CDL3WHITESOLDIERS()函数的返回值为:一维数组。 array

talib.CDL3WHITESOLDIERS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDL3WHITESOLDIERS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDL3WHITESOLDIERS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDL3WHITESOLDIERS(records);
    Log(ret);
}

CDL3WHITESOLDIERS()函数在talib库文档中的描述为:CDL3WHITESOLDIERS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLABANDONEDBABY

talib.CDLABANDONEDBABY()函数用于计算Abandoned Baby (K线图:弃婴)

talib.CDLABANDONEDBABY()函数的返回值为:一维数组。 array

talib.CDLABANDONEDBABY(inPriceOHLC) talib.CDLABANDONEDBABY(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数用于设置Penetration,默认值为0.3。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLABANDONEDBABY(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLABANDONEDBABY(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLABANDONEDBABY(records);
    Log(ret);
}

CDLABANDONEDBABY()函数在talib库文档中的描述为:CDLABANDONEDBABY(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLADVANCEBLOCK

talib.CDLADVANCEBLOCK()函数用于计算Advance Block (K线图:推进)

talib.CDLADVANCEBLOCK()函数的返回值为:一维数组。 array

talib.CDLADVANCEBLOCK(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLADVANCEBLOCK(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLADVANCEBLOCK(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLADVANCEBLOCK(records);
    Log(ret);
}

CDLADVANCEBLOCK()函数在talib库文档中的描述为:CDLADVANCEBLOCK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLBELTHOLD

talib.CDLBELTHOLD()函数用于计算Belt-hold (K线图:带住)

talib.CDLBELTHOLD()函数的返回值为:一维数组。 array

talib.CDLBELTHOLD(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLBELTHOLD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLBELTHOLD(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLBELTHOLD(records);
    Log(ret);
}

CDLBELTHOLD()函数在talib库文档中的描述为:CDLBELTHOLD(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLBREAKAWAY

talib.CDLBREAKAWAY()函数用于计算Breakaway (K线图:分离)

talib.CDLBREAKAWAY()函数的返回值为:一维数组。 array

talib.CDLBREAKAWAY(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLBREAKAWAY(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLBREAKAWAY(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLBREAKAWAY(records);
    Log(ret);
}

CDLBREAKAWAY()函数在talib库文档中的描述为:CDLBREAKAWAY(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCLOSINGMARUBOZU

talib.CDLCLOSINGMARUBOZU()函数用于计算Closing Marubozu (K线图:收盘光头光脚)

talib.CDLCLOSINGMARUBOZU()函数的返回值为:一维数组。 array

talib.CDLCLOSINGMARUBOZU(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLCLOSINGMARUBOZU(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLCLOSINGMARUBOZU(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLCLOSINGMARUBOZU(records);
    Log(ret);
}

CDLCLOSINGMARUBOZU()函数在talib库文档中的描述为:CDLCLOSINGMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCONCEALBABYSWALL

talib.CDLCONCEALBABYSWALL()函数用于计算Concealing Baby Swallow (K线图:藏婴吞没形态)

talib.CDLCONCEALBABYSWALL()函数的返回值为:一维数组。 array

talib.CDLCONCEALBABYSWALL(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLCONCEALBABYSWALL(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLCONCEALBABYSWALL(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLCONCEALBABYSWALL(records);
    Log(ret);
}

CDLCONCEALBABYSWALL()函数在talib库文档中的描述为:CDLCONCEALBABYSWALL(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLCOUNTERATTACK

talib.CDLCOUNTERATTACK()函数用于计算Counterattack (K线图:反击)

talib.CDLCOUNTERATTACK()函数的返回值为:一维数组。 array

talib.CDLCOUNTERATTACK(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLCOUNTERATTACK(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLCOUNTERATTACK(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLCOUNTERATTACK(records);
    Log(ret);
}

CDLCOUNTERATTACK()函数在talib库文档中的描述为:CDLCOUNTERATTACK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDARKCLOUDCOVER

talib.CDLDARKCLOUDCOVER()函数用于计算Dark Cloud Cover (K线图:乌云盖)

talib.CDLDARKCLOUDCOVER()函数的返回值为:一维数组。 array

talib.CDLDARKCLOUDCOVER(inPriceOHLC) talib.CDLDARKCLOUDCOVER(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数用于设置Penetration,默认值为0.5。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLDARKCLOUDCOVER(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLDARKCLOUDCOVER(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLDARKCLOUDCOVER(records);
    Log(ret);
}

CDLDARKCLOUDCOVER()函数在talib库文档中的描述为:CDLDARKCLOUDCOVER(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)

talib.CDLDOJI

talib.CDLDOJI()函数用于计算Doji (K线图:十字星 )

talib.CDLDOJI()函数的返回值为:一维数组。 array

talib.CDLDOJI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLDOJI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLDOJI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLDOJI(records);
    Log(ret);
}

CDLDOJI()函数在talib库文档中的描述为:CDLDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDOJISTAR

talib.CDLDOJISTAR()函数用于计算Doji Star (K线图:十字星)

talib.CDLDOJISTAR()函数的返回值为:一维数组。 array

talib.CDLDOJISTAR(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLDOJISTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLDOJISTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLDOJISTAR(records);
    Log(ret);
}

CDLDOJISTAR()函数在talib库文档中的描述为:CDLDOJISTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLDRAGONFLYDOJI

talib.CDLDRAGONFLYDOJI()函数用于计算Dragonfly Doji (K线图:蜻蜓十字星)

talib.CDLDRAGONFLYDOJI()函数的返回值为:一维数组。 array

talib.CDLDRAGONFLYDOJI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLDRAGONFLYDOJI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLDRAGONFLYDOJI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLDRAGONFLYDOJI(records);
    Log(ret);
}

CDLDRAGONFLYDOJI()函数在talib库文档中的描述为:CDLDRAGONFLYDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLENGULFING

talib.CDLENGULFING()函数用于计算Engulfing Pattern (K线图:吞没)

talib.CDLENGULFING()函数的返回值为:一维数组。 array

talib.CDLENGULFING(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLENGULFING(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLENGULFING(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLENGULFING(records);
    Log(ret);
}

CDLENGULFING()函数在talib库文档中的描述为:CDLENGULFING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLEVENINGDOJISTAR

talib.CDLEVENINGDOJISTAR()函数用于计算Evening Doji Star (K线图:黄昏十字星)

talib.CDLEVENINGDOJISTAR()函数的返回值为:一维数组。 array

talib.CDLEVENINGDOJISTAR(inPriceOHLC) talib.CDLEVENINGDOJISTAR(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数用于设置Penetration,默认值为0.3。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLEVENINGDOJISTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLEVENINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLEVENINGDOJISTAR(records);
    Log(ret);
}

CDLEVENINGDOJISTAR()函数在talib库文档中的描述为:CDLEVENINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLEVENINGSTAR

talib.CDLEVENINGSTAR()函数用于计算Evening Star (K线图:黄昏之星)

talib.CDLEVENINGSTAR()函数的返回值为:一维数组。 array

talib.CDLEVENINGSTAR(inPriceOHLC) talib.CDLEVENINGSTAR(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数用于设置Penetration,默认值为0.3。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLEVENINGSTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLEVENINGSTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLEVENINGSTAR(records);
    Log(ret);
}

CDLEVENINGSTAR()函数在talib库文档中的描述为:CDLEVENINGSTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLGAPSIDESIDEWHITE

talib.CDLGAPSIDESIDEWHITE()函数用于计算Up/Down-gap side-by-side white lines (K线图:上/下间隙并排的白色线条)

talib.CDLGAPSIDESIDEWHITE()函数的返回值为:一维数组。 array

talib.CDLGAPSIDESIDEWHITE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLGAPSIDESIDEWHITE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLGAPSIDESIDEWHITE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLGAPSIDESIDEWHITE(records);
    Log(ret);
}

CDLGAPSIDESIDEWHITE()函数在talib库文档中的描述为:CDLGAPSIDESIDEWHITE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLGRAVESTONEDOJI

talib.CDLGRAVESTONEDOJI()函数用于计算Gravestone Doji (K线图:墓碑十字线)

talib.CDLGRAVESTONEDOJI()函数的返回值为:一维数组。 array

talib.CDLGRAVESTONEDOJI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLGRAVESTONEDOJI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLGRAVESTONEDOJI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLGRAVESTONEDOJI(records);
    Log(ret);
}

CDLGRAVESTONEDOJI()函数在talib库文档中的描述为:CDLGRAVESTONEDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHAMMER

talib.CDLHAMMER()函数用于计算Hammer (K线图:锤)

talib.CDLHAMMER()函数的返回值为:一维数组。 array

talib.CDLHAMMER(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHAMMER(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHAMMER(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHAMMER(records);
    Log(ret);
}

CDLHAMMER()函数在talib库文档中的描述为:CDLHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHANGINGMAN

talib.CDLHANGINGMAN()函数用于计算Hanging Man (K线图:吊人)

talib.CDLHANGINGMAN()函数的返回值为:一维数组。 array

talib.CDLHANGINGMAN(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHANGINGMAN(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHANGINGMAN(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHANGINGMAN(records);
    Log(ret);
}

CDLHANGINGMAN()函数在talib库文档中的描述为:CDLHANGINGMAN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHARAMI

talib.CDLHARAMI()函数用于计算Harami Pattern (K线图:阴阳线)

talib.CDLHARAMI()函数的返回值为:一维数组。 array

talib.CDLHARAMI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHARAMI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHARAMI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHARAMI(records);
    Log(ret);
}

CDLHARAMI()函数在talib库文档中的描述为:CDLHARAMI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHARAMICROSS

talib.CDLHARAMICROSS()函数用于计算Harami Cross Pattern (K线图:交叉阴阳线)

talib.CDLHARAMICROSS()函数的返回值为:一维数组。 array

talib.CDLHARAMICROSS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHARAMICROSS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHARAMICROSS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHARAMICROSS(records);
    Log(ret);
}

CDLHARAMICROSS()函数在talib库文档中的描述为:CDLHARAMICROSS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIGHWAVE

talib.CDLHIGHWAVE()函数用于计算High-Wave Candle (K线图:长脚十字线 )

talib.CDLHIGHWAVE()函数的返回值为:一维数组。 array

talib.CDLHIGHWAVE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHIGHWAVE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHIGHWAVE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHIGHWAVE(records);
    Log(ret);
}

CDLHIGHWAVE()函数在talib库文档中的描述为:CDLHIGHWAVE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIKKAKE

talib.CDLHIKKAKE()函数用于计算Hikkake Pattern (K线图:陷阱)

talib.CDLHIKKAKE()函数的返回值为:一维数组。 array

talib.CDLHIKKAKE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHIKKAKE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHIKKAKE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHIKKAKE(records);
    Log(ret);
}

CDLHIKKAKE()函数在talib库文档中的描述为:CDLHIKKAKE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHIKKAKEMOD

talib.CDLHIKKAKEMOD()函数用于计算Modified Hikkake Pattern (K线图:改良的陷阱)

talib.CDLHIKKAKEMOD()函数的返回值为:一维数组。 array

talib.CDLHIKKAKEMOD(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHIKKAKEMOD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHIKKAKEMOD(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHIKKAKEMOD(records);
    Log(ret);
}

CDLHIKKAKEMOD()函数在talib库文档中的描述为:CDLHIKKAKEMOD(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLHOMINGPIGEON

talib.CDLHOMINGPIGEON()函数用于计算Homing Pigeon (K线图:信鸽)

talib.CDLHOMINGPIGEON()函数的返回值为:一维数组。 array

talib.CDLHOMINGPIGEON(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLHOMINGPIGEON(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLHOMINGPIGEON(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLHOMINGPIGEON(records);
    Log(ret);
}

CDLHOMINGPIGEON()函数在talib库文档中的描述为:CDLHOMINGPIGEON(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLIDENTICAL3CROWS

talib.CDLIDENTICAL3CROWS()函数用于计算Identical Three Crows (K线图:相同的三只乌鸦)

talib.CDLIDENTICAL3CROWS()函数的返回值为:一维数组。 array

talib.CDLIDENTICAL3CROWS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLIDENTICAL3CROWS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLIDENTICAL3CROWS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLIDENTICAL3CROWS(records);
    Log(ret);
}

CDLIDENTICAL3CROWS()函数在talib库文档中的描述为:CDLIDENTICAL3CROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLINNECK

talib.CDLINNECK()函数用于计算In-Neck Pattern (K线图:颈纹)

talib.CDLINNECK()函数的返回值为:一维数组。 array

talib.CDLINNECK(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLINNECK(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLINNECK(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLINNECK(records);
    Log(ret);
}

CDLINNECK()函数在talib库文档中的描述为:CDLINNECK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLINVERTEDHAMMER

talib.CDLINVERTEDHAMMER()函数用于计算Inverted Hammer (K线图:倒锤)

talib.CDLINVERTEDHAMMER()函数的返回值为:一维数组。 array

talib.CDLINVERTEDHAMMER(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLINVERTEDHAMMER(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLINVERTEDHAMMER(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLINVERTEDHAMMER(records);
    Log(ret);
}

CDLINVERTEDHAMMER()函数在talib库文档中的描述为:CDLINVERTEDHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLKICKING

talib.CDLKICKING()函数用于计算Kicking (K线图:踢)

talib.CDLKICKING()函数的返回值为:一维数组。 array

talib.CDLKICKING(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLKICKING(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLKICKING(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLKICKING(records);
    Log(ret);
}

CDLKICKING()函数在talib库文档中的描述为:CDLKICKING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLKICKINGBYLENGTH

talib.CDLKICKINGBYLENGTH()函数用于计算Kicking - bull/bear determined by the longer marubozu (K线图:踢牛/踢熊)

talib.CDLKICKINGBYLENGTH()函数的返回值为:一维数组。 array

talib.CDLKICKINGBYLENGTH(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLKICKINGBYLENGTH(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLKICKINGBYLENGTH(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLKICKINGBYLENGTH(records);
    Log(ret);
}

CDLKICKINGBYLENGTH()函数在talib库文档中的描述为:CDLKICKINGBYLENGTH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLADDERBOTTOM

talib.CDLLADDERBOTTOM()函数用于计算Ladder Bottom (K线图:梯底)

talib.CDLLADDERBOTTOM()函数的返回值为:一维数组。 array

talib.CDLLADDERBOTTOM(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLLADDERBOTTOM(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLLADDERBOTTOM(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLLADDERBOTTOM(records);
    Log(ret);
}

CDLLADDERBOTTOM()函数在talib库文档中的描述为:CDLLADDERBOTTOM(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLONGLEGGEDDOJI

talib.CDLLONGLEGGEDDOJI()函数用于计算Long Legged Doji (K线图:长腿十字线)

talib.CDLLONGLEGGEDDOJI()函数的返回值为:一维数组。 array

talib.CDLLONGLEGGEDDOJI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLLONGLEGGEDDOJI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLLONGLEGGEDDOJI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLLONGLEGGEDDOJI(records);
    Log(ret);
}

CDLLONGLEGGEDDOJI()函数在talib库文档中的描述为:CDLLONGLEGGEDDOJI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLLONGLINE

talib.CDLLONGLINE()函数用于计算Long Line Candle (K线图:长线)

talib.CDLLONGLINE()函数的返回值为:一维数组。 array

talib.CDLLONGLINE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLLONGLINE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLLONGLINE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLLONGLINE(records);
    Log(ret);
}

CDLLONGLINE()函数在talib库文档中的描述为:CDLLONGLINE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMARUBOZU

talib.CDLMARUBOZU()函数用于计算Marubozu (K线图:光头光脚)

talib.CDLMARUBOZU()函数的返回值为:一维数组。 array

talib.CDLMARUBOZU(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLMARUBOZU(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLMARUBOZU(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLMARUBOZU(records);
    Log(ret);
}

CDLMARUBOZU()函数在talib库文档中的描述为:CDLMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMATCHINGLOW

talib.CDLMATCHINGLOW()函数用于计算Matching Low (K线图:匹配低)

talib.CDLMATCHINGLOW()函数的返回值为:一维数组。 array

talib.CDLMATCHINGLOW(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLMATCHINGLOW(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLMATCHINGLOW(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLMATCHINGLOW(records);
    Log(ret);
}

CDLMATCHINGLOW()函数在talib库文档中的描述为:CDLMATCHINGLOW(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLMATHOLD

talib.CDLMATHOLD()函数用于计算Mat Hold (K线图:垫住)

talib.CDLMATHOLD()函数的返回值为:一维数组。 array

talib.CDLMATHOLD(inPriceOHLC) talib.CDLMATHOLD(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数为可选参数,用于指定上升/下降趋势线的宽度占比,默认值为0.5。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLMATHOLD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLMATHOLD(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLMATHOLD(records);
    Log(ret);
}

CDLMATHOLD()函数在talib库文档中的描述为:CDLMATHOLD(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)

talib.CDLMORNINGDOJISTAR

talib.CDLMORNINGDOJISTAR()函数用于计算Morning Doji Star (K线图:早晨十字星)

talib.CDLMORNINGDOJISTAR()函数的返回值为:一维数组。 array

talib.CDLMORNINGDOJISTAR(inPriceOHLC) talib.CDLMORNINGDOJISTAR(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数用于指定验证开盘价和实体部分重合的程度,默认值为0.3。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLMORNINGDOJISTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLMORNINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLMORNINGDOJISTAR(records);
    Log(ret);
}

CDLMORNINGDOJISTAR()函数在talib库文档中的描述为:CDLMORNINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)

talib.CDLMORNINGSTAR

talib.CDLMORNINGSTAR()函数用于计算Morning Star (K线图:晨星)

talib.CDLMORNINGSTAR()函数的返回值为:一维数组。 array

talib.CDLMORNINGSTAR(inPriceOHLC) talib.CDLMORNINGSTAR(inPriceOHLC, optInPenetration)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组 optInPenetration参数为趋势确认所需价格浮动百分比阈值,取值范围[0,1],默认值为0.3。 optInPenetration false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLMORNINGSTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLMORNINGSTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLMORNINGSTAR(records);
    Log(ret);
}

CDLMORNINGSTAR()函数在talib库文档中的描述为:CDLMORNINGSTAR(Records[Open,High,Low,Close],Penetration=0.3) = Array(outInteger)

talib.CDLONNECK

talib.CDLONNECK()函数用于计算On-Neck Pattern (K线图:颈型)

talib.CDLONNECK()函数的返回值为:一维数组。 array

talib.CDLONNECK(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLONNECK(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLONNECK(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLONNECK(records);
    Log(ret);
}

CDLONNECK()函数在talib库文档中的描述为:CDLONNECK(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLPIERCING

talib.CDLPIERCING()函数用于计算Piercing Pattern (K线图:穿孔模式)

talib.CDLPIERCING()函数的返回值为:一维数组。 array

talib.CDLPIERCING(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLPIERCING(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLPIERCING(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLPIERCING(records);
    Log(ret);
}

CDLPIERCING()函数在talib库文档中的描述为:CDLPIERCING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLRICKSHAWMAN

talib.CDLRICKSHAWMAN()函数用于计算Rickshaw Man (K线图:车夫)

talib.CDLRICKSHAWMAN()函数的返回值为:一维数组。 array

talib.CDLRICKSHAWMAN(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLRICKSHAWMAN(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLRICKSHAWMAN(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLRICKSHAWMAN(records);
    Log(ret);
}

CDLRICKSHAWMAN()函数在talib库文档中的描述为:CDLRICKSHAWMAN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLRISEFALL3METHODS

talib.CDLRISEFALL3METHODS()函数用于计算Rising/Falling Three Methods (K线图:上升/下降三法)

talib.CDLRISEFALL3METHODS()函数的返回值为:一维数组。 array

talib.CDLRISEFALL3METHODS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLRISEFALL3METHODS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLRISEFALL3METHODS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLRISEFALL3METHODS(records);
    Log(ret);
}

CDLRISEFALL3METHODS()函数在talib库文档中的描述为:CDLRISEFALL3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSEPARATINGLINES

talib.CDLSEPARATINGLINES()函数用于计算Separating Lines (K线图:分割线)

talib.CDLSEPARATINGLINES()函数的返回值为:一维数组。 array

talib.CDLSEPARATINGLINES(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSEPARATINGLINES(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSEPARATINGLINES(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSEPARATINGLINES(records);
    Log(ret);
}

CDLSEPARATINGLINES()函数在talib库文档中的描述为:CDLSEPARATINGLINES(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSHOOTINGSTAR

talib.CDLSHOOTINGSTAR()函数用于计算Shooting Star (K线图:流星)

talib.CDLSHOOTINGSTAR()函数的返回值为:一维数组。 array

talib.CDLSHOOTINGSTAR(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSHOOTINGSTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSHOOTINGSTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSHOOTINGSTAR(records);
    Log(ret);
}

CDLSHOOTINGSTAR()函数在talib库文档中的描述为:CDLSHOOTINGSTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSHORTLINE

talib.CDLSHORTLINE()函数用于计算Short Line Candle (K线图:短线)

talib.CDLSHORTLINE()函数的返回值为:一维数组。 array

talib.CDLSHORTLINE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSHORTLINE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSHORTLINE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSHORTLINE(records);
    Log(ret);
}

CDLSHORTLINE()函数在talib库文档中的描述为:CDLSHORTLINE(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSPINNINGTOP

talib.CDLSPINNINGTOP()函数用于计算Spinning Top (K线图:陀螺)

talib.CDLSPINNINGTOP()函数的返回值为:一维数组。 array

talib.CDLSPINNINGTOP(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSPINNINGTOP(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSPINNINGTOP(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSPINNINGTOP(records);
    Log(ret);
}

CDLSPINNINGTOP()函数在talib库文档中的描述为:CDLSPINNINGTOP(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSTALLEDPATTERN

talib.CDLSTALLEDPATTERN()函数用于计算Stalled Pattern (K线图:停滞模式)

talib.CDLSTALLEDPATTERN()函数的返回值为:一维数组。 array

talib.CDLSTALLEDPATTERN(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSTALLEDPATTERN(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSTALLEDPATTERN(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSTALLEDPATTERN(records);
    Log(ret);
}

CDLSTALLEDPATTERN()函数在talib库文档中的描述为:CDLSTALLEDPATTERN(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLSTICKSANDWICH

talib.CDLSTICKSANDWICH()函数用于计算Stick Sandwich (K线图:棍子三明治)

talib.CDLSTICKSANDWICH()函数的返回值为:一维数组。 array

talib.CDLSTICKSANDWICH(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLSTICKSANDWICH(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLSTICKSANDWICH(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLSTICKSANDWICH(records);
    Log(ret);
}

CDLSTICKSANDWICH()函数在talib库文档中的描述为:CDLSTICKSANDWICH(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTAKURI

talib.CDLTAKURI()函数用于计算Takuri (Dragonfly Doji with very long lower shadow) (K线图:托里)

talib.CDLTAKURI()函数的返回值为:一维数组。 array

talib.CDLTAKURI(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLTAKURI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLTAKURI(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLTAKURI(records);
    Log(ret);
}

CDLTAKURI()函数在talib库文档中的描述为:CDLTAKURI(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTASUKIGAP

talib.CDLTASUKIGAP()函数用于计算Tasuki Gap (K线图:翼隙)

talib.CDLTASUKIGAP()函数的返回值为:一维数组。 array

talib.CDLTASUKIGAP(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLTASUKIGAP(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLTASUKIGAP(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLTASUKIGAP(records);
    Log(ret);
}

CDLTASUKIGAP()函数在talib库文档中的描述为:CDLTASUKIGAP(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTHRUSTING

talib.CDLTHRUSTING()函数用于计算Thrusting Pattern (K线图:推模式)

talib.CDLTHRUSTING()函数的返回值为:一维数组。 array

talib.CDLTHRUSTING(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLTHRUSTING(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLTHRUSTING(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLTHRUSTING(records);
    Log(ret);
}

CDLTHRUSTING()函数在talib库文档中的描述为:CDLTHRUSTING(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLTRISTAR

talib.CDLTRISTAR()函数用于计算Tristar Pattern (K线图:三星模式)

talib.CDLTRISTAR()函数的返回值为:一维数组。 array

talib.CDLTRISTAR(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLTRISTAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLTRISTAR(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLTRISTAR(records);
    Log(ret);
}

CDLTRISTAR()函数在talib库文档中的描述为:CDLTRISTAR(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLUNIQUE3RIVER

talib.CDLUNIQUE3RIVER()函数用于计算Unique 3 River (K线图:独特的3河)

talib.CDLUNIQUE3RIVER()函数的返回值为:一维数组。 array

talib.CDLUNIQUE3RIVER(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLUNIQUE3RIVER(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLUNIQUE3RIVER(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLUNIQUE3RIVER(records);
    Log(ret);
}

CDLUNIQUE3RIVER()函数在talib库文档中的描述为:CDLUNIQUE3RIVER(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLUPSIDEGAP2CROWS

talib.CDLUPSIDEGAP2CROWS()函数用于计算Upside Gap Two Crows (K线图:双飞乌鸦)

talib.CDLUPSIDEGAP2CROWS()函数的返回值为:一维数组。 array

talib.CDLUPSIDEGAP2CROWS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLUPSIDEGAP2CROWS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLUPSIDEGAP2CROWS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLUPSIDEGAP2CROWS(records);
    Log(ret);
}

CDLUPSIDEGAP2CROWS()函数在talib库文档中的描述为:CDLUPSIDEGAP2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.CDLXSIDEGAP3METHODS

talib.CDLXSIDEGAP3METHODS()函数用于计算Upside/Downside Gap Three Methods (K线图:上行/下行缺口三方法)

talib.CDLXSIDEGAP3METHODS()函数的返回值为:一维数组。 array

talib.CDLXSIDEGAP3METHODS(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CDLXSIDEGAP3METHODS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CDLXSIDEGAP3METHODS(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CDLXSIDEGAP3METHODS(records);
    Log(ret);
}

CDLXSIDEGAP3METHODS()函数在talib库文档中的描述为:CDLXSIDEGAP3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)

talib.AD

talib.AD()函数用于计算Chaikin A/D Line (线随机指标)

talib.AD()函数的返回值为:一维数组。 array

talib.AD(inPriceHLCV)

inPriceHLCV参数用于指定K线数据。 inPriceHLCV true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.AD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.AD(records.High, records.Low, records.Close, records.Volume)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.AD(records);
    Log(ret);
}

AD()函数在talib库文档中的描述为:AD(Records[High,Low,Close,Volume]) = Array(outReal)

talib.ADOSC

talib.ADOSC()函数用于计算Chaikin A/D Oscillator (佳庆指标)

talib.ADOSC()函数的返回值为:一维数组。 array

talib.ADOSC(inPriceHLCV) talib.ADOSC(inPriceHLCV, optInFastPeriod, optInSlowPeriod)

inPriceHLCV参数用于指定K线数据。 inPriceHLCV true {@struct/Record Record}结构数组 optInFastPeriod参数用于设置快周期。 optInFastPeriod false number optInSlowPeriod参数用于设置慢周期。 optInSlowPeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ADOSC(records, 3, 10)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ADOSC(records.High, records.Low, records.Close, records.Volume, 3, 10)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ADOSC(records, 3, 10);
    Log(ret);
}

ADOSC()函数在talib库文档中的描述为:ADOSC(Records[High,Low,Close,Volume],Fast Period = 3,Slow Period = 10) = Array(outReal)

talib.OBV

talib.OBV()函数用于计算On Balance Volume (能量潮)

talib.OBV()函数的返回值为:一维数组。 array

talib.OBV(inReal) talib.OBV(inReal, inPriceV)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 inPriceV参数用于指定K线数据。 inPriceV false {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.OBV(records, records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.OBV(records.Close, records.Volume)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.OBV(records);
    Log(ret);
}

OBV()函数在talib库文档中的描述为:OBV(Records[Close],Records[Volume]) = Array(outReal)

talib.ACOS

talib.ACOS()函数用于计算Vector Trigonometric ACos (反余弦函数)

talib.ACOS()函数的返回值为:一维数组。 array

talib.ACOS(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.ACOS(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.ACOS(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.ACOS(data);
    Log(ret);
}

ACOS()函数在talib库文档中的描述为:ACOS(Records[Close]) = Array(outReal)

talib.ASIN

talib.ASIN()函数用于计算Vector Trigonometric ASin (反正弦函数)

talib.ASIN()函数的返回值为:一维数组。 array

talib.ASIN(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.ASIN(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.ASIN(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.ASIN(data);
    Log(ret);
}

ASIN()函数在talib库文档中的描述为:ASIN(Records[Close]) = Array(outReal)

talib.ATAN

talib.ATAN()函数用于计算Vector Trigonometric ATan (反正切函数)

talib.ATAN()函数的返回值为:一维数组。 array

talib.ATAN(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-3.14/2, 0, 3.14/2]
    var ret = talib.ATAN(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-3.14/2, 0, 3.14/2]
    ret = talib.ATAN(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-3.14/2, 0, 3.14/2};
    auto ret = talib.ATAN(data);
    Log(ret);
}

ATAN()函数在talib库文档中的描述为:ATAN(Records[Close]) = Array(outReal)

talib.CEIL

talib.CEIL()函数用于计算Vector Ceil (取整函数)

talib.CEIL()函数的返回值为:一维数组。 array

talib.CEIL(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CEIL(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CEIL(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CEIL(records);
    Log(ret);
}

CEIL()函数在talib库文档中的描述为:CEIL(Records[Close]) = Array(outReal)

talib.COS

talib.COS()函数用于计算Vector Trigonometric Cos (余弦函数)

talib.COS()函数的返回值为:一维数组。 array

talib.COS(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-3.14, 0, 3.14]
    var ret = talib.COS(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-3.14, 0, 3.14]
    ret = talib.COS(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-3.14, 0, 3.14};
    auto ret = talib.COS(data);
    Log(ret);
}

COS()函数在talib库文档中的描述为:COS(Records[Close]) = Array(outReal)

talib.COSH

talib.COSH()函数用于计算Vector Trigonometric Cosh (双曲余弦值)

talib.COSH()函数的返回值为:一维数组。 array

talib.COSH(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.COSH(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.COSH(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.COSH(data);
    Log(ret);
}

COSH()函数在talib库文档中的描述为:COSH(Records[Close]) = Array(outReal)

talib.EXP

talib.EXP()函数用于计算Vector Arithmetic Exp (指数函数)

talib.EXP()函数的返回值为:一维数组。 array

talib.EXP(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [0, 1, 2]
    var ret = talib.EXP(data)    // e^0, e^1, e^2
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [0, 1.0, 2.0]
    ret = talib.EXP(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {0, 1.0, 2.0};
    auto ret = talib.EXP(data);
    Log(ret);
}

EXP()函数在talib库文档中的描述为:EXP(Records[Close]) = Array(outReal)

talib.FLOOR

talib.FLOOR()函数用于计算Vector Floor (向下取整)

talib.FLOOR()函数的返回值为:一维数组。 array

talib.FLOOR(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.FLOOR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.FLOOR(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.FLOOR(records);
    Log(ret);
}

FLOOR()函数在talib库文档中的描述为:FLOOR(Records[Close]) = Array(outReal)

talib.LN

talib.LN()函数用于计算Vector Log Natural (自然对数)

talib.LN()函数的返回值为:一维数组。 array

talib.LN(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [1, 2, 3]
    var ret = talib.LN(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [1.0, 2.0, 3.0]
    ret = talib.LN(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {1, 2, 3};
    auto ret = talib.LN(data);
    Log(ret);
}

LN()函数在talib库文档中的描述为:LN(Records[Close]) = Array(outReal)

talib.LOG10

talib.LOG10()函数用于计算Vector Log10 (对数函数)

talib.LOG10()函数的返回值为:一维数组。 array

talib.LOG10(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [10, 100, 1000]
    var ret = talib.LOG10(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [10.0, 100.0, 1000.0]
    ret = talib.LOG10(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {10, 100, 1000};
    auto ret = talib.LOG10(data);
    Log(ret);
}

LOG10()函数在talib库文档中的描述为:LOG10(Records[Close]) = Array(outReal)

talib.SIN

talib.SIN()函数用于计算Vector Trigonometric Sin (正弦值)

talib.SIN()函数的返回值为:一维数组。 array

talib.SIN(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-3.14/2, 0, 3.14/2]
    var ret = talib.SIN(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-3.14/2, 0, 3.14/2]
    ret = talib.SIN(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-3.14/2, 0, 3.14/2};
    auto ret = talib.SIN(data);
    Log(ret);
}

SIN()函数在talib库文档中的描述为:SIN(Records[Close]) = Array(outReal)

talib.SINH

talib.SINH()函数用于计算Vector Trigonometric Sinh (双曲正弦函数)

talib.SINH()函数的返回值为:一维数组。 array

talib.SINH(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.SINH(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.SINH(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.SINH(data);
    Log(ret);
}

SINH()函数在talib库文档中的描述为:SINH(Records[Close]) = Array(outReal)

talib.SQRT

talib.SQRT()函数用于计算Vector Square Root (平方根)

talib.SQRT()函数的返回值为:一维数组。 array

talib.SQRT(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [4, 64, 100]
    var ret = talib.SQRT(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [4.0, 64.0, 100.0]
    ret = talib.SQRT(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {4, 64, 100};
    auto ret = talib.SQRT(data);
    Log(ret);
}

SQRT()函数在talib库文档中的描述为:SQRT(Records[Close]) = Array(outReal)

talib.TAN

talib.TAN()函数用于计算Vector Trigonometric Tan (正切)

talib.TAN()函数的返回值为:一维数组。 array

talib.TAN(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.TAN(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.TAN(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.TAN(data);
    Log(ret);
}

TAN()函数在talib库文档中的描述为:TAN(Records[Close]) = Array(outReal)

talib.TANH

talib.TANH()函数用于计算Vector Trigonometric Tanh (双曲正切函数)

talib.TANH()函数的返回值为:一维数组。 array

talib.TANH(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var data = [-1, 0, 1]
    var ret = talib.TANH(data)
    Log(ret)
}
import talib
import numpy as np
def main():
    data = [-1.0, 0, 1.0]
    ret = talib.TANH(np.array(data))
    Log(ret)
void main() {
    std::vector<double> data = {-1, 0, 1};
    auto ret = talib.TANH(data);
    Log(ret);
}

TANH()函数在talib库文档中的描述为:TANH(Records[Close]) = Array(outReal)

talib.MAX

talib.MAX()函数用于计算Highest value over a specified period (最大值)

talib.MAX()函数的返回值为:一维数组。 array

talib.MAX(inReal) talib.MAX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MAX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MAX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MAX(records);
    Log(ret);
}

MAX()函数在talib库文档中的描述为:MAX(Records[Close],Time Period = 30) = Array(outReal)

talib.MAXINDEX

talib.MAXINDEX()函数用于计算Index of highest value over a specified period (最大值索引)

talib.MAXINDEX()函数的返回值为:一维数组。 array

talib.MAXINDEX(inReal) talib.MAXINDEX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MAXINDEX(records, 5)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MAXINDEX(records.Close, 5)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MAXINDEX(records, 5);
    Log(ret);
}

MAXINDEX()函数在talib库文档中的描述为:MAXINDEX(Records[Close],Time Period = 30) = Array(outInteger)

talib.MIN

talib.MIN()函数用于计算Lowest value over a specified period (最小值)

talib.MIN()函数的返回值为:一维数组。 array

talib.MIN(inReal) talib.MIN(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MIN(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MIN(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MIN(records);
    Log(ret);
}

MIN()函数在talib库文档中的描述为:MIN(Records[Close],Time Period = 30) = Array(outReal)

talib.MININDEX

talib.MININDEX()函数用于计算Index of lowest value over a specified period (最小值索引)

talib.MININDEX()函数的返回值为:一维数组。 array

talib.MININDEX(inReal) talib.MININDEX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MININDEX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MININDEX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MININDEX(records);
    Log(ret);
}

MININDEX()函数在talib库文档中的描述为:MININDEX(Records[Close],Time Period = 30) = Array(outInteger)

talib.MINMAX

talib.MINMAX()函数用于计算Lowest and highest values over a specified period (最小最大值)

talib.MINMAX()函数的返回值为:二维数组。该二维数组的第一个元素为最小值数组,第二个元素为最大值数组。 array

talib.MINMAX(inReal) talib.MINMAX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MINMAX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MINMAX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MINMAX(records);
    Log(ret);
}

MINMAX()函数在talib库文档中的描述为:MINMAX(Records[Close],Time Period = 30) = [Array(outMin),Array(outMax)]

talib.MINMAXINDEX

talib.MINMAXINDEX()函数用于计算Indexes of lowest and highest values over a specified period (最小最大值索引)

talib.MINMAXINDEX()函数的返回值为:二维数组。该二维数组的第一个元素为最小值索引数组,第二个元素为最大值索引数组。 array

talib.MINMAXINDEX(inReal) talib.MINMAXINDEX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MINMAXINDEX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MINMAXINDEX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MINMAXINDEX(records);
    Log(ret);
}

MINMAXINDEX()函数在talib库文档中的描述为:MINMAXINDEX(Records[Close],Time Period = 30) = [Array(outMinIdx),Array(outMaxIdx)]

talib.SUM

talib.SUM()函数用于计算Summation (求和)

talib.SUM()函数的返回值为:一维数组。 array

talib.SUM(inReal) talib.SUM(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.SUM(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.SUM(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.SUM(records);
    Log(ret);
}

SUM()函数在talib库文档中的描述为:SUM(Records[Close],Time Period = 30) = Array(outReal)

talib.HT_DCPERIOD

talib.HT_DCPERIOD()函数用于计算Hilbert Transform - Dominant Cycle Period (希尔伯特变换, 主周期)

talib.HT_DCPERIOD()函数的返回值为:一维数组。 array

talib.HT_DCPERIOD(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_DCPERIOD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_DCPERIOD(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_DCPERIOD(records);
    Log(ret);
}

HT_DCPERIOD()函数在talib库文档中的描述为:HT_DCPERIOD(Records[Close]) = Array(outReal)

talib.HT_DCPHASE

talib.HT_DCPHASE()函数用于计算Hilbert Transform - Dominant Cycle Phase (希尔伯特变换,主阶段)

talib.HT_DCPHASE()函数的返回值为:一维数组。 array

talib.HT_DCPHASE(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_DCPHASE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_DCPHASE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_DCPHASE(records);
    Log(ret);
}

HT_DCPHASE()函数在talib库文档中的描述为:HT_DCPHASE(Records[Close]) = Array(outReal)

talib.HT_PHASOR

talib.HT_PHASOR()函数用于计算Hilbert Transform - Phasor Components (希尔伯特变换,相成分)

talib.HT_PHASOR()函数的返回值为:二维数组。 array

talib.HT_PHASOR(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_PHASOR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_PHASOR(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_PHASOR(records);
    Log(ret);
}

HT_PHASOR()函数在talib库文档中的描述为:HT_PHASOR(Records[Close]) = [Array(outInPhase),Array(outQuadrature)]

talib.HT_SINE

talib.HT_SINE()函数用于计算Hilbert Transform - SineWave (希尔伯特变换,正弦波)

talib.HT_SINE()函数的返回值为:二维数组。 array

talib.HT_SINE(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_SINE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_SINE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_SINE(records);
    Log(ret);
}

HT_SINE()函数在talib库文档中的描述为:HT_SINE(Records[Close]) = [Array(outSine),Array(outLeadSine)]

talib.HT_TRENDMODE

talib.HT_TRENDMODE()函数用于计算Hilbert Transform - Trend vs Cycle Mode (希尔伯特变换-趋势与周期模式)

talib.HT_TRENDMODE()函数的返回值为:一维数组。 array

talib.HT_TRENDMODE(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_TRENDMODE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_TRENDMODE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_TRENDMODE(records);
    Log(ret);
}

HT_TRENDMODE()函数在talib库文档中的描述为:HT_TRENDMODE(Records[Close]) = Array(outInteger)

talib.ATR

talib.ATR()函数用于计算Average True Range (平均真实波幅)

talib.ATR()函数的返回值为:一维数组。 array

talib.ATR(inPriceHLC) talib.ATR(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ATR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ATR(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ATR(records);
    Log(ret);
}

ATR()函数在talib库文档中的描述为:ATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.NATR

talib.NATR()函数用于计算Normalized Average True Range (归一化平均值范围)

talib.NATR()函数的返回值为:一维数组。 array

talib.NATR(inPriceHLC) talib.NATR(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.NATR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.NATR(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.NATR(records);
    Log(ret);
}

NATR()函数在talib库文档中的描述为:NATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.TRANGE

talib.TRANGE()函数用于计算True Range (真实范围)

talib.TRANGE()函数的返回值为:一维数组。 array

talib.TRANGE(inPriceHLC)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TRANGE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TRANGE(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TRANGE(records);
    Log(ret);
}

TRANGE()函数在talib库文档中的描述为:TRANGE(Records[High,Low,Close]) = Array(outReal)

talib.BBANDS

talib.BBANDS()函数用于计算Bollinger Bands (布林带)

talib.BBANDS()函数的返回值为:二维数组。该数组包含三个元素分别是:上线数组、中线数组、下线数组。 array

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)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为5。 optInTimePeriod false number optInNbDevUp参数用于设置上线乘数,默认值为2。 optInNbDevUp false number optInNbDevDn参数用于设置下线乘数,默认值为2。 optInNbDevDn false number optInMAType参数用于设置均线类型,默认值为0。 optInMAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.BBANDS(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.BBANDS(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.BBANDS(records);
    Log(ret);
}

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

talib.DEMA()函数用于计算Double Exponential Moving Average (双指数移动平均线)

talib.DEMA()函数的返回值为:一维数组。 array

talib.DEMA(inReal) talib.DEMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.DEMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.DEMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.DEMA(records);
    Log(ret);
}

DEMA()函数在talib库文档中的描述为:DEMA(Records[Close],Time Period = 30) = Array(outReal)

talib.EMA

talib.EMA()函数用于计算Exponential Moving Average (指数移动平均线)

talib.EMA()函数的返回值为:一维数组。 array

talib.EMA(inReal) talib.EMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.EMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.EMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.EMA(records);
    Log(ret);
}

EMA()函数在talib库文档中的描述为:EMA(Records[Close],Time Period = 30) = Array(outReal)

talib.HT_TRENDLINE

talib.HT_TRENDLINE()函数用于计算Hilbert Transform - Instantaneous Trendline (希尔伯特变换,瞬时趋势)

talib.HT_TRENDLINE()函数的返回值为:一维数组。 array

talib.HT_TRENDLINE(inReal)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.HT_TRENDLINE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.HT_TRENDLINE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.HT_TRENDLINE(records);
    Log(ret);
}

HT_TRENDLINE()函数在talib库文档中的描述为:HT_TRENDLINE(Records[Close]) = Array(outReal)

talib.KAMA

talib.KAMA()函数用于计算Kaufman Adaptive Moving Average (适应性移动平均线)

talib.KAMA()函数的返回值为:一维数组。 array

talib.KAMA(inReal) talib.KAMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.KAMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.KAMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.KAMA(records);
    Log(ret);
}

KAMA()函数在talib库文档中的描述为:KAMA(Records[Close],Time Period = 30) = Array(outReal)

talib.MA

talib.MA()函数用于计算Moving average (移动平均线)

talib.MA()函数的返回值为:一维数组。 array

talib.MA(inReal) talib.MA(inReal, optInTimePeriod) talib.MA(inReal, optInTimePeriod, optInMAType)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number optInMAType参数用于设置均线类型,默认值为0。 optInMAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MA(records);
    Log(ret);
}

MA()函数在talib库文档中的描述为:MA(Records[Close],Time Period = 30,MA Type = 0) = Array(outReal)

talib.MAMA

talib.MAMA()函数用于计算MESA Adaptive Moving Average (MESA 移动平均线)

talib.MAMA()函数的返回值为:二维数组。 array

talib.MAMA(inReal) talib.MAMA(inReal, optInFastLimit) talib.MAMA(inReal, optInFastLimit, optInSlowLimit)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastLimit参数用于设置Fast Limit,默认值为0.5。 optInFastLimit false number optInSlowLimit参数用于设置Slow Limit,默认值为0.05。 optInSlowLimit false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MAMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MAMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MAMA(records);
    Log(ret);
}

MAMA()函数在talib库文档中的描述为:MAMA(Records[Close],Fast Limit = 0.5,Slow Limit = 0.05) = [Array(outMAMA),Array(outFAMA)]

talib.MIDPOINT

talib.MIDPOINT()函数用于计算MidPoint over period (中点)

talib.MIDPOINT()函数的返回值为:一维数组。 array

talib.MIDPOINT(inReal) talib.MIDPOINT(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MIDPOINT(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MIDPOINT(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MIDPOINT(records);
    Log(ret);
}

MIDPOINT()函数在talib库文档中的描述为:MIDPOINT(Records[Close],Time Period = 14) = Array(outReal)

talib.MIDPRICE

talib.MIDPRICE()函数用于计算Midpoint Price over period (中点价格)

talib.MIDPRICE()函数的返回值为:一维数组。 array

talib.MIDPRICE(inPriceHL) talib.MIDPRICE(inPriceHL, optInTimePeriod)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MIDPRICE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MIDPRICE(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MIDPRICE(records);
    Log(ret);
}

MIDPRICE()函数在talib库文档中的描述为:MIDPRICE(Records[High,Low],Time Period = 14) = Array(outReal)

talib.SAR

talib.SAR()函数用于计算Parabolic SAR (抛物线转向)

talib.SAR()函数的返回值为:一维数组。 array

talib.SAR(inPriceHL) talib.SAR(inPriceHL, optInAcceleration) talib.SAR(inPriceHL, optInAcceleration, optInMaximum)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInAcceleration参数用于设置Acceleration Factor,默认值为0.02。 optInAcceleration false number optInMaximum参数用于设置AF Maximum,默认值为0.2。 optInMaximum false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.SAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.SAR(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.SAR(records);
    Log(ret);
}

SAR()函数在talib库文档中的描述为:SAR(Records[High,Low],Acceleration Factor = 0.02,AF Maximum = 0.2) = Array(outReal)

talib.SAREXT

talib.SAREXT()函数用于计算Parabolic SAR - Extended (增强型抛物线转向)

talib.SAREXT()函数的返回值为:一维数组。 array

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)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInStartValue参数用于设置Start Value,默认值为0。 optInStartValue false number optInOffsetOnReverse参数用于设置Offset on Reverse,默认值为0。 optInOffsetOnReverse false number optInAccelerationInitLong参数用于设置AF Init Long,默认值为0.02。 optInAccelerationInitLong false number optInAccelerationLong参数用于设置AF Long,默认值为0.02。 optInAccelerationLong false number optInAccelerationMaxLong参数用于设置AF Max Long,默认值为0.2。 optInAccelerationMaxLong false number optInAccelerationInitShort参数用于设置AF Init Short,默认值为0.02。 optInAccelerationInitShort false number optInAccelerationShort参数用于设置AF Short,默认值为0.02。 optInAccelerationShort false number optInAccelerationMaxShort参数用于设置AF Max Short,默认值为0.2。 optInAccelerationMaxShort false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.SAREXT(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.SAREXT(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.SAREXT(records);
    Log(ret);
}

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

talib.SMA()函数用于计算Simple Moving Average (简单移动平均)

talib.SMA()函数的返回值为:一维数组。 array

talib.SMA(inReal) talib.SMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.SMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.SMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.SMA(records);
    Log(ret);
}

SMA()函数在talib库文档中的描述为:SMA(Records[Close],Time Period = 30) = Array(outReal)

talib.T3

talib.T3()函数用于计算Triple Exponential Moving Average (T3) (三指数移动平均)

talib.T3()函数的返回值为:一维数组。 array

talib.T3(inReal) talib.T3(inReal, optInTimePeriod) talib.T3(inReal, optInTimePeriod, optInVFactor)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为5。 optInTimePeriod false number optInVFactor参数用于设置Volume Factor,默认值为0.7。 optInVFactor false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.T3(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.T3(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.T3(records);
    Log(ret);
}

T3()函数在talib库文档中的描述为:T3(Records[Close],Time Period = 5,Volume Factor = 0.7) = Array(outReal)

talib.TEMA

talib.TEMA()函数用于计算Triple Exponential Moving Average (三指数移动平均)

talib.TEMA()函数的返回值为:一维数组。 array

talib.TEMA(inReal) talib.TEMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TEMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TEMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TEMA(records);
    Log(ret);
}

TEMA()函数在talib库文档中的描述为:TEMA(Records[Close],Time Period = 30) = Array(outReal)

talib.TRIMA

talib.TRIMA()函数用于计算Triangular Moving Average (三指数移动平均)

talib.TRIMA()函数的返回值为:一维数组。 array

talib.TRIMA(inReal) talib.TRIMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TRIMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TRIMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TRIMA(records);
    Log(ret);
}

TRIMA()函数在talib库文档中的描述为:TRIMA(Records[Close],Time Period = 30) = Array(outReal)

talib.WMA

talib.WMA()函数用于计算Weighted Moving Average (加权移动平均)

talib.WMA()函数的返回值为:一维数组。 array

talib.WMA(inReal) talib.WMA(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.WMA(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.WMA(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.WMA(records);
    Log(ret);
}

WMA()函数在talib库文档中的描述为:WMA(Records[Close],Time Period = 30) = Array(outReal)

talib.LINEARREG

talib.LINEARREG()函数用于计算Linear Regression (线性回归)

talib.LINEARREG()函数的返回值为:一维数组。 array

talib.LINEARREG(inReal) talib.LINEARREG(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.LINEARREG(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.LINEARREG(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.LINEARREG(records);
    Log(ret);
}

LINEARREG()函数在talib库文档中的描述为:LINEARREG(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_ANGLE

talib.LINEARREG_ANGLE()函数用于计算Linear Regression Angle (线性回归的角度)

talib.LINEARREG_ANGLE()函数的返回值为:一维数组。 array

talib.LINEARREG_ANGLE(inReal) talib.LINEARREG_ANGLE(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.LINEARREG_ANGLE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.LINEARREG_ANGLE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.LINEARREG_ANGLE(records);
    Log(ret);
}

LINEARREG_ANGLE()函数在talib库文档中的描述为:LINEARREG_ANGLE(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_INTERCEPT

talib.LINEARREG_INTERCEPT()函数用于计算Linear Regression Intercept (线性回归截距)

talib.LINEARREG_INTERCEPT()函数的返回值为:一维数组。 array

talib.LINEARREG_INTERCEPT(inReal) talib.LINEARREG_INTERCEPT(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.LINEARREG_INTERCEPT(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.LINEARREG_INTERCEPT(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.LINEARREG_INTERCEPT(records);
    Log(ret);
}

LINEARREG_INTERCEPT()函数在talib库文档中的描述为:LINEARREG_INTERCEPT(Records[Close],Time Period = 14) = Array(outReal)

talib.LINEARREG_SLOPE

talib.LINEARREG_SLOPE()函数用于计算Linear Regression Slope (线性回归斜率)

talib.LINEARREG_SLOPE()函数的返回值为:一维数组。 array

talib.LINEARREG_SLOPE(inReal) talib.LINEARREG_SLOPE(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.LINEARREG_SLOPE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.LINEARREG_SLOPE(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.LINEARREG_SLOPE(records);
    Log(ret);
}

LINEARREG_SLOPE()函数在talib库文档中的描述为:LINEARREG_SLOPE(Records[Close],Time Period = 14) = Array(outReal)

talib.STDDEV

talib.STDDEV()函数用于计算Standard Deviation (标准偏差)

talib.STDDEV()函数的返回值为:一维数组。 array

talib.STDDEV(inReal) talib.STDDEV(inReal, optInTimePeriod) talib.STDDEV(inReal, optInTimePeriod, optInNbDev)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为5。 optInTimePeriod false number optInNbDev参数用于设置Deviations,默认值为1。 optInNbDev false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.STDDEV(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.STDDEV(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.STDDEV(records);
    Log(ret);
}

STDDEV()函数在talib库文档中的描述为:STDDEV(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)

talib.TSF

talib.TSF()函数用于计算Time Series Forecast (时间序列预测)

talib.TSF()函数的返回值为:一维数组。 array

talib.TSF(inReal) talib.TSF(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TSF(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TSF(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TSF(records);
    Log(ret);
}

TSF()函数在talib库文档中的描述为:TSF(Records[Close],Time Period = 14) = Array(outReal)

talib.VAR

talib.VAR()函数用于计算Variance (方差)

talib.VAR()函数的返回值为:一维数组。 array

talib.VAR(inReal) talib.VAR(inReal, optInTimePeriod) talib.VAR(inReal, optInTimePeriod, optInNbDev)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为5。 optInTimePeriod false number optInNbDev参数用于设置Deviations,默认值为1。 optInNbDev false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.VAR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.VAR(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.VAR(records);
    Log(ret);
}

VAR()函数在talib库文档中的描述为:VAR(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)

talib.ADX

talib.ADX()函数用于计算Average Directional Movement Index (平均趋向指数)

talib.ADX()函数的返回值为:一维数组。 array

talib.ADX(inPriceHLC) talib.ADX(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ADX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ADX(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ADX(records);
    Log(ret);
}

ADX()函数在talib库文档中的描述为:ADX(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.ADXR

talib.ADXR()函数用于计算Average Directional Movement Index Rating (评估指数)

talib.ADXR()函数的返回值为:一维数组。 array

talib.ADXR(inPriceHLC) talib.ADXR(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ADXR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ADXR(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ADXR(records);
    Log(ret);
}

ADXR()函数在talib库文档中的描述为:ADXR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.APO

talib.APO()函数用于计算Absolute Price Oscillator (绝对价格振荡指数)

talib.APO()函数的返回值为:一维数组。 array

talib.APO(inReal) talib.APO(inReal, optInFastPeriod) talib.APO(inReal, optInFastPeriod, optInSlowPeriod) talib.APO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastPeriod参数用于设置快周期,默认值为12。 optInFastPeriod false number optInSlowPeriod参数用于设置慢周期,默认值为26。 optInSlowPeriod false number optInMAType参数用于设置均线类型,默认值为0。 optInMAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.APO(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.APO(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.APO(records);
    Log(ret);
}

APO()函数在talib库文档中的描述为:APO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)

talib.AROON

talib.AROON()函数用于计算Aroon (阿隆指标)

talib.AROON()函数的返回值为:二维数组。 array

talib.AROON(inPriceHL) talib.AROON(inPriceHL, optInTimePeriod)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.AROON(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.AROON(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.AROON(records);
    Log(ret);
}

AROON()函数在talib库文档中的描述为:AROON(Records[High,Low],Time Period = 14) = [Array(outAroonDown),Array(outAroonUp)]

talib.AROONOSC

talib.AROONOSC()函数用于计算Aroon Oscillator (阿隆震荡线)

talib.AROONOSC()函数的返回值为:一维数组。 array

talib.AROONOSC(inPriceHL) talib.AROONOSC(inPriceHL, optInTimePeriod)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.AROONOSC(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.AROONOSC(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.AROONOSC(records);
    Log(ret);
}

AROONOSC()函数在talib库文档中的描述为:AROONOSC(Records[High,Low],Time Period = 14) = Array(outReal)

talib.BOP

talib.BOP()函数用于计算Balance Of Power (均势指标)

talib.BOP()函数的返回值为:一维数组。 array

talib.BOP(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.BOP(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.BOP(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.BOP(records);
    Log(ret);
}

BOP()函数在talib库文档中的描述为:BOP(Records[Open,High,Low,Close]) = Array(outReal)

talib.CCI

talib.CCI()函数用于计算Commodity Channel Index (顺势指标)

talib.CCI()函数的返回值为:一维数组。 array

talib.CCI(inPriceHLC) talib.CCI(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CCI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CCI(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CCI(records);
    Log(ret);
}

CCI()函数在talib库文档中的描述为:CCI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.CMO

talib.CMO()函数用于计算Chande Momentum Oscillator (钱德动量摆动指标)

talib.CMO()函数的返回值为:一维数组。 array

talib.CMO(inReal) talib.CMO(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.CMO(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.CMO(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.CMO(records);
    Log(ret);
}

CMO()函数在talib库文档中的描述为:CMO(Records[Close],Time Period = 14) = Array(outReal)

talib.DX

talib.DX()函数用于计算Directional Movement Index (动向指数)

talib.DX()函数的返回值为:一维数组。 array

talib.DX(inPriceHLC) talib.DX(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.DX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.DX(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.DX(records);
    Log(ret);
}

DX()函数在talib库文档中的描述为:DX(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.MACD

talib.MACD()函数用于计算Moving Average Convergence/Divergence (指数平滑移动平均线)

talib.MACD()函数的返回值为:二维数组。 array

talib.MACD(inReal) talib.MACD(inReal, optInFastPeriod) talib.MACD(inReal, optInFastPeriod, optInSlowPeriod) talib.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastPeriod参数用于设置快周期,默认值为12。 optInFastPeriod false number optInSlowPeriod参数用于设置慢周期,默认值为26。 optInSlowPeriod false number optInSignalPeriod参数用于设置信号周期,默认值为9。 optInSignalPeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MACD(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MACD(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MACD(records);
    Log(ret);
}

MACD()函数在talib库文档中的描述为:MACD(Records[Close],Fast Period = 12,Slow Period = 26,Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]

talib.MACDEXT

talib.MACDEXT()函数用于计算MACD with controllable MA type (MA型可控 MACD)

talib.MACDEXT()函数的返回值为:二维数组。 array

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)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastPeriod参数用于设置快周期,默认值为12。 optInFastPeriod false number optInFastMAType参数用于设置快均线类型,默认值为0。 optInFastMAType false number optInSlowPeriod参数用于设置慢周期,默认值为26。 optInSlowPeriod false number optInSlowMAType参数用于设置慢均线类型,默认值为0。 optInSlowMAType false number optInSignalPeriod参数用于设置信号周期,默认值为9。 optInSignalPeriod false number optInSignalMAType参数用于设置信号均线类型,默认值为0。 optInSignalMAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MACDEXT(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MACDEXT(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MACDEXT(records);
    Log(ret);
}

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

talib.MACDFIX()函数用于计算Moving Average Convergence/Divergence Fix 12/26 (移动平均收敛/发散修复12/26)

talib.MACDFIX()函数的返回值为:二维数组。 array

talib.MACDFIX(inReal) talib.MACDFIX(inReal, optInSignalPeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInSignalPeriod参数用于设置信号周期,默认值为9。 optInSignalPeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MACDFIX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MACDFIX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MACDFIX(records);
    Log(ret);
}

MACDFIX()函数在talib库文档中的描述为:MACDFIX(Records[Close],Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]

talib.MFI

talib.MFI()函数用于计算Money Flow Index (货币流量指数)

talib.MFI()函数的返回值为:一维数组。 array

talib.MFI(inPriceHLCV) talib.MFI(inPriceHLCV, optInTimePeriod)

inPriceHLCV参数用于指定K线数据。 inPriceHLCV true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MFI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MFI(records.High, records.Low, records.Close, records.Volume)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MFI(records);
    Log(ret);
}

MFI()函数在talib库文档中的描述为:MFI(Records[High,Low,Close,Volume],Time Period = 14) = Array(outReal)

talib.MINUS_DI

talib.MINUS_DI()函数用于计算Minus Directional Indicator (负向指标)

talib.MINUS_DI()函数的返回值为:一维数组。 array

talib.MINUS_DI(inPriceHLC) talib.MINUS_DI(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MINUS_DI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MINUS_DI(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MINUS_DI(records);
    Log(ret);
}

MINUS_DI()函数在talib库文档中的描述为:MINUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.MINUS_DM

talib.MINUS_DM()函数用于计算Minus Directional Movement (负向运动)

talib.MINUS_DM()函数的返回值为:一维数组。 array

talib.MINUS_DM(inPriceHL) talib.MINUS_DM(inPriceHL, optInTimePeriod)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MINUS_DM(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MINUS_DM(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MINUS_DM(records);
    Log(ret);
}

MINUS_DM()函数在talib库文档中的描述为:MINUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)

talib.MOM

talib.MOM()函数用于计算Momentum (动量)

talib.MOM()函数的返回值为:一维数组。 array

talib.MOM(inReal) talib.MOM(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为10。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MOM(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MOM(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MOM(records);
    Log(ret);
}

MOM()函数在talib库文档中的描述为:MOM(Records[Close],Time Period = 10) = Array(outReal)

talib.PLUS_DI

talib.PLUS_DI()函数用于计算Plus Directional Indicator (更向指示器)

talib.PLUS_DI()函数的返回值为:一维数组。 array

talib.PLUS_DI(inPriceHLC) talib.PLUS_DI(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.PLUS_DI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.PLUS_DI(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.PLUS_DI(records);
    Log(ret);
}

PLUS_DI()函数在talib库文档中的描述为:PLUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.PLUS_DM

talib.PLUS_DM()函数用于计算Plus Directional Movement (定向运动)

talib.PLUS_DM()函数的返回值为:一维数组。 array

talib.PLUS_DM(inPriceHL) talib.PLUS_DM(inPriceHL, optInTimePeriod)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.PLUS_DM(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.PLUS_DM(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.PLUS_DM(records);
    Log(ret);
}

PLUS_DM()函数在talib库文档中的描述为:PLUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)

talib.PPO

talib.PPO()函数用于计算Percentage Price Oscillator (价格振荡百分比)

talib.PPO()函数的返回值为:一维数组。 array

talib.PPO(inReal) talib.PPO(inReal, optInFastPeriod) talib.PPO(inReal, optInFastPeriod, optInSlowPeriod) talib.PPO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInFastPeriod参数用于设置快周期,默认值为12。 optInFastPeriod false number optInSlowPeriod参数用于设置慢周期,默认值为26。 optInSlowPeriod false number optInMAType参数用于设置均线类型,默认值为0。 optInMAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.PPO(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.PPO(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.PPO(records);
    Log(ret);
}

PPO()函数在talib库文档中的描述为:PPO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)

talib.ROC

talib.ROC()函数用于计算Rate of change : ((price/prevPrice)-1)*100 (变动率指标)

talib.ROC()函数的返回值为:一维数组。 array

talib.ROC(inReal) talib.ROC(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为10。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ROC(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ROC(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ROC(records);
    Log(ret);
}

ROC()函数在talib库文档中的描述为:ROC(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCP

talib.ROCP()函数用于计算Rate of change Percentage: (price-prevPrice)/prevPrice (价格变化率)

talib.ROCP()函数的返回值为:一维数组。 array

talib.ROCP(inReal) talib.ROCP(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为10。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ROCP(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ROCP(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ROCP(records);
    Log(ret);
}

ROCP()函数在talib库文档中的描述为:ROCP(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCR

talib.ROCR()函数用于计算Rate of change ratio: (price/prevPrice) (价格变化率)

talib.ROCR()函数的返回值为:一维数组。 array

talib.ROCR(inReal) talib.ROCR(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为10。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ROCR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ROCR(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ROCR(records);
    Log(ret);
}

ROCR()函数在talib库文档中的描述为:ROCR(Records[Close],Time Period = 10) = Array(outReal)

talib.ROCR100

talib.ROCR100()函数用于计算Rate of change ratio 100 scale: (price/prevPrice)*100 (价格变化率)

talib.ROCR100()函数的返回值为:一维数组。 array

talib.ROCR100(inReal) talib.ROCR100(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为10。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ROCR100(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ROCR100(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ROCR100(records);
    Log(ret);
}

ROCR100()函数在talib库文档中的描述为:ROCR100(Records[Close],Time Period = 10) = Array(outReal)

talib.RSI

talib.RSI()函数用于计算Relative Strength Index (相对强弱指标)

talib.RSI()函数的返回值为:一维数组。 array

talib.RSI(inReal) talib.RSI(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.RSI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.RSI(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.RSI(records);
    Log(ret);
}

RSI()函数在talib库文档中的描述为:RSI(Records[Close],Time Period = 14) = Array(outReal)

talib.STOCH

talib.STOCH()函数用于计算Stochastic (STOCH指标)

talib.STOCH()函数的返回值为:二维数组。 array

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)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInFastK_Period参数用于设置Fast-K周期,默认值为5。 optInFastK_Period false number optInSlowK_Period参数用于设置Slow-K周期,默认值为3。 optInSlowK_Period false number optInSlowK_MAType参数用于设置Slow-K均线类型,默认值为0。 optInSlowK_MAType false number optInSlowD_Period参数用于设置Slow-D周期,默认值为3。 optInSlowD_Period false number optInSlowD_MAType参数用于设置Slow-D均线类型,默认值为0。 optInSlowD_MAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.STOCH(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.STOCH(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.STOCH(records);
    Log(ret);
}

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

talib.STOCHF()函数用于计算Stochastic Fast (快速STOCH指标)

talib.STOCHF()函数的返回值为:二维数组。 array

talib.STOCHF(inPriceHLC) talib.STOCHF(inPriceHLC, optInFastK_Period) talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period) talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period, optInFastD_MAType)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInFastK_Period参数用于设置Fast-K周期,默认值为5。 optInFastK_Period false number optInFastD_Period参数用于设置Fast-D周期,默认值为3。 optInFastD_Period false number optInFastD_MAType参数用于设置Fast-D均线类型,默认值为0。 optInFastD_MAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.STOCHF(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.STOCHF(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.STOCHF(records);
    Log(ret);
}

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

talib.STOCHRSI()函数用于计算Stochastic Relative Strength Index (随机强弱指数)

talib.STOCHRSI()函数的返回值为:二维数组。 array

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)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number optInFastK_Period参数用于设置Fast-K周期,默认值为5。 optInFastK_Period false number optInFastD_Period参数用于设置Fast-D周期,默认值为3。 optInFastD_Period false number optInFastD_MAType参数用于设置Fast-D均线类型,默认值为0。 optInFastD_MAType false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.STOCHRSI(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.STOCHRSI(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.STOCHRSI(records);
    Log(ret);
}

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

talib.TRIX()函数用于计算1-day Rate-Of-Change (ROC) of a Triple Smooth EMA (三重指数平滑平均线)

talib.TRIX()函数的返回值为:一维数组。 array

talib.TRIX(inReal) talib.TRIX(inReal, optInTimePeriod)

inReal参数用于指定K线数据。 inReal true {@struct/Record Record}结构数组、数值数组 optInTimePeriod参数用于设置周期,默认值为30。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TRIX(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TRIX(records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TRIX(records);
    Log(ret);
}

TRIX()函数在talib库文档中的描述为:TRIX(Records[Close],Time Period = 30) = Array(outReal)

talib.ULTOSC

talib.ULTOSC()函数用于计算Ultimate Oscillator (极限振子)

talib.ULTOSC()函数的返回值为:一维数组。 array

talib.ULTOSC(inPriceHLC) talib.ULTOSC(inPriceHLC, optInTimePeriod1) talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2) talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2, optInTimePeriod3)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod1参数用于设置第一周期,默认值为7。 optInTimePeriod1 false number optInTimePeriod2参数用于设置第二周期,默认值为14。 optInTimePeriod2 false number optInTimePeriod3参数用于设置第三周期,默认值为28。 optInTimePeriod3 false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.ULTOSC(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.ULTOSC(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.ULTOSC(records);
    Log(ret);
}

ULTOSC()函数在talib库文档中的描述为:ULTOSC(Records[High,Low,Close],First Period = 7,Second Period = 14,Third Period = 28) = Array(outReal)

talib.WILLR

talib.WILLR()函数用于计算Williams’ %R (威廉指标)

talib.WILLR()函数的返回值为:一维数组。 array

talib.WILLR(inPriceHLC) talib.WILLR(inPriceHLC, optInTimePeriod)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组 optInTimePeriod参数用于设置周期,默认值为14。 optInTimePeriod false number

function main() {
    var records = exchange.GetRecords()
    var ret = talib.WILLR(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.WILLR(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.WILLR(records);
    Log(ret);
}

WILLR()函数在talib库文档中的描述为:WILLR(Records[High,Low,Close],Time Period = 14) = Array(outReal)

talib.AVGPRICE

talib.AVGPRICE()函数用于计算Average Price (平均价格)

talib.AVGPRICE()函数的返回值为:一维数组。 array

talib.AVGPRICE(inPriceOHLC)

inPriceOHLC参数用于指定K线数据。 inPriceOHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.AVGPRICE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.AVGPRICE(records.Open, records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.AVGPRICE(records);
    Log(ret);
}

AVGPRICE()函数在talib库文档中的描述为:AVGPRICE(Records[Open,High,Low,Close]) = Array(outReal)

talib.MEDPRICE

talib.MEDPRICE()函数用于计算Median Price (中位数价格)

talib.MEDPRICE()函数的返回值为:一维数组。 array

talib.MEDPRICE(inPriceHL)

inPriceHL参数用于指定K线数据。 inPriceHL true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.MEDPRICE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.MEDPRICE(records.High, records.Low)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.MEDPRICE(records);
    Log(ret);
}

MEDPRICE()函数在talib库文档中的描述为:MEDPRICE(Records[High,Low]) = Array(outReal)

talib.TYPPRICE

talib.TYPPRICE()函数用于计算Typical Price (典型价格)

talib.TYPPRICE()函数的返回值为:一维数组。 array

talib.TYPPRICE(inPriceHLC)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.TYPPRICE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.TYPPRICE(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.TYPPRICE(records);
    Log(ret);
}

TYPPRICE()函数在talib库文档中的描述为:TYPPRICE(Records[High,Low,Close]) = Array(outReal)

talib.WCLPRICE

talib.WCLPRICE()函数用于计算Weighted Close Price (加权收盘价)

talib.WCLPRICE()函数的返回值为:一维数组。 array

talib.WCLPRICE(inPriceHLC)

inPriceHLC参数用于指定K线数据。 inPriceHLC true {@struct/Record Record}结构数组

function main() {
    var records = exchange.GetRecords()
    var ret = talib.WCLPRICE(records)
    Log(ret)
}
import talib
def main():
    records = exchange.GetRecords()
    ret = talib.WCLPRICE(records.High, records.Low, records.Close)
    Log(ret)
void main() {
    auto records = exchange.GetRecords();
    auto ret = talib.WCLPRICE(records);
    Log(ret);
}

WCLPRICE()函数在talib库文档中的描述为:WCLPRICE(Records[High,Low,Close]) = Array(outReal)

结构体