avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Được tạo ra trong: 2021-04-07 21:30:05, cập nhật trên: 2024-12-05 21:59:36
comments   11
hits   4372

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Trong các bài viết trước, chúng tôi đã triển khai một robot giao dịch sao chép giao ngay đơn giản. Hôm nay, chúng tôi sẽ triển khai phiên bản hợp đồng của một robot giao dịch sao chép đơn giản.

Ý tưởng thiết kế

Có một sự khác biệt lớn giữa phiên bản hợp đồng của robot giao dịch sao chép và phiên bản giao ngay. Giao dịch sao chép giao ngay chủ yếu có thể đạt được bằng cách theo dõi những thay đổi trong tài sản tài khoản. Phiên bản tương lai yêu cầu theo dõi những thay đổi trong vị thế tài khoản. Do đó, tình hình trong phiên bản tương lai phức tạp hơn vì hợp đồng tương lai có vị thế mua, vị thế bán và các hợp đồng khác nhau. Chuỗi thông tin chi tiết này cần được xử lý. Ý tưởng cốt lõi là theo dõi những thay đổi về vị trí. Kích hoạt hành động sao chép dựa trên sự thay đổi vị trí. Khi mới được thiết kế, người ta dự định sẽ xử lý cả vị thế mua và bán cùng lúc, nhưng người ta thấy rằng điều này sẽ trở nên rất phức tạp. Sau khi phân tích vấn đề, người ta quyết định xử lý các vị thế mua và bán riêng biệt.

Thực hiện chiến lược

Các thông số chiến lược:

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Kiểm tra ngược được hỗ trợ và bạn có thể trực tiếp sử dụng các thiết lập mặc định để kiểm tra ngược các quan sát.

Mã nguồn chiến lược:

/*backtest
start: 2021-03-18 00:00:00
end: 2021-04-07 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*/

function test() {
    // 测试函数
    var ts = new Date().getTime()    
    if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) {
        Sleep(1000 * 60 * 10)
        var nowPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var longPosAmount = nowPosAmount.long
        var shortPosAmount = nowPosAmount.short
        var x = Math.random()
        if (x > 0.7) {
            exchange.SetDirection("buy")
            exchange.Buy(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x < 0.2) {
            exchange.SetDirection("sell")
            exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) {
            exchange.SetDirection("closebuy")
            exchange.Sell(-1, longPosAmount, "参考账户测试平仓#FF0000")
        } else if(shortPosAmount > 4) {
            exchange.SetDirection("closesell")
            exchange.Buy(-1, _N(shortPosAmount / 2, 0), "参考账户测试平仓#FF0000")
        }
    }
}

function getPosAmount(pos, ct) {
    var longPosAmount = 0
    var shortPosAmount = 0
    _.each(pos, function(ele) {
        if (ele.ContractType == ct && ele.Type == PD_LONG) {
            longPosAmount = ele.Amount
        } else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
            shortPosAmount = ele.Amount
        }
    })
    return {long: longPosAmount, short: shortPosAmount}
}

function trade(e, ct, type, delta) {
    var nowPosAmount = getPosAmount(_C(e.GetPosition), ct)
    var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
    if (delta > 0) {
        // 开仓
        var tradeFunc = type == PD_LONG ? e.Buy : e.Sell
        e.SetDirection(type == PD_LONG ? "buy" : "sell")
        tradeFunc(-1, delta)
    } else if (delta < 0) {
        // 平仓
        var tradeFunc = type == PD_LONG ? e.Sell : e.Buy
        e.SetDirection(type == PD_LONG ? "closebuy" : "closesell")
        if (nowAmount <= 0) {
            Log("未检测到持仓")
            return 
        }
        tradeFunc(-1, Math.min(nowAmount, Math.abs(delta)))
    } else {
        throw "错误"
    }
}

function main() {
    LogReset(1)
    if (exchanges.length < 2) {
        throw "没有跟单的交易所"
    }
    var exName = exchange.GetName()
    // 检测参考交易所
    if (!exName.includes("Futures_")) {
        throw "仅支持期货跟单"
    }
    Log("开始监控", exName, "交易所", "#FF0000")
    
    // 检测跟单交易所
    for (var i = 1 ; i < exchanges.length ; i++) {
        if (exchanges[i].GetName() != exName) {
            throw "跟单的期货交易所和参考交易所不同!"
        }
    }
    
    // 设置交易对、合约
    _.each(exchanges, function(e) {
        if (!IsVirtual()) {
            e.SetCurrency(refCurrency)
            if (isSimulate) {
                if (e.GetName() == "Futures_OKCoin") {
                    e.IO("simulate", true)
                }
            }
        }
        e.SetContractType(refCt)
    })

    var initRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
    while(true) {
        if (IsVirtual()) {    // 回测时才模拟
            test()            // 测试函数,模拟参考账户主动交易,触发跟单账户跟单        
        }
        Sleep(5000)
        var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var tbl = {
            type : "table", 
            title : "持仓",
            cols : ["名称", "标签", "多仓", "空仓", "账户资产(Stocks)", "账户资产(Balance)"],
            rows : []
        }
        _.each(exchanges, function(e) {
            var pos = getPosAmount(_C(e.GetPosition), refCt)
            var acc = _C(e.GetAccount)
            tbl.rows.push([e.GetName(), e.GetLabel(), pos.long, pos.short, acc.Stocks, acc.Balance])
        })
        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
        
        // 计算仓位变动量
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // 检测变动
        if (longPosDelta == 0 && shortPosDelta == 0) {
            continue
        } else {
            // 检测到仓位变动
            for (var i = 1 ; i < exchanges.length ; i++) {
                // 执行多头动作
                if (longPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行多头跟单,变动量:", longPosDelta)
                    trade(exchanges[i], refCt, PD_LONG, longPosDelta)
                }
                // 执行空头动作
                if (shortPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行空头跟单,变动量:", shortPosDelta)
                    trade(exchanges[i], refCt, PD_SHORT, shortPosDelta)
                }
            }
        }

        // 执行跟单操作后,更新
        initRefPosAmount = nowRefPosAmount
    }
}

Bài kiểm tra

Vì OKEX có thể sử dụng đĩa mô phỏng OKEX sau khi cập nhật giao diện V5 nên tôi đã sử dụng hai API KEY của đĩa mô phỏng OKEX để thử nghiệm thuận tiện.

Đối tượng trao đổi đầu tiên được thêm vào là trao đổi tham chiếu và trao đổi bản sao sẽ theo tài khoản trao đổi này để hoạt động. Trên trang giao dịch mô phỏng OKEX, hãy đặt thủ công 3 hợp đồng ETH theo quý dựa trên tài khoản sàn giao dịch.

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Có thể thấy rằng thị trường thực phát hiện những thay đổi về vị thế tài khoản giao dịch tham chiếu và sau đó theo dõi các hoạt động.

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Chúng ta hãy thử đóng hai vị thế hợp đồng mà chúng ta vừa mở. Các vị thế sau khi đóng như trong hình:

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Theo dõi hoạt động theo thời gian thực và chốt 2 hợp đồng.

Robot giao dịch sao chép hợp đồng tiền kỹ thuật số đơn giản

Chiến lược này được thiết kế theo cách đơn giản và dễ hiểu, không có bất kỳ sự tối ưu hóa nào. Việc cải thiện vẫn cần phải xử lý các chi tiết như phát hiện tài sản khi theo lệnh. Để đơn giản trong thiết kế, các lệnh thị trường được sử dụng để theo lệnh . Chiến lược này chỉ cung cấp ý tưởng học tập, còn giao dịch thực tế sẽ được tối ưu hóa theo nhu cầu.

Địa chỉ chiến lược: https://www.fmz.com/strategy/270012

Rất vui lòng để lại tin nhắn.