商品期货资金管理策略(教学)

Author: 雨幕, Date: 2021-12-15 10:36:58
Tags:

相关文章:https://www.fmz.cn/digest-topic/8567


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

// 全局变量
var p = $.NewPositionManager()
var n = 1 

function GetOrders(symbol, orders) {
    var ret = []
    for (var i = 0 ; i < orders.length ; i++) {
        if (orders[i].ContractType == symbol) {
            ret.push(orders[i])
        }
    }
    return ret 
}

function CancelOrders(symbol, orders) {
    for (var i = 0 ; i < orders.length ; i++) {
        if (orders[i].ContractType == symbol) {
            exchange.CancelOrder(orders[i].Id, orders[i])
            Sleep(500)
        }
    }
}

function trade(distance, price, amount) {
    var tradeFunc = null 
    if (distance == "buy") {
        tradeFunc = exchange.Buy
    } else if (distance == "sell") {
        tradeFunc = exchange.Sell
    } else if (distance == "closebuy") {
        tradeFunc = exchange.Sell
    } else {
        tradeFunc = exchange.Buy
    }
    exchange.SetDirection(distance)
    return tradeFunc(price, amount)
}

function openLong(price, amount) {
    return trade("buy", price, amount)
}

function openShort(price, amount) {
    return trade("sell", price, amount)
}

function coverLong(price, amount, pos) {
    var direction = pos.Type == PD_LONG ? "closebuy_today" : "closebuy"
    return trade("closebuy", price, amount)
}

function coverShort(price, amount, pos) {
    var direction = pos.Type == PD_LONG ? "closebuy_today" : "closebuy"
    return trade("closesell", price, amount)
}

function onTick() {
    var info = exchange.SetContractType(symbol)
    if (!info) {
        return 
    }
    
    var r = exchange.GetRecords()
    if (!r) {
        return 
    }
    $.PlotRecords(r, symbol)
    
    var allOrders = exchange.GetOrders()
    if (!allOrders) {
        return 
    }
    var orders = GetOrders(symbol, allOrders)
    
    // 检测挂单
    var buyOrder = null 
    var sellOrder = null 
    if (orders.length == 2) {
        for (var i = 0 ; i < orders.length ; i++) {
            if (orders[i].Type == ORDER_TYPE_BUY) {
                buyOrder = orders[i]
            } else if (orders[i].Type == ORDER_TYPE_SELL) {
                sellOrder = orders[i]
            }
        }
        if (!buyOrder || !sellOrder) {
            CancelOrders(symbol, GetOrders(symbol, _C(exchange.GetOrders)))
            return 
        }
    } else if (orders.length == 1) {
        CancelOrders(symbol, GetOrders(symbol, _C(exchange.GetOrders)))
        return 
    }
    
    var ticker = exchange.GetTicker()
    if (!ticker) {
        return 
    }
    
    var pos = exchange.GetPosition()
    if (!pos) {
        return 
    }
    var longPos = p.GetPosition(symbol, PD_LONG, pos)
    var shortPos = p.GetPosition(symbol, PD_SHORT, pos)

    var sellId = null
    var buyId = null 
    
    if (longPos && shortPos) {             // 同时持有多空仓位
        throw "同时持有多空仓位"
    } else if (orders.length == 0 && !longPos && !shortPos) {    // 无持仓 
        buyId = openLong(parseInt(ticker.Last - openTarget * n - info.PriceTick), amount)   
        $.PlotHLine(parseInt(ticker.Last - openTarget * n - info.PriceTick), "buy", "red")
        sellId = openShort(parseInt(ticker.Last + openTarget * n + info.PriceTick), amount)
        $.PlotHLine(parseInt(ticker.Last + openTarget * n + info.PriceTick), "sell", "green")
    } else if (orders.length == 0 && longPos && !shortPos) {     // 只持有多头持仓
        buyId = openLong(parseInt(ticker.Last - openTarget * n - info.PriceTick), amount)
        $.PlotHLine(parseInt(ticker.Last - openTarget * n - info.PriceTick), "buy", "red")
        sellId = coverLong(parseInt(longPos.Price + closeTarget * Math.min(amount / longPos.Amount, 1) + info.PriceTick), longPos.Amount, longPos)
        $.PlotHLine(parseInt(longPos.Price + closeTarget * Math.min(amount / longPos.Amount, 1) + info.PriceTick), "sell", "green")
    } else if (orders.length == 0 && !longPos && shortPos) {     // 只持有空头持仓
        buyId = coverShort(parseInt(shortPos.Price - closeTarget * Math.min(amount / shortPos.Amount, 1) - info.PriceTick), shortPos.Amount, shortPos)
        $.PlotHLine(parseInt(shortPos.Price - closeTarget * Math.min(amount / shortPos.Amount, 1) - info.PriceTick), "buy", "red")
        sellId = openShort(parseInt(ticker.Last + openTarget * n + info.PriceTick), amount)
        $.PlotHLine(parseInt(ticker.Last + openTarget * n + info.PriceTick), "sell", "green")
    }
    
    if (orders.length == 0 && (!sellId || !buyId)) {
        CancelOrders(symbol, GetOrders(symbol, _C(exchange.GetOrders)))
        return 
    }
    
    var tblPos = {
        "type" : "table",
        "title" : "持仓",
        "cols" : ["持仓品种", "数量", "价格", "方向", "浮动盈亏"],
        "rows" : []
    }
    if (longPos) {
        tblPos.rows.push([longPos.ContractType, longPos.Amount, longPos.Price, longPos.Type == PD_LONG ? "多" : "空", longPos.Profit])
    }
    if (shortPos) {
        tblPos.rows.push([shortPos.ContractType, shortPos.Amount, shortPos.Price, shortPos.Type == PD_LONG ? "多" : "空", shortPos.Profit])
    }
    
    var tblOrders = {
        "type" : "table",
        "title" : "挂单",
        "cols" : ["订单品种", "数量", "价格", "方向"],
        "rows" : []
    }
    if (buyOrder) {
        tblOrders.rows.push([buyOrder.ContractType, buyOrder.Amount, buyOrder.Price, buyOrder.Type == ORDER_TYPE_BUY ? "买" : "卖"])
    }
    if (sellOrder) {
        tblOrders.rows.push([sellOrder.ContractType, sellOrder.Amount, sellOrder.Price, sellOrder.Type == ORDER_TYPE_BUY ? "买" : "卖"])
    }    

    var acc = exchange.GetAccount()
    if (!acc) {
        return 
    }
    var tblAccount = $.AccountToTable(exchange.GetRawJSON(), "资金信息")
    
    return [tblPos, tblOrders, tblAccount]
}

function main() {
    var msg = null 
    var tbls = null 
    while (true) {
        if (exchange.IO("status")) {
            if ($.IsTrading(symbol)) {
                var ret = onTick()
                if (ret) {
                    tbls = ret 
                }
                msg = "已连接"
            }            
        } else {
            msg = "未连接"
        }
        LogStatus("时间:", _D(), "连接状态:", msg, "\n", "`" + JSON.stringify(tbls) + "`")
        Sleep(5000)
    }
}

更多内容