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

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}

Log Trade