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

自定义数据源

发明者量化交易平台的回测系统支持自定义数据源,回测系统使用GET方法请求自定义的URL(可公开可访问的网址)来获取外部数据源进行回测,附加的请求参数如下:

参数 意义 说明
symbol 品种名 现货行情数据例如:BTC_USDT,期货行情数据例如:BTC_USDT.swap,期货永续合约资金费率数据例如:BTC_USDT.funding,期货永续合约价格指数数据例如:BTC_USDT.index
eid 交易所 例如:OKX、Futures_OKX
round 数据精度 为true,表示由自定义数据源反馈的数据中定义具体精度。发明者量化交易平台回测系统向自定义数据源发送的请求固定为:round=true
period K线数据的周期(毫秒) 例如:60000为1分钟周期
depth 深度档数 1-20
trades 是否需要分笔数据 真(1)/假(0)
from 开始时间 unix时间戳
to 结束时间 unix时间戳
detail 请求数据的品种详细信息 为true,表示需要由自定义数据源提供。发明者量化交易平台回测系统向自定义数据源发送的请求固定为:detail=true
custom 可以忽略该参数

现货交易所、期货交易所对象的数据源设置为自定义数据源(feeder)时回测系统向自定义数据源服务发送请求的例子:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Bitget&from=1351641600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_OKX&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=1

数据格式

返回的格式必须为以下两种格式其中之一(系统自动识别):

  • 模拟级Tick,以下是JSON数据范例:
  {
      "detail": {
          "eid": "Binance",
          "symbol": "BTC_USDT",
          "alias": "BTCUSDT",
          "baseCurrency": "BTC",
          "quoteCurrency": "USDT",
          "marginCurrency": "USDT",
          "basePrecision": 5,
          "quotePrecision": 2,
          "minQty": 0.00001,
          "maxQty": 9000,
          "minNotional": 5,
          "maxNotional": 9000000,
          "priceTick": 0.01,
          "volumeTick": 0.00001,
          "marginLevel": 10
      },
      "schema":["time", "open", "high", "low", "close", "vol"],
      "data":[
          [1564315200000, 9531300, 9531300, 9497060, 9497060, 787],
          [1564316100000, 9495160, 9495160, 9474260, 9489460, 338]
      ]
  }
  • 实盘级Tick,以下是JSON数据范例: Tick级回测的数据(包含盘口深度信息,深度格式为[价格, 量]的数组。可有多级深度,asks为价格升序,bids为价格倒序)。
  {
      "detail": {
          "eid": "Binance",
          "symbol": "BTC_USDT",
          "alias": "BTCUSDT",
          "baseCurrency": "BTC",
          "quoteCurrency": "USDT",
          "marginCurrency": "USDT",
          "basePrecision": 5,
          "quotePrecision": 2,
          "minQty": 0.00001,
          "maxQty": 9000,
          "minNotional": 5,
          "maxNotional": 9000000,
          "priceTick": 0.01,
          "volumeTick": 0.00001,
          "marginLevel": 10
      },
      "schema":["time", "asks", "bids", "trades", "close", "vol"],
      "data":[
          [1564315200000, [[9531300, 10]], [[9531300, 10]], [[1564315200000, 0, 9531300, 10]], 9497060, 787],
          [1564316100000, [[9531300, 10]], [[9531300, 10]], [[1564316100000, 0, 9531300, 10]], 9497060, 787]
      ]
  }
字段 说明
detail 请求数据的品种详细信息,包含计价币名称、交易币名称,精度,最小下单量等
schema 指定data数组中列的属性,区分大小写。仅限于 time, open, high, low, close, vol, asks, bids, trades
data 按照schema设置的列结构,记录的数据。

detail字段

字段 说明
eid 交易所Id,注意某个交易所现货与期货是不同的eid
symbol 交易品种代码
alias 当前交易品种代码对应的交易所中的symbol
baseCurrency 交易币种
quoteCurrency 计价币种
marginCurrency 保证金币种
basePrecision 交易币种精度
quotePrecision 计价币种精度
minQty 最小下单量
maxQty 最大下单量
minNotional 最小下单金额
maxNotional 最大下单金额
priceTick 价格一跳
volumeTick 下单量最小变动数值(下单量一跳)
marginLevel 期货杠杆值
contractType 对于永续合约设置为:swap,回测系统会继续发送资金费率、价格指数请求

特殊的列属性asksbidstrades

字段 说明 备注
asks / bids [[价格, 数量], …] 例如实盘级 Tick数据范例中的数据:[[9531300, 10]]
trades [[时间, 方向(0:买,1:卖), 价格, 数量], …] 例如实盘级 Tick数据范例中的数据:[[1564315200000, 0, 9531300, 10]]

期货交易所的永续合约回测时,自定义数据源还需要额外的资金费率数据、价格指数数据。只有当请求的行情数据返回时,返回的结构中detail字段包含"contractType": "swap"键值对,回测系统才会继续发送对于资金费率的请求。 当回测系统收到资金费率数据时,才会继续发送对于价格指数数据的请求。

资金费率数据结构如下:

{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.funding",
        "alias": "BTC_USDT.funding",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "marginCurrency": "",
        "basePrecision": 8,
        "quotePrecision": 8,
        "minQty": 1,
        "maxQty": 10000,
        "minNotional": 1,
        "maxNotional": 100000000,
        "priceTick": 1e-8,
        "volumeTick": 1e-8,
        "marginLevel": 10
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [
            1584921600000,
            -16795,
            -16795,
            -16795,
            -16795,
            0
        ],
        [
            1584950400000,
            -16294,
            -16294,
            -16294,
            -16294,
            0
        ]
        // ...
    ]
}
  • 相邻的周期间隔8小时
  • 例如币安资金费率8小时更新一次,资金费率数据为什么为-16795? 因为和K线数据一样,为了避免网络传输过程中浮点数的精度丢失,数据采用整型;资金费率数据也可能为负值。

回测系统发出的资金费率数据请求,举例为:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.funding&to=1611244800&trades=0

价格指数数据结构如下:


{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.index",
        "alias": "BTCUSDT",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "index",
        "marginCurrency": "USDT",
        "basePrecision": 3,
        "quotePrecision": 1,
        "minQty": 0.001,
        "maxQty": 1000,
        "minNotional": 0,
        "maxNotional": 1.7976931348623157e+308,
        "priceTick": 0.1,
        "volumeTick": 0.001,
        "marginLevel": 10,
        "volumeMultiple": 1
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [1584921600000, 58172, 59167, 56902, 58962, 0],
        [1584922500000, 58975, 59428, 58581, 59154, 0],
        // ...
    ]
}

回测系统发出的价格指数数据请求,举例为:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.index&to=1611244800&trades=0

自定义数据源范例

指定数据源地址,例如:http://120.24.2.20:9090/data。自定义数据源服务程序使用Golang编写:

package main

import (
    "fmt"
    "net/http"
    "encoding/json"
)

func Handle (w http.ResponseWriter, r *http.Request) {
    // e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data

    // request: GET http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=OKX&from=1584921600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
    //              http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1599958800&period=3600000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=0
    fmt.Println("request:", r)

    // response
    defer func() {
        // response data
        /* e.g. data
        {
            "detail": {
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10
            },
            "schema": [
                "time",
                "open",
                "high",
                "low",
                "close",
                "vol"
            ],
            "data": [
                [1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151],
                [1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738],
                [1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875],
                [1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777],
                [1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292],
                [1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666],
                [1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405],
                [1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768],
                [1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797],
                [1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692]
            ]
        }
        */
        
        // /* 模拟级 Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time","open","high","low","close","vol"},
            "data": []interface{}{
                []int64{1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151},  // 1610755200000 : 2021-01-16 08:00:00
                []int64{1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738},  // 1610841600000 : 2021-01-17 08:00:00
                []int64{1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875},
                []int64{1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777},
                []int64{1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292},
                []int64{1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666},
                []int64{1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405},
                []int64{1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768},
                []int64{1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797},
                []int64{1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692},
            },
        }
        // */

        /* 实盘级 Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time", "asks", "bids", "trades", "close", "vol"},
            "data": []interface{}{
                []interface{}{1610755200000, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{1610755200000, 0, 9531300, 10}}, 9497060, 787},
                []interface{}{1610841600000, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{1610841600000, 0, 9531300, 11}}, 9497061, 789},                
            },
        }
        */

        b, _ := json.Marshal(ret)
        w.Write(b)
    }()
}

func main () {
    fmt.Println("listen http://localhost:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe(":9090", nil)
}

测试策略,JavaScript范例:

/*backtest
start: 2021-01-16 08:00:00
end: 2021-01-22 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
args: [["number",2]]
*/

function main() {
    var ticker = exchange.GetTicker()
    var records = exchange.GetRecords()
    Log(exchange.GetName(), exchange.GetCurrency())
    Log(ticker)
    Log(records)
}
保存回测设置 本地回测引擎