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

满墙的显示器太浪费!80行代码的实盘帮你搞定

Author: 雨幕(youquant), Created: 2022-04-06 17:36:12, Updated: 2023-11-20 20:38:05

img

满墙的显示器太浪费!80行代码的实盘帮你搞定

你一定见过专业的交易员的办公桌是这样的。

img

本篇教你如何用优宽量化实现类似的需求,只用80行代码,就能省下一大笔买设备的钱。

多品种、多图行情显示

我想同时看几个关注的商品期货合约品种,例如:螺纹钢主力、甲醇主力、铁矿石主力、PTA主力等。我们只需要给策略实盘传入这些合约代码:rb888,MA888,i888,TA888,p888,OI888,au888

例如这样:

img

增加交易按钮、信息显示

增加一键开仓、平仓,当前价格,持仓数量等信息的显示。

例如这样:

img

我还想可以动态增加某个合约,移除某个合约

给代码设计上交互相关的处理:

例如这样:

img

所有这些只要80行代码就可以实现,你敢信么!

策略源码

var subscribeSymbols = []
function main() {
    LogReset(1)
    SetErrorFilter("Error: 90 CTP")
    _.each(symbols.split(","), function(symbol) {
        subscribeSymbols.push(symbol)
    })
    var tbl = {type : "table", title : "商品期货数据", cols : ["合约代码", "当前价格", "持仓", "盈亏", "开多", "开空", "平多", "平空"], rows: []}
    var q = $.NewTaskQueue()
    var p = $.NewPositionManager()
    while (true) {
        var msg = "未连接"       
        if (exchange.IO("status")) {
            msg = "已经连接"
            tbl = {type : "table", title : "商品期货数据", cols : ["合约代码", "当前价格", "持仓(多)", "持仓(空)", "盈亏", "开多", "开空", "平多", "平空"], rows: []}
            _.each(subscribeSymbols, function(symbol) {
                var tblRow = [symbol, "--", "--", "--", "--", "--", "--", "--", "--"]
                if ($.IsTrading(symbol)) {
                    var info = exchange.SetContractType(symbol)            
                    var r = exchange.GetRecords()                    
                    if (info && r && r.length > 0) {
                        $.PlotMultRecords(symbol, symbol + "`Kline", r, {layout: 'single', col: 3, height: '400px'})
                        $.PlotMultHLine(symbol, r[r.length - 1].Close, "currPrice", "red", "ShortDot")
                        var pos = [p.GetPosition(info.InstrumentID, PD_LONG), p.GetPosition(info.InstrumentID, PD_SHORT)]
                        var openLong = {"type": "button", "name": "开多仓1手", "cmd": "buy_" + info.InstrumentID, "description": symbol +"开多仓1手", "class": "btn btn-xs btn-danger"}
                        var coverLong = {"type": "button", "name": "平多仓1手", "cmd": "closebuy_" + info.InstrumentID, "description": symbol +"平多仓1手", "class": "btn btn-xs btn-warning"}
                        var openShort = {"type": "button", "name": "开空仓1手", "cmd": "sell_" + info.InstrumentID, "description": symbol +"开空仓1手", "class": "btn btn-xs btn-success"}
                        var coverShort = {"type": "button", "name": "平空仓1手", "cmd": "closesell_" + info.InstrumentID, "description": symbol +"平空仓1手", "class": "btn btn-xs btn-warning"}
                        tblRow = [symbol + "(" + info.InstrumentID + ")", r[r.length - 1].Close, (pos[0] ? pos[0].Amount : 0), (pos[1] ? pos[1].Amount : 0), (pos[0] ? pos[0].Profit : 0) + (pos[1] ? pos[1].Profit : 0), openLong, openShort, coverLong, coverShort]                        
                    }
                }
                tbl.rows.push(tblRow)                
            })
            q.poll()
        }        
        LogStatus(_D(), msg, "\n", "`" + JSON.stringify(tbl) + "`")        
        var cmd = GetCommand()
        if (cmd) {
            var arrCmd = cmd.split(":")
            if (arrCmd.length == 2) {
                if (arrCmd[0] == "addSymbol") {
                    var addIndex = -1
                    for (var i = 0 ; i < subscribeSymbols.length ; i++) {
                        if (subscribeSymbols[i] == arrCmd[1]) {
                            addIndex = i
                        }
                    }
                    if (addIndex == -1) {
                        subscribeSymbols.push(arrCmd[1])
                    }
                } else if (arrCmd[0] == "removeSymbol") {
                    var removeIndex = -1
                    for (var i = 0 ; i < subscribeSymbols.length ; i++) {
                        if (subscribeSymbols[i] == arrCmd[1]) {
                            removeIndex = i
                        }
                    }
                    if (removeIndex != -1) {
                        subscribeSymbols.splice(removeIndex, 1)
                        $.removeChart(arrCmd[1])
                    }                    
                }
            } else if (arrCmd.length == 1) {
                arrCmd = cmd.split("_")
                if (arrCmd.length == 2) {
                    var direction = arrCmd[0]
                    var cmdSymbol = arrCmd[1]
                    q.pushTask(exchange, cmdSymbol, direction, 1, function(task, ret) {
                        Log(task.desc, ret)
                    })
                }
            }
        }        
        Sleep(1000)
    }
}

策略使用到了两个模板类库:

img

  • 商品期货交易类库:为所有优宽策略的内置类库,在策略编辑页面直接可以勾选引用。
  • 多图表画线类库:该类库已经公开在策略广场,直接复制到自己的策略库中即可在其它策略中引用。类库说明上有使用帖子链接。

完整策略地址:https://www.youquant.com/strategy/355634

使用simnow测试

img

增加了a888合约,移除了rb888合约。

img

平掉了开出的仓位

img

改造、扩展

基于优宽强大、灵活的设计架构,该例子策略还可以开发扩展出更多的功能,玩转优宽就是玩转了量化交易。


更多内容