資源の読み込みに... 荷物...

負債の負債の負債の負債の負債の負債の負債の負債の負債の負債

作者: リン・ハーンニナバダス作成日:2022年4月24日 11:32:48 更新日:2022年4月24日 15:50:56

負債の負債の負債の負債の負債の負債の負債の負債の負債の負債

このとき FMZ Quant がもたらした戦略は負債の負債の負債の負債の負債の負債の負債の負債の負債の負債短縮してDDH.

オプション取引の勉強のために,私たちは通常,いくつかの側面で概念をマスターする必要があります:

  • オプションの価格設定モデル B-Sモデル オプション価格は, 底値, 実行価格, 期限までの日数, (暗黙の) 変動率,および 非リスク金利率に基づいて決定される.

  • オプションリスクに対する負債:

    • デルタ オプションの方向性リスク.デルタ値が +0.5である場合,底盤価格の上昇と減少時のオプションの利益と損失のパフォーマンスは0.50スポットとみなすことができます.
    • Gamma 方向リスクの加速速度.例えば,コールオプション.Gamma のために,底辺価格がストライク価格である場所から,デルタは価格の上昇過程で+0.50から+1.00に近づきます.
    • Theta 時間の衰退.オプションを購入する際には,当たる価格が恒定である場合,毎日の経過とともに,Theta値 (DeribitはUSDで定価) によって表示される料金を支払う. 毎日の流れで,Theta値で表示される手数料を受け取ります. 価格が上昇するにつれて,
    • ベーガ 不安定性露出. オプションを購入すると,ベーガはポジティブな値,すなわち長期暗黙の不安定性として表現されます.暗黙の不安定性が増加すると,ベーガに露出することで利益を得ることができます.逆の状況も同様です. オプションを売ると,暗黙の不安定性が低下し,利益を得ることができます.

DDH戦略説明:

  • DDH 原則の説明 オプションと先物間のデルタをバランスすることで,取引方向のリスク中立性が達成される.オプションデルタが底辺の価格の変化とともに変化するので,先物と先物間のデルタは変化しない. オプション・コントラクトのポジションを保持し,フューチャーを使用してデルタをヘッジしバランスすると,底下の価格が変化すると,全体的なデルタは再び不均衡に見えます.オプション・ポジションとフューチャー・ポジションの組み合わせでは,デルタをバランスするために恒常的なダイナミック・ヘッジが必要です.

    例えば: コールオプションを購入すると,我々は上昇傾向にあります.この時点で,全体的なデルタ中立性 (0または0に近い) を達成するために,オプションデルタをヘッジするために先物をショートする必要があります. 期日やオプション契約の暗黙の変動などの要因を無視しましょう. シナリオ1: 基本価格が上昇すると,オプションデルタは増加し,全体的なデルタは正数に移動します. 再びヘッジするために先物が必要であり,短期先物への継続のためにいくつかのショートポジションが開かれ,全体的なデルタが再びバランスになります. (リバランスする前に,オプションデルタは大きい,フューチャーデルタは比較的小さい,コールオプションの限界利益はショートコントラクトの限界損失を上回り,ポートフォリオ全体が利益を得る) シナリオ2: 基本価格が下がると オプションデルタが下がり 全体のデルタがマイナス数値に移動し 短期先物ポジションが閉じて 全体のデルタバランスが戻ります (再バランス前にオプションデルタは小さいし,フューチャーデルタは比較的大きいし,コールオプションの限界損失はショート契約の限界利益より小さいし,ポートフォリオ全体は利益を得る)

    だから理想的には 市場が変動する限り 底付け株の上昇と減少は 両方とも利益をもたらすのです

    しかし,他の要因も考慮する必要があります. 時間価値,取引コストなどです.

    湖の師匠の説明を引用しました

    ガンマ・スカルピングの焦点はデルタではなく,ダイナミック・デルタ・ヘジングは,その過程で潜在的価格リスクを避けるための方法に過ぎない.ガンマ・スカルピングはアルファに焦点を当てている.アルファは株式選択のアルファではない.ここで,アルファ=ガンマ/セータ,つまり,ユニットセータの時間衰退によってガンマがどのくらい交換されるか.それがポイントである.浮動利益の両方で上昇と減少の組み合わせを構築することは可能であり,確実に時間衰退に伴い,問題はコストパフォーマンスの比率である. 著者: Xu Zhe 原記事リンク:https://www.zhihu.com/question/51630805/answer/128096385

DDH戦略設計

  • 総合市場インターフェースの封筒化 構造設計
  • 戦略 UI デザイン
  • 戦略の相互作用設計
  • 自動ヘッジ機能の設計

ソースコード:

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

戦略はチュートリアルで,主に勉強のために使用されますので,ボットで使用する際には注意してください.


もっと