avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Được tạo ra trong: 2021-03-26 11:18:53, cập nhật trên: 2024-12-05 21:55:32
comments   6
hits   3894

Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Chiến lược được đưa ra bởi lượng hóa FMZ này làChiến lược phòng ngừa rủi ro động Delta của Deribit Option, được gọi là chiến lược DDH (phòng ngừa delta động).

Khi tìm hiểu về giao dịch quyền chọn, chúng ta thường cần nắm vững các khái niệm sau:

  • Mô hình định giá quyền chọn, mô hình B-S, giá quyền chọn được xác định dựa trên [giá tài sản cơ sở], [giá thực hiện], [thời gian còn lại cho đến khi hết hạn], [biến động (ngụ ý)] và [lãi suất không rủi ro].

  • Tùy chọn phơi bày:

    • Delta — rủi ro theo hướng của một quyền chọn. Nếu Delta là +0,50, thì hiệu suất lãi lỗ của quyền chọn này khi giá cơ sở tăng hoặc giảm có thể được coi là 0,50 giao ngay.
    • Gamma — sự gia tốc của rủi ro theo hướng. Ví dụ, đối với quyền chọn mua, do tác động của Gamma, bắt đầu từ thời điểm giá cơ sở bằng giá thực hiện, khi giá tiếp tục tăng, Delta sẽ dần dịch chuyển từ +0,50 đến +1,00.
    • Theta—Phơi sáng theo thời gian. Khi bạn mua một quyền chọn, nếu giá cơ sở không thay đổi, bạn sẽ phải trả một khoản phí được biểu thị bằng số tiền Theta (Deribit tính bằng USD) cho mỗi ngày trôi qua. Khi bạn bán một quyền chọn, nếu giá cơ sở không thay đổi, bạn sẽ nhận được một khoản phí được biểu thị bằng số tiền Theta cho mỗi ngày trôi qua.
    • Vega — Phơi nhiễm với biến động. Khi bạn mua một quyền chọn, Vega sẽ dương, nghĩa là bạn đang có độ biến động dài hạn. Khi độ biến động ngụ ý tăng lên, bạn sẽ được hưởng lợi từ mức độ tiếp xúc với Vega của mình. Ngược lại, khi bạn bán quyền chọn, mức độ biến động ngụ ý sẽ giảm và bạn sẽ có lãi.

Giải thích về chiến lược DDH:

  • Giải thích nguyên lý DDH Bằng cách cân bằng Delta của quyền chọn và hợp đồng tương lai, có thể đạt được tính trung lập rủi ro theo hướng giao dịch. Vì Delta của quyền chọn sẽ thay đổi theo giá của tài sản cơ sở nên Delta của hợp đồng tương lai và hợp đồng giao ngay không đổi. Sau khi nắm giữ vị thế hợp đồng quyền chọn và sử dụng hợp đồng tương lai để phòng ngừa và cân bằng Delta, tổng thể Delta sẽ lại mất cân bằng khi giá của tài sản cơ sở thay đổi. Đối với sự kết hợp giữa các vị thế quyền chọn và vị thế tương lai, cần phải liên tục phòng ngừa động và cân bằng Delta.

Ví dụ: Khi chúng ta mua quyền chọn mua, chúng ta đang nắm giữ vị thế tăng giá. Vào thời điểm này, cần phải bán khống hợp đồng tương lai để phòng ngừa Delta của quyền chọn và đạt được mức trung tính Delta tổng thể (0 hoặc gần 0). Chúng tôi sẽ không xem xét các yếu tố như thời gian còn lại cho đến khi hết hạn hợp đồng quyền chọn và tính biến động tại thời điểm hiện tại. Trường hợp 1: Khi giá của tài sản cơ sở tăng, Delta của phần quyền chọn tăng và Delta tổng thể di chuyển về một số dương. Cần có hợp đồng tương lai để phòng ngừa rủi ro một lần nữa và một phần vị thế bán khống nên được mở để tiếp tục bán khống hợp đồng tương lai để cân bằng Nhìn chung là Delta một lần nữa. (Trước khi tái cân bằng, Delta của quyền chọn lớn, trong khi Delta của hợp đồng tương lai tương đối nhỏ. Lợi nhuận biên của quyền chọn mua vượt quá mức lỗ biên của hợp đồng bán khống và toàn bộ danh mục đầu tư sẽ tạo ra lợi nhuận.)

Trường hợp 2: Khi giá của tài sản cơ sở giảm, Delta của phần quyền chọn cũng giảm và tổng thể Delta sẽ tiến tới một con số âm, đóng một phần các vị thế tương lai bán khống để cân bằng lại tổng thể Delta. (Trước khi tái cân bằng, Delta của quyền chọn là nhỏ, trong khi Delta của hợp đồng tương lai lại tương đối lớn. Khoản lỗ biên của quyền chọn mua nhỏ hơn lợi nhuận biên của hợp đồng bán khống, do đó toàn bộ danh mục đầu tư vẫn sẽ có lãi.)

Vì vậy, lý tưởng nhất là cả sự tăng và giảm của tài sản cơ bản đều sẽ tạo ra lợi nhuận, miễn là thị trường có biến động.

Tuy nhiên, các yếu tố khác cần xem xét bao gồm: giá trị thời gian, chi phí giao dịch, v.v.

Vậy nên tôi xin trích dẫn lời giải thích của chuyên gia Zhihu:

  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

Giải thích thiết kế chiến lược DDH

  • Đóng gói giao diện thị trường tổng hợp và thiết kế khung
  • Thiết kế UI Chiến lược
  • Thiết kế tương tác chiến lược
  • Thiết kế chức năng bảo hiểm tự động

Mã nguồn:

// 构造函数
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)
    }
}


Các thông số chiến lược: Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Địa chỉ chiến lược: https://www.fmz.com/strategy/265090

Chiến lược hoạt động:

Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Chiến lược phòng ngừa rủi ro động Delta của Deribit Option

Chiến lược này là một chiến lược giảng dạy, chủ yếu để học. Vui lòng sử dụng nó một cách thận trọng trong giao dịch thực tế.