Market
exchange.GetTicker
获取当前设置的交易对、合约代码对应的Ticker结构,即行情数据。GetTicker()函数是交易所对象exchange的成员函数,exchange对象的成员函数(方法)仅与exchange对象相关,后续文档中不再赘述。
exchange.GetTicker()
exchange.GetTicker(symbol)示例
测试 exchange.GetTicker() 函数:
javascript
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)
}
python
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"])
rust
fn main() {
while exchange.IO("status").unwrap_or_default() != "true" {
Sleep(1000);
}
Log!(exchange.SetContractType("rb888"));
let ticker = exchange.GetTicker(None).unwrap();
Log!("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume);
}
c++
void main() {
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);
}返回值
| 类型 | 描述 |
|
|
参数
| 名称 | 类型 | 必填 | 描述 |
symbol | string | 否 | 参数 |
参考
备注
在回测系统中,exchange.GetTicker()函数返回的Ticker数据中,High、Low为模拟值,取自当时盘口的卖一价与买一价。
在商品期货策略实盘中,如果没有行情推送过来,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协议为例:json{ "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 }
exchange.GetDepth
获取当前设置的交易对、合约代码对应的Depth结构,即订单簿数据。
结构体Depth包含两个结构体数组,分别为Asks[]和Bids[]。Asks和Bids数组中的元素均包含以下结构体变量:
| 数据类型 | 变量名 | 说明 |
|---|---|---|
| number | Price | 价格 |
| number | Amount | 数量 |
exchange.GetDepth()
exchange.GetDepth(symbol)示例
测试exchange.GetDepth()函数:
javascript
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)
}
python
def main():
while not exchange.IO("status"):
Sleep(1000)
Log(exchange.SetContractType("rb888"))
depth = exchange.GetDepth()
price = depth["Asks"][0]["Price"]
Log("卖一价为:", price)
rust
fn main() {
while exchange.IO("status").unwrap_or_default() != "true" {
Sleep(1000);
}
Log!(exchange.SetContractType("rb888"));
let depth = exchange.GetDepth(None).unwrap();
let price = depth.Asks[0].Price;
Log!("卖一价为:", price);
}
c++
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);
}返回值
| 类型 | 描述 |
|
|
参数
| 名称 | 类型 | 必填 | 描述 |
symbol | string | 否 | 参数 |
参考
备注
在回测系统中,使用模拟级 Tick回测时,exchange.GetDepth()函数返回数据的各档位均为模拟值。
在回测系统中,使用实盘级 Tick回测时,exchange.GetDepth()函数返回的数据为秒级别深度快照。
商品期货实盘交易时需要注意:
涨停时,卖单卖一的价格为涨停价格,订单量为 0;跌停时,买单买一的价格为跌停价格,订单量为 0。通过判断买一、卖一订单数据中的订单量,即可判断当前是否处于涨停或跌停状态。
exchange.GetTrades
获取当前设置的交易对、合约代码对应的Trade结构数组,即市场的成交数据。对于商品期货,通过算法根据行情数据(Tick 数据)推算出市场成交记录。
exchange.GetTrades()
exchange.GetTrades(symbol)示例
测试exchange.GetTrades()函数:
javascript
function main() {
// 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
while(!exchange.IO("status")) {
Sleep(1000)
}
Log(exchange.SetContractType("rb888"))
var trades = exchange.GetTrades()
Log(trades)
}
python
def main():
while not exchange.IO("status"):
Sleep(1000)
Log(exchange.SetContractType("rb888"))
trades = exchange.GetTrades()
Log(trades)
rust
fn main() {
// 鉴于测试代码,不使用商品期货策略一般架构,这里仅仅判断exchange.IO("status")函数,判断连接期货公司前置机成功后立即执行测试代码。股票证券无需使用exchange.IO("status")判断连接状态
while exchange.IO("status").unwrap_or_default() != "true" {
Sleep(1000);
}
Log!(exchange.SetContractType("rb888"));
let trades = exchange.GetTrades(None).unwrap();
Log!(trades);
}
c++
void main() {
while(exchange.IO("status") == 0) {
Sleep(1000);
}
Log(exchange.SetContractType("rb888"));
auto trades = exchange.GetTrades();
Log(trades);
}返回值
| 类型 | 描述 |
|
|
参数
| 名称 | 类型 | 必填 | 描述 |
symbol | string | 否 | 参数 |
参考
备注
根据 Tick 数据推算成交记录的策略示例:
exchange.GetRecords
获取当前设置的交易对、合约代码所对应的Record结构数组,即K线数据。
exchange.GetRecords()
exchange.GetRecords(symbol)
exchange.GetRecords(symbol, period)
exchange.GetRecords(symbol, period, limit)
exchange.GetRecords(period)
exchange.GetRecords(period, limit)示例
-
对于 exchange.GetRecords(Period) 函数,商品期货的实盘与回测均支持自定义周期,参数 Period 的单位为秒。
javascriptfunction main() { // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过 exchange.IO("status") 函数判断是否成功连接期货公司前置机,连接成功后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while(!exchange.IO("status")) { Sleep(1000) } Log(exchange.SetContractType("rb888")) // 打印周期为 120 秒(2 分钟)的 K 线数据 Log(exchange.GetRecords(60 * 2)) // 打印周期为 5 分钟的 K 线数据 Log(exchange.GetRecords(PERIOD_M5)) }pythondef main(): while not exchange.IO("status"): Sleep(1000) Log(exchange.SetContractType("rb888")) Log(exchange.GetRecords(60 * 2)) Log(exchange.GetRecords(PERIOD_M5))rustfn main() { // 由于是测试代码,未采用商品期货策略的通用架构,这里仅通过 exchange.IO("status") 函数判断是否成功连接期货公司前置机,连接成功后立即执行测试代码。股票证券无需使用 exchange.IO("status") 判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } Log!(exchange.SetContractType("rb888")); // 打印周期为 120 秒(2 分钟)的 K 线数据 Log!(exchange.GetRecords(None, 60 * 2, None)); // 打印周期为 5 分钟的 K 线数据 Log!(exchange.GetRecords(None, PERIOD_M5, None)); }c++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]); } -
输出 K 线柱数据:
javascriptfunction 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]) }pythondef 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])rustfn main() { // 由于这是测试代码,未采用商品期货策略的通用架构,此处仅通过 exchange.IO("status") 函数判断,在成功连接期货公司前置机后立即执行测试代码。股票、证券无需使用 exchange.IO("status") 判断连接状态 while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } Log!(exchange.SetContractType("rb888")); let records = exchange.GetRecords(None, PERIOD_H1, None).unwrap(); 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.len() - 1], "上一根 K 线", records[records.len() - 2]); }c++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线数据:
javascriptfunction main() { while(!exchange.IO("status")) { Sleep(1000) } var records = exchange.GetRecords("rb888") Log("当前K线(最新)", records[records.length - 1]) }pythondef main(): while not exchange.IO("status"): Sleep(1000) records = exchange.GetRecords("rb888") Log("当前K线(最新)", records[-1])rustfn main() { while exchange.IO("status").unwrap_or_default() != "true" { Sleep(1000); } let records = exchange.GetRecords("rb888", None, None).unwrap(); Log!("当前K线(最新)", records[records.len() - 1]); }c++void main() { while(exchange.IO("status") == 0) { Sleep(1000); } auto records = exchange.GetRecords("rb888"); Log("当前K线(最新)", records[records.size() - 1]); }
返回值
| 类型 | 描述 |
|
|
参数
| 名称 | 类型 | 必填 | 描述 |
symbol | string | 否 | 参数 |
period | number | 否 | 参数 |
limit | string | 否 | 参数 |
参考
备注
默认K线周期可在回测、实盘页面进行设置。如果在调用exchange.GetRecords()函数时指定了参数,则获取的是该参数指定周期对应的K线数据;如果调用时未指定参数,则按照回测、实盘参数中设置的K线周期返回对应的K线数据。
返回值为Record结构数组,返回的K线数据会随时间累积,累积的K线柱数量上限受exchange.SetMaxBarLen()函数设置的影响,未设置时默认上限为5000个K线柱。当K线数据达到累积上限后,之后每更新加入一根K线柱的同时会删除时间最早的一根K线柱(类似队列的先进先出)。
初始调用GetRecords函数时获取的K线柱数量:
- 回测系统中会预先取回回测周期起始时刻之前的1000根K线柱,作为初始K线数据。
参数period设置为5,即表示请求获取以5秒为周期的K线数据。
如果period参数不能被60整除(即所代表的周期不是以分钟为单位的周期),系统底层则使用tick数据合成所需的K线数据。
如果period参数能被60整除,则最小使用1分钟K线数据(尽可能使用较大的周期)来合成所需的K线数据。
股票证券:
- 富途证券
在K线周期为日线周期以下时,调用GetRecords()函数返回的数据中,数组的每个元素为一根K线柱数据(即Record结构体),每根K线柱数据结构的Time属性为该周期的结束时间(毫秒级时间戳),而非起始时间(毫秒级时间戳)。
在K线周期为日线周期时,Record结构体的Time属性为该周期的起始时间(毫秒级时间戳)。
在回测系统的模拟级别回测中,由于需要设置底层K线周期(回测系统进行模拟级别回测时,会根据设置的底层K线周期使用对应的K线数据生成Tick数据),因此需要注意:策略中获取的K线数据周期不能小于底层K线周期。因为在模拟级别回测中,各个周期的K线数据在回测系统中都是通过底层K线周期对应的K线数据合成的。
在C++语言中,如果需要自行构造K线数据,可参考以下代码范例:
c++
#include <sstream>
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
// 输出显示:Records[10]
Log(r);
auto ma = TA.MA(r,10);
// 输出显示:[nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
Log(ma);
}
exchange.GetPeriod
获取在回测或实盘运行策略时,于优宽量化交易平台网页上所设置的K线周期,即调用exchange.GetRecords()函数且不传入参数时使用的默认K线周期。
exchange.GetPeriod()示例
获取当前默认的K线周期。
javascript
function main() {
// 例如,回测或实盘时在优宽量化交易平台网页上设置的K线周期为1小时
var period = exchange.GetPeriod()
Log("K线周期:", period / (60 * 60), "小时")
}
python
def main():
period = exchange.GetPeriod()
Log("K线周期:", period / (60 * 60), "小时")
rust
fn main() {
// 例如,回测或实盘时在优宽量化交易平台网页上设置的K线周期为1小时
let period = exchange.GetPeriod();
Log!("K线周期:", period as f64 / (60.0 * 60.0), "小时");
}
c++
void main() {
auto period = exchange.GetPeriod();
Log("K线周期:", period / (60 * 60.0), "小时");
}返回值
| 类型 | 描述 |
number | K线周期的长度,为整数数值,单位为秒。 |
参考
exchange.SetMaxBarLen
设置 K 线的最大长度。
exchange.SetMaxBarLen(n)示例
测试exchange.SetMaxBarLen()函数:
javascript
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)
}
python
def main():
while not exchange.IO("status"):
Sleep(1000)
exchange.SetMaxBarLen(50)
Log(exchange.SetContractType("rb888"))
r = exchange.GetRecords()
Log(len(r), r)
rust
fn main() {
// 由于是测试代码,未采用商品期货策略的通用架构,此处仅通过exchange.IO("status")函数判断成功连接期货公司前置机后立即执行测试代码。股票证券策略无需使用exchange.IO("status")判断连接状态
while exchange.IO("status").unwrap_or_default() != "true" {
Sleep(1000);
}
exchange.SetMaxBarLen(50);
Log!(exchange.SetContractType("rb888"));
let records = exchange.GetRecords(None, None, None).unwrap();
Log!(records.len(), records);
}
c++
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]);
}参数
| 名称 | 类型 | 必填 | 描述 |
n | number | 是 | 参数 |
参考
备注
对于商品期货策略,exchange.SetMaxBarLen(Len)函数在运行时决定 K 线柱(BAR)数量的上限。
exchange.SetMaxBarLen函数必须在调用exchange.SetContractType函数之前执行,因为一旦调用exchange.SetContractType函数,系统底层便已开始处理 K 线数据。
exchange.GetRate
获取交易所对象当前设置的汇率。
exchange.GetRate()示例
获取交易所对象当前设置的汇率。
javascript
function main(){
Log(exchange.GetTicker())
// 设置汇率转换
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("当前汇率:", exchange.GetRate())
}
python
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("当前汇率:", exchange.GetRate())
rust
fn main() {
Log!(exchange.GetTicker(None));
// 设置汇率转换
exchange.SetRate(7);
Log!(exchange.GetTicker(None));
Log!("当前汇率:", exchange.GetRate());
}
c++
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
Log("当前汇率:", exchange.GetRate());
}返回值
| 类型 | 描述 |
number | 交易所对象当前的汇率值。 |
参考
备注
如果没有调用exchange.SetRate()设置过转换汇率,exchange.GetRate()函数将返回默认汇率值1,即当前显示的计价货币(quoteCurrency)相关数据未经过汇率转换。
如果已使用exchange.SetRate()设置了汇率值(例如exchange.SetRate(7)),那么通过exchange交易所对象获取的行情、深度、下单价格等所有价格信息,都会乘以所设置的汇率7进行转换。
如果exchange对应的是以美元为计价货币的交易所,在调用exchange.SetRate(7)后,实盘中所有价格都会乘以7,转换为接近人民币(CNY)的价格。此时使用exchange.GetRate()获取的汇率值即为7。
exchange.SetData
exchange.SetData() 函数用于设置策略运行时所加载的数据。
exchange.SetData(key, value)示例
在策略中直接写入数据,数据格式需与以下示例中的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}]。
javascript
/*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)
}
}
python
'''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)
rust
/*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"}]
*/
fn main() {
let data = r#"[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]"#;
exchange.SetData("test", data);
loop {
Log!(exchange.GetData("test"));
Sleep(1000);
}
}
c++
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"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);
}
}返回值
| 类型 | 描述 |
number | 参数 |
参数
| 名称 | 类型 | 必填 | 描述 |
key | string | 是 | 数据集合的名称。 |
value | array | 是 |
|
参考
备注
所加载的数据可以是任意经济指标、行业数据、相关指数等,用于策略量化考核各类可量化的信息。
exchange.GetData
exchange.GetData()函数用于获取由exchange.SetData()函数加载的数据,或外部链接提供的数据。
exchange.GetData(key)
exchange.GetData(key, timeout)示例
-
获取直接写入数据的调用方式示例。
javascript/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"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) } }python'''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)rust/*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"}] */ fn main() { let data = format!( r#"[[1579536000000, "{}"], [1579622400000, "{}"], [1579708800000, "{}"]]"#, _D(1579536000000), _D(1579622400000), _D(1579708800000) ); exchange.SetData("test", &data); loop { Log!(exchange.GetData("test")); Sleep(1000 * 60 * 60 * 24); } }c++/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"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); } } -
支持通过外部链接请求数据,请求返回的数据格式如下:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }其中,
schema定义了数据主体中每条记录的数据格式,该格式固定为["time","data"],与data属性中每条数据的格式一一对应。
data属性中存储的是数据主体,每条数据由毫秒级时间戳和数据内容构成(数据内容可以是任何可 JSON 编码的数据)。以下为测试用的服务程序,使用 Go 语言编写:
golangpackage main import ( "fmt" "net/http" "encoding/json" ) func Handle (w http.ResponseWriter, r *http.Request) { defer func() { fmt.Println("req:", *r) ret := map[string]interface{}{ "schema": []string{"time","data"}, "data": []interface{}{ []interface{}{1579536000000, "abc"}, []interface{}{1579622400000, 123}, []interface{}{1579708800000, map[string]interface{}{"price":123}}, []interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}}, }, } b, _ := json.Marshal(ret) w.Write(b) }() } func main () { fmt.Println("listen http://localhost:9090") http.HandleFunc("/data", Handle) http.ListenAndServe(":9090", nil) }程序接收到请求后返回的应答数据:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }测试策略代码如下:
javascript/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ function main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000) } }python'''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] ''' def main(): while True: Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000)rust/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ fn main() { loop { Log!(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Sleep(1000); } }c++/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ void main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Sleep(1000); } } -
获取外部链接数据的调用方式。
javascriptfunction main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) }pythondef main(): Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))rustfn main() { Log!(exchange.GetData("http://xxx.xx.x.xx:9090/data")); }c++void main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); } -
请求在datadata平台上创建的查询数据,要求应答的数据格式如下(schema中必须包含time、data字段的描述):
json{ "data": [], "schema": ["time", "data"] }其中"data"字段为所需的数据内容,且"data"字段中的数据需与"schema"中约定的字段保持一致。调用
exchange.GetData()函数时,将返回一个JSON对象,例如:{"Time":1579795200000, "Data":"..."}。javascriptfunction main() { // 链接中的xxx部分为查询数据的编码,此处xxx仅为示例。具体查询链接可登录datadata.cn平台创建,也可在优宽量化平台的「数据探索」页面创建 Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data")) }pythondef main(): Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data"))rustfn main() { // 链接中的xxx部分为查询数据的编码,此处xxx仅为示例。具体查询链接可登录datadata.cn平台创建,也可在优宽量化平台的「数据探索」页面创建 Log!(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data")); }c++void main() { Log(exchange.GetData("https://www.datadata.cn/api/v1/query/xxx/data")); }
返回值
| 类型 | 描述 |
object | 数据集合中的记录。 |
参数
| 名称 | 类型 | 必填 | 描述 |
key | string | 是 | 数据集合的名称。 |
timeout | number | 否 | 用于设置缓存超时时间,单位为毫秒。实盘时默认的缓存超时时间为一分钟。 |
参考
备注
回测时一次性获取全部数据,实盘时缓存一分钟的数据。
在回测系统中,当使用访问接口请求数据的方式时,回测系统会自动为请求添加from(时间戳,单位为秒)、to(时间戳,单位为秒)、period(底层K线周期,时间戳,单位为毫秒)等参数,用于确定所要获取数据的时间范围。
exchange.GetMarkets
exchange.GetMarkets()函数用于获取已订阅交易品种的市场信息。
exchange.GetMarkets()示例
在回测系统中调用 exchange.GetMarkets() 函数时,仅返回已订阅的合约信息。
javascript
/*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)
}
}
python
'''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)
rust
/*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"}]
*/
fn main() {
let arr_symbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"];
for _i in 0..10 {
if exchange.IO("status").unwrap_or_default() == "true" {
for symbol in arr_symbol {
exchange.SetContractType(symbol).unwrap();
}
// Rust 中直接拼接 JSON 字符串构造状态栏表格
let markets = exchange.GetMarkets();
let mut rows: Vec<String> = Vec::new();
for (key, market) in &markets {
rows.push(format!(
r#"["{}", "{}", "{}", "{}", {}, {}, {}, {}, {}, {}, {}, {}, {}]"#,
key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal
));
}
let tbl = format!(
r#"{{"type": "table", "title": "test markets", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [{}]}}"#,
rows.join(", ")
);
LogStatus!(_D(None), "\n", format!("`{}`", tbl));
return;
}
Sleep(1000);
}
}
c++
/*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);
}
}返回值
| 类型 | 描述 |
object | 包含 |
参考
备注
exchange.GetMarkets()函数的返回值为一个字典,其中键名为合约代码。例如:
json
{
"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()函数仅返回已订阅品种的相关数据。
exchange.GetTickers
exchange.GetTickers()函数用于获取已订阅交易品种的聚合行情数据(由Ticker结构组成的数组)。
exchange.GetTickers()示例
在回测系统中调用exchange.GetTickers()函数时,仅返回已订阅合约的聚合行情数据。
javascript
/*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)
}
}
python
'''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)
rust
/*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"}]
*/
fn main() {
let arr_symbol = ["rb2501", "MA888", "i2501", "p2501", "TA501"];
for _i in 0..10 {
if exchange.IO("status").unwrap_or_default() == "true" {
for symbol in arr_symbol {
exchange.SetContractType(symbol).unwrap();
}
// Rust 中直接拼接 JSON 字符串构造状态栏表格
let tickers = exchange.GetTickers().unwrap();
let mut rows: Vec<String> = Vec::new();
for ticker in &tickers {
rows.push(format!(
r#"["{}", {}, {}, {}, {}, {}, {}, {}, {}, {}]"#,
ticker.Symbol, ticker.Buy, ticker.Sell, ticker.Open, ticker.Last, ticker.High, ticker.Low, ticker.Volume, ticker.Time, ticker.OpenInterest
));
}
let tbl = format!(
r#"{{"type": "table", "title": "test tickers", "cols": ["Symbol", "Buy", "Sell", "Open", "Last", "High", "Low", "Volume", "Time", "OpenInterest"], "rows": [{}]}}"#,
rows.join(", ")
);
LogStatus!(_D(None), "\n", format!("`{}`", tbl));
return;
}
Sleep(1000);
}
}
c++
/*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()函数仅返回已订阅品种的相关数据。