Binance Sustainable Multicurrency Hedging Strategy Original version (Doing more overshooting do more overshooting) 13th April latest stop loss module

Author: The grass, Date: 2020-04-04 21:24:43
Tags: Binance

This policy is now available in the fee upgrade version, plus WeChat wangweibing_ustb to learn more.

This is important!

  • I'm sure you'll want to read this study first.https://www.fmz.com/digest-topic/5294■ Understand a range of issues such as strategy principles, risks, how to screen trades, how to set parameters, opening positions and the ratio of total capital.
  • The previous research report needs to be downloaded and uploaded to your own research environment. The actual modification runs again. If you have read this report, you have recently updated the latest week's data.
  • If the robot stops for a long time, it must restart the data, or build a new robot.
  • The strategy cannot be directly retested, it needs to be retested in the research environment.
  • The policy code and the default parameters are for research purposes only, and real-time operation requires caution.The risks
  • Strategy can't be profitable every day, you can look back at history, 1-2 weeks of crossovers and pullbacks are normal and need to be handled correctly.
  • The code is open, you can modify it yourself, if there are any problems, welcome feedback, it is best to join the Inventor Binance community (there is a method to join the research report) to get updates
  • The strategy only supports binary futures, needs to run in full-stock mode, do not set up bidirectional holding!!, when creating the robot with default trading pairs and K-line cycles, the strategy does not use the K-line
  • Tactics and other tactics, as well as manual operations, are in conflict and need to be taken into account.
  • In the test phase, you can rent Ali Cloud Hong Kong servers on the platform with one click, and rent them yourself by the month is cheaper ((the minimum configuration is available, deploy the tutorial:https://www.fmz.com/bbs-topic/2848)
  • Binance futures and spot currency need to be added separately, Binance futures areFutures_Binance
  • This reboot strategy has no effect, but the newly built robot will re-record the historical data.
  • The policy may be updated based on user feedback, with direct Ctrl+A to copy the code cover save (generally no parameters are updated), and restart the bot to use the latest code.
  • The strategy does not start with trading, the first time it is started, it needs to record data, it needs to wait for the market to change before trading.

Content updated on 4.16

Changed the stop loss bug

Changed the default parameters:

var Alpha = 0.001 //指数移动平均的Alpha参数,设置的越大,基准价格跟踪越敏感,最终持仓也会越低,降低了杠杆,但会降低收益,具体需要根据回测结果自己权衡
var Update_base_price_time_interval = 60 //多久更新一次基准价格, 单位秒,和Alpha参数相关,Alpha 设置的越小,这个间隔也可以设置的更小

4.13 Updated content

Stop_loss set to 0.8 indicates when the funds reach below 80% of the initial funds, stop loss, empty all positions, stop strategy. As the strategy runs, Stop_loss can be set to greater than 1 (reset effect), for example from 1000 to 1500, Stop_loss set to 1.3, then back to 1300 yuan stop loss.

Max_diff and Min_diff limit the degree of deviation, which needs to be determined based on one's trade_value, total capital and risk tolerance.

For a simple example, if 20 coins are being traded, one of the coins will gradually increase in value to a deviation of 0.4 and will no longer be traded, while the other coins will remain unchanged, losing 7 times the trade_value.

var Stop_loss = 0.8 
var Max_diff = 0.4 //当偏差diff大于0.4时,不继续加空仓, 自行设置
var Min_diff = -0.3 //当diff小于-0.3时,不继续加多仓, 自行设置

4.10 Updated content

Copy the policy code to the local policy, overwrite it directly to save, restart the machine to take effect, and keep the original position.

Binance futures do a lot of overshooting and do a lot of overshooting strategies important to optimize notebook code address:https://www.fmz.com/bbs-topic/5364

The main problem is the comparison between the latest price and the initial price at which the strategy was launched, which will deviate more and more over time, a coin may hold a lot of positions, the risk is high, and will eventually hold a lot of positions, increasing the risk and the drawback.

The latest index = mean (sum) /EMA (coin price/bitcoin price) is more flexible, can track the latest price changes, is more flexible, and is found to reduce the strategy holdings and also reduce the drawdown. More stable. Most importantly, the original strategy is very high risk, very likely to break out, but is now almost unaffected if several unusual trading pairs are added.

For seamless upgrades, two of the parameters are written in the first two lines of the policy code, which can be changed as needed.

Alpha = 0.04 Index Moving equilibrium Alpha parameter, the larger the set, the more sensitive the benchmark price tracking, the fewer trades, the lower the final holding, lowering the leverage, but lowering the returns, lowering the maximum drawdown, can increase the turnover, specifically need to weigh themselves according to the results of the retest. Update_base_price_time_interval = 30*60 The longer a benchmark price is updated, in units of seconds, and related to the Alpha parameter, the smaller the Alpha setting, the smaller the interval that can be set

If you read the article and want to trade all currencies, here is the listETH,BCH,XRP,EOS,LTC,TRX,ETC,LINK,XLM,ADA,XMR,DASH,ZEC,XTZ,BNB,ATOM,ONT,IOTA,BAT,VET,NEO,QTUM,IOST

Join the WeChat group to get updates on the Battle of the Binance Gang

If you add the following micro-signal, you will automatically be dragged into the group:

https://www.fmz.comimg

The Principles of Strategy

Coins that are above the Bitcoin-Coin Price Index and below the Index will be made to default, and the greater the deviation, the larger the position. This strategy does not hedge asymmetric positions with BTC, but can also include BTC in the trading pair. Performance in the last two months (leverage around 3 times, data updated to 4.8):img

Strategic logic

1. update the market and account holdings, the first run will record the initial price (newly added currencies are calculated according to the time of joining) 2. update the index, the index is the coin-bitcoin price index = mean ((sum)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 3. Judging by the deviation index, doing more work, judging the position according to the deviation size 4. The order and quantity of the order will be determined by the Ice Mountain commission, according to the transaction price of the counterparty (buy and sell at the same price).The following order is immediately canceled (so you'll see a lot of unsuccessful canceled cells 400: {code:-2011,msg:Unknown order sent.}, normal phenomenon) 5.再次循环

Leverage in the status bar represents collateral that has been accounted for and needs to be kept low to meet new openings

Policy parameters

img

  • Trade_symbols: Currencies traded, needing to be screened by the research platform themselves, can also join BTC
  • Trade_value: Trade_value: The price of Bitcoin (BTC) has a value of 1% per deviation of the index, and it is recommended to set it at 3-10% of the total capital depending on the total capital invested and risk preferences. The size of the leverage can be reviewed by reviewing the research environment, and the Trade_value can be less than the Adjust_value, such as half of the Adjust_value, which is equivalent to a holding value of 2% deviation of the index.
  • Adjust_value: Adjust the deviation value of the contract. When the index deviates from * Trade_value - current holdings > Adjust_value, the difference between the target holdings and the current holdings exceeds this value, the trade will begin. Too much adjustment is slow, too little trading is frequent, can not be less than 10, otherwise the minimum transaction will not be reached, it is recommended to set it to more than 40% of the Trade_value.
  • Ice_value: Ice_value, also can not be less than 10, in fact, select Adjust_value and Ice_value the smaller one, if more funds can be set relatively large some such adjustment is faster, it is recommended not less than 20% of the Adjust_value, so 5 times the iceberg can complete the transaction, of course, when the Trade_value is not large, Ice_value can be set relatively large, one or two times can be adjusted to the place.
  • Interval: Cyclic sleep time, which can be set to be smaller, such as 1s, but cannot exceed the binary frequency limit.
  • Reset: Reset historical data, resets the initial price of the policy reference to the current price, generally without setting

Strategic risks

Note that if a coin goes out of the independent market, for example, if it rises several times relative to the index, it will accumulate a large number of empty positions on the currency, and the same large decline will also make the strategy do a lot more.




var Alpha = 0.001 //指数移动平均的Alpha参数,设置的越大,基准价格跟踪越敏感,最终持仓也会越低,降低了杠杆,但会降低收益,具体需要根据回测结果自己权衡
var Update_base_price_time_interval = 60 //多久更新一次基准价格, 单位秒,和Alpha参数相关,Alpha 设置的越小,这个间隔也可以设置的更小

//Stop_loss设置为0.8表示当资金达到低于初始资金的80%时,止损,清空所有仓位,停止策略。
//随着策略运行,Stop_loss可以设置大于1(重启生效),比如从1000赚到1500,Stop_loss设置为1.3,则回撤到1300元止损。不想止损可以把这个参数设置的很小。
//风险是大家都用这种止损会形成踩踏,加大亏损。
//初始资金在状态栏的init_balance字段,注意提现等操作会影响,别不小心止损了。
//如果还是怕黑天鹅事件,比如某个币归0等,可以手动提现出来。

var Stop_loss = 0.8 
var Max_diff = 0.4 //当偏差diff大于0.4时,不继续加空仓, 自行设置
var Min_diff = -0.3 //当diff小于-0.3时,不继续加多仓, 自行设置

if(IsVirtual()){
    throw '不能回测,回测参考 https://www.fmz.com/digest-topic/5294 '
}
if(exchange.GetName() != 'Futures_Binance'){
    throw '只支持币安期货交易所,和现货交易所不同,需要单独添加,名称为Futures_Binance'
}
var trade_symbols = Trade_symbols.split(',')
var symbols = trade_symbols
var index = 1 //指数
if(trade_symbols.indexOf('BTC')<0){
    symbols = trade_symbols.concat(['BTC'])
}
var update_profit_time = 0
var update_base_price_time= Date.now()
var assets = {}
var init_prices = {}


var trade_info = {}
var exchange_info = HttpQuery('https://fapi.binance.com/fapi/v1/exchangeInfo')
if(!exchange_info){
    throw '无法连接币安网络,需要海外托管者'
}
exchange_info = JSON.parse(exchange_info)
for (var i=0; i<exchange_info.symbols.length; i++){
    if(symbols.indexOf(exchange_info.symbols[i].baseAsset) > -1){
       assets[exchange_info.symbols[i].baseAsset] = {amount:0, hold_price:0, value:0, bid_price:0, ask_price:0, 
                                                     btc_price:0, btc_change:1,btc_diff:0,
                                                     realised_profit:0, margin:0, unrealised_profit:0}
       trade_info[exchange_info.symbols[i].baseAsset] = {minQty:parseFloat(exchange_info.symbols[i].filters[1].minQty),
                                                         priceSize:parseInt((Math.log10(1.1/parseFloat(exchange_info.symbols[i].filters[0].tickSize)))),
                                                         amountSize:parseInt((Math.log10(1.1/parseFloat(exchange_info.symbols[i].filters[1].stepSize))))
                                                        }
    }
}
assets.USDT = {unrealised_profit:0, margin:0, margin_balance:0, total_balance:0, leverage:0, update_time:0, init_balance:0, stop_balance:0, short_value:0, long_value:0, profit:0}

function updateAccount(){ //更新账户和持仓
    exchange.SetContractType('swap')
    var account = exchange.GetAccount()
    var pos = exchange.GetPosition()
    if (!account || !pos){
        Log('update account time out')
        return
    }
    assets.USDT.update_time = Date.now()
    for(var i=0; i<trade_symbols.length; i++){
        assets[trade_symbols[i]].margin = 0
        assets[trade_symbols[i]].unrealised_profit = 0
        assets[trade_symbols[i]].hold_price = 0
        assets[trade_symbols[i]].amount = 0
    } 
    for(var j=0; j<account.Info.positions.length; j++){
        if(account.Info.positions[j].positionSide == 'BOTH'){
            var pair = account.Info.positions[j].symbol 
            var coin = pair.slice(0,pair.length-4)
            if(trade_symbols.indexOf(coin) < 0){continue}
            assets[coin].margin = parseFloat(account.Info.positions[j].initialMargin) + parseFloat(account.Info.positions[j].maintMargin)
            assets[coin].unrealised_profit = parseFloat(account.Info.positions[j].unrealizedProfit)
        }
    }
    assets.USDT.margin = _N(parseFloat(account.Info.totalInitialMargin) + parseFloat(account.Info.totalMaintMargin),2)
    assets.USDT.margin_balance = _N(parseFloat(account.Info.totalMarginBalance),2)
    assets.USDT.total_balance = _N(parseFloat(account.Info.totalWalletBalance),2)
    if(assets.USDT.init_balance == 0){
        if(_G('init_balance')){
            assets.USDT.init_balance = _N(_G('init_balance'),2)
        }else{
            assets.USDT.init_balance = assets.USDT.total_balance 
            _G('init_balance',assets.USDT.init_balance)
        }
    }
    assets.USDT.profit = _N(assets.USDT.margin_balance - assets.USDT.init_balance, 2)
    assets.USDT.stop_balance = _N(Stop_loss*assets.USDT.init_balance, 2)
    assets.USDT.total_balance = _N(parseFloat(account.Info.totalWalletBalance),2)
    assets.USDT.unrealised_profit = _N(parseFloat(account.Info.totalUnrealizedProfit),2)
    assets.USDT.leverage = _N(assets.USDT.margin/assets.USDT.total_balance,2)
    pos = JSON.parse(exchange.GetRawJSON())
    if(pos.length > 0){
        for(var k=0; k<pos.length; k++){
            var pair = pos[k].symbol
            var coin = pair.slice(0,pair.length-4)
            if(trade_symbols.indexOf(coin) < 0){continue}
            if(pos[k].positionSide != 'BOTH'){continue}
            assets[coin].hold_price = parseFloat(pos[k].entryPrice)
            assets[coin].amount = parseFloat(pos[k].positionAmt)
            assets[coin].unrealised_profit = parseFloat(pos[k].unRealizedProfit)
        }
    }
}

function updateIndex(){ //更新指数
    
    if(!_G('init_prices') || Reset){
        Reset = false
        for(var i=0; i<trade_symbols.length; i++){
            init_prices[trade_symbols[i]] = (assets[trade_symbols[i]].ask_price+assets[trade_symbols[i]].bid_price)/(assets.BTC.ask_price+assets.BTC.bid_price)
        }
        Log('保存启动时的价格')
        _G('init_prices',init_prices)
    }else{
        init_prices = _G('init_prices')
        if(Date.now() - update_base_price_time > Update_base_price_time_interval*1000){
            update_base_price_time = Date.now()
            for(var i=0; i<trade_symbols.length; i++){ //更新初始价格
                init_prices[trade_symbols[i]] = init_prices[trade_symbols[i]]*(1-Alpha)+Alpha*(assets[trade_symbols[i]].ask_price+assets[trade_symbols[i]].bid_price)/(assets.BTC.ask_price+assets.BTC.bid_price)
            }
            _G('init_prices',init_prices)
        }
        var temp = 0
        for(var i=0; i<trade_symbols.length; i++){
            assets[trade_symbols[i]].btc_price =  (assets[trade_symbols[i]].ask_price+assets[trade_symbols[i]].bid_price)/(assets.BTC.ask_price+assets.BTC.bid_price)
            if(!(trade_symbols[i] in init_prices)){
                Log('添加新的币种',trade_symbols[i])
                init_prices[trade_symbols[i]] = assets[trade_symbols[i]].btc_price / index
                _G('init_prices',init_prices)
            }
            assets[trade_symbols[i]].btc_change = _N(assets[trade_symbols[i]].btc_price/init_prices[trade_symbols[i]],4)
            temp += assets[trade_symbols[i]].btc_change
        }
        index = _N(temp/trade_symbols.length, 4)
    }
    
}

function updateTick(){ //更新行情
    var ticker = HttpQuery('https://fapi.binance.com/fapi/v1/ticker/bookTicker')
    try {
        ticker = JSON.parse(ticker)
    }catch(e){
        Log('get ticker time out')
        return
    }
    assets.USDT.short_value = 0
    assets.USDT.long_value = 0
    for(var i=0; i<ticker.length; i++){
        var pair = ticker[i].symbol 
        var coin = pair.slice(0,pair.length-4)
        if(symbols.indexOf(coin) < 0){continue}
        assets[coin].ask_price = parseFloat(ticker[i].askPrice)
        assets[coin].bid_price = parseFloat(ticker[i].bidPrice)
        assets[coin].ask_value = _N(assets[coin].amount*assets[coin].ask_price, 2)
        assets[coin].bid_value = _N(assets[coin].amount*assets[coin].bid_price, 2)
        if(trade_symbols.indexOf(coin) < 0){continue}
        if(assets[coin].amount<0){
            assets.USDT.short_value += Math.abs((assets[coin].ask_value+assets[coin].bid_value)/2)
        }else{
            assets.USDT.long_value += Math.abs((assets[coin].ask_value+assets[coin].bid_value)/2)
        }
        assets.USDT.short_value = _N(assets.USDT.short_value,0)
        assets.USDT.long_value = _N(assets.USDT.long_value,0)
    }
    updateIndex()
    for(var i=0; i<trade_symbols.length; i++){
        assets[trade_symbols[i]].btc_diff = _N(assets[trade_symbols[i]].btc_change - index, 4)
    }
}

function trade(symbol, dirction, value){ //交易
    if(Date.now()-assets.USDT.update_time > 10*1000){
        Log('更新账户延时,不交易')
        return
    }
    var price = dirction == 'sell' ? assets[symbol].bid_price : assets[symbol].ask_price
    var amount = _N(Math.min(value,Ice_value)/price, trade_info[symbol].amountSize)
    if(amount < trade_info[symbol].minQty){
        Log(symbol, '合约价值偏离或冰山委托订单的大小设置过小,达不到最小成交, 至少需要: ', _N(trade_info[symbol].minQty*price,0)+1)
        return
    }
    exchange.IO("currency", symbol+'_'+'USDT')
    exchange.SetContractType('swap')
    exchange.SetDirection(dirction)
    var f = dirction == 'buy' ? 'Buy' : 'Sell'
    var id = exchange[f](price, amount, symbol)
    if(id){
        exchange.CancelOrder(id) //订单会立即撤销
    }
    return id
}



function updateStatus(){ //状态栏信息
        var table = {type: 'table', title: '交易对信息', 
             cols: ['币种', '数量', '持仓价格',  '当前价格', '偏离平均', '持仓价值', '保证金', '未实现盈亏'],
             rows: []}
    for (var i=0; i<symbols.length; i++){
        var price = _N((assets[symbols[i]].ask_price + assets[symbols[i]].bid_price)/2, trade_info[symbols[i]].priceSize)
        var value = _N((assets[symbols[i]].ask_value + assets[symbols[i]].bid_value)/2, 2)
        var infoList = [symbols[i], assets[symbols[i]].amount, assets[symbols[i]].hold_price, price, assets[symbols[i]].btc_diff, value, _N(assets[symbols[i]].margin,3), _N(assets[symbols[i]].unrealised_profit,3)]
        table.rows.push(infoList)
    }
    var logString = _D() + '   ' + JSON.stringify(assets.USDT) + ' Index:' + index + '\n'
    LogStatus(logString + '`' + JSON.stringify(table) + '`')
    
    if(Date.now()-update_profit_time > Log_profit_interval*1000){
        LogProfit(_N(assets.USDT.margin_balance,3))
        update_profit_time = Date.now()
    }
    
}

function stopLoss(){ //止损函数
    while(true){
        if(assets.USDT.margin_balance < Stop_loss*assets.USDT.init_balance && assets.USDT.init_balance > 0){
            Log('触发止损,当前资金:', assets.USDT.margin_balance, '初始资金:', assets.USDT.init_balance)
            Ice_value = 200 //止损的快一些,可修改
            updateAccount()
            updateTick()
            var trading = false //是否正在交易
            for(var i=0; i<trade_symbols.length; i++){
                var symbol = trade_symbols[i]
                if(assets[symbol].ask_price == 0){ continue }
                if(assets[symbol].bid_value >= trade_info[symbol].minQty*assets[symbol].bid_price){
                    trade(symbol, 'sell', assets[symbol].bid_value)
                    trading = true
                }
                if(assets[symbol].ask_value <= -trade_info[symbol].minQty*assets[symbol].ask_price){
                    trade(symbol, 'buy', -assets[symbol].ask_value)
                    trading = true
                }
            }
            Sleep(1000)
            if(!trading){
                throw '止损结束,如果需要重新运行策略,需要调低止损'
            }
        }else{ //不用止损
            return
        }
    }    
}

function onTick(){ //策略逻辑部分
    for(var i=0; i<trade_symbols.length; i++){
        var symbol = trade_symbols[i]
        if(assets[symbol].ask_price == 0){ continue }
        var aim_value = -Trade_value * _N(assets[symbol].btc_diff/0.01,3)
        if(aim_value - assets[symbol].ask_value >= Adjust_value && assets[symbol].btc_diff > Min_diff && assets.USDT.long_value-assets.USDT.short_value <= 1.1*Trade_value){
            trade(symbol,'buy', aim_value - assets[symbol].ask_value)
        }
        if(aim_value - assets[symbol].bid_value <= -Adjust_value && assets[symbol].btc_diff < Max_diff && assets.USDT.short_value-assets.USDT.long_value <= 1.1*Trade_value){
            trade(symbol,'sell', -(aim_value - assets[symbol].bid_value))
        }
    }
}

function main() {
    while(true){
        updateAccount()
        updateTick()
        stopLoss() //止损
        onTick()
        updateStatus()
        Sleep(Interval*1000)
    }
}

Related

More

tiagombalsa @tmbs95 add me on telegram, interested

The bride too.Please tell me, in the function onTick ((), there is a line like this, assets.USDT.long_value-assets.USDT.short_value <= 1.1*Trade_value, I understand that this is set to prevent too much space imbalance.

mikelslCan't find it on WeChat?

Capital of the Exchange ChainMax_diff and Min_diff aren't supposed to be 0.04 and -0.03?

The Air Force will never be a slave.Give this closed circle a little bit of sunlight.

The grass /upload/asset/1b39347a88aa4cff916.jpg

Quantification of district classesThe person suggested to do more overshooting to do nothing overshooting strategy to eliminate the BNB, this deal is the BNB wanted to attract popularity, it is estimated that the overshooting; can not be seen from the historical perspective now

The bride too.This is two things.

The bride too.A coin goes out of the independent market, this multi-space balance setting can prevent big losses, so the decision can not be imbalanced. Only to find a way to open a hedge account. Now the various currencies are bullish, feeling unsuited to run this strategy, the retracement is a little big.

The grassYou are wrong, wangweibing_ustb

izhangsanIn fact, if you look at the code, you will know the results of the retest of the entire currency, no need to worry. In the addition, Alpha = 0.05, add LINK, ETC, BNB, the initial historical retracement is 3%, the maximum retracement of the extreme market is less than 25%, Trade_Value with 3% of the safe over-total currency.