O recurso está a ser carregado... Carregamento...

A estratégia de guerra dos milhares de legiões 3

Autora:Ervas daninhas, Data: 2020-09-09 13:45:11
Tags:SegredoBinance

A estratégia de arbitragem de borboleta de Binance, não pode ser testada novamente.https://www.fmz.com/digest-topic/6102

É necessário ler este manual de estratégia e não é possível executá-lo sem o cérebro. O código de estratégia é apenas para referência, pode ser modificado se necessário e recebe feedback.

Princípios estratégicos

Os contratos de Bitcoin, como o BTC e o ETH, existem simultaneamente em três contratos: o permanente BTCUSD_PERP, o BTCUSD_200925 no trimestre anterior e o BTCUSD_201225 no trimestre seguinte.

Os contratos permanentes podem ser tratados como ações em tempo real, geralmente dois contratos de cobertura têm três diferenças: temporário-permanente, subsequente-permanente, subsequente-permanente. O suporte de borboleta requer a operação de três contratos, com diferença de (sequente-permanente) - (sequente-permanente), ou seja, diferença = subsequente + permanente-2* temporário.

Parâmetros de estratégia

  • Moedas de troca: necessitam de três variedades de moedas que possam existir simultaneamente e que sejam permanentes, estacionais e subsequentes.
  • Número de folhas: Número de folhas de cada grelha.
  • A diferença de preço da rede: para cada desvio de uma diferença, faça mais ou faça um.
  • Parâmetro de equilíbrio de diferença Alpha: usado para calcular o valor médio do diferencial, pode ser usado por defeito ou pode ser redimensionado.
  • Número de pedidos de Ice Mountain: Se o número de pedidos de abertura for muito grande, para reduzir o fenômeno de uma perna, pode ser definido o número mínimo de pedidos de abertura por vez, o desvantagem é que o preço do baralho não é o mesmo. Não é necessário que Ice Mountain confie este parâmetro.

Se a linha média do diferencial for 100, o diferencial atual é 200, o número de peças seguintes é 2, o diferencial de abertura da rede é 30, então a detenção neste momento é: 6 peças vazias no segundo trimestre, 6 peças vazias permanentes, mais 12 peças no mesmo período. Não está claro.

Atenção

  • A taxa de troca requer aproximadamente a detenção unidirecional, ou seja, a detenção simultânea de vários espaços.
  • A garantia é para o modelo de estoque completo.
  • Esta estratégia não é uma estratégia de operação sem cérebro, testando-a cuidadosamente, entendendo os princípios.
  • A revisão de artigos de pesquisa não é uma situação real, sem a necessidade de otimização excessiva de parâmetros.
  • Os robôs não funcionam por longos períodos de tempo e são necessários novos robôs para evitar uma diferença de preços muito grande.
  • O parâmetro de diferença de preço de abertura da rede deve cobrir a taxa de transação, por exemplo, a taxa de abertura da rede é de 2 mil, o preço do Bitcoin é de 10 mil, então deve ser pelo menos maior que 8 * 10000 * 0.0002 = 16, além de um certo saldo, pode ser definido como 25-30.
  • A diferença de tempo entre a entrega do segundo trimestre - o mesmo período, o mesmo período - é cada vez maior e, finalmente, o mesmo período se aproxima do permanente, o preço da borboleta é na verdade o preço entre o segundo trimestre e o permanente, não pode ser executado e precisa ser parado ou observado duas semanas antes da entrega.
  • O seguinte pedido utiliza o IOC, e a parte que pode ser concluída imediatamente no preço da encomenda (ou melhor) será concluída imediatamente. A parte que não pode ser concluída imediatamente será cancelada; portanto, não é necessário retirar o pedido.
  • A estratégia também pode ser modificada ligeiramente para um equilíbrio entre a estação e a duração ou a estação e a duração.
  • A estratégia é não abrir muitas posições de liquidação, e é possível não abrir uma única no dia.
  • O robô só começa a calcular a diferença média quando começa a funcionar, sem fazer retrocesso histórico.
  • É provável que a estratégia seja auto-optimizada por causa de uma perna única causada por uma falha na transação.
  • A redução dos preços adicionados ao deslizamento não afeta muito o número de posições abertas pequenas, mas o número de posições abertas grandes precisa de otimização própria, como a encomenda do iceberg.

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

Relacionados

Mais.

O Dinho cantandoPor que não conseguimos acessar as informações da conta?

Arranque alto e baixoA diferença de preço é que o preço de venda é muito maior do que o preço de compra, e então o custo real é muito maior do que o preço de venda.

Brand_MovedPor que o diff_sell tem dois bidPrice-askPrice e o diff_buy tem dois askPrice-bidPrice?

O inverno é estranho.Que arrogância!

Não, não.Copo Sagrado da Erva

gavin.abcO deus da relva é arrogante (Break)!!!

JingfengzO deus da grama