রিসোর্স লোড হচ্ছে... লোডিং...

ডেরিবিত অপশনের ডায়নামিক ডেল্টা হেজিং

লেখক:নিনাবাদাস, সৃষ্টিঃ ২০২২-০৪-২৪ ১১ঃ৩২ঃ৪৮, আপডেটঃ ২০২২-০৪-২৪ ১৫ঃ৫০ঃ৫৬

ডেরিবিত অপশনের ডায়নামিক ডেল্টা হেজিং

এ বার এফএমজেড কোয়ান্টের কৌশল হচ্ছেডেরিবিত অপশনের ডায়নামিক ডেল্টা হেজিং, সংক্ষেপে ডিডিএইচ।

অপশন ট্রেডিং এর অধ্যয়নের জন্য, আমাদের সাধারণত বিভিন্ন দিক থেকে ধারণাগুলি আয়ত্ত করতে হবেঃ

  • অপশন মূল্য নির্ধারণের মডেল; বি-এস মডেল; অপশন মূল্য নির্ধারণ করা হয় মূল্য নির্ধারণের মূল্য, ব্যবহারের মূল্য, সমাপ্তির দিন, অনুমোদিত) অস্থিরতা এবং ঝুঁকিহীন সুদের হার

  • অপশন ঝুঁকি এক্সপোজারঃ

    • ডেল্টা বিকল্পের দিকনির্দেশমূলক ঝুঁকি। যদি ডেল্টা মান +০.৫ হয়, তবে মূল মূল্যের বৃদ্ধি ও পতনের সময় বিকল্পের লাভ ও ক্ষতির কার্যকারিতা ০.৫০ স্পট হিসাবে বিবেচনা করা যেতে পারে।
    • গামা দিকনির্দেশমূলক ঝুঁকির ত্বরান্বিত গতি। উদাহরণস্বরূপ, একটি কল বিকল্প। গামার কারণে, যেখানে অন্তর্নিহিত মূল্য স্ট্রাইক মূল্যে রয়েছে, ডেল্টা দামের বৃদ্ধি প্রক্রিয়ায় +0.50 থেকে +1.00 এর কাছাকাছি আসবে।
    • থিটা সময় ক্ষয়. যখন আপনি বিকল্প কিনতে, যদি অন্তর্নিহিত মূল্য ধ্রুবক থাকে, প্রতিটি পেরিয়ে যাওয়া দিন সঙ্গে, আপনি থিটা মান দ্বারা প্রদর্শিত একটি চার্জ দিতে হবে (Deribit ডলার মূল্য নির্ধারণ করা হয়). যখন আপনি অপশন বিক্রি করেন, এবং মূল মূল্য ধ্রুবক থাকে, প্রতিটি পেরিয়ে যাওয়া দিনের সাথে, আপনি একটি ফি পাবেন Theta মান দ্বারা প্রদর্শিত।
    • ভেগা অস্থিরতা এক্সপোজার। যখন আপনি বিকল্প কিনবেন, তখন ভেগা একটি ইতিবাচক মান হিসাবে প্রকাশ করা হয়, যথা দীর্ঘ নিহিত অস্থিরতা। যখন নিহিত অস্থিরতা বৃদ্ধি পায়, আপনি ভেগাতে প্রকাশ করে মুনাফা করতে পারেন। বিপরীত পরিস্থিতিও ঠিক তেমনই। যখন আপনি বিকল্প বিক্রি করেন, তখন নিহিত অস্থিরতা হ্রাস পায় এবং আপনার মুনাফা হবে।

ডিডিএইচ কৌশল ব্যাখ্যাঃ

  • ডিডিএইচ নীতি ব্যাখ্যা বিকল্প এবং ফিউচারগুলির ডেল্টা ভারসাম্য বজায় রেখে, ট্রেডিং দিকের ঝুঁকি নিরপেক্ষতা অর্জন করা হয়। যেহেতু বিকল্প ডেল্টা অন্তর্নিহিত মূল্যের পরিবর্তনের সাথে পরিবর্তিত হয়, তাই ফিউচার এবং স্পটগুলির ডেল্টা অপরিবর্তিত থাকবে। একটি বিকল্প চুক্তি অবস্থান ধরে রাখার পরে এবং ডেল্টা হেজিং এবং ভারসাম্য বজায় রাখার জন্য ফিউচার ব্যবহার করার পরে, অন্তর্নিহিত মূল্য পরিবর্তন হিসাবে, সামগ্রিক ডেল্টা আবার ভারসাম্যহীন প্রদর্শিত হবে। বিকল্প অবস্থান এবং ফিউচার অবস্থানের সংমিশ্রণের জন্য, ডেল্টা ভারসাম্য বজায় রাখতে ধ্রুবক গতিশীল হেজিং প্রয়োজন।

    উদাহরণস্বরূপঃ যখন আমরা একটি কল অপশন কিনি, তখন আমাদের একটি উত্থানমুখী অবস্থান থাকে। এই সময়ে, সামগ্রিক ডেল্টা নিরপেক্ষতা (0 বা 0 এর কাছাকাছি) অর্জনের জন্য বিকল্প ডেল্টা হেজ করার জন্য ফিউচারগুলি সংক্ষিপ্ত করা প্রয়োজন। চলুন জেনে নেওয়া যাক যে কোন ফ্যাক্টর, যেমন মেয়াদ শেষ হওয়ার দিন এবং অপশন চুক্তির অন্তর্নিহিত অস্থিরতা। ১ম দৃশ্যকল্পঃ যখন অন্তর্নিহিত মূল্য বৃদ্ধি পায়, তখন বিকল্প ডেল্টা বৃদ্ধি পায় এবং সামগ্রিক ডেল্টা একটি ইতিবাচক সংখ্যায় চলে যায়। ফিউচারগুলি আবার হেজিংয়ের জন্য প্রয়োজন হয় এবং কিছু শর্ট পজিশনগুলি শর্ট ফিউচারে চালিয়ে যাওয়ার জন্য খোলা হয়, যাতে সামগ্রিক ডেল্টা আবার ভারসাম্যপূর্ণ হয়। (পুনরায় ভারসাম্য বজায় রাখার আগে, বিকল্প ডেল্টা বড়, ফিউচার ডেল্টা তুলনামূলকভাবে ছোট, কল অপশনের সীমান্ত লাভ শর্ট কন্ট্রাক্টের সীমান্ত ক্ষতির চেয়ে বেশি এবং পুরো পোর্টফোলিও লাভ করবে) । দ্বিতীয় দৃশ্যকল্পঃ যখন মূল মূল্য কমে যায়, তখন বিকল্প ডেল্টা কমে যায় এবং সামগ্রিক ডেল্টা নেতিবাচক সংখ্যায় চলে যায় এবং কিছু শর্ট ফিউচার পজিশন বন্ধ হয়ে যায় যাতে সামগ্রিক ডেল্টা ভারসাম্য আবার তৈরি হয়। (পুনরায় ব্যালেন্সিংয়ের আগে, বিকল্প ডেল্টা ছোট, ফিউচার ডেল্টা তুলনামূলকভাবে বড়, কল অপশনের সীমান্ত ক্ষতি শর্ট কন্ট্রাক্টের সীমান্ত লাভের চেয়ে কম এবং পুরো পোর্টফোলিও এখনও লাভ করবে) ।

    অতএব, আদর্শভাবে, মূলধনের উত্থান এবং পতন উভয়ই মুনাফা নিয়ে আসে, যতক্ষণ না বাজারটি ওঠানামা করে।

    তবে, অন্যান্য কারণগুলি বিবেচনা করা দরকারঃ সময় মূল্য, ট্রেডিং খরচ এবং অন্যান্য।

    তাই, আমি জিহু থেকে একজন মাস্টারের ব্যাখ্যা উদ্ধৃত করলাম:

    গামা স্কেলপিং এর ফোকাস ডেল্টা নয়, গতিশীল ডেল্টা হেজিং প্রক্রিয়াতে অন্তর্নিহিত মূল্য ঝুঁকি এড়ানোর একটি উপায়। গামা স্কেলপিং আলফায় ফোকাস করে। আলফা স্টক নির্বাচনের আলফা নয়। এখানে, আলফা = গামা / থিটা, অর্থাৎ ইউনিট থিটার সময় ক্ষয় দ্বারা গামা কতটা বিনিময় করা হয়। এটিই বিষয়। ভাসমান মুনাফা উভয়ই বৃদ্ধি এবং পতনের সংমিশ্রণ তৈরি করা সম্ভব, অবশ্যই সময় ক্ষয় সহ, এবং সমস্যাটি খরচ কর্মক্ষমতা অনুপাত। লেখক: Xu Zhe; মূল নিবন্ধের লিঙ্কঃhttps://www.zhihu.com/question/51630805/answer/128096385

ডিডিএইচ কৌশল নকশা

  • সমষ্টিগত বাজার ইন্টারফেস, কাঠামোগত নকশা।
  • কৌশল ইউআই ডিজাইন;
  • কৌশলগত ইন্টারঅ্যাকশন ডিজাইন;
  • স্বয়ংক্রিয় হেজিং ফাংশন ডিজাইন।

সোর্স কোডঃ

// constructor 
function createManager(e, subscribeList, msg) {
	var self = {}
    self.supportList = ["Futures_Binance", "Huobi", "Futures_Deribit"]  // from the supported platforms

    // 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 as: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // the market data in need; define the data format as: {bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null 
    self.pos = null 

    // initialization function 
    self.init = function() { 
    	// judge whether the platform is supported 
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    self.setBase = function(base) {
        // switch base address, used to switch to the simulated bot 
        self.e.SetBase(base)
        Log(self.name, self.label, "switch to simulated bot:", base)
    }

    // judge the 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 {
            // arrange 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
    }
    
    // return the positon 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 : []
        }
        /* the position data format 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])
                }
                // traverse 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 
    }

    // initialize 
    self.init()
	return self 
}


function main() {
    // initialize, and vacuum logs
    if(isResetLog) {
    	LogReset(1)
    }

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

    // switch to the simulated 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
        }

        // interaction 
        var cmd = GetCommand()
        if(cmd) {
            // process interaction 
            Log("interactive command:", cmd)
            var arr = cmd.split(":")
            // cmdClearLog 
            if(arr[0] == "setContractType") {
                // parseFloat(arr[1])
                m1.e.SetContractType(arr[1])
                Log("exchanges[0] sets contract:", 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("executed price:", price, "executed amount:", amount, "executed 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("executed price:", price, "executed amount:", amount, "executed direction:", arr[0])
            } else if (arr[0] == "setHedgeDeltaStep") {
                hedgeDeltaStep = parseFloat(arr[1])
                Log("set hedgeDeltaStep:", hedgeDeltaStep)
            } 
        }
        
        // obtain futures contract price 
        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) {
                // delta value is more than 0, hedge futures and make short                   
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.ask1, -1)                
                if (amount > 10) {
                    Log("exceeding the hedging threshold value, the current total delta:", sumDelta, "call futures")
                    m2.e.SetContractType("BTC-PERPETUAL")                    
                    m2.e.SetDirection("buy")
                    m2.e.Buy(-1, amount)
                } else {
                	hedgeMsg += ", hedging order amount is less than 10"
                }
            } else {
                // delta value is less than 0, hedge futures and make long
                var amount = _N(Math.abs(sumDelta) * perpetualTicker.bid1, -1)
                if (amount > 10) {
                    Log("exceeding the hedging threshold value, the current total delta:", sumDelta, "put futures")
                    m2.e.SetContractType("BTC-PERPETUAL")
                    m2.e.SetDirection("sell")
                    m2.e.Sell(-1, amount)
                } else {
                	hedgeMsg += ", hedging order amount is less than 0"
                }
            }
        }

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


কৌশলগত পরামিতি:img

কৌশল ঠিকানাঃhttps://www.fmz.com/strategy/265090

কৌশল অপারেশন:

img

img

কৌশলটি একটি টিউটোরিয়াল, মূলত অধ্যয়নের জন্য ব্যবহৃত হয়, তাই দয়া করে একটি বটে ব্যবহারে সতর্ক থাকুন।


আরো