리소스 로딩... 로딩...

비안안 계약 나비 연산 (천군 대전 전략 3)

저자:초목, 2020-09-09 13:45:11
태그:울타리바이낸스

안 나비 套利 전략, 재검토할 수 없다.https://www.fmz.com/digest-topic/6102

이 전략 설명서를 읽어야 하며, 뇌 없이 실행할 수 없습니다. 전략 코드는 참조용이며, 필요에 따라 수정될 수 있습니다. 피드백은 환영합니다.

전략적 원칙

비트코인 토지 계약은 BTC와 ETH와 같은 세 개의 계약이 동시에 존재합니다. 즉, 영구적인 BTCUSD_PERP, 이 분기 BTCUSD_200925와 다음 분기 BTCUSD_201225입니다.

영구계약은 현금으로 사용할 수 있으며, 일반적으로 두 개의 계약은 세 가지 미화점을 가지고 있습니다: 현시즌-영시, 하계-영시, 하계-영시. 나비형 배당은 세 개의 계약을 운영해야하며, 미화점은 ((하계-영시) -하계-영시) 이다. 즉, 미화점은 = 하계 + 영구-2* 현시즌. 더 많은 미화점은 더 많은 하계와 영구계약을 개설하고, 빈 2 개의 현시즌 계약을 개설해야합니다.

전략 매개 변수

  • 거래 통화: 세 가지 종류의 지속가능한, 계절, 계절이 동시에 존재해야 한다.
  • 다음 페이지의 숫자: 각 격자의 다음 페이지의 숫자.
  • 네트워크 오프닝 오프닝 가격: 오프닝 한 개 이상으로 더 많은 오프닝 또는 오프닝 한 개.
  • 차이 평형 매개 변수 알파: 차이 평가를 계산하는 평균 값, 기본 사용 또는 자체 재검토 가능.
  • 아이시만 위탁 거래 수: 개설 거래 수가 너무 많을 경우, 단발 현상을 줄이기 위해 매번 최소 개설 거래 수를 설정할 수 있으며, 단점은 도매가격이 늦어지는 것입니다. 아이시만 위탁이 필요하지 않습니다. 이 매개 변수 설정은 다음 거래 수와 같습니다.

만약 가격의 평균선이 100이고, 현재 가격이 200이고, 다음 단서 수는 2이고, 격자 오픈 단서 가격은 30이고, 이 때 보유는: 다음 계기 공백 6개, 영구 공백 6개, 해당 계기 12개 이상이다. 명확하지 않다. 코드를 구체적으로 볼 수 있다.

주의사항

  • 거래 비율은 약 1방향 보유, 즉 동시에 여러 개의 공간을 보유하는 것을 필요로 한다.
  • 자금은 전액 모드입니다.
  • 이 전략은 뇌가 작동하지 않는 전략이 아니며 원칙을 이해하면 신중하게 테스트하십시오.
  • 연구 논문의 재검토는 실제 상황이 아니라 파라미터를 과도하게 최적화 할 필요가 없습니다.
  • 로봇이 오랫동안 작동하지 않아서 가격 차이가 너무 커지는 것을 방지하기 위해 새로운 로봇이 필요합니다.
  • 격자 열기 가격 차이 매개 변수는 반드시 처리 비용을 커버해야 합니다. 예를 들어, 단일 처리 비용이 2만원, 비트코인 가격이 1만원인 경우, 최소 8*1만만*0.0002=16보다 크거나 25-30로 설정할 수 있습니다.
  • 임대 2분기 - 임대, 임대 - 영구적의 시간차가 점점 커지고, 결국 임대에 가까운 영구적, 나비적 배당은 사실상 임대와 영구적 사이의 배당이며, 실행될 수 없으며, 임대 2주 전에 중지하거나 계속 실행되는지 관찰해야 한다.
  • 아래의 주문은 IOC를 사용하며, 주문 가격 (또는 더 우수한 가격) 으로 즉시 거래될 수 있는 부분, 즉시 완전히 거래할 수 없는 부분은 취소됩니다. 따라서 취소 할 필요가 없습니다.
  • 이 전략의 약간의 개조를 통해 현재와 상시 또는 후기와 상시 사이의 이치로 변경할 수도 있습니다.
  • 이 전략은 종종 거래소를 열지 않으며 하루에도 단 한 장도 열지 않을 수 있습니다.
  • 로봇이 작동하기 시작한 지 얼마 되지 않아서 평균 차이를 통계적으로 계산하기 시작했고, 역사적인 거리를 거슬러 가지지 않았습니다.
  • 이 전략은 거래가 불가능한 단일 다리 때문에 자체적으로 최적화 될 가능성이 높습니다.
  • 하위单加滑价, 작은 오픈 오프닝 수에 대한 영향은 크지 않습니다. 큰 오픈 오프닝 수에 대한 자체 최적화가 필요합니다.

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

관련

더 많은

은 노래왜 계정 정보를 열 수 없는 걸까요?

높은 흡입 낮은 던지기이 차이는 구매/판매 가격에 따라 계산할 수 있습니다. 왜냐하면 거래 가치는 구매/판매 가격보다 훨씬 더 많을 가능성이 있기 때문에

Brand_Moved왜 diff_sell가 bidPrice-askPrice를 두 번 가져갔고 diff_buy가 askPrice-bidPrice를 두 번 가져갔을까요?

여름과 여름!

초록색 신의 성스러운 잔

gavin.abc () () ()

풀의 신