got asked on r/algotrading how i organize my trading repos. here’s my setup after 4 months of refactoring.
repo structure #
i have 4 main repos:
1. trading-strategies (private)
- all my actual strategies
- backtests
- optimization code
- performance analysis
2. trading-infrastructure (private)
- broker API wrappers
- data feed connections
- order management
- position tracking
- risk management
3. trading-tools (public)
- generic utilities
- technical indicators
- backtesting helpers
- visualization tools
- nothing proprietary
4. trading-research (private)
- jupyter notebooks
- strategy ideas
- failed experiments
- market analysis
why separate repos? #
modularity:
- can update infrastructure without touching strategies
- can share tools publicly without exposing strategies
- easier to test each component independently
security:
- strategies stay private
- tools can be public (builds reputation on github)
- API keys never committed (environment variables)
deployment:
- infrastructure runs 24/7 on server
- strategies can be started/stopped independently
- tools installed as python packages
directory structure #
trading-strategies/
├── strategies/
│ ├── premium_selling/
│ │ ├── __init__.py
│ │ ├── iv_rank_strategy.py
│ │ ├── config.yaml
│ │ └── backtest.py
│ ├── mean_reversion/
│ └── volatility/
├── backtests/
│ ├── results/
│ └── analysis/
├── optimization/
├── tests/
├── requirements.txt
└── README.md
trading-infrastructure/
├── brokers/
│ ├── interactive_brokers.py
│ ├── tastyworks.py
│ └── base_broker.py
├── data/
│ ├── polygon_client.py
│ ├── data_manager.py
│ └── storage/
├── execution/
│ ├── order_manager.py
│ ├── position_manager.py
│ └── risk_manager.py
├── monitoring/
│ ├── alerting.py
│ └── metrics.py
├── config/
│ ├── production.yaml
│ └── development.yaml
├── tests/
└── README.md
key principles #
1. separation of concerns
strategy code doesn’t know about broker APIs:
# strategies/premium_selling/iv_rank_strategy.py
class IVRankStrategy:
def generate_signals(self, market_data):
# Pure strategy logic
# No broker-specific code
# Returns generic Signal objects
pass
# infrastructure/execution/order_manager.py
class OrderManager:
def execute_signal(self, signal, broker):
# Handles broker-specific execution
# Strategy doesn't care which broker
pass
2. configuration files
all settings in yaml, not hardcoded:
# strategies/premium_selling/config.yaml
strategy:
name: "IV Rank Premium Selling"
enabled: true
entry:
iv_rank_min: 45
delta_max: 0.20
dte_min: 30
dte_max: 45
exit:
profit_target: 0.50
stop_loss: 2.00
dte_min: 2
position:
max_positions: 5
capital_per_trade: 10000
max_loss_per_trade: 425
3. environment variables for secrets
# Never commit API keys
import os
POLYGON_API_KEY = os.getenv('POLYGON_API_KEY')
IB_HOST = os.getenv('IB_HOST', '127.0.0.1')
IB_PORT = int(os.getenv('IB_PORT', 7497))
# Keys stored in .env (gitignored)
# or in server environment variables
4. thorough tests
# tests/test_iv_rank_strategy.py
import pytest
from strategies.premium_selling import IVRankStrategy
def test_iv_rank_filter():
strategy = IVRankStrategy()
# IV rank too low, should reject
assert strategy.passes_iv_filter(iv_rank=30) == False
# IV rank acceptable, should pass
assert strategy.passes_iv_filter(iv_rank=50) == True
def test_signal_generation():
strategy = IVRankStrategy()
market_data = load_test_data()
signals = strategy.generate_signals(market_data)
assert len(signals) > 0
assert all(s.iv_rank > 45 for s in signals)
what goes in each repo #
trading-strategies:
- strategy logic
- entry/exit rules
- position sizing
- backtests
- optimization
trading-infrastructure:
- broker connections
- data feeds
- order execution
- risk management
- monitoring/alerting
trading-tools (public):
- technical indicators
- backtesting framework
- data utilities
- charting helpers
- generic trading utilities
trading-research:
- jupyter notebooks
- exploratory analysis
- failed strategy ideas
- market research
- optimization experiments
git workflow #
development:
- create feature branch
- write tests
- implement feature
- run tests locally
- commit with descriptive message
testing:
- push to github
- run full test suite on server
- paper trade for 1 week minimum
- review results
production:
- merge to main branch
- deploy to production server
- start with minimum position size
- scale up after 2 weeks
commit messages #
i use conventional commits format:
feat: add IV percentile filter to premium selling strategy
fix: correct slippage calculation in backtest
docs: update strategy README with performance metrics
test: add correlation checking tests
refactor: simplify order execution logic
makes git history searchable.
branching strategy #
main: production code, always deployable develop: integration branch for new features feature/xxx: individual feature branches hotfix/xxx: urgent production fixes
pre-commit hooks #
# .git/hooks/pre-commit
#!/bin/bash
# Run tests before allowing commit
pytest tests/
# Check for debugging code
if grep -r "import pdb" strategies/; then
echo "Error: Found debugging code (pdb)"
exit 1
fi
# Check for hardcoded secrets
if grep -r "api_key.*=.*['\"].*['\"]" . --include="*.py"; then
echo "Error: Found hardcoded API key"
exit 1
fi
what i keep private vs public #
private:
- actual trading strategies
- performance data
- optimization results
- broker configurations
- anything that makes me money
public:
- generic utilities
- backtesting framework
- technical indicators
- chart generators
- data processing tools
github actions (automated testing) #
# .github/workflows/test.yml
name: Run Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.11
- run: pip install -r requirements.txt
- run: pytest tests/ --cov
runs tests automatically on every push.
documentation #
every strategy has README.md with:
- description
- entry/exit rules
- expected performance
- risk parameters
- backtest results
- known issues
keeps me from forgetting what i was thinking when i wrote it.
backup strategy #
github is primary, but i also:
- local backup to external drive (weekly)
- backup to second git server (daily)
- encrypted backup to cloud (monthly)
losing strategy code = catastrophic. redundancy matters.
code review #
i’m solo but i still do code review:
- write code in feature branch
- let it sit 24 hours
- review with fresh eyes
- merge if it still looks good
helps catch stupid mistakes.
performance tracking in git #
i tag releases with performance metrics:
git tag -a v1.2.0 -m "
IV Rank Strategy v1.2.0
- Sharpe: 1.85
- Win rate: 68%
- Max DD: -8%
- Backtest: 2020-2023
"
can see how strategy evolved over time.
lessons learned #
what works:
- separate repos for different concerns
- yaml configs for everything
- extensive tests
- clear commit messages
what doesn’t work:
- monolithic repo with everything
- hardcoded values
- no tests
- “WIP” commit messages
mistakes i made:
- put strategies and infrastructure in same repo initially (nightmare to separate later)
- committed API key once (had to regenerate)
- didn’t write tests early (pain to add later)
- no documentation (forgot how my own code works)
time investment #
organizing code properly = ~20 hours initially
saves ~5 hours per week in debugging and maintenance
paid for itself in first month.
2:55pm. someone will probably ask for my public trading-tools repo. might open source it if people are interested.
-AK