[TOC]
优宽量化交易平台经过多年的技术迭代,进行了多次重构,虽然作为用户的我们可能未曾察觉。在过去的几个月中,平台在用户体验方面进行了大量优化和升级,包括全面升级UI界面,丰富常用量化交易工具,以及增加更多回测数据支持。
为了让策略设计更加便捷、交易逻辑更加清晰,且初学者更容易上手,平台升级了策略使用的API接口。使用最新版本的托管者即可启用这些新功能。平台依然最大程度地兼容旧接口的调用。有关API接口新增功能等信息已同步更新至优宽量化交易平台的API文档:
语法手册:https://www.youquant.com/syntax-guide 用户指南:https://www.youquant.com/user-guide
那么通过本篇让我们一起来速览都有哪些接口升级更新以及对于老旧策略使用时需要哪些改动以兼容当前API。
新增的exchange.GetHistoryOrders()
函数用来获取全部合约(也可以指定某个合约)的历史成交订单(只能查询当前交易日范围),
详细的函数说明,可以查询API文档语法手册:
https://www.youquant.com/syntax-guide#fun_exchange.gethistoryorders
function main() {
var tbl = {type: "table", title: "test", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var orders = exchange.GetHistoryOrders() // 不传参数
// var orders = exchange.GetHistoryOrders("rb2410") // 传参数
for (var order of orders) {
tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
return orders.length
}
Sleep(1000)
}
}
旧版本的获取持仓数据函数为exchange.GetPosition()
。此次升级为了更加贴合函数命名语义增加了新的获取持仓函数:exchange.GetPositions()
。同时依然兼容/升级GetPosition
函数。
exchange.GetPositions()
函数有三种调用形式:
https://www.youquant.com/syntax-guide#fun_exchange.getpositions
function main() {
var tbl1 = {"type": "table", "title": "test GetPosition/GetPositions", "cols": ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], "rows": []}
var tbl2 = {"type": "table", "title": "test GetPosition/GetPositions", "cols": ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], "rows": []}
var dictType = {
"PD_LONG": PD_LONG,
"PD_SHORT": PD_SHORT,
"PD_LONG_YD": PD_LONG_YD,
"PD_SHORT_YD": PD_SHORT_YD,
}
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var pos1 = exchange.GetPositions()
var pos2 = exchange.GetPosition()
Log("pos1.length:", pos1.length, "pos1:", pos1)
Log("pos2.length:", pos2.length, "pos2:", pos2)
if (pos1 && pos2) {
for (var p of pos1) {
tbl1.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
}
for (var p of pos2) {
tbl2.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
}
}
LogStatus(_D(), dictType, "\n", "`" + JSON.stringify([tbl1, tbl2]) + "`")
return
}
Sleep(1000)
}
}
新增的exchange.CreateOrder()
函数可谓是此次升级中的重点,exchange.CreateOrder()
函数最大的功能是直接在该函数的参数中指定下单的品种、方向。这样就不再依赖系统当前设置的交易对、合约代码、交易方向等设置了。
在多品种交易下单场景中、并发场景中极大程度的降低了设计复杂度。exchange.CreateOrder()
函数的四个参数分别是symbol
、side
、price
、amount
。用来指定订单的合约代码、方向、价格、数量。
var symbols = ["MA409", "i2501", "rb2410", "TA409"]
function CancellAll() {
var orders = exchange.GetOrders()
for (var order of orders) {
exchange.CancelOrder(order["Id"], order)
Sleep(1000)
}
Log("GetOrders:", exchange.GetOrders())
}
function main() {
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
for (var symbol of symbols) {
var info = exchange.SetContractType(symbol)
var t = exchange.GetTicker()
if (info && t) {
Log("测试 Buy/Sell", "#FF0000")
exchange.SetDirection("buy")
var id1 = exchange.Buy(t.Last - 10, 1) // 低于最新成交价,为了挂单
exchange.SetDirection("sell")
var id2 = exchange.Sell(t.Last + 10, 1) // 同理
Log("测试 CreateOrder", "#FF0000")
var id3 = exchange.CreateOrder(symbol, "buy", t.Last - 20, 1, "测试CreateOrder", "#FF0000")
var id4 = exchange.CreateOrder(symbol, "sell", t.Last + 20, 1, "测试CreateOrder", "#FF0000")
}
}
Sleep(5000)
CancellAll() // 撤销所有挂单
return
}
Sleep(1000)
}
}
https://www.youquant.com/syntax-guide#fun_exchange.createorder
行情函数exchange.GetTicker()
本次升级主要是增加了symbol
参数。使得该函数可以脱离当前合约代码直接按照参数指定的合约代码,请求行情数据。简化了代码编写过程。同时依然兼容不传参的调用方式,最大程度兼容平台旧策略。
function main() {
var symbols = ["rb2410", "MA888"]
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var tbl = {
type: "table", title: "test:", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume", "OpenInterest"], rows: []
}
var index = 0
for (var symbol of symbols) {
var info = exchange.SetContractType(symbol)
Log(info)
var ticker = null
if (index == 0) {
ticker = exchange.GetTicker() // 测试不带参数
Log(ticker)
} else {
ticker = exchange.GetTicker(symbol) // 测试带参数
Log(ticker)
}
index++
// 检查返回的结构
if (info && ticker) {
tbl["rows"].push([
ticker["Symbol"],
ticker["High"],
ticker["Open"],
ticker["Low"],
ticker["Last"],
ticker["Buy"],
ticker["Sell"],
ticker["Time"],
ticker["Volume"],
ticker["OpenInterest"],
])
}
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
return
}
Sleep(1000)
}
}
请求一批指定合约的行情数据设计变得更加简单。
与GetTicker
函数相同exchange.GetDepth()
函数此次也增加了symbol
参数。可以实现在请求深度数据时直接指定品种。
function main() {
var symbols = ["rb2410", "MA888"]
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var tbl = {type: "table", title: "test:", cols: ["symbol", "Bids.length", "Asks.length", "Bids[0]", "Asks[0]", "Time"], rows: []}
var index = 0
for (var symbol of symbols) {
var info = exchange.SetContractType(symbol)
Log(info)
var depth = null
if (index == 0) {
depth = exchange.GetDepth() // 测试不带参数
Log("测试GetDepth不传参", depth)
} else {
depth = exchange.GetDepth(symbol) // 测试带参数
Log("测试GetDepth传参", depth)
}
index++
}
return
}
Sleep(1000)
}
}
与GetTicker
函数相同exchange.GetTrades()
函数此次也增加了symbol
参数。可以实现在请求市场成交数据时直接指定品种。
GetRecords
函数本次做出了较大调整,除了支持symbol
参数直接指定请求的K线数据的品种信息。保留了原有的period
参数用来指定K线周期,还增加了一个limit
参数用来指定请求时期望的K线长度。同时也兼容旧版本的GetRecords
函数只传入period
周期参数的调用方式。
exchange.GetRecords()
函数的调用方式:
function main() {
var symbols = ["MA888", "rb2410", "i2409", "hc2410"]
Log("当前默认K线周期", exchange.GetPeriod())
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var index = 0
for (var symbol of symbols) {
var info = exchange.SetContractType(symbol)
Log(info)
var r = null
if (index == 0) {
exchange.SetMaxBarLen(2000) // 测试
r = exchange.GetRecords() // 测试不带参数
Log("索引:", index, ",合约:", symbols[index], ",BAR间隔:", r[1]["Time"] - r[0]["Time"], r[2]["Time"] - r[1]["Time"], "最新价格:", r[r.length - 1]["Close"])
} else if (index == 1) {
r = exchange.GetRecords(symbol, 60 * 5) // 测试指定symbol period
Log("索引:", index, ",合约:", symbols[index], ",BAR间隔:", r[1]["Time"] - r[0]["Time"], r[2]["Time"] - r[1]["Time"], "最新价格:", r[r.length - 1]["Close"])
} else if (index == 2) {
// r = exchange.GetRecords(symbol, 60 * 60 * 24, 999)
r = exchange.GetRecords(symbol, 60, 999) // 测试指定symbol period limit
Log("索引:", index, ",合约:", symbols[index], ",BAR间隔:", r[1]["Time"] - r[0]["Time"], r[2]["Time"] - r[1]["Time"], "最新价格:", r[r.length - 1]["Close"])
} else if (index == 3) {
r = exchange.GetRecords(symbol) // 测试指定symbol
Log("索引:", index, ",合约:", symbols[index], ",BAR间隔:", r[1]["Time"] - r[0]["Time"], r[2]["Time"] - r[1]["Time"], "最新价格:", r[r.length - 1]["Close"])
}
index++
if (info && r) {
Log(symbol, "r.length:", r.length, "#FF0000")
}
}
return
}
Sleep(1000)
}
}
GetOrders
函数也增加了symbol
参数,可以直接指定查询当前未完成订单(挂单)的合约代码;不传symbol
参数则是获取所有合约的当前未完成订单。
var tbl = {type: "table", title: "test", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
function main() {
for (var i = 0; i < 10; i++) {
if (exchange.IO("status")) {
var info = exchange.SetContractType("hc2410")
var orders = exchange.GetOrders() // 测试1
// var orders = exchange.GetOrders("rb2410") // 测试2
// var orders = exchange.GetOrders("hc2410") // 测试3
Log("orders.length:", orders.length, ", orders:", orders)
for (var order of orders) {
tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
return
}
Sleep(1000)
}
}
此次更新给Ticker
结构体增加了Symbol
字段,该字段记录当前Ticker
结构为哪个品种的行情信息。例如在商品期货中如果当前这个Ticker
数据为螺纹钢合约rb2410的行情数据,此时Ticker
结构中Symbol
字段为:rb2410
。
此次更新给Order
结构体增加了Symbol
字段,该字段格式、定义与exchange.GetTicker()
函数的symbol
参数格式、定义完全一致。
此次更新给Position
结构体增加了Symbol
字段,该字段格式、定义与exchange.GetTicker()
函数的symbol
参数格式、定义完全一致。
新增字段Equity
、UPnL
。
Equity 当前账户权益,包含可用资金、仓位保证金、盈亏等。
UPnL 当前所有持仓的盈亏总和。
根据本次升级,回测系统正在适配中。