传统模型跨期套利策略(传统商品期货)

Author: 雨幕(youquant), Date: 2021-08-19 14:28:43
Tags:

相关文章

https://www.youquant.com/digest-topic/7795


/*backtest
start: 2021-02-01 09:00:00
end: 2021-04-01 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
*/

// 全局变量
var interest_rate = 1 + rate * diffMonth / 12 //  远近合约月份之间的利率系数理论值
var q = $.NewTaskQueue()        // 创建商品期货交易类库模版类库中的交易对象
var p = $.NewPositionManager()

function main() {
    var lastPlotTS = 0
    var strState = ""
    while (true) {
        Sleep(interval)
        LogStatus(_D(), strState)

        strState = ""
        if (exchange.IO("status")) {
            if (!$.IsTrading(symbolNear) || !$.IsTrading(symbolFar)) {
                strState += "不在交易时间|"               
                continue 
            }

            // 获取近期行情数据
            var infoNear = exchange.SetContractType(symbolNear)
            if (!infoNear) {
                strState += "订阅" + symbolNear + "合约失败|"
                continue
            }
            var tickerNear = exchange.GetTicker()

            // 获取远期行情数据
            var infoFar = exchange.SetContractType(symbolFar)
            if (!infoFar) {
                strState += "订阅" + symbolFar + "合约失败|"
                continue
            }
            var tickerFar = exchange.GetTicker()

            if (!tickerNear || !tickerFar) {
                strState += "行情获取失败|"
                continue
            }

            // 更新持仓
            var nearSymbolHold = 0
            var farSymbolHold = 0
            var pos = _C(exchange.GetPosition)
            for (var i = 0 ; i < pos.length ; i++) {
                if (pos[i].ContractType == symbolNear) {
                    nearSymbolHold += pos[i].Amount 
                } else if (pos[i].ContractType == symbolFar) {
                    farSymbolHold += pos[i].Amount
                }
            }

            // theory_price 理论远期合约价格
            var theory_price = tickerNear.Last * interest_rate
            // theory 近期实际价格和远期理论价格的价差
            var theory = tickerNear.Last - theory_price
            // 近期合约和远期合约实际价差
            var real = tickerNear.Last - tickerFar.Last 

            // 触发下线
            var floor = theory - openDiff
            // 触发上线
            var cap = theory + openDiff
            
            // 平仓线
            var close_low = theory - coverDiff
            var close_high = theory + coverDiff

            // 判断触发条件
            if (nearSymbolHold == 0 && farSymbolHold == 0 && real < floor) {   // 买近卖远
                Log("买近卖远,real:", real, "floor:", floor, "#FF0000")
                q.pushTask(exchange, symbolNear, "buy", amount, function(task, ret) {
                    Log(task.desc, ret)
                    if (ret) {
                        q.pushTask(exchange, symbolFar, "sell", amount, function(task, ret) {
                            Log(task.desc, ret)
                        })
                    }
                })
            } else if (nearSymbolHold == 0 && farSymbolHold == 0 && real > cap) {   // 卖近买远
                Log("卖近买远,real:", real, "floor:", floor, "#CD32CD")
                q.pushTask(exchange, symbolNear, "sell", amount, function(task, ret) {
                    Log(task.desc, ret)
                    if (ret) {
                        q.pushTask(exchange, symbolFar, "buy", amount, function(task, ret) {
                            Log(task.desc, ret)
                        })
                    }
                })
            } else if ((nearSymbolHold != 0 || farSymbolHold != 0) && real > close_low && real < close_high) {   // 当差价进入设置的非套利区间,平仓
                // coverall
                Log("平仓,real:", real, "close_low:", close_low, "close_high:", close_high)
                q.pushTask(exchange, symbolNear, "coverall", -1, function(task, ret) {
                    Log(task.desc, ret)
                    if (ret) {
                        q.pushTask(exchange, symbolFar, "coverall", -1, function(task, ret) {
                            Log(task.desc, ret)
                        })
                    }
                })
            }
            q.poll()
            strState += "已链接|"            
            if (new Date().getTime() - lastPlotTS > 1000 * 60 * 60) {
                $.PlotLine("floor", floor)
                $.PlotLine("cap", cap)
                $.PlotLine("close_low", close_low)
                $.PlotLine("close_high", close_high)
                $.PlotLine("real", real)
                lastPlotTS = new Date().getTime()
            }
        } else {
            strState += "未连接|"
        }        
    }
}



更多内容