avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada mesej peribadi
4
fokus pada
1271
Pengikut

Robot perdagangan salinan mudah kontrak mata wang digital

Dicipta dalam: 2021-04-07 21:30:05, dikemas kini pada: 2024-12-05 21:59:36
comments   11
hits   4372

Robot perdagangan salinan mudah kontrak mata wang digital

Robot perdagangan salinan mudah kontrak mata wang digital

Dalam artikel sebelum ini, kami melaksanakan robot perdagangan salinan spot yang mudah Hari ini, kami akan melaksanakan versi kontrak robot perdagangan salinan mudah.

Idea reka bentuk

Terdapat perbezaan besar antara versi kontrak robot perdagangan salinan dan versi dagangan spot boleh dicapai terutamanya dengan memantau perubahan dalam aset akaun. Versi niaga hadapan memerlukan pemantauan perubahan dalam kedudukan akaun. Oleh itu, keadaan dalam versi niaga hadapan adalah lebih rumit, kerana niaga hadapan mempunyai kedudukan panjang, kedudukan pendek, dan kontrak yang berbeza. Siri butiran ini perlu diproses. Idea teras adalah untuk memantau perubahan dalam kedudukan. Cetuskan tindakan salin berdasarkan perubahan kedudukan. Apabila ia mula-mula direka, ia telah dirancang untuk mengendalikan kedua-dua kedudukan panjang dan pendek bersama-sama, tetapi didapati bahawa ini akan menjadi sangat rumit. Selepas menganalisis masalah, ia telah memutuskan untuk mengendalikan kedudukan panjang dan pendek secara berasingan.

Pelaksanaan Strategi

Parameter strategi:

Robot perdagangan salinan mudah kontrak mata wang digital

Ujian belakang disokong, dan anda boleh terus menggunakan tetapan lalai untuk pemerhatian ujian belakang.

Kod sumber strategi:

/*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
    }
}

ujian

Memandangkan OKEX boleh menggunakan cakera simulasi OKEX selepas mengemas kini antara muka V5, saya menggunakan dua KEY API cakera simulasi OKEX untuk ujian yang mudah.

Objek pertukaran pertama yang ditambahkan ialah pertukaran rujukan, dan pertukaran salinan akan mengikuti akaun pertukaran ini untuk beroperasi. Pada halaman dagangan simulasi OKEX, letakkan secara manual 3 kontrak berasaskan syiling suku tahunan ETH berdasarkan akaun pertukaran.

Robot perdagangan salinan mudah kontrak mata wang digital

Ia boleh dilihat bahawa pasaran sebenar mengesan perubahan dalam kedudukan akaun pertukaran rujukan dan kemudian mengikuti operasi.

Robot perdagangan salinan mudah kontrak mata wang digital

Cuba kita tutup dua jawatan kontrak yang baru kita buka Jawatan selepas ditutup adalah seperti yang ditunjukkan dalam rajah:

Robot perdagangan salinan mudah kontrak mata wang digital

Ikuti operasi masa nyata dan tutup 2 kontrak.

Robot perdagangan salinan mudah kontrak mata wang digital

Strategi ini direka bentuk dengan cara yang mudah dan mudah difahami, tanpa sebarang pengoptimuman. Penambahbaikan masih perlu menangani butiran seperti pengesanan aset apabila mengikut pesanan Demi kesederhanaan dalam reka bentuk, pesanan pasaran digunakan untuk mengikuti pesanan . Strategi ini hanya menyediakan idea pembelajaran, dan perdagangan sebenar akan dioptimumkan mengikut keperluan.

Alamat strategi: https://www.fmz.com/strategy/270012

Selamat datang untuk meninggalkan mesej.