algame is a powerful, modular backtesting framework for algorithmic trading. Easily test multiple strategies across assets and timeframes, visualize results with a TradingView-like GUI, and integrate custom data or engines. Flexible, user-friendly, and future-ready.
Project description
🎮 Algame-MRIMADHA
📈 A Modern Algorithmic Trading & Backtesting Framework
By traders, for traders - Making algo trading accessible without compromising power
Installation • Quick Start • Documentation • Examples • Contributing
🌟 Why Algame?
After years of frustration with existing backtesting frameworks that were either too rigid or too complex, we created Algame with one goal: make algorithmic trading accessible while keeping it powerful.
Through our journey, we learned:
- Traders need flexibility in strategy development
- Real-world trading requires robust testing
- Visual tools accelerate development
- Code shouldn't be a barrier to algo trading
Our Solution? A Framework That:
- 🎯 Adapts to your style (code, visual, or both)
- 🔧 Handles complexity behind simple interfaces
- 📊 Provides professional-grade analysis
- 🔄 Integrates with tools you already use
🚀 Installation
pip install algame-mrimadha
Development Version:
pip install git+https://github.com/mrigesh/algame-mrimadha.git
🏃♂️ Quick Start
Code Your First Strategy
from algame.strategy import StrategyBase
from algame.core import EngineManager
from algame.data import YahooData
class SimpleSMAStrategy(StrategyBase):
def initialize(self):
# Add 20-day SMA indicator
self.sma = self.add_indicator('SMA', self.data.Close, period=20)
def next(self):
# Buy when price crosses above SMA
if self.data.Close[-1] > self.sma[-1] and \
self.data.Close[-2] <= self.sma[-2]:
self.buy()
# Sell when price crosses below SMA
elif self.data.Close[-1] < self.sma[-1] and \
self.data.Close[-2] >= self.sma[-2]:
self.sell()
# Load data
data = YahooData.download('AAPL', '2020-01-01', '2023-12-31')
# Run backtest
engine = EngineManager()
results = engine.run_backtest(SimpleSMAStrategy, data)
# Print results
print(f"Total Return: {results.metrics['total_return']:.2f}%")
print(f"Sharpe Ratio: {results.metrics['sharpe_ratio']:.2f}")
Or Use the GUI
from algame.gui import start_app
start_app()
✨ Key Features
🎯 Multi-Everything Support
Multi-Asset Trading
# Trade multiple assets simultaneously
data = {
'AAPL': yahoo.download('AAPL'),
'GOOGL': yahoo.download('GOOGL'),
'BTC-USD': yahoo.download('BTC-USD')
}
class MultiAssetStrategy(StrategyBase):
def next(self):
for symbol, asset_data in self.data.items():
# Your logic here
pass
Multi-Timeframe Analysis
# Mix timeframes in your strategy
class MultiTimeframeStrategy(StrategyBase):
def initialize(self):
# Daily timeframe
self.daily_sma = self.add_indicator('SMA', self.data['1d'].Close, 20)
# Hourly timeframe
self.hourly_rsi = self.add_indicator('RSI', self.data['1h'].Close, 14)
🔌 Pluggable Architecture
Custom Data Sources
from algame.data import DataSourceBase
class MyDataSource(DataSourceBase):
def fetch_data(self, symbol, start, end):
# Your data fetching logic
pass
# Register and use
register_data_source('my_source', MyDataSource)
data = load_data('AAPL', source='my_source')
Custom Indicators
from algame.indicators import IndicatorBase
class CustomIndicator(IndicatorBase):
def calculate(self, data):
# Your indicator logic
return result
# Use in strategy
class MyStrategy(StrategyBase):
def initialize(self):
self.custom = self.add_indicator(CustomIndicator, self.data.Close)
🎨 Strategy Building
Visual Builder
Template-Based Development
from algame.strategy import MomentumTemplate
class MyStrategy(MomentumTemplate):
def setup_parameters(self):
self.lookback = 20
self.threshold = 0.02
def generate_signals(self):
# Customize momentum logic
pass
🔄 PineScript Converter
Convert your TradingView strategies:
from algame.tools.converter import convert_strategy
# PineScript code
pine_code = """
//@version=5
strategy("My Strategy", overlay=true)
// Inputs
fast_length = input(10, "Fast Length")
slow_length = input(20, "Slow Length")
// Calculations
fast_ma = ta.sma(close, fast_length)
slow_ma = ta.sma(close, slow_length)
// Entry conditions
if ta.crossover(fast_ma, slow_ma)
strategy.entry("Long", strategy.long)
if ta.crossunder(fast_ma, slow_ma)
strategy.close("Long")
"""
# Convert to Python
python_code = convert_strategy(pine_code)
print(python_code)
📊 Advanced Analysis
from algame.analysis import PerformanceMetrics, RiskAnalysis
# Calculate metrics
metrics = PerformanceMetrics(results.equity_curve, results.trades)
print(f"Sharpe Ratio: {metrics.sharpe_ratio:.2f}")
print(f"Max Drawdown: {metrics.max_drawdown:.2f}%")
print(f"Win Rate: {metrics.win_rate:.1f}%")
# Risk analysis
risk = RiskAnalysis(results.returns, results.positions)
optimal_size = risk.calculate_position_size(
risk_per_trade=0.02, # 2% risk per trade
stop_loss=0.05 # 5% stop loss
)
📘 Documentation
API Reference
Core APIs
Engine API
The engine API provides the core backtesting functionality.
EngineManager
from algame.core import EngineManager
manager = EngineManager(config=None)
Methods:
-
run_backtest(strategy, data, parameters=None): Run a backtestresults = manager.run_backtest( strategy=MyStrategy, data=market_data, parameters={'sma_period': 20} )
-
optimize_strategy(strategy, parameter_space, **kwargs): Optimize strategy parametersresults = manager.optimize_strategy( strategy=MyStrategy, parameter_space={ 'sma_period': range(10, 50, 5), 'rsi_period': range(10, 30, 5) }, metric='sharpe_ratio' )
BacktestResult
Contains backtest results and performance metrics.
Attributes:
equity_curve: Equity curve as pandas Seriestrades: List of Trade objectsmetrics: Dictionary of performance metricsdrawdowns: Drawdown seriesreturns: Return series
Data API
The data API handles market data management.
DataManager
from algame.core.data import DataManager
manager = DataManager()
Methods:
-
get_data(symbol, source='yahoo', **kwargs): Load market datadata = manager.get_data( symbol='AAPL', source='yahoo', start='2020-01-01', end='2023-12-31' )
-
register_source(source_name, source_class): Register custom data sourcemanager.register_source('my_source', MyDataSource)
MarketData
Container for market data.
Methods:
resample(timeframe): Resample to new timeframeadd_indicator(name, function, *args): Add technical indicatorvalidate(): Validate data quality
Strategy API
The strategy API defines the interface for trading strategies.
StrategyBase
Base class for all trading strategies.
from algame.strategy import StrategyBase
class MyStrategy(StrategyBase):
def initialize(self):
"""Initialize strategy components."""
pass
def next(self):
"""Generate trading signals."""
pass
Methods:
initialize(): Setup strategy (indicators, parameters)next(): Generate trading signalsbuy(size=1.0, **kwargs): Place buy ordersell(size=1.0, **kwargs): Place sell orderclose(): Close current position
Analysis API
The analysis API provides performance analysis tools.
PerformanceMetrics
from algame.analysis import PerformanceMetrics
metrics = PerformanceMetrics(equity_curve, trades)
Metrics:
- Total Return
- Annual Return
- Sharpe Ratio
- Sortino Ratio
- Max Drawdown
- Win Rate
- Profit Factor
RiskAnalysis
from algame.analysis import RiskAnalysis
risk = RiskAnalysis(returns, positions)
Methods:
calculate_position_size(risk_per_trade, stop_loss)stress_test(scenarios)analyze_drawdowns()
GUI API
The GUI API provides the graphical interface components.
MainWindow
from algame.gui import MainWindow
window = MainWindow(root)
Components:
- DataPanel: Data management
- StrategyPanel: Strategy development
- ResultsPanel: Results analysis
- ConverterPanel: PineScript conversion
Tools API
Additional utilities and tools.
PineScriptConverter
from algame.tools.converter import PineScriptConverter
converter = PineScriptConverter()
Methods:
-
convert(pine_code): Convert PineScript to Python -
convert_file(input_file, output_file): Convert PineScript file -
Strategy Development Guide
Strategy Development Guide
Introduction
This guide covers:
- Basic strategy structure
- Technical indicators
- Entry/exit signals
- Risk management
- Advanced techniques
Basic Strategy Structure
Every strategy inherits from StrategyBase:
from algame.strategy import StrategyBase
class MyStrategy(StrategyBase):
def __init__(self, parameters=None):
super().__init__(parameters)
self.parameters = parameters or {
'sma_period': 20,
'rsi_period': 14,
'risk_per_trade': 0.02
}
def initialize(self):
"""Setup strategy components."""
# Add technical indicators
self.sma = self.add_indicator('SMA', self.data.Close,
period=self.parameters['sma_period'])
self.rsi = self.add_indicator('RSI', self.data.Close,
period=self.parameters['rsi_period'])
def next(self):
"""Generate trading signals."""
if not self.position.is_open:
if self.data.Close[-1] > self.sma[-1] and \
self.rsi[-1] < 70:
self.buy()
else:
if self.data.Close[-1] < self.sma[-1] or \
self.rsi[-1] > 70:
self.sell()
Using Technical Indicators
Built-in Indicators
# Moving Averages
self.sma = self.add_indicator('SMA', self.data.Close, period=20)
self.ema = self.add_indicator('EMA', self.data.Close, period=20)
self.wma = self.add_indicator('WMA', self.data.Close, period=20)
# Oscillators
self.rsi = self.add_indicator('RSI', self.data.Close, period=14)
self.macd = self.add_indicator('MACD', self.data.Close,
fast=12, slow=26, signal=9)
self.stoch = self.add_indicator('Stochastic', self.data.Close, period=14)
# Volatility
self.bb = self.add_indicator('Bollinger', self.data.Close,
period=20, std_dev=2)
self.atr = self.add_indicator('ATR', self.data, period=14)
# Volume
self.obv = self.add_indicator('OBV', self.data.Close, self.data.Volume)
self.vwap = self.add_indicator('VWAP', self.data)
Custom Indicators
from algame.indicators import IndicatorBase
class CustomIndicator(IndicatorBase):
def __init__(self, period):
self.period = period
def calculate(self, data):
# Your calculation logic
return result
# Use in strategy
self.custom = self.add_indicator(CustomIndicator(20), self.data.Close)
Entry/Exit Signals
Signal Types
- Price Action:
def next(self):
# Breakout
if self.data.Close[-1] > self.data.High[-20:].max():
self.buy()
# Support/Resistance
if self.data.Close[-1] < self.data.Low[-20:].min():
self.sell()
- Indicator Crossovers:
def next(self):
# MA Crossover
if self.fast_ma[-1] > self.slow_ma[-1] and \
self.fast_ma[-2] <= self.slow_ma[-2]:
self.buy()
# RSI Conditions
if self.rsi[-1] < 30:
self.buy()
elif self.rsi[-1] > 70:
self.sell()
- Multiple Conditions:
def next(self):
# Trend following with volume confirmation
trend_up = self.data.Close[-1] > self.sma[-1]
volume_high = self.data.Volume[-1] > self.data.Volume[-20:].mean()
rsi_ok = self.rsi[-1] < 70
if trend_up and volume_high and rsi_ok:
self.buy()
Risk Management
Position Sizing
def calculate_position_size(self):
"""Calculate position size based on risk."""
risk_amount = self.portfolio_value * self.parameters['risk_per_trade']
stop_distance = self.atr[-1] * 2 # 2 ATR stop
if stop_distance > 0:
return risk_amount / stop_distance
return 0
def next(self):
if self.entry_signal():
size = self.calculate_position_size()
if size > 0:
self.buy(size=size)
Stop Loss & Take Profit
def next(self):
if not self.position.is_open:
if self.entry_signal():
entry_price = self.data.Close[-1]
atr = self.atr[-1]
self.buy(
size=1.0,
sl=entry_price - (atr * 2), # 2 ATR stop
tp=entry_price + (atr * 3) # 3 ATR target
)
Advanced Techniques
Multi-Timeframe Analysis
class MultiTimeframeStrategy(StrategyBase):
def initialize(self):
# Daily timeframe
self.daily_sma = self.add_indicator('SMA', self.data['1d'].Close, 20)
# Hourly timeframe
self.hourly_rsi = self.add_indicator('RSI', self.data['1h'].Close, 14)
def next(self):
# Use both timeframes
if self.data['1d'].Close[-1] > self.daily_sma[-1] and \
self.hourly_rsi[-1] < 30:
self.buy()
Portfolio Management
class PortfolioStrategy(StrategyBase):
def initialize(self):
# Setup indicators for each asset
self.indicators = {}
for symbol in self.data.keys():
self.indicators[symbol] = {
'sma': self.add_indicator('SMA', self.data[symbol].Close, 20),
'rsi': self.add_indicator('RSI', self.data[symbol].Close, 14)
}
def next(self):
# Analyze each asset
for symbol, indicators in self.indicators.items():
if self.entry_signal(symbol, indicators):
# Calculate position size
weight = self.calculate_weight(symbol)
self.buy(symbol, size=weight)
Machine Learning Integration
from sklearn.ensemble import RandomForestClassifier
class MLStrategy(StrategyBase):
def initialize(self):
# Prepare features
self.feature_windows = [5, 10, 20]
self.features = self.prepare_features()
# Train model
self.model = RandomForestClassifier()
self.model.fit(self.features, self.labels)
def prepare_features(self):
# Create technical features
features = []
for window in self.feature_windows:
features.extend([
self.data.Close.rolling(window).mean(),
self.data.Close.rolling(window).std(),
self.data.Volume.rolling(window).mean()
])
return features
def next(self):
# Make prediction
current_features = self.get_current_features()
prediction = self.model.predict(current_features)
if prediction == 1:
self.buy()
elif prediction == -1:
self.sell()
- Advanced Features
Advanced Features
Event-Driven Backtesting
Custom Risk Metrics
Creating Custom Risk Metrics
from algame.analysis import RiskMetric
class CustomDrawdownMetric(RiskMetric):
def __init__(self, lookback=20):
self.lookback = lookback
def calculate(self, returns):
"""Calculate custom drawdown metric."""
equity = (1 + returns).cumprod()
rolling_max = equity.rolling(self.lookback).max()
drawdowns = (equity - rolling_max) / rolling_max
return drawdowns.min()
# Use in strategy
class MyStrategy(StrategyBase):
def initialize(self):
self.risk_metric = CustomDrawdownMetric(lookback=20)
def next(self):
risk_score = self.risk_metric.calculate(self.returns)
if risk_score < -0.1: # 10% drawdown threshold
self.reduce_exposure()
Advanced Backtesting Features
Walk-Forward Analysis
from algame.core.engine import WalkForwardTest
# Define test parameters
wf_test = WalkForwardTest(
strategy=MyStrategy,
train_period='6M',
test_period='2M',
overlap=0.5
)
# Run walk-forward optimization
results = wf_test.run(
data=market_data,
parameter_space={
'sma_period': range(10, 50, 5),
'risk_per_trade': [0.01, 0.02, 0.03]
}
)
# Analyze results
wf_test.plot_performance()
wf_test.parameter_stability()
Monte Carlo Analysis
from algame.analysis import MonteCarloSimulation
class MonteCarloStrategy(StrategyBase):
def analyze_risk(self):
# Setup simulation
mc = MonteCarloSimulation(
strategy=self,
num_simulations=1000,
variables={
'slippage': ('normal', 0.001, 0.0002),
'execution_delay': ('uniform', 0, 2)
}
)
# Run simulation
results = mc.run()
# Analyze results
confidence_intervals = mc.get_confidence_intervals()
var_estimate = mc.calculate_var(confidence=0.95)
return {
'confidence': confidence_intervals,
'var_95': var_estimate,
'worst_case': results.min()
}
Machine Learning Integration
Feature Engineering
from algame.ml import FeatureEngineering
class MLStrategy(StrategyBase):
def create_features(self):
engineer = FeatureEngineering(self.data)
# Technical features
engineer.add_ta_features([
('sma', [20, 50, 200]),
('rsi', [14]),
('bbands', [20, 2.0])
])
# Price features
engineer.add_price_features([
'returns',
'log_returns',
'realized_volatility'
])
# Volume features
engineer.add_volume_features([
'vwap',
'volume_profile',
'volume_delta'
])
return engineer.get_features()
### Model Training & Prediction
```python
from algame.ml import ModelTrainer
from sklearn.ensemble import GradientBoostingClassifier
class PredictiveStrategy(StrategyBase):
def initialize(self):
# Prepare data
X, y = self.prepare_training_data()
# Train model
self.trainer = ModelTrainer(
model=GradientBoostingClassifier(),
features=X,
labels=y,
cv_splits=5
)
self.model = self.trainer.train()
def next(self):
# Get current features
features = self.get_current_features()
# Make prediction
prob = self.model.predict_proba(features)[0]
# Trade based on prediction confidence
if prob[1] > 0.7: # 70% confidence for long
self.buy()
elif prob[0] > 0.7: # 70% confidence for short
self.sell()
Custom Data Integration
Real-Time Data Handlers
from algame.data import RealTimeHandler
class CustomDataHandler(RealTimeHandler):
def __init__(self, symbols):
super().__init__(symbols)
self.subscribers = []
def connect(self):
"""Connect to data source."""
# Your connection logic
pass
def subscribe(self, callback):
"""Subscribe to updates."""
self.subscribers.append(callback)
def on_data(self, data):
"""Handle incoming data."""
# Process data
processed = self.process_data(data)
# Notify subscribers
for callback in self.subscribers:
callback(processed)
# Use in live trading
handler = CustomDataHandler(['AAPL', 'GOOGL'])
strategy = MyStrategy(data_handler=handler)
Advanced GUI Components
Custom Indicators Panel
from algame.gui.components import IndicatorPanel
class CustomIndicatorPanel(IndicatorPanel):
def __init__(self, master):
super().__init__(master)
self.create_controls()
def create_controls(self):
"""Create indicator controls."""
# Add parameters
self.add_parameter('period', 14, (5, 50))
self.add_parameter('threshold', 0.5, (0, 1))
# Add plot options
self.add_plot_option('color', 'blue')
self.add_plot_option('style', 'line')
def calculate(self):
"""Calculate indicator values."""
# Your calculation logic
pass
def plot(self, ax):
"""Plot indicator."""
# Your plotting logic
pass
Strategy Analytics Dashboard
from algame.gui.components import AnalyticsDashboard
class StrategyDashboard(AnalyticsDashboard):
def __init__(self, master):
super().__init__(master)
self.create_panels()
def create_panels(self):
"""Create dashboard panels."""
# Performance metrics
self.add_metrics_panel()
# Charts
self.add_equity_chart()
self.add_drawdown_chart()
# Trade analysis
self.add_trade_list()
self.add_trade_statistics()
def update(self, results):
"""Update dashboard with new results."""
self.update_metrics(results.metrics)
self.update_charts(results.equity_curve)
self.update_trades(results.trades)
These advanced features make Algame a powerful platform for both research and trading. Use them to:
- Implement sophisticated strategies
- Integrate machine learning
- Create custom analysis tools
- Build professional-grade GUIs Events
from algame.core.engine import Event, EventType
class MyStrategy(StrategyBase):
def initialize(self):
# Register custom event
self.register_event(
EventType.CUSTOM,
'volatility_spike',
self.handle_volatility_spike
)
def next(self):
# Check for volatility spike
if self.data.High[-1] - self.data.Low[-1] > self.atr[-1] * 2:
self.emit_event('volatility_spike', {
'magnitude': self.data.High[-1] - self.data.Low[-1],
'volume': self.data.Volume[-1]
})
def handle_volatility_spike(self, event):
"""Handle volatility spike event."""
if event.data['volume'] > self.data.Volume[-20:].mean():
self.close() # Close positions on high volatility
Advanced Order Types
Conditional Orders
class MyStrategy(StrategyBase):
def place_conditional_order(self):
# OCO (One-Cancels-Other)
self.buy(
size=1.0,
condition={
'type': 'OCO',
'orders': [
{'type': 'limit', 'price': self.data.Close[-1] * 0.98},
{'type': 'stop', 'price': self.data.Close[-1] * 1.02}
]
}
)
def place_trailing_stop(self):
# Trailing stop
self.sell(
size=self.position.size,
condition={
'type': 'trailing_stop',
'distance': self.atr[-1] * 2
}
)
Portfolio Optimization
Risk Parity
from algame.analysis import RiskParity
class RiskParityStrategy(StrategyBase):
def optimize_weights(self):
# Calculate risk-parity weights
optimizer = RiskParity(
returns=self.get_returns(),
risk_measure='conditional_var'
)
weights = optimizer.optimize()
return weights
def rebalance_portfolio(self):
weights = self.optimize_weights()
for asset, weight in weights.items():
current_weight = self.get_position_weight(asset)
if abs(current_weight - weight) > 0.05: # 5% threshold
self.rebalance_position(asset, weight)
- Best Practices
Best Practices
Strategy Development
1. Code Structure
✅ Do:
class WellStructuredStrategy(StrategyBase):
def __init__(self, parameters=None):
super().__init__(parameters)
self.validate_parameters()
def initialize(self):
# Group indicator initialization
self.setup_indicators()
# Group risk parameters
self.setup_risk_management()
def setup_indicators(self):
"""Initialize technical indicators."""
self.sma = self.add_indicator('SMA', self.data.Close,
self.parameters['sma_period'])
self.rsi = self.add_indicator('RSI', self.data.Close,
self.parameters['rsi_period'])
def setup_risk_management(self):
"""Setup risk parameters."""
self.max_risk = self.parameters['risk_per_trade']
self.stop_atr = self.parameters['stop_atr']
def next(self):
# Clear decision flow
if not self.position.is_open:
if self.entry_signal():
self.enter_position()
else:
if self.exit_signal():
self.exit_position()
def entry_signal(self):
"""Generate entry signals."""
return (self.trend_signal() and
self.momentum_signal() and
self.risk_allows_entry())
def exit_signal(self):
"""Generate exit signals."""
return (self.stop_loss_hit() or
self.take_profit_hit() or
self.trend_reversal())
❌ Don't:
class PoorlyStructuredStrategy(StrategyBase):
def next(self):
# Hard to understand and maintain
if (self.data.Close[-1] > self.data.Close[-20:].mean() and
self.data.Volume[-1] > 1000000 and
abs(self.data.Close[-1] - self.data.Close[-2]) < 0.02 and
self.position.size == 0):
self.buy(size=1.0)
elif self.position.size > 0 and self.data.Close[-1] < self.data.Close[-20:].mean():
self.sell()
2. Risk Management
✅ Do:
def calculate_position_size(self):
"""Calculate position size based on risk."""
account_risk = self.portfolio_value * self.max_risk
stop_distance = self.calculate_stop_distance()
if stop_distance <= 0:
return 0
return account_risk / stop_distance
def calculate_stop_distance(self):
"""Calculate adaptive stop distance."""
atr = self.atr[-1]
return max(
atr * self.stop_atr, # ATR-based stop
self.data.Close[-1] * 0.01 # Minimum 1% stop
)
❌ Don't:
def next(self):
# Fixed position size ignores risk
self.buy(size=100)
# Fixed stop loss ignores volatility
self.set_stop_loss(self.data.Close[-1] * 0.95)
3. Data Handling
✅ Do:
def validate_data(self):
"""Validate input data."""
required_columns = ['Open', 'High', 'Low', 'Close', 'Volume']
# Check required columns
if not all(col in self.data.columns for col in required_columns):
raise ValueError(f"Missing required columns: {required_columns}")
# Check for missing values
if self.data.isnull().any().any():
self.handle_missing_data()
def handle_missing_data(self):
"""Handle missing values."""
# Forward fill prices
self.data.loc[:, ['Open', 'High', 'Low', 'Close']] = \
self.data[['Open', 'High', 'Low', 'Close']].ffill()
# Fill volume with 0
self.data['Volume'] = self.data['Volume'].fillna(0)
❌ Don't:
def next(self):
# Dangerous direct indexing without checks
price = self.data.Close[-1]
if np.isnan(price):
price = 0 # Bad handling of missing data
4. Performance Optimization
✅ Do:
class OptimizedStrategy(StrategyBase):
def initialize(self):
# Pre-calculate expensive computations
self.setup_indicators()
# Use numpy arrays for performance
self._prices = self.data.Close.to_numpy()
self._volumes = self.data.Volume.to_numpy()
def next(self):
# Use vectorized operations
returns = np.diff(self._prices[-20:])
volatility = returns.std()
# Efficient boolean logic
trend_up = self._prices[-1] > self.sma[-1]
vol_high = self._volumes[-1] > self._volumes[-20:].mean()
if trend_up and vol_high:
self.buy()
❌ Don't:
def next(self):
# Expensive calculations in loop
for i in range(20):
if self.data.Close[-i] > self.data.Close[-i-1]:
# Process each point
pass
5. Testing & Validation
✅ Do:
class RobustStrategy(StrategyBase):
def validate_parameters(self):
"""Validate strategy parameters."""
required = ['sma_period', 'rsi_period', 'risk_per_trade']
# Check required parameters
for param in required:
if param not in self.parameters:
raise ValueError(f"Missing required parameter: {param}")
# Validate values
if self.parameters['risk_per_trade'] > 0.02:
raise ValueError("Risk per trade cannot exceed 2%")
def validate_results(self, results):
"""Validate strategy results."""
# Check for realistic performance
if results.metrics['max_drawdown'] > 30:
logger.warning("High drawdown detected")
# Check for excessive trading
trades_per_day = len(results.trades) / len(self.data)
if trades_per_day > 5:
logger.warning("High trading frequency detected")
❌ Don't:
def next(self):
# No parameter validation
size = self.parameters.get('size', 100)
self.buy(size=size) # Could be dangerous
# No results validation
if self.pnl > 1000000:
logger.info("Great success!") # Could be unrealistic
Common Pitfalls to Avoid
- Lookahead Bias
# ❌ Wrong: Using future data
def next(self):
future_high = self.data.High[len(self.data)].max() # Lookahead!
# ✅ Correct: Only use available data
def next(self):
current_high = self.data.High[:len(self.data)].max()
- Survivorship Bias
# ❌ Wrong: Using current S&P 500 list historically
universe = sp500_current_symbols
# ✅ Correct: Use point-in-time data
universe = get_historical_sp500_composition(date)
🔧 Under Development
Features coming soon:
- Live Trading Support
- Enhanced PineScript Converter
- Machine Learning Integration
- Portfolio Optimization
- Advanced Order Types
- Strategy Marketplace
👥 Authors
- Mrigesh Thakur - Lead Developer - GitHub
- Dharuva Thakur - Core Developer - GitHub
- Maanas Sood - Core Developer - GitHub
📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by traders who code
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file algame_mrimadha-0.1.0.tar.gz.
File metadata
- Download URL: algame_mrimadha-0.1.0.tar.gz
- Upload date:
- Size: 31.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
696fd471f3f25cddce9a1260fd9496a6cd65e19284744de160d1ad54c172df2c
|
|
| MD5 |
74140a44d14fa596ba0965351343356d
|
|
| BLAKE2b-256 |
e6f81b14954896766c3445a4a42ff094d935ea1ec7e6ebfafcfa279cd7f0dcee
|
File details
Details for the file algame_MRIMADHA-0.1.0-py3-none-any.whl.
File metadata
- Download URL: algame_MRIMADHA-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb2ffccc354460e34b85bb11975a596c7e52cb9e58a400d66a7222c0e405f70f
|
|
| MD5 |
28f833f1fd90bd5fdd5664bbe66c509c
|
|
| BLAKE2b-256 |
814c5cc7c138eb1c9d5a85197428d6d350cfc6b2634aef12fcb11dcc30ce6c65
|