← 모든 예제
예제 39
Gamma flip cross
the gamma flip: the strike where the options market's net gamma changes sign. Above it dealers damp moves, below it they feed
- 분류
- Host: 터미널의 데이터와 엔진 필요
- 권한
- market.readworkspace.readworkspace.write
- 실행하기 전에
- a terminal connected to a backend that reads the options chain; a BTC or ETH chart
- 하는 일
- sounds the alert chime when the flip was crossed. Reads only.
- 실행 방법
- grant market.read, workspace.read and workspace.write, Run. Attach it to "Every N seconds" (300 s) to keep watch.
- 언어
>=0.1.1, <0.2.0- 호스트
>=0.1.7, <0.2.0- 필요한 것
- market >=0.1.3, <0.2.0options >=0.1.0, <0.2.0workspace >=0.1.0, <0.2.0alert >=0.1.0, <0.2.0event >=0.1.0, <0.2.0
소스
// Purpose: the gamma flip: the strike where the options market's net gamma changes sign. Above it dealers damp moves, below it they feed // them. Reports which side of the flip the last close is on, how far, how much the market moved in the last hour -- and raises an alert when // the close crossed it in the last fifteen minutes. **Needs the flip at both ends of the window**: when the options chain was not read at // either (or has no flip), it says so and reports no crossing, because a flip carried over from an old chain is a level that is not there. // Category: host // Permissions: market.read, workspace.read, workspace.write // Preconditions: a terminal connected to a backend that reads the options chain; a BTC or ETH chart // Side effects: sounds the alert chime when the flip was crossed. Reads only. // Run: grant market.read, workspace.read and workspace.write, Run. Attach it to "Every N seconds" (300 s) to keep watch. lang ">=0.1.1, <0.2.0"; host "ttt" ">=0.1.7, <0.2.0"; requires "market" ">=0.1.3, <0.2.0"; requires "options" ">=0.1.0, <0.2.0"; requires "workspace" ">=0.1.0, <0.2.0"; requires "alert" ">=0.1.0, <0.2.0"; requires "event" ">=0.1.0, <0.2.0"; import std.text; import std.ind; import std.stats; fn main() -> Result<Unit, Error> { let chart = workspace.active_chart().expect("no chart is open"); let asset = if text.starts_with(chart.symbol, "ETH") { "ETH" } else { "BTC" }; let now = event.current().time; let candles = market.chart_candles(chart.symbol, "5m", 13)?; if candles.len() < 4 { print("no reading: fewer than four closed five-minute bars"); return Ok(()); } let last = candles.last().expect("a bar"); let before = candles.get(candles.len() - 4).expect("a bar"); let gamma_now = options.gamma_at(asset, now)?; match gamma_now.unknown { Some(why) => { print("no reading: " + why); return Ok(()); } None => {} } if gamma_now.flip.is_none() { print(asset + ": the chain has no flip -- net gamma does not change sign within the listed strikes"); return Ok(()); } let flip = gamma_now.flip.expect("checked above"); // The flip is in USD (the options' strikes) and the candles in USDT: the language never converts between them, so the comparison is of // the numbers, which takes USDT as worth one USD. Said here because it is an assumption, and a depeg is when it fails. let level = flip.amount(); let above = last.close.amount() > level; let distance = to_float(last.close.amount() / level - 1.0) * 100.0; print(chart.symbol + " closed at " + to_string(last.close) + ", " + to_string(distance) + " % " + (if above { "above" } else { "below" }) + " the flip at " + to_string(flip) + (if above { " (dealers damp moves)" } else { " (dealers feed moves)" })); // Realized volatility of the last twelve bars (or the bars there are), per bar. let mut closes: List<Float> = []; for c in candles { closes.push(to_float(c.close.amount())); } match stats.stdev(ind.known(ind.log_returns(closes))) { Some(vol) => print("realized volatility of the last " + to_string(candles.len()) + " bars: " + to_string(vol * 100.0) + " % per bar"), None => print("realized volatility: too few bars"), } // The flip fifteen minutes ago, from the chain the capture read then: unknown stays unknown. let gamma_then = options.gamma_at(asset, now - 15min)?; match gamma_then.unknown { Some(why) => { print("no crossing verdict: no chain fifteen minutes ago (" + why + ")"); return Ok(()); } None => {} } if gamma_then.flip.is_none() { print("no crossing verdict: the chain fifteen minutes ago had no flip"); return Ok(()); } let flip_then = gamma_then.flip.expect("checked above"); let above_then = before.close.amount() > flip_then.amount(); if above != above_then { alert.notify("Gamma flip crossed", chart.symbol + " went " + (if above { "above" } else { "below" }) + " the gamma flip (" + to_string(flip) + ")")?; print("CROSSED the flip in the last fifteen minutes: " + (if above_then { "above" } else { "below" }) + " -> " + (if above { "above" } else { "below" })); } else { print("no crossing in the last fifteen minutes"); } return Ok(()); }