Định nghĩa của các khoản đầu tư khác

Tác giả:Lydia., Tạo: 2022-11-01 17:49:07, Cập nhật: 2023-09-15 20:49:52

img

Chiến lược mà FMZ Quant đưa ra là Deribit Options Delta Dynamic Hedging, hay ngắn gọn là DDH (Dynamic Delta Hedging).

Để nghiên cứu giao dịch tùy chọn, chúng ta thường phải nắm vững các khái niệm sau:

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

· Khả năng tiếp xúc với các quyền chọn:

-Delta Nguy cơ hướng của một tùy chọn. Nếu Delta là +0.50, thì tùy chọn, thực hiện lợi nhuận hoặc lỗ khi giá đề tài tăng hoặc giảm, có thể được coi là 0.50 điểm. -Gamma Tăng tốc độ rủi ro theo hướng. Ví dụ, trong trường hợp các tùy chọn mua, do Gamma, Delta sẽ dần dần di chuyển từ +0,50 đến +1,00 khi giá tiếp tục tăng từ thời điểm giá đối tượng ở mức giá quyền lực. Khi bạn mua một tùy chọn, nếu giá đối tượng không thay đổi, cho mỗi ngày trôi qua, bạn trả phí được hiển thị trong số tiền Theta (Deribit được mệnh giá bằng USD). Khi bạn bán một tùy chọn, nếu giá đối tượng không thay đổi, bạn sẽ nhận được phí hiển thị trong số tiền Theta mỗi ngày. Khi bạn mua một lựa chọn, Vega là tích cực, tức là biến động dài. Khi biến động ngụ ý tăng lên, bạn kiếm được trên sự tiếp xúc Vega. Và ngược lại, khi bạn bán các lựa chọn, bạn kiếm được khi biến động ngụ ý giảm.

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

· Giải thích nguyên tắc DDH Hướng giao dịch trung lập rủi ro được đạt được bằng cách khớp Delta của các tùy chọn và tương lai. Sau khi có một vị trí trong một hợp đồng quyền chọn và cân bằng Delta với bảo hiểm tương lai, tổng thể Delta sẽ trở nên không cân bằng một lần nữa khi giá đối tượng chuyển động.

· Ví dụ: Khi chúng ta mua một lựa chọn mua, chúng ta nắm giữ một vị trí theo hướng dài tại thời điểm này. Tại thời điểm này, cần phải đi ngắn các hợp đồng tương lai để bảo hiểm Delta của các tùy chọn, đạt đến tổng thể Delta trung tính (0 hoặc gần 0). Hãy bỏ qua thời gian còn lại cho đến khi hết hạn hợp đồng quyền chọn, biến động và các yếu tố khác. Kịch bản 1: Khi giá của chủ đề tăng lên, Delta của các tùy chọn tăng lên, và tổng số Delta di chuyển đến một số tích cực, và tương lai cần phải bảo hiểm lại. (Trước khi tái cân bằng, Delta của các tùy chọn là lớn, trong khi tương lai tương đối nhỏ. Lợi nhuận biên của các tùy chọn mua vượt quá lỗ biên của các vị trí ngắn hợp đồng và toàn bộ danh mục đầu tư sẽ mang lại.)

Kịch bản 2: Khi giá của chủ đề giảm, phần quyền chọn của Delta giảm và tổng số Delta di chuyển đến một số âm, đóng một phần vị trí tương lai ngắn và đưa tổng số Delta vào cân bằng trở lại. (Trước khi tái cân bằng, tại thời điểm này, Delta của các tùy chọn là nhỏ, trong khi tương lai là tương đối lớn.

Do đó, trong tình trạng lý tưởng, sự gia tăng và giảm của chủ đề sẽ mang lại lợi ích miễn là thị trường biến động.

Tuy nhiên, cũng có những yếu tố cần xem xét: giá trị thời gian, chi phí giao dịch và các yếu tố khác.

Do đó, lời giải thích của một tên quan trọng trên Zhihu được trích dẫn:

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

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

· Khối hợp giao diện thị trường tổng hợp, thiết kế khuôn khổ · 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 che chắn tự động Mã nguồn:

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

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

Hoạt động chiến lược:

img

Chiến lược này là một chiến lược hướng dẫn, hướng đến học tập, xin vui lòng sử dụng nó một cách thận trọng trong bot thực sự.


Có liên quan

Thêm nữa