Skip to content

Commit b4b0021

Browse files
committed
Add Pro C++ Multithreading, PyTorch LSTM, and Performance Metrics
1 parent 03d8152 commit b4b0021

File tree

4 files changed

+263
-2
lines changed

4 files changed

+263
-2
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Time Series Forecasting with LSTM (PyTorch)\n",
8+
"\n",
9+
"Long Short-Term Memory (LSTM) networks are a type of Recurrent Neural Network (RNN) capable of learning order dependence in sequence prediction problems.\n",
10+
"\n",
11+
"**Objective:** Predict the next value in a sine wave (proxy for a cyclical asset pattern).\n",
12+
"\n",
13+
"**Steps:**\n",
14+
"1. Generate synthetic data.\n",
15+
"2. Preprocess sequences (Sliding Window).\n",
16+
"3. Build LSTM model in PyTorch.\n",
17+
"4. Train and Evaluate."
18+
]
19+
},
20+
{
21+
"cell_type": "code",
22+
"execution_count": null,
23+
"metadata": {},
24+
"outputs": [],
25+
"source": [
26+
"import torch\n",
27+
"import torch.nn as nn\n",
28+
"import numpy as np\n",
29+
"import matplotlib.pyplot as plt\n",
30+
"\n",
31+
"# 1. Generate Data\n",
32+
"t = np.linspace(0, 100, 1000)\n",
33+
"data = np.sin(t)\n",
34+
"\n",
35+
"# 2. Sliding Window (Lookback)\n",
36+
"def create_sequences(data, seq_length):\n",
37+
" xs = []\n",
38+
" ys = []\n",
39+
" for i in range(len(data)-seq_length-1):\n",
40+
" x = data[i:(i+seq_length)]\n",
41+
" y = data[i+seq_length]\n",
42+
" xs.append(x)\n",
43+
" ys.append(y)\n",
44+
" return np.array(xs), np.array(ys)\n",
45+
"\n",
46+
"seq_length = 20\n",
47+
"X, y = create_sequences(data, seq_length)\n",
48+
"\n",
49+
"# Convert to Tensor\n",
50+
"X_train = torch.from_numpy(X).float().unsqueeze(2) # (Batch, Seq, Feature)\n",
51+
"y_train = torch.from_numpy(y).float()\n",
52+
"\n",
53+
"# 3. LSTM Model\n",
54+
"class LSTMModel(nn.Module):\n",
55+
" def __init__(self, input_size=1, hidden_layer_size=50, output_size=1):\n",
56+
" super().__init__()\n",
57+
" self.hidden_layer_size = hidden_layer_size\n",
58+
" self.lstm = nn.LSTM(input_size, hidden_layer_size)\n",
59+
" self.linear = nn.Linear(hidden_layer_size, output_size)\n",
60+
"\n",
61+
" def forward(self, input_seq):\n",
62+
" lstm_out, _ = self.lstm(input_seq.view(len(input_seq), 1, -1))\n",
63+
" predictions = self.linear(lstm_out.view(len(input_seq), -1))\n",
64+
" return predictions[-1]\n",
65+
"\n",
66+
"model = LSTMModel()\n",
67+
"loss_function = nn.MSELoss()\n",
68+
"optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
69+
"\n",
70+
"# 4. Train Loop\n",
71+
"epochs = 10\n",
72+
"print(\"Training...\")\n",
73+
"for i in range(epochs):\n",
74+
" for seq, labels in zip(X_train, y_train):\n",
75+
" optimizer.zero_grad()\n",
76+
" y_pred = model(seq)\n",
77+
" single_loss = loss_function(y_pred, labels.unsqueeze(0))\n",
78+
" single_loss.backward()\n",
79+
" optimizer.step()\n",
80+
" if i % 2 == 0:\n",
81+
" print(f'Epoch: {i} Loss: {single_loss.item():.5f}')\n",
82+
"\n",
83+
"print(\"Training Complete.\")\n",
84+
"\n",
85+
"# 5. Prediction (Validation)\n",
86+
"model.eval()\n",
87+
"test_seq = X_train[0]\n",
88+
"with torch.no_grad():\n",
89+
" pred = model(test_seq)\n",
90+
" print(f\"Target: {y_train[0].item():.4f}, Predicted: {pred.item():.4f}\")"
91+
]
92+
}
93+
],
94+
"metadata": {
95+
"kernelspec": {
96+
"display_name": "Python 3",
97+
"language": "python",
98+
"name": "python3"
99+
},
100+
"language_info": {
101+
"codemirror_mode": {
102+
"name": "ipython",
103+
"version": 3
104+
},
105+
"file_extension": ".py",
106+
"mimetype": "text/x-python",
107+
"name": "python",
108+
"nbconvert_exporter": "python",
109+
"pygments_lexer": "ipython3",
110+
"version": "3.8.5"
111+
}
112+
},
113+
"nbformat": 4,
114+
"nbformat_minor": 4
115+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import numpy as np
2+
import pandas as pd
3+
4+
class PerformanceMetrics:
5+
"""
6+
Library for calculating Strategy Performance Metrics.
7+
"""
8+
9+
@staticmethod
10+
def calculate_returns(prices):
11+
"""Calculates simple percent returns."""
12+
return prices.pct_change().dropna()
13+
14+
@staticmethod
15+
def sharpe_ratio(returns, risk_free_rate=0.0, periods_per_year=252):
16+
"""
17+
Sharpe Ratio = (Mean Return - Risk Free) / Std Dev
18+
"""
19+
excess_returns = returns - risk_free_rate / periods_per_year
20+
if returns.std() == 0:
21+
return 0.0
22+
return np.sqrt(periods_per_year) * excess_returns.mean() / returns.std()
23+
24+
@staticmethod
25+
def sortino_ratio(returns, risk_free_rate=0.0, periods_per_year=252):
26+
"""
27+
Sortino Ratio = (Mean Return - Risk Free) / Downside Deviation
28+
"""
29+
excess_returns = returns - risk_free_rate / periods_per_year
30+
downside_returns = returns[returns < 0]
31+
32+
downside_std = downside_returns.std()
33+
if downside_std == 0:
34+
return 0.0
35+
36+
return np.sqrt(periods_per_year) * excess_returns.mean() / downside_std
37+
38+
@staticmethod
39+
def max_drawdown(prices):
40+
"""
41+
Calculates Maximum Drawdown (Peak to Valley).
42+
"""
43+
cumulative = (1 + prices.pct_change().dropna()).cumprod()
44+
peak = cumulative.cummax()
45+
drawdown = (cumulative - peak) / peak
46+
return drawdown.min()
47+
48+
@staticmethod
49+
def calmar_ratio(returns, prices, periods_per_year=252):
50+
"""
51+
Calmar Ratio = Annualized Return / Max Drawdown
52+
"""
53+
max_dd = abs(PerformanceMetrics.max_drawdown(prices))
54+
if max_dd == 0:
55+
return 0.0
56+
57+
annual_return = returns.mean() * periods_per_year
58+
return annual_return / max_dd
59+
60+
if __name__ == "__main__":
61+
# Test Data
62+
prices = pd.Series([100, 102, 104, 103, 105, 108, 101, 103], name="Price")
63+
returns = PerformanceMetrics.calculate_returns(prices)
64+
65+
print(f"Sharpe Ratio: {PerformanceMetrics.sharpe_ratio(returns):.4f}")
66+
print(f"Sortino Ratio: {PerformanceMetrics.sortino_ratio(returns):.4f}")
67+
print(f"Max Drawdown: {PerformanceMetrics.max_drawdown(prices):.4f}")
68+
print(f"Calmar Ratio: {PerformanceMetrics.calmar_ratio(returns, prices):.4f}")
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <cmath>
4+
#include <random>
5+
#include <thread>
6+
#include <future>
7+
#include <chrono>
8+
9+
/**
10+
* Multithreaded Monte Carlo Option Pricer.
11+
*
12+
* Demonstrates:
13+
* 1. Parallel execution using std::async (Task-based parallelism).
14+
* 2. Thread-local Random Number Generation (avoiding locking contention).
15+
* 3. Numerical integration for derivatives pricing.
16+
*/
17+
18+
// Function to generate Gaussian noise (Box-Muller transform or std::normal_distribution)
19+
// We use a thread-local generator for performance.
20+
double calculate_payoff_sum(int num_sims, double S, double K, double r, double v, double T) {
21+
// Thread-local random number engine
22+
static thread_local std::mt19937 generator(std::hash<std::thread::id>{}(std::this_thread::get_id()));
23+
std::normal_distribution<double> distribution(0.0, 1.0);
24+
25+
double payoff_sum = 0.0;
26+
double drift = (r - 0.5 * v * v) * T;
27+
double vol_sqrt_T = v * std::sqrt(T);
28+
29+
for (int i = 0; i < num_sims; ++i) {
30+
double Z = distribution(generator);
31+
double S_T = S * std::exp(drift + vol_sqrt_T * Z);
32+
payoff_sum += std::max(S_T - K, 0.0); // Call Option Payoff
33+
}
34+
return payoff_sum;
35+
}
36+
37+
int main() {
38+
// Option Parameters
39+
double S = 100.0; // Spot Price
40+
double K = 100.0; // Strike Price
41+
double r = 0.05; // Risk-free Rate
42+
double v = 0.2; // Volatility
43+
double T = 1.0; // Time to Maturity (1 year)
44+
45+
int total_sims = 10'000'000;
46+
int num_threads = std::thread::hardware_concurrency();
47+
int sims_per_thread = total_sims / num_threads;
48+
49+
std::cout << "Pricing Call Option (S=" << S << ", K=" << K << ")...\n";
50+
std::cout << "Simulations: " << total_sims << " | Threads: " << num_threads << "\n";
51+
52+
auto start_time = std::chrono::high_resolution_clock::now();
53+
54+
// Launch tasks
55+
std::vector<std::future<double>> futures;
56+
for (int i = 0; i < num_threads; ++i) {
57+
futures.push_back(std::async(std::launch::async, calculate_payoff_sum, sims_per_thread, S, K, r, v, T));
58+
}
59+
60+
// Aggregate results
61+
double total_payoff = 0.0;
62+
for (auto& f : futures) {
63+
total_payoff += f.get();
64+
}
65+
66+
double price = (total_payoff / total_sims) * std::exp(-r * T);
67+
68+
auto end_time = std::chrono::high_resolution_clock::now();
69+
std::chrono::duration<double> elapsed = end_time - start_time;
70+
71+
std::cout << "------------------------------------------------\n";
72+
std::cout << "Call Price: " << price << "\n";
73+
std::cout << "Time Taken: " << elapsed.count() << " seconds\n";
74+
std::cout << "Sims/Sec: " << total_sims / elapsed.count() << "\n";
75+
76+
return 0;
77+
}

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@ 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).
3637
* **Template Metaprogramming:** [Compile-Time Greeks](./06_quantitative_development/cpp_low_latency/examples/compile_time_greeks.cpp) (C++20 `consteval` LUTs).
37-
* **Market Data:** [ITCH Feed Handler](./06_quantitative_development/data_engineering/market_data/itch_parser_mock.py).
3838
* **Architecture:** [HFT Infrastructure](./06_quantitative_development/system_design/architecture_notes/hft_architecture.md).
3939

4040
### 🧠 Interview Mastery
4141
* **The Roadmap:** [8-Week Study Plan](./07_interview_preparation/study_roadmap.md).
4242
* **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).
4345
* **Jane Street Guide:** [Probability & Betting](./07_interview_preparation/company_insights/jane_street_guide.md).
44-
* **Quant Math:** [Green Book Companion](./01_foundations/mathematics/probability/quant_probability_guide.md).
4546

4647
---
4748

0 commit comments

Comments
 (0)