Skip to content

Commit 7150628

Browse files
committed
release: paperium v2 - LSTM
1 parent 7d7f4df commit 7150628

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2749
-10515
lines changed

README.md

Lines changed: 687 additions & 196 deletions
Large diffs are not rendered by default.

config.py

Lines changed: 34 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""
22
IHSG Quantitative Trading Model Configuration
3+
Refactored for LSTM + Triple Barrier Labeling (Paper Implementation)
34
"""
45
from dataclasses import dataclass, field
56
from typing import List
@@ -10,109 +11,65 @@
1011
@dataclass
1112
class DataConfig:
1213
"""Data fetching configuration"""
13-
# Stock universe - Comprehensive Liquid IHSG Universe (IDX80 + Kompas100 + Liquid Growth)
14+
# Stock universe
1415
stock_universe: List[str] = field(default_factory=lambda: IDX_UNIVERSE)
1516

1617
# Data storage
1718
db_path: str = "data/ihsg_trading.db"
1819

1920
# Historical data settings
20-
lookback_days: int = 365 * 5 # 5 years of history
21-
min_data_points: int = 252 # Minimum data points for calculation
22-
23-
24-
@dataclass
25-
class SignalConfig:
26-
"""Signal generation parameters"""
27-
# Technical indicators
28-
rsi_period: int = 14
29-
macd_fast: int = 12
30-
macd_slow: int = 26
31-
macd_signal: int = 9
32-
bb_period: int = 20
33-
bb_std: float = 2.0
34-
atr_period: int = 14
35-
36-
# Mean reversion
37-
zscore_period: int = 20
38-
zscore_entry_threshold: float = 2.0
21+
lookback_days: int = 365 * 5 # 5 years
22+
min_data_points: int = 252
3923

40-
# Momentum
41-
momentum_periods: List[int] = field(default_factory=lambda: [5, 10, 20])
24+
# Sequence generation
25+
window_size: int = 100 # From Paper: Optimal Window Size
4226

4327

4428
@dataclass
4529
class MLConfig:
46-
"""Machine learning model configuration"""
47-
# Training windows (5 years total - using more of your 5-year historical data)
48-
training_window: int = 1008 # 4 years of trading days for training
49-
validation_window: int = 252 # 1 year of trading days for validation
50-
validation_split: float = 0.2 # Deprecated, use validation_window instead
51-
52-
# Prediction target (aligned with max_holding_days for day trading)
53-
target_horizon: int = 5 # Predict 5-day forward return (matches max hold)
54-
55-
# XGBoost parameters (Conservative Defaults with Strong Regularization)
56-
# Note: Based on training results, 50 trees is the sweet spot before overfitting
57-
# Regularization allows using more trees without overfitting
58-
n_estimators: int = 500
59-
max_depth: int = 4
60-
learning_rate: float = 0.05
61-
min_child_weight: int = 5
62-
63-
# Regularization parameters (prevent overfitting)
64-
subsample: float = 0.7 # Use 70% of data per tree (randomness prevents overfitting)
65-
colsample_bytree: float = 0.7 # Use 70% of features per tree
66-
gamma: float = 0.2 # Minimum loss reduction required to split (conservative)
67-
reg_alpha: float = 1.0 # Stronger L1 regularization (feature selection)
68-
reg_lambda: float = 2.0 # Stronger L2 regularization
69-
70-
use_gpu: bool = False
30+
"""Machine learning model configuration (LSTM)"""
31+
# Model Architecture (Paper: Hidden Size 8 was optimal)
32+
input_size: int = 5 # Open, High, Low, Close, Volume
33+
hidden_size: int = 8
34+
num_layers: int = 2 # Starting with 2 stacked LSTMs
35+
dropout: float = 0.0
36+
37+
# Training
38+
batch_size: int = 64
39+
learning_rate: float = 0.001
40+
epochs: int = 50
41+
patience: int = 10 # Early stopping
42+
43+
# Triple Barrier Labeling (Optimized for IHSG)
44+
# Found via optimization: Horizon=5, Barrier=3.0%
45+
tbl_horizon: int = 5
46+
tbl_barrier: float = 0.03
47+
num_classes: int = 3 # 0: Loss, 1: Hold, 2: Profit
7148

72-
# Feature settings
73-
feature_lags: List[int] = field(default_factory=lambda: [1, 2, 3, 5, 10, 15, 20])
7449

7550
@dataclass
7651
class ExitConfig:
7752
"""Exit strategy configuration"""
78-
stop_loss_atr_mult: float = 2.0 # Tighter stop (2.0x is standard for swing)
79-
take_profit_atr_mult: float = 5.0 # Reduced from 10.0. (4-6x is a "Home Run" in 5 days)
80-
trailing_stop_atr_mult: float = 2.5 # Trail loosely to let winners run
81-
82-
# Time-based exit (hold longer for bigger moves)
83-
max_holding_days: int = 5
53+
# Legacy ATR-based exits (kept for PositionManager compatibility)
54+
# TBL barrier is 3%, so we map roughly to that.
55+
# If ATR is ~2%, then 1.5x ATR = 3%.
56+
stop_loss_atr_mult: float = 1.5
57+
take_profit_atr_mult: float = 1.5
58+
signal_threshold: float = 0.5
8459

85-
# Fixed stops (fallback for extreme cases)
86-
max_loss_pct: float = 0.08 # Tighten max loss to 8% (preservation is key)
87-
min_profit_pct: float = 0.15 # Realistic 15% upside target for 1 week
88-
89-
signal_threshold: float = 0.55 # Minimum ML signal to enter/hold position
9060

9161
@dataclass
9262
class PortfolioConfig:
93-
"""Portfolio management configuration"""
94-
# Total portfolio value for sizing calculations
95-
total_value: float = 100_000_000 # Default 100M IDR
96-
97-
# Position sizing
98-
max_positions: int = 8 # Reduced: Focus capital on best ideas
99-
base_position_pct: float = 0.125 # 12.5% per trade
100-
max_sector_exposure: float = 0.25 # 25% max per sector
101-
102-
# Liquidity filter
103-
min_avg_volume: int = 2_000_000 # 2M shares minimum
104-
min_market_cap: float = 2e12 # 2 Trillion IDR minimum
105-
106-
# Risk management
107-
max_portfolio_volatility: float = 0.20 # 20% annual vol target
108-
max_correlation: float = 0.6 # Avoid highly correlated positions
63+
"""Portfolio simulation settings"""
64+
total_value: float = 100_000_000.0 # Default 100M IDR
65+
max_positions: int = 10
66+
risk_per_trade: float = 0.02 # 2% Risk per trade (Optional usage)
10967

11068

11169
@dataclass
11270
class Config:
11371
"""Master configuration"""
11472
data: DataConfig = field(default_factory=DataConfig)
115-
signal: SignalConfig = field(default_factory=SignalConfig)
11673
ml: MLConfig = field(default_factory=MLConfig)
11774
exit: ExitConfig = field(default_factory=ExitConfig)
11875
portfolio: PortfolioConfig = field(default_factory=PortfolioConfig)

images/eval.png

1.39 MB
Loading

images/hyperparameter.png

1.36 MB
Loading

images/menu.png

1.41 MB
Loading

images/morning-signals.png

-437 KB
Binary file not shown.

images/pre-training.png

1.57 MB
Loading

images/setup.png

1.5 MB
Loading

images/signals.png

1.53 MB
Loading

images/stock-analysis.png

-448 KB
Binary file not shown.

0 commit comments

Comments
 (0)