
BS, GAMMA, DELTA, THETA, VEGA
В мире количественных сделок существует, казалось бы, парадокс: опционы могут быть стабильно прибыльными, когда розничные инвесторы беспокоятся о рыночных колебаниях. В чем же секрет? Ответ заключается в сегодняшней стратегии снятия шерсти с лошади, основанной на модели Блэка-Шоулза.
В основе этой стратегии лежит идея моделирования рынка опционов: создание портфеля опционов с синтетической длинной страдддл, использование эффекта паука для динамического хеджирования, чтобы получить прибыль от арбитража волатильности. Проще говоря, это значит, что математика работает для нас, а не борьба с рыночными эмоциями.
Модель Блэка-Шоулза - это не просто академическая теория, это фундамент современного ценообразования опционов. В этой стратегии мы обращаем внимание на пять греческих букв:
Delta(Δ): измерение чувствительности цены опционов к изменениям цены активов на их индексе. Для портфеля трансформерных опционов изменения в Дельте дают нам сигналы хеджирования.
Gamma(Γ):изменение дельты, что является основой стратегии. Положительная конь означает, что дельта увеличивается, когда цена растет, а дельта уменьшается, когда цена падает, что создает для нас возможность “покупать низко и продавать высоко”.
Theta(Θ)Временная девальвация - это то, что нам нужно преодолеть. Только тогда, когда реальная волатильность превышает скрытую волатильность, прибыль от торговли Puma может покрыть временную девальвацию.
Vega(ν)В то же время, в некоторых странах, например, в Китае, в некоторых странах, например, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае.
С точки зрения реализации кода, стратегия рассчитывает эти греческие буквы с помощью стандартного Black-Scholes формулы и обеспечивает точность вычислений с помощью стандартной функции правильного распределения (с использованием приближения Абрамовича и Стегуна).
Стратегия включает в себя три уровня фильтрации сигналов:
Первый уровень: идентификация системы волатильности Судить о текущей среде волатильности, сравнивая историческую волатильность с соотношением имплицитной волатильности. Когда историческая волатильность / имплицитная волатильность > 1.2, это указывает на то, что рынок фактически колеблется больше, чем ожидалось в ценообразовании опционов, что является идеальной средой для снятия шерсти с лошади.
Второй уровень: деколтеры для кобылы Когда движение цены превышает определенное кратное ATR, вызывается сигнал торговли. Эта конструкция является хитрой: она гарантирует, что мы будем совершать хеджируемые сделки только тогда, когда движение цены будет достаточным, чтобы избежать чрезмерной торговли.
Третий уровень: дельта-сберегательная зона Когда чистый дельта-отклонение от нейтральной позиции в портфеле трансграничных опционов превышает установленную пороговую величину, создается сигнал хеджирования. Это имитирует поведение маркетологов, поддерживающих нейтральную позицию дельта.
По логическому анализу стратегии, наиболее вероятные сценарии использования включают:
Высокая волатильностьВ то время как реальная волатильность рынка постоянно превышает скрытую волатильность, сделки с Puma могут приносить дополнительную прибыль.
Возвращение в трендовую ситуациюКраткосрочные реверсы в сильных трендах часто создают хорошие возможности для отколов.
Воздействие событийВ этом случае, как отмечается в статье, “прибыль и убыток” - это “положение, при котором убыток и убыток прибыли, прибыли и убытка прибыли, прибыль и убыток прибыли, прибыль и убыток прибыли, прибыль и убыток при прибыли, прибыль и убыток при прибыли”.
Следует отметить, что стратегия имеет ограниченную эффективность на рынках с низким уровнем волатильности, поскольку движения цены недостаточны для запуска эффективного торгового сигнала.
Управление рисками в этой стратегии отражает уровень профессиональной количественной торговли:
Динамическое управление позициями: Корректировка размеров позиций в зависимости от волатильности, уменьшение позиций при высокой волатильности и увеличение позиций при низкой волатильности, что в значительной степени отличается от традиционного управления фиксированными позициями.
Многоуровневые механизмы удержанияСроки выхода из сделки: в сочетании с множественными ATR, максимальной защитой от вывода и механизмом выхода, основанным на временных значениях.
Ограничение совместной позиции: контролировать общий риск, ограничивая максимальное количество одновременных позиций.
Инновации:
Потенциальные ограничения:
На основе глубокого анализа кода я предлагаю:
Эта стратегия демонстрирует привлекательность количественной торговли: математические модели упрощают сложное поведение рынка в исполняемые правила торговли. Хотя это не гарантирует, что каждая сделка будет прибыльной, в долгосрочной перспективе это дает нам торговую структуру с положительной ожидаемой стоимостью.
Эта стратегия, несомненно, является отличным примером для количественных трейдеров, которые хотят глубже понять сущность торговли опционами. Она не только показывает, как перевести теорию на практику, но, что более важно, она раскрывает, как профессиональные трейдеры думают о рынке: не прогнозируя направление, а управляя риском, пусть вероятности работают на нас.
/*backtest
start: 2025-01-04 00:00:00
end: 2026-01-02 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy("Black-Scholes Gamma Scalping Strategy",
overlay=true,
default_qty_type=strategy.percent_of_equity,
default_qty_value=10,
pyramiding=5)
// ============================================================================
// STRATEGY CONCEPT:
// This strategy simulates gamma scalping - a volatility arbitrage technique
// used by options market makers. The core idea:
//
// 1. We model a synthetic long straddle position (long call + long put)
// 2. The straddle has positive gamma, meaning delta changes as price moves
// 3. We continuously delta-hedge by trading the underlying
// 4. If realized volatility > implied volatility, hedging profits exceed theta decay
// 5. Trading signals generated when price moves create hedging opportunities
//
// The Black-Scholes equation provides: Delta, Gamma, Theta, Vega
// ============================================================================
// === INPUT PARAMETERS ===
string grp_opt = "Option Parameters"
strike_offset_pct = input.float(0.0, "Strike Offset from Current Price %", group=grp_opt, step=0.5)
days_to_expiry = input.int(30, "Days to Expiration", group=grp_opt, minval=1, maxval=365)
implied_vol = input.float(0.25, "Implied Volatility (Annual)", group=grp_opt, minval=0.05, maxval=2.0, step=0.01)
risk_free_rate = input.float(0.05, "Risk-Free Rate (Annual)", group=grp_opt, step=0.001)
dividend_yield = input.float(0.0, "Dividend Yield (Annual)", group=grp_opt, step=0.001)
string grp_vol = "Volatility Analysis"
hist_vol_period = input.int(20, "Historical Volatility Period", group=grp_vol, minval=5)
vol_ratio_threshold = input.float(1.2, "HV/IV Ratio for Long Vol Signal", group=grp_vol, minval=1.0, step=0.05)
vol_ratio_short = input.float(0.8, "HV/IV Ratio for Short Vol Signal", group=grp_vol, minval=0.1, maxval=1.0, step=0.05)
string grp_trade = "Trading Parameters"
gamma_scalp_threshold = input.float(0.5, "Gamma Scalp Threshold (ATR mult)", group=grp_trade, minval=0.1, step=0.1)
hedge_band_pct = input.float(2.0, "Delta Hedge Band %", group=grp_trade, minval=0.5, step=0.5)
use_vol_filter = input.bool(true, "Use Volatility Regime Filter", group=grp_trade)
max_positions = input.int(3, "Max Concurrent Positions", group=grp_trade, minval=1, maxval=10)
string grp_risk = "Risk Management"
stop_loss_atr_mult = input.float(2.0, "Stop Loss (ATR Multiple)", group=grp_risk, minval=0.5, step=0.5)
take_profit_atr_mult = input.float(3.0, "Take Profit (ATR Multiple)", group=grp_risk, minval=1.0, step=0.5)
max_drawdown_pct = input.float(15.0, "Max Drawdown % to Pause Trading", group=grp_risk, minval=5.0, step=1.0)
// ============================================================================
// BLACK-SCHOLES MATHEMATICAL FUNCTIONS
// ============================================================================
// --- Standard Normal CDF (Abramowitz & Stegun approximation) ---
norm_cdf(float x) =>
float result = 0.0
if na(x)
result := na
else
float ax = math.abs(x)
if ax > 10
result := x > 0 ? 1.0 : 0.0
else
float t = 1.0 / (1.0 + 0.2316419 * ax)
float d = 0.3989422804 * math.exp(-0.5 * x * x) // 1/sqrt(2*pi) * exp(-x²/2)
float p = t * (0.31938153 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429))))
result := x >= 0 ? 1.0 - d * p : d * p
result
// --- Standard Normal PDF ---
norm_pdf(float x) =>
na(x) ? na : 0.3989422804 * math.exp(-0.5 * x * x)
// --- Black-Scholes d1 and d2 ---
bs_d1(float S, float K, float r, float q, float sigma, float T) =>
T > 0 and sigma > 0 ? (math.log(S / K) + (r - q + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T)) : na
bs_d2(float S, float K, float r, float q, float sigma, float T) =>
float d1 = bs_d1(S, K, r, q, sigma, T)
na(d1) ? na : d1 - sigma * math.sqrt(T)
// --- Greeks ---
// Call Delta
call_delta(float S, float K, float r, float q, float sigma, float T) =>
T <= 0 ? (S >= K ? 1.0 : 0.0) : math.exp(-q * T) * norm_cdf(bs_d1(S, K, r, q, sigma, T))
// Put Delta
put_delta(float S, float K, float r, float q, float sigma, float T) =>
T <= 0 ? (S <= K ? -1.0 : 0.0) : math.exp(-q * T) * (norm_cdf(bs_d1(S, K, r, q, sigma, T)) - 1)
// Gamma (same for call and put)
option_gamma(float S, float K, float r, float q, float sigma, float T) =>
if T <= 0 or sigma <= 0
0.0
else
float d1 = bs_d1(S, K, r, q, sigma, T)
math.exp(-q * T) * norm_pdf(d1) / (S * sigma * math.sqrt(T))
// ============================================================================
// HISTORICAL VOLATILITY CALCULATION
// ============================================================================
// Calculate annualized historical volatility
calc_historical_vol(int period) =>
float log_return = math.log(close / close[1])
float std_dev = ta.stdev(log_return, period)
// Annualization factor based on timeframe
float periods_per_year = switch
timeframe.isdaily => 365.0
timeframe.isweekly => 52.0
timeframe.ismonthly => 12.0
=> 365.0 * 390.0 / (timeframe.isminutes ? timeframe.multiplier : 1440.0)
nz(std_dev * math.sqrt(periods_per_year), 0.20)
hist_vol = calc_historical_vol(hist_vol_period)
// ============================================================================
// STRATEGY CALCULATIONS
// ============================================================================
// Dynamic strike price (ATM or offset)
float atm_strike = math.round(close / syminfo.mintick) * syminfo.mintick
float strike_price = atm_strike * (1 + strike_offset_pct / 100)
// Time to expiration in years
float tau = days_to_expiry / 365.0
// Calculate Greeks for synthetic straddle (1 call + 1 put at same strike)
float c_delta = call_delta(close, strike_price, risk_free_rate, dividend_yield, implied_vol, tau)
float p_delta = put_delta(close, strike_price, risk_free_rate, dividend_yield, implied_vol, tau)
float straddle_delta = c_delta + p_delta // Net delta of straddle
float gamma = option_gamma(close, strike_price, risk_free_rate, dividend_yield, implied_vol, tau)
float straddle_gamma = 2 * gamma // Straddle has 2x gamma
// Volatility ratio: Historical / Implied
float vol_ratio = hist_vol / implied_vol
// ATR for position sizing and stops
float atr = ta.atr(14)
// ============================================================================
// TRADING SIGNALS
// ============================================================================
// --- Signal 1: Volatility Regime ---
// Long volatility when realized > implied (gamma scalping profitable)
// Short volatility when realized < implied (collect theta)
bool long_vol_regime = vol_ratio > vol_ratio_threshold
bool short_vol_regime = vol_ratio < vol_ratio_short
// --- Signal 2: Gamma Scalp Trigger ---
// When price moves significantly, delta changes. We trade to capture this.
float price_move = close - close[1]
float move_threshold = atr * gamma_scalp_threshold
bool significant_up_move = price_move > move_threshold
bool significant_down_move = price_move < -move_threshold
// --- Signal 3: Delta Hedge Bands ---
// Trade when straddle delta deviates from neutral
float delta_band = hedge_band_pct / 100
bool delta_long_signal = straddle_delta < -delta_band // Need to buy to hedge
bool delta_short_signal = straddle_delta > delta_band // Need to sell to hedge
// --- Combined Entry Signals ---
bool vol_filter = use_vol_filter ? long_vol_regime : true
// Long entry: Price dropped significantly OR delta needs positive hedge
bool long_entry = vol_filter and (significant_down_move or delta_long_signal)
// Short entry: Price rose significantly OR delta needs negative hedge
bool short_entry = vol_filter and (significant_up_move or delta_short_signal)
// ============================================================================
// RISK MANAGEMENT
// ============================================================================
// Track equity for drawdown protection
var float equity_peak = strategy.initial_capital
equity_peak := math.max(equity_peak, strategy.equity)
float current_drawdown = (equity_peak - strategy.equity) / equity_peak * 100
bool drawdown_exceeded = current_drawdown > max_drawdown_pct
// Position counting
int open_trades = strategy.opentrades
// ============================================================================
// STRATEGY EXECUTION
// ============================================================================
// Stop loss and take profit levels
float long_stop = close - atr * stop_loss_atr_mult
float long_target = close + atr * take_profit_atr_mult
float short_stop = close + atr * stop_loss_atr_mult
float short_target = close - atr * take_profit_atr_mult
// Entry conditions
bool can_trade = not drawdown_exceeded and open_trades < max_positions
if can_trade
// Long entries
if long_entry and strategy.position_size <= 0
strategy.entry("GammaLong", strategy.long,
comment="Δ:" + str.tostring(straddle_delta, "#.##") + " Γ:" + str.tostring(straddle_gamma, "#.###"))
strategy.exit("LongExit", "GammaLong", stop=long_stop, limit=long_target)
// Short entries
if short_entry and strategy.position_size >= 0
strategy.entry("GammaShort", strategy.short,
comment="Δ:" + str.tostring(straddle_delta, "#.##") + " Γ:" + str.tostring(straddle_gamma, "#.###"))
strategy.exit("ShortExit", "GammaShort", stop=short_stop, limit=short_target)
// Exit on extreme conditions
if drawdown_exceeded
strategy.close_all(comment="Drawdown Protection")
// Exit if volatility regime shifts against us
if use_vol_filter and short_vol_regime and strategy.position_size != 0
strategy.close_all(comment="Vol Regime Shift")
// ============================================================================
// VISUALIZATIONS
// ============================================================================
// Plot straddle delta
plot(straddle_delta, "Straddle Delta", color=color.blue, linewidth=2)
hline(0, "Zero Delta", color=color.gray, linestyle=hline.style_dashed)
hline(delta_band, "Upper Band", color=color.red, linestyle=hline.style_dotted)
hline(-delta_band, "Lower Band", color=color.green, linestyle=hline.style_dotted)
// Background color for volatility regime
bgcolor(long_vol_regime ? color.new(color.green, 90) : short_vol_regime ? color.new(color.red, 90) : na)
// Entry signals
plotshape(long_entry and can_trade, "Long Signal", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(short_entry and can_trade, "Short Signal", shape.triangledown, location.abovebar, color.red, size=size.small)
// ============================================================================
// ALERTS
// ============================================================================
alertcondition(long_entry and can_trade, "Gamma Long Entry", "BS Strategy: Long entry signal - Delta={{straddle_delta}}")
alertcondition(short_entry and can_trade, "Gamma Short Entry", "BS Strategy: Short entry signal - Delta={{straddle_delta}}")
alertcondition(drawdown_exceeded, "Drawdown Alert", "BS Strategy: Max drawdown exceeded - trading paused")