Kontrak mata wang digital mudah diuruskan oleh robot

Penulis:Mimpi kecil, Dicipta: 2021-04-07 21:30:05, Dikemas kini: 2023-09-24 19:35:33

img

Kontrak mata wang digital mudah diuruskan oleh robot

Dalam artikel sebelumnya, kami telah mewujudkan bot pemesanan mudah, dan hari ini kami telah mewujudkan bot pemesanan mudah versi kontrak.

Idea Reka Bentuk

Versi kontrak mencatatkan robot dan versi tunai mempunyai perbezaan yang besar. Versi tunai dapat dicapai dengan memantau perubahan aset akaun. Versi niaga hadapan memerlukan pemantauan perubahan saham akaun. Oleh itu, versi niaga hadapan agak rumit, kerana niaga hadapan mempunyai banyak pegangan, pegangan kosong, dan kontrak yang berbeza. Perincian mengenai rangkaian ini perlu diuruskan. Mengikut pergerakan pemegang saham untuk mencetuskan tindakan tunggal. Pada awalnya dirancang untuk memproses pelbagai kepala, kepala kosong bersama-sama, tetapi mendapati bahawa ini akan menjadi rumit. Selepas masalah analisis, keputusan dibuat untuk memproses pelbagai kepala, kepala kosong secara berasingan.

Strategi yang dilaksanakan

Parameter strategi:

img

Sokongan retesting, boleh langsung menggunakan tetapan lalai untuk retesting observation.

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 telah mengemas kini antara muka V5 dan boleh menggunakan cakera OKEX, saya menggunakan dua cakera OKEX API KEY untuk ujian yang sangat mudah.

Objek bursa pertama yang ditambahkan adalah bursa rujukan, dan setiap bursa akan beroperasi mengikut akaun bursa ini. Pada halaman OKEX analog, gunakan akaun pertukaran untuk menghidupkan kontrak binari triwulanan 3 ETH.

img

Seperti yang dapat dilihat, rak sebenar telah mengesan perubahan dalam akaun saham bursa rujukan, dan kemudian mengikuti operasi tersebut.

img

Jika kita cuba mengimbangi kedua-dua kedudukan kontrak yang baru sahaja dibuka, kedudukan selepas penggantungan adalah seperti berikut:

img

Di samping itu, mereka juga telah membuat keputusan untuk mengakhiri kontrak mereka.

img

Strategi ini direka dengan cara yang mudah difahami, tanpa melakukan pengoptimuman, bahagian yang disempurnakan juga perlu menangani butiran seperti pemeriksaan aset semasa pembayaran. Untuk reka bentuk yang mudah, pembayaran hanya menggunakan senarai harga pasaran. Strategi ini hanya memberikan idea pembelajaran, yang sebenarnya dioptimumkan sendiri mengikut keperluan.

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

Selamat datang untuk komen.


Berkaitan

Lebih lanjut

pw1013Dua bursa yang berbeza tidak boleh dihubungkan.

Mingxi1005Bilakah pencipta boleh menjumpai mata wang dan memenangi kontrak niaga hadapan?

AklkcSaya harap ada versi pembayaran untuk Bitcoin USDT.

lau99Saya ingin mempunyai versi kontrak yang kekal, API pelaku????

zhousoneSaya berharap ada versi kontrak kekal token usdt

qqlove23Terima kasih kerana berkongsi, sangat berguna untuk dipelajari.

Mimpi kecilOleh kerana spesifikasi kontrak mungkin berbeza di bursa, kod pesanan mungkin disesuaikan mengikut keadaan tertentu.

pw1013Saya menggunakan pertukaran bibox, dengan pulangan komisen sebanyak 80%, dan FMZ menyokongnya dengan sempurna.

pw1013Jika anda ingin menukar bibox futures yang saya gunakan sekarang, di mana anda perlu menukarnya jika anda ingin menyambungkannya dengan bursa okx orang lain?

Mimpi kecilIni boleh dilakukan, hanya dengan mengubah kodnya.

Mimpi kecilDi sini untuk menilai bursa ini, belum ada pihak yang menghubungi kami.