Perdagangan mata wang China (BTC)

Penulis:Rumput, Tarikh: 2020-09-09 13:45:11
Tag:HedgeBinance

Pada tahun 2010, Malaysia telah meramalkan bahawa ia akan menjadi satu negara yang paling berkuasa di dunia, dengan jumlah penduduk yang lebih tinggi daripada negara lain.https://www.fmz.com/digest-topic/6102

Memerlukan membaca buku panduan ini, tidak boleh berjalan tanpa otak. Kod dasar hanya untuk rujukan, diubah jika diperlukan, maklum balas dialu-alukan.

Prinsip-prinsip strategi

Kontrak Bitcoin Bits seperti BTC, ETH, dan lain-lain terdapat tiga kontrak pada masa yang sama, iaitu BTCUSD_PERP, BTCUSD_200925 pada suku ini, dan BTCUSD_201225 pada suku kedua.

Kontrak kekal boleh dianggap sebagai tunai, biasanya dua kontrak untuk melakukan lindung nilai mempunyai tiga perbezaan: musim-permanen, musim-permanen, musim-permanen, musim-permanen. Suasana kupu-kupu memerlukan tiga kontrak untuk beroperasi, perbezaan adalah ((musim-permanen) - (musim-permanen), iaitu perbezaan = musim-permanen + kekal-2 * musim-permanen.

Parameter strategi

  • Mata wang dagangan: memerlukan tiga jenis yang kekal, semasa dan seterusnya.
  • Bilangan lembaran bawah: Bilangan lembaran bawah untuk setiap grid.
  • Harga pembukaan grid: setiap kali anda menyimpang dari satu harga, buat lebih banyak atau buat kosong.
  • Parameter perpindahan perbezaan Alpha: digunakan untuk mengira purata perbezaan, boleh digunakan secara lalai atau boleh diukur semula sendiri.
  • Bilangan tawaran Ice Mountain: Jika jumlah tawaran terbuka terlalu besar, untuk mengurangkan fenomena kaki tunggal, anda boleh menetapkan jumlah tawaran terbuka minimum setiap kali, kelemahan adalah harga yang tidak tepat. Tidak perlu Ice Mountain menugaskan parameter ini.

Jika garis purata perbezaan adalah 100, perbezaan semasa adalah 200, jumlah pesanan berikutnya adalah 2, perbezaan pesanan pembukaan grid adalah 30, maka pada masa ini pegangan adalah: 6 kekosongan musim kedua, 6 kekosongan kekal, 12 lebih banyak pada musim itu. Tidak jelas boleh melihat kod secara spesifik.

Perhatian

  • Peratusan pertukaran kira-kira memerlukan pegangan satu arah, iaitu memegang banyak ruang pada masa yang berbeza.
  • Di sini, anda boleh melihat beberapa gambar yang menarik.
  • Strategi ini bukan strategi operasi tanpa otak, uji dengan teliti jika anda memahami prinsipnya.
  • Kajian kajian tidak akan diuji semula dengan keadaan sebenar, tanpa perlu mengoptimumkan parameter terlalu banyak.
  • Robot tidak berfungsi untuk masa yang lama, dan robot baru perlu dibina untuk mengelakkan perbezaan harga yang terlalu besar.
  • Parameter perbezaan harga pembukaan grid mestilah meliputi yuran, contohnya yuran pembukaan tunggal adalah 2,000,000, harga Bitcoin adalah 10,000, maka sekurang-kurangnya lebih besar daripada 8 * 10,000 * 0.0002 = 16, ditambah dengan baki tertentu, boleh ditetapkan sebagai 25-30.
  • Perbezaan masa antara penghantaran musim kedua - musim yang sama, musim yang sama - kekal semakin besar, dan akhirnya musim yang hampir kekal, suku bunga kupu-kupu sebenarnya adalah suku bunga antara musim kedua dan kekal, tidak dapat dijalankan, dan perlu dihentikan atau dilihat sama ada terus beroperasi dua minggu sebelum penghantaran.
  • Permohonan di bawah menggunakan IOC, bahagian yang boleh diselesaikan dengan segera pada harga yang diamanahkan (atau harga yang lebih baik) akan diselesaikan, bahagian yang tidak dapat diselesaikan sepenuhnya dengan segera akan dibatalkan. Oleh itu, tidak perlu ditarik balik.
  • Strategi ini juga boleh diubah dengan sedikit penyesuaian kepada peratusan antara musim semasa dan kekal atau musim berikutnya dan kekal.
  • Strategi ini tidak akan membuka banyak perdagangan atau mungkin tidak akan membuka satu hari pun.
  • Robot baru mula beroperasi untuk menganggarkan perbezaan purata, tanpa melihat semula sejarah.
  • Strategi ini mungkin dapat dioptimumkan sendiri kerana tidak dapat mencapai kesepakatan dengan kaki tunggal.
  • Harga yang lebih rendah ditambah dengan harga geser, tidak banyak kesan untuk jumlah tawaran terbuka yang kecil, untuk jumlah tawaran terbuka yang besar memerlukan pengoptimuman sendiri, seperti penghantaran gunung es.

if(IsVirtual()){
    throw '不能回测,回测参考研究文章 https://www.fmz.com/digest-topic/6102'
}
if(exchange.GetName() != 'Futures_Binance'){
    throw '只支持币安期货交易所,和现货交易所不同,需要单独添加,名称为Futures_Binance'
}
if(Grid == 0){
    throw '需要设置网格差价,需要覆盖8份手续费,可设置为当前价*fee*15'
}

exchange.SetBase("https://dapi.binance.com") //切换至交割合约

var exchange_info = HttpQuery('https://dapi.binance.com/dapi/v1/exchangeInfo')
if(!exchange_info){
    throw '无法连接币安网络,需要非公用海外托管者'
}
exchange_info = JSON.parse(exchange_info)
trade_info = {} //合约基础信息
trade_contract = {NEXT_QUARTER:'',CURRENT_QUARTER:'',PERPETUAL:''} //需要交易的合约代码
for (var i=0; i<exchange_info.symbols.length; i++){
   trade_info[exchange_info.symbols[i].symbol] =  exchange_info.symbols[i]
   if(exchange_info.symbols[i].baseAsset == Symbol && exchange_info.symbols[i].contractType in trade_contract && exchange_info.symbols[i].contractStatus == 'TRADING'){
       trade_contract[exchange_info.symbols[i].contractType] = exchange_info.symbols[i].symbol
   }
}
if(!(trade_contract.NEXT_QUARTER && trade_contract.CURRENT_QUARTER && trade_contract.PERPETUAL)){
    throw '无法找到蝶式对冲的三个合约'
}
var pricePrecision = trade_info[trade_contract.PERPETUAL].pricePrecision //价格精度

var ticker = {}
var account = {}
var position = {}

var diff_mean = null //差价均价
if(_G('diff_mean') && _G('symbol') == Symbol){ //防止切换币种,差价出错
    diff_mean = _G('diff_mean')
}else{
    _G('symbol',Symbol)
}

var diff_buy = 0 //做多的差价
var diff_sell = 0 //做空的差价
Trade_value = _N(Trade_value, 0)
 
var init_asset = 0 //初始资金
if(_G('init_asset')){
    init_asset = _G('init_asset')
}else{
    updateAccount()
    init_asset = parseFloat(account[Symbol].marginBalance)
    _G('init_asset', init_asset)
}
var update_status_time = 0
var update_account_time = Date.now()

function onexit(){
    _G('diff_mean', diff_mean)
}

function updateTicker(){
    var bookTicker =  HttpQuery('https://dapi.binance.com/dapi/v1/ticker/bookTicker')
    try {
        bookTicker = JSON.parse(bookTicker)
        for(var i=0;i<bookTicker.length;i++){
            ticker[bookTicker[i].symbol] = bookTicker[i]
        }
    } catch (e) {
        Log('无法获取行情')
    }
}

function updateAccount(){
    var acc = exchange.IO("api", "GET", "/dapi/v1/account", "timestamp="+Date.now())
    if(!acc){
        Log('无法获取账户')
        return
    }
    for(var i=0;i<acc.assets.length;i++){
        account[acc.assets[i].asset] = acc.assets[i]
    }
}

function updatePosition(){
    var pos = exchange.IO("api", "GET", "/dapi/v1/positionRisk", "timestamp="+Date.now())
    if(!pos){
        Log('无法获取仓位')
        return
    }
    for(var i=0;i<pos.length;i++){
        position[pos[i].symbol] = pos[i]
    }
}

function updateStatus(){
    if(Date.now() - update_status_time < 4000){
        return
    }
    update_status_time = Date.now()
    if(Date.now() - update_account_time >  5*60*1000){
        update_account_time = Date.now()
        updateAccount()
        LogProfit(_N(parseFloat(account[Symbol].marginBalance) - init_asset, 5))
    }
    
    $.PlotLine('buy', _N(diff_buy, pricePrecision))
    $.PlotLine('sell', _N(diff_sell, pricePrecision))
    $.PlotLine('mean', _N(diff_mean, pricePrecision+3))
    
    var table1 = {type: 'table', title: '账户信息', 
             cols: ['账户余额', '未实现盈亏', '保证金余额',  '可用余额', '维持保证金', '起始保证金', 'BNB', '初始余额', '收益', '平均差价', '做多差价', '做空差价', '下单量'],
             rows: [[_N(parseFloat(account[Symbol].walletBalance),5), _N(parseFloat(account[Symbol].unrealizedProfit),5), _N(parseFloat(account[Symbol].marginBalance),5), 
                     _N(parseFloat(account[Symbol].availableBalance),5),  _N(parseFloat(account[Symbol].maintMargin),5), _N(parseFloat(account[Symbol].initialMargin),5), 
                     _N(parseFloat(account.BNB.walletBalance),5), _N(init_asset,5),
                      _N(parseFloat(account[Symbol].marginBalance) - init_asset,5), _N(diff_mean, pricePrecision+1),
                     _N(diff_buy, pricePrecision),_N(diff_sell, pricePrecision), Trade_value
                    ]]}
    var table2 = {type: 'table', title: '对冲信息', 
             cols: ['合约', '持仓张数', 'Bid', 'Ask', '持仓价值', '杠杆', '开仓均价', '未实现盈亏'],
             rows: []}
    for(var contract in trade_contract){
        var symbol = trade_contract[contract]
        table2.rows.push([symbol, position[symbol].positionAmt, ticker[symbol].bidPrice, ticker[symbol].askPrice, 
                          parseInt(position[symbol].positionAmt)*parseInt(trade_info[symbol].contractSize), position[symbol].leverage,
                         position[symbol].entryPrice, position[symbol].unRealizedProfit])
    }
    var logString = _D()+'  策略代码最后更新时间9月29日\n'
    LogStatus(logString + '`' + JSON.stringify(table1) + '`'+'\n'+'`' + JSON.stringify(table2) + '`')
}

function trade(symbol, side, price, amount){
    //IOC下单,未成交部分会自动撤销
    exchange.Log(side == 'BUY' ? LOG_TYPE_BUY : LOG_TYPE_SELL, price, amount, ' buy: ' + _N(diff_buy, pricePrecision) + ' sell: '+ _N(diff_sell, pricePrecision) + ' mean: '+_N(diff_mean, pricePrecision+3))
    exchange.IO("api", "POST","/dapi/v1/order","symbol="+symbol+"&side="+side+"&type=LIMIT&timeInForce=IOC&quantity="+amount+"&price="+price+"&timestamp="+Date.now())
}


function onTicker(){
    
    //由于是吃单,需要分别计算做多和做空的差价
    diff_sell = parseFloat(ticker[trade_contract.NEXT_QUARTER].bidPrice) + parseFloat(ticker[trade_contract.PERPETUAL].bidPrice) -
                2*parseFloat(ticker[trade_contract.CURRENT_QUARTER].askPrice)
    diff_buy = parseFloat(ticker[trade_contract.NEXT_QUARTER].askPrice) + parseFloat(ticker[trade_contract.PERPETUAL].askPrice)  -
                2*parseFloat(ticker[trade_contract.CURRENT_QUARTER].bidPrice)

    
    if(!diff_mean){diff_mean = (diff_buy+diff_sell)/2}
    diff_mean = diff_mean*(1-Alpha) + Alpha*(diff_buy+diff_sell)/2 //差价均价的更新
    
    
    var aim_buy_amount = -Trade_value*(diff_buy - diff_mean)/Grid
    var aim_sell_amount = -Trade_value*(diff_sell - diff_mean)/Grid 
    
    if(aim_buy_amount - parseFloat(position[trade_contract.PERPETUAL].positionAmt) > Trade_value){ //做多差价,价格加了滑价
        trade(trade_contract.PERPETUAL, 'BUY', _N(parseFloat(ticker[trade_contract.PERPETUAL].askPrice)*1.01, pricePrecision), _N(Math.min(aim_buy_amount-parseFloat(position[trade_contract.PERPETUAL].positionAmt),Ice_value),0))
    }
    if(aim_buy_amount - parseFloat(position[trade_contract.NEXT_QUARTER].positionAmt) > Trade_value){
        trade(trade_contract.NEXT_QUARTER, 'BUY', _N(parseFloat(ticker[trade_contract.NEXT_QUARTER].askPrice)*1.01,pricePrecision), _N(Math.min(aim_buy_amount-parseFloat(position[trade_contract.NEXT_QUARTER].positionAmt),Ice_value),0))
    }
    if(-2*aim_buy_amount - parseFloat(position[trade_contract.CURRENT_QUARTER].positionAmt) < -2*Trade_value){
        trade(trade_contract.CURRENT_QUARTER, 'SELL', _N(parseFloat(ticker[trade_contract.CURRENT_QUARTER].bidPrice)*0.99,pricePrecision), _N(2*Math.min(aim_buy_amount+parseFloat(position[trade_contract.CURRENT_QUARTER].positionAmt),Ice_value),0))
    }
    
    if(aim_sell_amount - parseFloat(position[trade_contract.PERPETUAL].positionAmt) < -Trade_value){ //做空差价
        trade(trade_contract.PERPETUAL, 'SELL', _N(parseFloat(ticker[trade_contract.PERPETUAL].bidPrice)*0.99,pricePrecision), _N(Math.min(parseFloat(position[trade_contract.PERPETUAL].positionAmt)-aim_sell_amount,Ice_value),0))
    }
    if(aim_sell_amount - parseFloat(position[trade_contract.NEXT_QUARTER].positionAmt) < -Trade_value){
        trade(trade_contract.NEXT_QUARTER, 'SELL', _N(parseFloat(ticker[trade_contract.NEXT_QUARTER].bidPrice)*0.99,pricePrecision), _N(Math.min(parseFloat(position[trade_contract.NEXT_QUARTER].positionAmt)-aim_sell_amount,Ice_value),0))
    }
    if(-2*aim_sell_amount - parseFloat(position[trade_contract.CURRENT_QUARTER].positionAmt) > 2*Trade_value){
        trade(trade_contract.CURRENT_QUARTER, 'BUY', _N(parseFloat(ticker[trade_contract.CURRENT_QUARTER].askPrice)*1.01,pricePrecision), _N(-2*Math.min(aim_sell_amount-parseFloat(position[trade_contract.CURRENT_QUARTER].positionAmt),Ice_value),0))
    }
}

function main() {
    updateAccount()
    updatePosition()
    while(true){
        updateTicker()
        updatePosition()
        onTicker()
        updateStatus()
        Sleep(1*1000)
    }
}

Berkaitan

Lebih lanjut

Ding menyanyiApakah sebab anda tidak dapat mengakses maklumat akaun?

Menarik tinggi dan melemparkan rendahJika kita mengira perbezaannya dengan harga jual beli, adakah ia boleh dioptimumkan, kerana nilai perdagangan mungkin jauh lebih besar daripada harga jual beli, maka ia akan menjadi kos sebenar yang jauh lebih tinggi daripada harga jual beli.

Brand_MovedKenapa diff_sell mengambil dua bidPrice-askPrice, sedangkan diff_buy mengambil dua askPrice-bidPrice?

Musim sejuk yang luar biasaBerani!

Oh, Tuhan.Cangkir suci

gavin.abc"Sudah lama saya tidak mendengar perkataan itu", katanya.

jingfengzTuhan Rumput