Sumber dimuat naik... memuat...

Sumber dan API terkini untuk platform FMZ

Penulis:Rumput, Dicipta: 2024-07-10 16:36:54, Dikemas kini: 2024-07-12 15:53:41

img

Pengantar

Dalam artikel sebelumnya, kami telah membincangkan prinsip dan ujian semula untuk berpasangan.https://www.fmz.com/digest-topic/10457 Ini adalah kod sumber yang berguna berdasarkan platform FMZ, dengan strategi yang lebih mudah dan jelas untuk pelajar pemula.  Platform FMZ telah meningkatkan sebahagian API baru-baru ini untuk menjadi lebih mesra kepada pelbagai perdagangan.  Artikel ini akan membincangkan secara terperinci kod sumber JavaScript untuk dasar ini.  Walaupun hanya seratus baris, dasar ini mengandungi semua aspek yang diperlukan oleh dasar yang lengkap.https://www.fmz.com/strategy/456143Boleh disalin secara langsung.

Penggunaan platform FMZ

Jika anda tidak biasa dengan platform FMZ, saya sangat mengesyorkan anda membaca tutorial ini:https://www.fmz.com/bbs-topic/4145◦ Mengulas mengenai fungsi asas platform dan bagaimana untuk menggunakan robot dari awal hingga akhir.

Rangka Kerja Strategik

Berikut adalah rangka kerja dasar yang paling mudah, fungsi utama adalah masuk. Strategi jaminan kitaran mati dijalankan secara berterusan, dengan memasukkan masa tidur yang kecil untuk mengelakkan kekerapan akses terlalu cepat melebihi had bursa.

function main(){
    while(true){
        //策略内容
        Sleep(Interval * 1000) //Sleep
    }
}

Mencatatkan data sejarah

Robot akan mula semula berulang kali kerana pelbagai sebab, seperti terdapat kesilapan, mengemas kini parameter, mengemas kini dasar, dan lain-lain, yang memerlukan menyimpan beberapa data untuk digunakan pada permulaan seterusnya. Di sini ditunjukkan bagaimana menyimpan hak istimewa awal untuk mengira keuntungan. Fungsi G dapat menyimpan pelbagai data.

let init_eq = 0 //定义初始权益
if(!_G('init_eq')){  //如果没有储存_G('init_eq')返回null
    init_eq = total_eq
    _G('init_eq', total_eq) //由于没有储存,初始权益为当前权益,并在这里储存
}else{
    init_eq = _G('init_eq') //如果储存,读取初始权益的值
}

Kesalahan dalam strategi

Apabila mendapatkan data mengenai kedudukan, pasaran, dan lain-lain melalui API, kerana pelbagai sebab, mungkin akan kembali sebagai salah. Ini akan menyebabkan polisi berhenti dengan kesalahan apabila data dipanggil secara langsung, yang memerlukan mekanisme pengampunan kesalahan. Fungsi akan cuba semula secara automatik selepas kesalahan sehingga data yang betul dikembalikan.

let pos = _C(exchange.GetPosition, pair)

let ticker_A = exchange.GetTicker(pair_a)
let ticker_B = exchange.GetTicker(pair_b)
if(!ticker_A || !ticker_B){
    continue //如果数据不可用,就跳出这次循环
}

API yang serasi dengan pelbagai mata wang

Fungsi seperti GetPosition, GetTicker, GetRecords boleh memasukkan parameter pasangan transaksi untuk mendapatkan data yang sesuai tanpa perlu menetapkan pasangan pertukaran yang terikat, yang memudahkan keserasian strategi pelbagai transaksi.https://www.fmz.com/digest-topic/10451◦ Sudah tentu, anda memerlukan hos terbaru untuk menyokong, jika anda mempunyai hos yang terlalu lama, anda perlu menaik taraf.

Parameter strategi

  • Pair_A Perdagangan mata wang A: pasangan dagangan A yang diperlukan untuk pasangan dagangan, memerlukan pasangan dagangan yang dipilih sendiri, boleh merujuk kepada pengenalan dan ulasan artikel sebelumnya.
  • Pair_B Perdagangan mata wang B: Pasangan transaksi B yang memerlukan pasangan transaksi
  • Quote Mata wang asas: Mata wang yang dijamin oleh bursa niaga hadapan, biasanya USDT
  • Saiz grid Pct: berlawanan dengan berapa banyak penambahan, lihat artikel mengenai prinsip strategi, tidak boleh terlalu kecil kerana kos prosedur dan titik geser
  • Trade_Value Nilai urus niaga: nilai urus niaga yang ditingkatkan untuk setiap deviasi saiz grid
  • Ice_Value Nilai penghantaran gunung es: jika nilai urus niaga terlalu besar, anda boleh membuka dagangan dengan nilai penghantaran gunung es, biasanya boleh ditetapkan sebesar nilai urus niaga
  • Max_Value Holding: Holding terbesar dalam mata wang tunggal untuk mengelakkan risiko yang terlalu besar
  • N parameter harga purata: parameter yang digunakan untuk mengira perbandingan harga purata, unitnya adalah jam, seperti 100 mewakili purata 100h
  • Interval Waktu Tidur: Waktu Tidur untuk setiap selang kitaran strategi

Maklumat lengkap mengenai strategi

Jika anda masih belum faham, anda boleh menyelesaikan pertanyaan anda dengan menggunakan dokumentasi API FMZ, alat debugging dan alat dialog AI yang biasa digunakan di pasaran.

function GetPosition(pair){
    let pos = _C(exchange.GetPosition, pair)
    if(pos.length == 0){ //返回为空代表没有持仓
        return {amount:0, price:0, profit:0}
    }else if(pos.length > 1){ //策略要设置为单向持仓模式
        throw '不支持双向持仓'
    }else{ //为了方便,多仓持仓量为正,空仓持仓量为负
        return {amount:pos[0].Type == 0 ? pos[0].Amount : -pos[0].Amount, price:pos[0].Price, profit:pos[0].Profit}
    }
}

function GetRatio(){
    let kline_A = exchange.GetRecords(Pair_A+"_"+Quote+".swap", 60*60, N) //小时K线
    let kline_B = exchange.GetRecords(Pair_B+"_"+Quote+".swap", 60*60, N)
    let total = 0
    for(let i= Math.min(kline_A.length,kline_B.length)-1; i >= 0; i--){ //反过来计算,避免K线长度不够
        total += kline_A[i].Close / kline_B[i].Close
    }
    return total / Math.min(kline_A.length,kline_B.length)
}

function GetAccount(){
    let account = _C(exchange.GetAccount)
    let total_eq = 0
    if(exchange.GetName == 'Futures_OKCoin'){ //由于这里的API并不兼容,目前仅OKX期货交易所获取到总权益
        total_eq = account.Info.data[0].totalEq //其他交易所的宗权益Info中也包含,可以自己对着交易所API文档找找
    }else{
        total_eq = account.Balance //其它交易所暂时使用可用余额,会造成计算收益错误,但不影响策略使用
    }
    let init_eq = 0
    if(!_G('init_eq')){
        init_eq = total_eq
        _G('init_eq', total_eq)
    }else{
        init_eq = _G('init_eq')
    }
    LogProfit(total_eq - init_eq)
    return total_eq
}

function main(){
    var precision = exchange.GetMarkets() //这里获取精度
    var last_get_ratio_time = Date.now()
    var ratio = GetRatio()
    var total_eq = GetAccount()
    while(true){
        let start_loop_time = Date.now()
        if(Date.now() - last_get_ratio_time > 10*60*1000){ //每10分钟更新下均价和账户信息
            ratio = GetRatio()
            total_eq = GetAccount()
            last_get_ratio_time = Date.now()
        }
        let pair_a = Pair_A+"_"+Quote+".swap" //交易对的设置形如BTC_USDT.swap
        let pair_b = Pair_B+"_"+Quote+".swap"
        let CtVal_a = "CtVal" in precision[pair_a] ? precision[pair_a].CtVal : 1 //有的交易所用张来代表数量,如一张代表0.01个币,因此需要换算下
        let CtVal_b = "CtVal" in precision[pair_b] ? precision[pair_b].CtVal : 1 //不含这个字段的不用张
        let position_A = GetPosition(pair_a)
        let position_B = GetPosition(pair_b)
        let ticker_A = exchange.GetTicker(pair_a)
        let ticker_B = exchange.GetTicker(pair_b)
        if(!ticker_A || !ticker_B){ //如果返回数据异常,跳出这次循环
            continue
        }
        let diff = (ticker_A.Last / ticker_B.Last - ratio) / ratio //计算偏离的比例
        let aim_value = - Trade_Value * diff / Pct //目标持有的仓位
        let id_A = null
        let id_B = null
        //以下是具体的开仓逻辑
        if( -aim_value + position_A.amount*CtVal_a*ticker_A.Last > Trade_Value && position_A.amount*CtVal_a*ticker_A.Last > -Max_Value){
            id_A = exchange.CreateOrder(pair_a, "sell", ticker_A.Buy, _N(Ice_Value / (ticker_A.Buy * CtVal_a), precision[pair_a].AmountPrecision))
        }
        if( -aim_value - position_B.amount*CtVal_b*ticker_B.Last > Trade_Value && position_B.amount*CtVal_b*ticker_B.Last < Max_Value){
            id_B = exchange.CreateOrder(pair_b, "buy", ticker_B.Sell, _N(Ice_Value / (ticker_B.Sell * CtVal_b), precision[pair_b].AmountPrecision))
        }
        if( aim_value - position_A.amount*CtVal_a*ticker_A.Last > Trade_Value && position_A.amount*CtVal_a*ticker_A.Last < Max_Value){
            id_A = exchange.CreateOrder(pair_a, "buy", ticker_A.Sell, _N(Ice_Value / (ticker_A.Sell * CtVal_a), precision[pair_a].AmountPrecision))
        }
        if( aim_value + position_B.amount*CtVal_b*ticker_B.Last > Trade_Value &&  position_B.amount*CtVal_b*ticker_B.Last > -Max_Value){
            id_B = exchange.CreateOrder(pair_b, "sell", ticker_B.Buy, _N(Ice_Value / (ticker_B.Buy * CtVal_b), precision[pair_b].AmountPrecision))
        }
        if(id_A){
            exchange.CancelOrder(id_A) //这里直接撤销
        }
        if(id_B){
            exchange.CancelOrder(id_B)
        }
        let table = {
            type: "table",
            title: "交易信息",
            cols: ["初始权益", "当前权益", Pair_A+"仓位", Pair_B+"仓位", Pair_A+"持仓价", Pair_B+"持仓价", Pair_A+"收益", Pair_B+"收益", Pair_A+"价格", Pair_B+"价格", "当前比价", "平均比价", "偏离均价", "循环延时"],
            rows: [[_N(_G('init_eq'),2), _N(total_eq,2), _N(position_A.amount*CtVal_a*ticker_A.Last, 1), _N(position_B.amount*CtVal_b*ticker_B.Last,1),
                _N(position_A.price, precision[pair_a].PircePrecision), _N(position_B.price, precision[pair_b].PircePrecision),
                _N(position_A.profit, 1), _N(position_B.profit, 1), ticker_A.Last, ticker_B.Last,
                _N(ticker_A.Last / ticker_B.Last,6), _N(ratio, 6), _N(diff, 4), (Date.now() - start_loop_time)+"ms"
            ]]
        }
        LogStatus("`" + JSON.stringify(table) + "`") //这个函数会在机器人页面显示包含以上信息的表格
        Sleep(Interval * 1000) //休眠时间为ms
    }
}

Lebih lanjut

77924998Adakah terdapat versi Python?

kacang 888/upload/asset/21c799a2c667c13fcb0bd.png Perut agak licin.

Pencipta Kuantiti - Impian KecilUjian semula tidak menyokong fungsi GetMarkets buat masa ini, boleh menunggu sedikit.

ChaoZhangMengemas kini ke hos terkini