avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada Pesan pribadi
4
fokus pada
1271
Pengikut

Kontrak mata uang digital robot perdagangan salinan sederhana

Dibuat di: 2021-04-07 21:30:05, diperbarui pada: 2024-12-05 21:59:36
comments   11
hits   4372

Kontrak mata uang digital robot perdagangan salinan sederhana

Kontrak mata uang digital robot perdagangan salinan sederhana

Pada artikel sebelumnya, kami telah menerapkan robot perdagangan salinan spot sederhana. Hari ini, kami akan menerapkan versi kontrak dari robot perdagangan salinan sederhana.

Ide desain

Ada perbedaan besar antara versi kontrak robot copy trading dan versi spot. Copy trading spot terutama dapat dicapai dengan memantau perubahan aset akun. Versi berjangka memerlukan pemantauan perubahan dalam posisi akun. Oleh karena itu, situasi dalam versi berjangka lebih rumit, karena berjangka memiliki posisi panjang, posisi pendek, dan kontrak yang berbeda. Rangkaian rincian ini perlu diproses. Ide intinya adalah memantau perubahan posisi. Memicu tindakan penyalinan berdasarkan perubahan posisi. Ketika pertama kali dirancang, ia direncanakan untuk menangani posisi panjang dan pendek secara bersamaan, tetapi ternyata hal ini akan menjadi sangat rumit. Setelah menganalisis masalahnya, diputuskan untuk menangani posisi panjang dan pendek secara terpisah.

Implementasi Strategi

Parameter strategi:

Kontrak mata uang digital robot perdagangan salinan sederhana

Pengujian ulang didukung, dan Anda dapat langsung menggunakan pengaturan default untuk pengamatan pengujian ulang.

Kode 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
    }
}

tes

Karena OKEX dapat menggunakan disk simulasi OKEX setelah memperbarui antarmuka V5, saya menggunakan dua KUNCI API disk simulasi OKEX untuk pengujian yang mudah.

Objek pertukaran pertama yang ditambahkan adalah pertukaran referensi, dan pertukaran salinan akan mengikuti akun pertukaran ini untuk beroperasi. Pada halaman simulasi perdagangan OKEX, tempatkan secara manual 3 kontrak berbasis koin triwulanan ETH berdasarkan akun bursa.

Kontrak mata uang digital robot perdagangan salinan sederhana

Dapat dilihat bahwa pasar riil mendeteksi perubahan posisi rekening pertukaran acuan dan kemudian menindaklanjuti operasinya.

Kontrak mata uang digital robot perdagangan salinan sederhana

Mari kita coba menutup dua posisi kontrak yang baru saja kita buka. Posisi setelah penutupan adalah seperti yang ditunjukkan pada gambar:

Kontrak mata uang digital robot perdagangan salinan sederhana

Ikuti operasi waktu nyata dan tutup 2 kontrak.

Kontrak mata uang digital robot perdagangan salinan sederhana

Strategi ini dirancang dengan cara yang sederhana dan mudah dipahami, tanpa pengoptimalan apa pun. Peningkatannya masih perlu menangani detail seperti deteksi aset saat mengikuti perintah. Demi kesederhanaan dalam desain, perintah pasar digunakan untuk mengikuti perintah . Strategi ini hanya menyediakan ide pembelajaran, dan perdagangan aktual akan dioptimalkan sesuai kebutuhan.

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

Selamat datang untuk meninggalkan pesan.