Skip to content

Commit f392b95

Browse files
committed
Add Options Greeks Viz, Execution Algos, and C++ Microbenchmark
1 parent b4b0021 commit f392b95

File tree

4 files changed

+267
-5
lines changed

4 files changed

+267
-5
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Visualizing Options Greeks (Black-Scholes)\n",
8+
"\n",
9+
"Understanding the sensitivity of options to underlying parameters is crucial for risk management.\n",
10+
"\n",
11+
"**The Greeks:**\n",
12+
"* **Delta ($\Delta$):** Rate of change of option price with respect to the underlying price.\n",
13+
"* **Gamma ($\Gamma$):** Rate of change of Delta (convexity).\n",
14+
"* **Vega ($\nu$):** Sensitivity to Volatility.\n",
15+
"* **Theta ($\Theta$):** Time decay.\n"
16+
]
17+
},
18+
{
19+
"cell_type": "code",
20+
"execution_count": null,
21+
"metadata": {},
22+
"outputs": [],
23+
"source": [
24+
"import numpy as np\n",
25+
"import matplotlib.pyplot as plt\n",
26+
"from scipy.stats import norm\n",
27+
"\n",
28+
"# Black-Scholes Formulas\n",
29+
"def black_scholes_greeks(S, K, T, r, sigma, option_type='call'):\n",
30+
" d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))\n",
31+
" d2 = d1 - sigma * np.sqrt(T)\n",
32+
" \n",
33+
" if option_type == 'call':\n",
34+
" delta = norm.cdf(d1)\n",
35+
" theta = (- (S * norm.pdf(d1) * sigma) / (2 * np.sqrt(T)) - r * K * np.exp(-r * T) * norm.cdf(d2))\n",
36+
" else:\n",
37+
" delta = norm.cdf(d1) - 1\n",
38+
" theta = (- (S * norm.pdf(d1) * sigma) / (2 * np.sqrt(T)) + r * K * np.exp(-r * T) * norm.cdf(-d2))\n",
39+
"\n",
40+
" gamma = norm.pdf(d1) / (S * sigma * np.sqrt(T))\n",
41+
" vega = S * norm.pdf(d1) * np.sqrt(T)\n",
42+
" \n",
43+
" return delta, gamma, vega, theta\n",
44+
"\n",
45+
"# Parameters\n",
46+
"K = 100\n",
47+
"r = 0.05\n",
48+
"sigma = 0.2\n",
49+
"T = 0.5 # 6 months\n",
50+
"\n",
51+
"# Spot range\n",
52+
"spots = np.linspace(50, 150, 100)\n",
53+
"deltas, gammas, vegas, thetas = [], [], [], []\n",
54+
"\n",
55+
"for s in spots:\n",
56+
" d, g, v, th = black_scholes_greeks(s, K, T, r, sigma, 'call')\n",
57+
" deltas.append(d)\n",
58+
" gammas.append(g)\n",
59+
" vegas.append(v)\n",
60+
" thetas.append(th)\n",
61+
"\n",
62+
"# Plotting\n",
63+
"fig, axs = plt.subplots(2, 2, figsize=(12, 10))\n",
64+
"\n",
65+
"axs[0, 0].plot(spots, deltas, color='blue')\n",
66+
"axs[0, 0].set_title('Delta (Direction)')\n",
67+
"axs[0, 0].axvline(K, linestyle='--', color='gray', alpha=0.5)\n",
68+
"axs[0, 0].grid(True)\n",
69+
"\n",
70+
"axs[0, 1].plot(spots, gammas, color='red')\n",
71+
"axs[0, 1].set_title('Gamma (Convexity)')\n",
72+
"axs[0, 1].axvline(K, linestyle='--', color='gray', alpha=0.5)\n",
73+
"axs[0, 1].grid(True)\n",
74+
"\n",
75+
"axs[1, 0].plot(spots, vegas, color='green')\n",
76+
"axs[1, 0].set_title('Vega (Volatility Sensitivity)')\n",
77+
"axs[1, 0].axvline(K, linestyle='--', color='gray', alpha=0.5)\n",
78+
"axs[1, 0].grid(True)\n",
79+
"\n",
80+
"axs[1, 1].plot(spots, thetas, color='purple')\n",
81+
"axs[1, 1].set_title('Theta (Time Decay)')\n",
82+
"axs[1, 1].axvline(K, linestyle='--', color='gray', alpha=0.5)\n",
83+
"axs[1, 1].grid(True)\n",
84+
"\n",
85+
"plt.suptitle(f'Call Option Greeks (K={K}, T={T}, $\sigma$={sigma})')\n",
86+
"plt.tight_layout()\n",
87+
"plt.show()"
88+
]
89+
}
90+
],
91+
"metadata": {
92+
"kernelspec": {
93+
"display_name": "Python 3",
94+
"language": "python",
95+
"name": "python3"
96+
},
97+
"language_info": {
98+
"codemirror_mode": {
99+
"name": "ipython",
100+
"version": 3
101+
},
102+
"file_extension": ".py",
103+
"mimetype": "text/x-python",
104+
"name": "python",
105+
"nbconvert_exporter": "python",
106+
"pygments_lexer": "ipython3",
107+
"version": "3.8.5"
108+
}
109+
},
110+
"nbformat": 4,
111+
"nbformat_minor": 4
112+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import numpy as np
2+
import pandas as pd
3+
import matplotlib.pyplot as plt
4+
5+
class ExecutionAlgorithms:
6+
"""
7+
Standard Execution Algorithms used to minimize market impact.
8+
"""
9+
10+
def __init__(self, total_quantity, start_time, end_time, volume_profile=None):
11+
"""
12+
:param total_quantity: Shares to buy/sell
13+
:param start_time: Index of start
14+
:param end_time: Index of end
15+
:param volume_profile: Expected market volume distribution (list or array) for VWAP
16+
"""
17+
self.Q = total_quantity
18+
self.T_start = start_time
19+
self.T_end = end_time
20+
self.N = end_time - start_time
21+
self.volume_profile = volume_profile
22+
23+
def get_twap_schedule(self):
24+
"""
25+
Time-Weighted Average Price (TWAP):
26+
Slices the order equally across all time buckets.
27+
"""
28+
quantity_per_slice = self.Q / self.N
29+
schedule = np.full(self.N, quantity_per_slice)
30+
return schedule
31+
32+
def get_vwap_schedule(self):
33+
"""
34+
Volume-Weighted Average Price (VWAP):
35+
Slices the order proportional to historical volume profile.
36+
"""
37+
if self.volume_profile is None:
38+
raise ValueError("Volume profile required for VWAP")
39+
40+
relevant_profile = np.array(self.volume_profile[self.T_start:self.T_end])
41+
total_market_vol = relevant_profile.sum()
42+
43+
# Proportional allocation
44+
schedule = (relevant_profile / total_market_vol) * self.Q
45+
return schedule
46+
47+
if __name__ == "__main__":
48+
# Example: Execute 100,000 shares over a trading day (390 minutes)
49+
total_qty = 100000
50+
minutes = 390
51+
52+
# Simulate a "U-Shape" volume profile (common in equities)
53+
# High volume at open/close, low in mid-day
54+
t = np.linspace(-1, 1, minutes)
55+
vol_profile = 1000 + 5000 * t**2 # Quadratic curve
56+
57+
algo = ExecutionAlgorithms(total_qty, 0, minutes, vol_profile)
58+
59+
twap = algo.get_twap_schedule()
60+
vwap = algo.get_vwap_schedule()
61+
62+
# Plotting
63+
plt.figure(figsize=(12, 6))
64+
plt.plot(vol_profile, label='Market Volume Profile (Proxy)', linestyle='--', alpha=0.5)
65+
plt.plot(twap, label='TWAP Schedule', linewidth=2)
66+
plt.plot(vwap, label='VWAP Schedule', linewidth=2)
67+
plt.title('Execution Schedules: TWAP vs VWAP')
68+
plt.xlabel('Minute')
69+
plt.ylabel('Shares to Execute')
70+
plt.legend()
71+
plt.show()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <iostream>
5+
#include <vector>
6+
#include <algorithm>
7+
#include <numeric>
8+
9+
// RDTSC: Read Time-Stamp Counter
10+
// Returns the number of clock cycles since the CPU was powered up.
11+
static inline uint64_t rdtsc() {
12+
unsigned int lo, hi;
13+
// 'volatile' prevents compiler reordering
14+
__asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi));
15+
return ((uint64_t)hi << 32) | lo;
16+
}
17+
18+
class MicroBenchmark {
19+
private:
20+
std::vector<uint64_t> measurements;
21+
const int iterations;
22+
23+
public:
24+
MicroBenchmark(int iters = 1000) : iterations(iters) {
25+
measurements.reserve(iters);
26+
}
27+
28+
template <typename Func>
29+
void run(const std::string& name, Func&& func) {
30+
measurements.clear();
31+
32+
// Warmup (cache loading)
33+
for (int i = 0; i < 100; ++i) {
34+
func();
35+
}
36+
37+
for (int i = 0; i < iterations; ++i) {
38+
uint64_t start = rdtsc();
39+
func();
40+
uint64_t end = rdtsc();
41+
measurements.push_back(end - start);
42+
}
43+
44+
print_stats(name);
45+
}
46+
47+
private:
48+
void print_stats(const std::string& name) {
49+
if (measurements.empty()) return;
50+
51+
std::sort(measurements.begin(), measurements.end());
52+
53+
double avg = std::accumulate(measurements.begin(), measurements.end(), 0.0) / measurements.size();
54+
uint64_t min = measurements.front();
55+
uint64_t max = measurements.back();
56+
uint64_t p50 = measurements[measurements.size() / 2];
57+
uint64_t p99 = measurements[measurements.size() * 0.99];
58+
59+
std::cout << "--- Benchmark: " << name << " ---" << std::endl;
60+
std::cout << "Cycles (Avg): " << avg << std::endl;
61+
std::cout << "Cycles (Min): " << min << std::endl;
62+
std::cout << "Cycles (P50): " << p50 << std::endl;
63+
std::cout << "Cycles (P99): " << p99 << std::endl; // Tail latency
64+
std::cout << "--------------------------------" << std::endl;
65+
}
66+
};
67+
68+
/* Example Usage
69+
int main() {
70+
MicroBenchmark bench;
71+
int x = 0;
72+
bench.run("Increment", [&](){
73+
x++;
74+
});
75+
return 0;
76+
}
77+
*/

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@ We have curated specialized resources that target the specific requirements of H
3333

3434
### ⚡ Low Latency & Systems
3535
* **C++ Mastery:** [Order Matching Engine](./06_quantitative_development/cpp_low_latency/examples/order_matching_engine.cpp), [Lock-Free Queue](./06_quantitative_development/cpp_low_latency/examples/lock_free_spsc_queue.cpp), & [Memory Pool](./06_quantitative_development/cpp_low_latency/examples/memory_pool.cpp).
36-
* **Concurrency:** [Multithreaded Monte Carlo](./06_quantitative_development/cpp_low_latency/examples/multithreaded_monte_carlo.cpp) (std::async, std::future).
37-
* **Template Metaprogramming:** [Compile-Time Greeks](./06_quantitative_development/cpp_low_latency/examples/compile_time_greeks.cpp) (C++20 `consteval` LUTs).
36+
* **Optimization:** [Microbenchmark Utils](./06_quantitative_development/cpp_low_latency/examples/microbenchmark_utils.hpp) (CPU Cycle Counting).
37+
* **Concurrency:** [Multithreaded Monte Carlo](./06_quantitative_development/cpp_low_latency/examples/multithreaded_monte_carlo.cpp).
38+
* **Template Metaprogramming:** [Compile-Time Greeks](./06_quantitative_development/cpp_low_latency/examples/compile_time_greeks.cpp).
3839
* **Architecture:** [HFT Infrastructure](./06_quantitative_development/system_design/architecture_notes/hft_architecture.md).
3940

4041
### 🧠 Interview Mastery
4142
* **The Roadmap:** [8-Week Study Plan](./07_interview_preparation/study_roadmap.md).
42-
* **Quant Strategies:** [Avellaneda-Stoikov Market Making](./05_algorithmic_trading/strategies/market_microstructure/avellaneda_stoikov_mm.py) & [Pairs Trading](./05_algorithmic_trading/strategies/systematic_strategies/pairs_trading_stat_arb.ipynb).
43-
* **AI/ML:** [LSTM Time Series Forecasting](./04_machine_learning_and_ai/deep_learning/lstm_price_prediction.ipynb) (PyTorch).
44-
* **Backtesting:** [Performance Metrics Library](./05_algorithmic_trading/backtesting_frameworks/performance_metrics.py) (Sharpe, Sortino, Drawdown).
43+
* **Quant Strategies:** [Avellaneda-Stoikov MM](./05_algorithmic_trading/strategies/market_microstructure/avellaneda_stoikov_mm.py), [Pairs Trading](./05_algorithmic_trading/strategies/systematic_strategies/pairs_trading_stat_arb.ipynb), & [Execution Algos (TWAP/VWAP)](./05_algorithmic_trading/strategies/execution/execution_algos.py).
44+
* **Visual Intuition:** [Options Greeks Dashboard](./03_financial_engineering/derivatives_pricing/greeks_visualization.ipynb).
45+
* **AI/ML:** [LSTM Time Series Forecasting](./04_machine_learning_and_ai/deep_learning/lstm_price_prediction.ipynb).
46+
* **Backtesting:** [Performance Metrics Library](./05_algorithmic_trading/backtesting_frameworks/performance_metrics.py).
4547
* **Jane Street Guide:** [Probability & Betting](./07_interview_preparation/company_insights/jane_street_guide.md).
4648

4749
---

0 commit comments

Comments
 (0)