Les ressources ont été chargées... Je charge...

La valeur de la déduction est la valeur de la déduction de l'épargne.

Auteur:FMZ~Lydia, Créé: 2022-11-01 17:49:07, Mis à jour: 2023-09-15 20:49:52

img

La stratégie proposée par FMZ Quant est la stratégie de couverture dynamique Delta Deribit Options, ou en abrégé DDH (couverture dynamique delta).

Pour l'étude du trading d'options, nous devons généralement maîtriser ces concepts:

· Modèle de tarification des options, modèle B-S, les prix des options sont déterminés sur la base de [prix de l'objet], [prix de la puissance utilisée], [temps restant jusqu'à l'expiration], [volatilité implicite] et [taux sans risque].

· Exposition à des options:

- Delta Le risque directionnel d'une option. Si le delta est de +0,50, alors l'option, qui réalise un profit ou une perte lorsque le prix de l'objet monte ou descend, peut être considérée comme un spot de 0,50. - Gamma Accélération du risque directionnel. Par exemple, dans le cas des options d'achat, en raison de la Gamma, le delta passera progressivement de +0,50 à +1,00 à mesure que le prix continue à augmenter à partir du moment où le prix de l'objet est au prix de puissance. Lorsque vous achetez une option, si le prix de l'objet ne change pas, pour chaque jour qui passe, vous payez les frais indiqués dans le montant Theta (Deribit est libellé en USD). Lorsque vous vendez une option, si le prix de l'objet ne change pas, vous recevrez la commission indiquée dans le montant Theta chaque jour. -Vega Exposition à la volatilité. lorsque vous achetez une option, Vega est positive, c'est-à-dire la volatilité à long terme. lorsque la volatilité implicite augmente, vous gagnez sur l'exposition Vega. et vice versa, lorsque vous vendez des options, vous gagnez à mesure que la volatilité implicite diminue.

Explication de la stratégie DDH:

· explication du principe DDH La direction de négociation neutre en termes de risque est obtenue en faisant correspondre le delta des options et des contrats à terme. Après avoir pris une position dans un contrat d'option et équilibré le delta avec la couverture à terme, le delta global deviendra déséquilibré à nouveau à mesure que le prix de l'objet se déplace.

· Par exemple: Lorsque nous achetons une option d'achat, nous détenons une position dans la direction longue à ce moment-là. À ce moment-là, il est nécessaire d'aller court sur les contrats à terme pour couvrir le delta des options, atteignant le delta neutre global (0 ou proche de 0). Nous ignorons le temps restant jusqu'à l'expiration du contrat d'option, la volatilité et d'autres facteurs. Scénario 1: Lorsque le prix de l'objet augmente, le delta des options augmente, et le delta global passe à un nombre positif, et les contrats à terme doivent être à nouveau couverts. (Avant le rééquilibrage, le delta des options est important, tandis que celui des contrats à terme est relativement faible. Le bénéfice marginal des options d'achat dépasse la perte marginale des positions courtes des contrats et l'ensemble du portefeuille sera rentable.)

Scénario 2: À mesure que le prix de l'objet tombe, la partie d'option du delta diminue et le delta global passe à un nombre négatif, clôturant une partie de la position à terme courte et rééquilibrant le delta global. (Avant le rééquilibrage, à ce stade, le delta des options est faible, tandis que celui des contrats à terme est relativement important. La perte marginale des options d'achat est inférieure au bénéfice marginal des positions courtes du contrat, et l'ensemble du portefeuille générera toujours des gains.)

Par conséquent, dans un état idéal, l'augmentation et la diminution du sujet apporteront des avantages tant que le marché fluctuera.

Cependant, il y a aussi des facteurs à prendre en considération: la valeur du temps, les coûts de transaction et d'autres facteurs.

Par conséquent, l'explication de l'homme fort sur Zhihu est citée:

The focus of Gamma Scalping is not on delta, dynamic delta hedging is just a way to avoid underlying price risk in the process.
Gamma Scaling focuses on alpha, which is not the alpha of stock selection. Here, alpha=gamma/theta, that is, how much gamma is exchanged for the time loss of unit Theta.
This is the point of concern. It is possible to construct a portfolio that floats both up and down, but it must be accompanied by time loss, and then the problem lies in the cost effectiveness.

Author: Xu Zhe
URL: https://www.zhihu.com/question/51630805/answer/128096385

Explication de la conception de la stratégie DDH

· Encapsulation de l'interface de marché agrégée, conception du cadre · Conception de l'interface utilisateur stratégique · conception d'interactions stratégiques · Conception de la fonction de couverture automatique Le code source:

// Construct functions
function createManager(e, subscribeList, msg) {
	var self = {}
    self.supportList = ["Futures_Binance", "Huobi", "Futures_Deribit"]  // of the supported exchanges

    // Object attributes
    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 = []                    // All market data obtained by the interface, define the data format: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // The required market data, define the data format: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null 
    self.pos = null 

    // Initialize the function
    self.init = function() { 
    	// Judge if the exchange is supported
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    self.setBase = function(base) {
        // Switching base address for switching to analog bot
        self.e.SetBase(base)
        Log(self.name, self.label, "switch to analog bot:", base)
    }

    // Judging data precision
    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
    }

    // Update assets
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

    // Update positions
    self.updatePos = function(httpMethod, url, params) {
        var pos = self.e.IO("api", httpMethod, url, params)
        var ret = []
        if (!pos) {
            return false 
        } else {
            // Organize data
            // {"jsonrpc":"2.0","result":[],"usIn":1616484238870404,"usOut":1616484238870970,"usDiff":566,"testnet":true}
            try {
                _.each(pos.result, function(ele) {
                    ret.push(ele)
                })
            } catch(err) {
                Log("Error:", err)
                return false 
            }
            self.pos = ret
        }
        return true 
    }

    // Update the market data
    self.updateTicker = function(url, callBackFuncGetArr, callBackFuncGetTicker) {
    	var tickers = []
    	var subscribeTickers = []
    	var ret = self.httpQuery(url)
    	if (!ret) {
    		return false 
    	}
    	// Log("test", ret)// test
    	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("Error:", 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("Error:", 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
    }
    
    // Back to the position table
    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 : []
        }
        /* Format of the position data returned by the interface
        {
            "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])
                }
                // Iterate through 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 
    }

    // Initialization
    self.init()
	return self 
}


function main() {
    // Initialization, clear logs
    if(isResetLog) {
    	LogReset(1)
    }

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

    // Switch to analog bot
    var base = "https://www.deribit.com"
    if (isTestNet) {    
        m1.setBase(testNetBase)    
        m2.setBase(testNetBase)
        base = testNetBase
    }

    while(true) {
        // Options
        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}}) 
        
        // Perpetual futures
        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
        }

        // Update positions
        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
        }

        // Interactions
        var cmd = GetCommand()
        if(cmd) {
            // Handle interactions
            Log("Interaction commands", cmd)
            var arr = cmd.split(":")
            // cmdClearLog 
            if(arr[0] == "setContractType") {
                // parseFloat(arr[1])
                m1.e.SetContractType(arr[1])
                Log("exchanges[0] contract set by exchange object.", 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("execution price: ", price, "execution amount: ", amount, "execution direction: ", 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("execution price: ", price, "execution amount: ", amount, "execution direction: ", arr[0])
            } else if (arr[0] == "setHedgeDeltaStep") {
                hedgeDeltaStep = parseFloat(arr[1])
                Log("set the parameter hedgeDeltaStep:", hedgeDeltaStep)
            } 
        }
        
        // Obtain the future contract prices
        var perpetualTicker = m2.getTicker("BTC-PERPETUAL")
        var hedgeMsg = " PERPETUAL:" + JSON.stringify(perpetualTicker)

        // Obtain the total delta value from the account data        
        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) {
                // Hedging futures go short if delta is greater than 0                 
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.ask1, -1)                
                if (amount > 10) {
                    Log("Exceed the hedging threshold, current total delta:", sumDelta, "Buy futures")
                    m2.e.SetContractType("BTC-PERPETUAL")                    
                    m2.e.SetDirection("buy")
                    m2.e.Buy(-1, amount)
                } else {
                	hedgeMsg += ", hedging order volume less than 10"
                }
            } else {
                // Hedging futures go long if delta is less than 0
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.bid1, -1)
                if (amount > 10) {
                    Log("Exceed the hedging threshold, current total delta:", sumDelta, "Sell futures")
                    m2.e.SetContractType("BTC-PERPETUAL")
                    m2.e.SetDirection("sell")
                    m2.e.Sell(-1, amount)
                } else {
                	hedgeMsg += ", hedging order volume less than 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)
    }
}

Adresse de la stratégie:https://www.fmz.com/strategy/265090

Opération stratégique:

img

Cette stratégie est une stratégie tutorielle, orientée vers l'apprentissage, veuillez l'utiliser avec prudence dans un vrai bot.


Relationnée

Plus de