Deribit opções Delta estratégia de hedge dinâmico

Autora:Sonhos pequenos, Criado: 2021-03-26 11:18:53, Atualizado: 2023-09-24 19:38:01

img

Deribit opções Delta estratégia de hedge dinâmico

A estratégia da quantificação do FMZ é:Deribit opções Delta estratégia de hedge dinâmicoA estratégia é conhecida como DDH (dynamic delta hedging).

Para aprender a negociar opções, geralmente temos que dominar esses conceitos:

  • Modelo de preços de opções, modelo B-S, preço de opções baseado no preço do item, preço do direito de escopo, preço do tempo restante do prazo de vencimento, preço da taxa de flutuação, preço da taxa de juros sem risco.

  • O risco de opções:

    • O risco direcional da opção delta é: se o delta for +0.50, a opção é considerada como sendo 0.50 em depósito.
    • A aceleração do risco na direção do Gamma. Por exemplo, opções binárias, devido à ação do Gamma, começam com o preço indicado no preço de mercado, e o Delta sobe gradualmente de +0.50 para +1.00.
    • Theta fuso Fusão de tempo. Quando você compra uma opção, se o preço do indicador não se mover, você pagará a taxa indicada no valor de Theta ("Deribit em USD") a cada dia. Quando você vende uma opção, se o preço do indicador não se mover, você receberá o custo indicado no valor Theta a cada dia.
    • O ganho da taxa de volatilidade do porta Vega. Quando você compra uma opção, a taxa de volatilidade do porta Vega é positiva, ou seja, a taxa de volatilidade é maior. Quando a taxa de volatilidade implícita aumenta, você ganha na porta Vega.

A estratégia do DDH é a seguinte:

  • O princípio do DDH explicado A neutralidade de risco da direção de negociação é alcançada pelo alinhamento do delta das opções e dos futuros. Como o delta das opções é variável e segue as mudanças de preços dos indicadores, o delta das opções e dos prontuários é invariável. Após a detenção de posições em contratos de opções e o equilíbrio com o delta do hedge de futuros, o delta geral reaparece no desequilíbrio com a variação do preço do item indicado. Para uma combinação como a posição de opções e a posição de futuros, o equilíbrio com o delta do hedge de futuros é necessário.

    Por exemplo: Quando compramos uma opção de venda, mantemos uma posição de venda de várias direções. Neste momento, é necessário fazer um futuro em branco para hedgear o delta da opção, atingindo o total de delta neutro ((0 ou próximo de 0)). A primeira coisa que fazemos é não considerar os fatores como o tempo restante de vencimento dos contratos de opções, a taxa de volatilidade e outros. Situação 1: O preço do item indicado subiu, o delta da parte de opções aumentou, o delta geral se move para o número positivo, o futuro precisa ser novamente hedgeado, e abrir uma parte do embalado continua como um futuro embalado, para que o delta geral volte a equilibrar. (Antes de equilibrar novamente, o delta do direito é grande neste período, o delta do futuro é relativamente pequeno, e se o lucro marginal da opção de hedge exceder o prejuízo marginal do contrato em branco, o portfólio inteiro terá ganhos)

    Situação 2: Os preços dos indicadores caíram, o delta da parte das opções diminuiu, o delta geral se moveu para o negativo, o equilíbrio de uma parte dos futuros de carência, o que torna o delta geral novamente equilibrado. (Antes de equilibrar novamente, o delta dos direitos é pequeno, o delta dos futuros é relativamente grande, e a perda marginal de opções binárias é menor do que o ganho marginal dos títulos vazios do contrato, o que significa que o portfólio inteiro ainda terá ganhos)

    Em um cenário ideal, a queda do preço pode trazer ganhos, desde que o mercado esteja flutuante.

    No entanto, há outros fatores a serem considerados: o valor do tempo, os custos de transação e outros.

    O que é que ele está a fazer?

    Gamma Scalping 的关注点并不是delta,dynamic delta hedging 只是过程中规避underlying价格风险的一种做法而已。
    Gamma Scalping 关注的是Alpha,此Alpha不是选股的Alpha,这里的Alpha = Gamma/Theta也就是单位Theta的时间损耗换来多少Gamma,
    这个是关注的点。可以构建出上涨和下跌都浮盈的组合,但一定伴随时间损耗,那问题就在于性价比了。
    
    作者:许哲
    链接:https://www.zhihu.com/question/51630805/answer/128096385
    

A estratégia do DDH é explicada

  • Pacotes de interface de mercado agregado, design de estrutura
  • Design de UI estratégico
  • Design estratégico de interação
  • Desenho de funções de cobertura automática

A fonte é:

// 构造函数
function createManager(e, subscribeList, msg) {
	var self = {}
    self.supportList = ["Futures_Binance", "Huobi", "Futures_Deribit"]  // 支持的交易所的

    // 对象属性
    self.e = e
    self.msg = msg
    self.name = e.GetName()
    self.type = self.name.includes("Futures_") ? "Futures" : "Spot"
    self.label = e.GetLabel()
    self.quoteCurrency = ""  
    self.subscribeList = subscribeList   // subscribeList : [strSymbol1, strSymbol2, ...]
    self.tickers = []                    // 接口获取的所有行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // 需要的行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null 
    self.pos = null 

    // 初始化函数
    self.init = function() { 
    	// 判断是否支持该交易所
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    self.setBase = function(base) {
        // 切换基地址,用于切换为模拟盘
        self.e.SetBase(base)
        Log(self.name, self.label, "切换为模拟盘:", base)
    }

    // 判断数据精度
    self.judgePrecision = function (p) {
        var arr = p.toString().split(".")
        if (arr.length != 2) {
            if (arr.length == 1) {
                return 0
            }
            throw "judgePrecision error, p:" + String(p)
        }
        
        return arr[1].length
    }

    // 更新资产
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

    // 更新持仓
    self.updatePos = function(httpMethod, url, params) {
        var pos = self.e.IO("api", httpMethod, url, params)
        var ret = []
        if (!pos) {
            return false 
        } else {
            // 整理数据
            // {"jsonrpc":"2.0","result":[],"usIn":1616484238870404,"usOut":1616484238870970,"usDiff":566,"testnet":true}
            try {
                _.each(pos.result, function(ele) {
                    ret.push(ele)
                })
            } catch(err) {
                Log("错误:", err)
                return false 
            }
            self.pos = ret
        }
        return true 
    }

    // 更新行情数据
    self.updateTicker = function(url, callBackFuncGetArr, callBackFuncGetTicker) {
    	var tickers = []
    	var subscribeTickers = []
    	var ret = self.httpQuery(url)
    	if (!ret) {
    		return false 
    	}
    	// Log("测试", ret)// 测试
    	try {
            _.each(callBackFuncGetArr(ret), function(ele) {
            	var ticker = callBackFuncGetTicker(ele)
            	tickers.push(ticker)
                if (self.subscribeList.length == 0) {
                    subscribeTickers.push(ticker)
                } else {
                	for (var i = 0 ; i < self.subscribeList.length ; i++) {                        
                    	if (self.subscribeList[i] == ticker.symbol) {
                    		subscribeTickers.push(ticker)
                    	}
                	}
                }
            })
        } catch(err) {
        	Log("错误:", err)
        	return false 
        }

        self.tickers = tickers
        self.subscribeTickers = subscribeTickers
        return true 
    }

    self.getTicker = function(symbol) {
    	var ret = null 
    	_.each(self.subscribeTickers, function(ticker) {
    		if (ticker.symbol == symbol) {
    			ret = ticker
    		}
    	})
    	return ret 
    }

    self.httpQuery = function(url) {
    	var ret = null
        try {
            var retHttpQuery = HttpQuery(url)
            ret = JSON.parse(retHttpQuery)
        } catch (err) {
            // Log("错误:", err)
            ret = null
        }
        return ret 
    }

    self.returnTickersTbl = function() {
        var tickersTbl = {
        	type : "table", 
        	title : "tickers",
        	cols : ["symbol", "ask1", "bid1"], 
        	rows : []
        }
        _.each(self.subscribeTickers, function(ticker) {        
        	tickersTbl.rows.push([ticker.symbol, ticker.ask1, ticker.bid1])
        })
        return tickersTbl
    }
    
    // 返回持仓表格
    self.returnPosTbl = function() {
        var posTbl = {
            type : "table", 
            title : "pos|" + self.msg,
            cols : ["instrument_name", "mark_price", "direction", "size", "delta", "index_price", "average_price", "settlement_price", "average_price_usd", "total_profit_loss"], 
            rows : []
        }
        /* 接口返回的持仓数据格式
        {
            "mark_price":0.1401105,"maintenance_margin":0,"instrument_name":"BTC-25JUN21-28000-P","direction":"buy",
            "vega":5.66031,"total_profit_loss":0.01226105,"size":0.1,"realized_profit_loss":0,"delta":-0.01166,"kind":"option",
            "initial_margin":0,"index_price":54151.77,"floating_profit_loss_usd":664,"floating_profit_loss":0.000035976,
            "average_price_usd":947.22,"average_price":0.0175,"theta":-7.39514,"settlement_price":0.13975074,"open_orders_margin":0,"gamma":0
        }
        */
        _.each(self.pos, function(ele) {
        	if(ele.direction != "zero") {
                posTbl.rows.push([ele.instrument_name, ele.mark_price, ele.direction, ele.size, ele.delta, ele.index_price, ele.average_price, ele.settlement_price, ele.average_price_usd, ele.total_profit_loss])
            }
        })
        return posTbl
    }

    self.returnOptionTickersTbls = function() {
        var arr = []
        var arrDeliveryDate = []
        _.each(self.subscribeTickers, function(ticker) {
            if (self.name == "Futures_Deribit") {
                var arrInstrument_name = ticker.symbol.split("-")
                var currency = arrInstrument_name[0]
                var deliveryDate = arrInstrument_name[1]
                var deliveryPrice = arrInstrument_name[2]
                var optionType = arrInstrument_name[3]

                if (!_.contains(arrDeliveryDate, deliveryDate)) {
                    arr.push({
                        type : "table", 
                        title : arrInstrument_name[1],
                        cols : ["PUT symbol", "ask1", "bid1", "mark_price", "underlying_price", "CALL symbol", "ask1", "bid1", "mark_price", "underlying_price"], 
                        rows : []
                    })
                    arrDeliveryDate.push(arrInstrument_name[1])
                }
                // 遍历arr
                _.each(arr, function(tbl) {
                    if (tbl.title == deliveryDate) {
                        if (tbl.rows.length == 0 && optionType == "P") {
                            tbl.rows.push([ticker.symbol, ticker.ask1, ticker.bid1, ticker.mark_price, ticker.underlying_price, "", "", "", "", ""])
                            return 
                        } else if (tbl.rows.length == 0 && optionType == "C") {
                            tbl.rows.push(["", "", "", "", "", ticker.symbol, ticker.ask1, ticker.bid1, ticker.mark_price, ticker.underlying_price])
                            return 
                        }                        
                        for (var i = 0 ; i < tbl.rows.length ; i++) {
                            if (tbl.rows[i][0] == "" && optionType == "P") {
                                tbl.rows[i][0] = ticker.symbol
                                tbl.rows[i][1] = ticker.ask1
                                tbl.rows[i][2] = ticker.bid1
                                tbl.rows[i][3] = ticker.mark_price
                                tbl.rows[i][4] = ticker.underlying_price
                                return 
                            } else if(tbl.rows[i][5] == "" && optionType == "C") {
                                tbl.rows[i][5] = ticker.symbol
                                tbl.rows[i][6] = ticker.ask1
                                tbl.rows[i][7] = ticker.bid1
                                tbl.rows[i][8] = ticker.mark_price
                                tbl.rows[i][9] = ticker.underlying_price
                                return 
                            }
                        }
                        if (optionType == "P") {
                            tbl.rows.push([ticker.symbol, ticker.ask1, ticker.bid1, ticker.mark_price, ticker.underlying_price, "", "", "", "", ""])
                        } else if(optionType == "C") {
                            tbl.rows.push(["", "", "", "", "", ticker.symbol, ticker.ask1, ticker.bid1, ticker.mark_price, ticker.underlying_price])
                        }
                    }
                })
            }
        })
        return arr 
    }

    // 初始化
    self.init()
	return self 
}


function main() {
    // 初始化,清空日志
    if(isResetLog) {
    	LogReset(1)
    }

    var m1 = createManager(exchanges[0], [], "option")
    var m2 = createManager(exchanges[1], ["BTC-PERPETUAL"], "future")

    // 切换为模拟盘
    var base = "https://www.deribit.com"
    if (isTestNet) {    
        m1.setBase(testNetBase)    
        m2.setBase(testNetBase)
        base = testNetBase
    }

    while(true) {
        // 期权
        var ticker1GetSucc = m1.updateTicker(base + "/api/v2/public/get_book_summary_by_currency?currency=BTC&kind=option", 
            function(data) {return data.result}, 
            function(ele) {return {bid1: ele.bid_price, ask1: ele.ask_price, symbol: ele.instrument_name, underlying_price: ele.underlying_price, mark_price: ele.mark_price}}) 
        
        // 永续期货
        var ticker2GetSucc = m2.updateTicker(base + "/api/v2/public/get_book_summary_by_currency?currency=BTC&kind=future", 
            function(data) {return data.result}, 
            function(ele) {return {bid1: ele.bid_price, ask1: ele.ask_price, symbol: ele.instrument_name}})
        if (!ticker1GetSucc || !ticker2GetSucc) {
            Sleep(5000)
            continue
        }

        // 更新持仓
        var pos1GetSucc = m1.updatePos("GET", "/api/v2/private/get_positions", "currency=BTC&kind=option")
        var pos2GetSucc = m2.updatePos("GET", "/api/v2/private/get_positions", "currency=BTC&kind=future")

        if (!pos1GetSucc || !pos2GetSucc) {
            Sleep(5000)
            continue
        }

        // 交互
        var cmd = GetCommand()
        if(cmd) {
            // 处理交互
            Log("交互命令:", cmd)
            var arr = cmd.split(":")
            // cmdClearLog 
            if(arr[0] == "setContractType") {
                // parseFloat(arr[1])
                m1.e.SetContractType(arr[1])
                Log("exchanges[0]交易所对象设置合约:", arr[1])
            } else if (arr[0] == "buyOption") {
                var actionData = arr[1].split(",")
                var price = parseFloat(actionData[0])
                var amount = parseFloat(actionData[1])
                m1.e.SetDirection("buy")
                m1.e.Buy(price, amount)
                Log("执行价格:", price, "执行数量:", amount, "执行方向:", arr[0])
            } else if (arr[0] == "sellOption") {
                var actionData = arr[1].split(",")
                var price = parseFloat(actionData[0])
                var amount = parseFloat(actionData[1])
                m1.e.SetDirection("sell")
                m1.e.Sell(price, amount)                
                Log("执行价格:", price, "执行数量:", amount, "执行方向:", arr[0])
            } else if (arr[0] == "setHedgeDeltaStep") {
                hedgeDeltaStep = parseFloat(arr[1])
                Log("设置参数hedgeDeltaStep:", hedgeDeltaStep)
            } 
        }
        
        // 获取期货合约价格
        var perpetualTicker = m2.getTicker("BTC-PERPETUAL")
        var hedgeMsg = " PERPETUAL:" + JSON.stringify(perpetualTicker)

        // 从账户数据中获取delta总值        
        var acc1GetSucc = m1.updateAcc(function(self) {
        	self.e.SetCurrency("BTC_USD")        
        	return self.e.GetAccount()
        })
        if (!acc1GetSucc) {
        	Sleep(5000)
        	continue
        }
        var sumDelta = m1.accData.Info.result.delta_total

        if (Math.abs(sumDelta) > hedgeDeltaStep && perpetualTicker) {
            if (sumDelta < 0) {
                // delta 大于0 对冲期货做空                
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.ask1, -1)                
                if (amount > 10) {
                    Log("超过对冲阈值,当前总delta:", sumDelta, "买入期货")
                    m2.e.SetContractType("BTC-PERPETUAL")                    
                    m2.e.SetDirection("buy")
                    m2.e.Buy(-1, amount)
                } else {
                	hedgeMsg += ", 对冲下单量小于10"
                }
            } else {
                // delta 小于0 对冲期货做多
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.bid1, -1)
                if (amount > 10) {
                    Log("超过对冲阈值,当前总delta:", sumDelta, "卖出期货")
                    m2.e.SetContractType("BTC-PERPETUAL")
                    m2.e.SetDirection("sell")
                    m2.e.Sell(-1, amount)
                } else {
                	hedgeMsg += ", 对冲下单量小于10"
                }
            }
        }

        LogStatus(_D(), "sumDelta:", sumDelta, hedgeMsg, 
        	"\n`" + JSON.stringify([m1.returnPosTbl(), m2.returnPosTbl()]) + "`", "\n`" + JSON.stringify(m2.returnTickersTbl()) + "`", "\n`" + JSON.stringify(m1.returnOptionTickersTbls()) + "`")
        Sleep(10000)
    }
}


Parâmetros da estratégia:img

A estratégia é endereçada:https://www.fmz.com/strategy/265090

A estratégia funciona:

img

img

Esta é uma estratégia de ensino, de aprendizagem e de uso prático.


Relacionados

Mais.

fantadongPode ser usado no disco real?

Biologia da órbitaO deribit parece ter ouvido falar de uma bolsa?

Sonhos pequenosA partir daí, o projeto pode ser projetado para modificar especificamente o código da estratégia.

fantadongÉ possível definir um intervalo de preços, por exemplo, para ultrapassar um determinado preço.

Sonhos pequenosOlá, a estratégia é apenas para ensino, testes, e o disco real pode ser modificado por você mesmo.

Sonhos pequenosSim, é a mais especializada das bolsas de opções no mundo das moedas, a bolsa de derivativos de ativos blockchain.