Skip to main content

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

Algame Logo

PyPI version License: MIT Python 3.8+ Documentation Status

📈 A Modern Algorithmic Trading & Backtesting Framework

By traders, for traders - Making algo trading accessible without compromising power

InstallationQuick StartDocumentationExamplesContributing


🌟 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()

GUI Screenshot


✨ 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

Strategy 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
)

Analysis Dashboard


📘 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 backtest

    results = manager.run_backtest(
        strategy=MyStrategy,
        data=market_data,
        parameters={'sma_period': 20}
    )
    
  • optimize_strategy(strategy, parameter_space, **kwargs): Optimize strategy parameters

    results = 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 Series
  • trades: List of Trade objects
  • metrics: Dictionary of performance metrics
  • drawdowns: Drawdown series
  • returns: 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 data

    data = manager.get_data(
        symbol='AAPL',
        source='yahoo',
        start='2020-01-01',
        end='2023-12-31'
    )
    
  • register_source(source_name, source_class): Register custom data source

    manager.register_source('my_source', MyDataSource)
    

MarketData

Container for market data.

Methods:

  • resample(timeframe): Resample to new timeframe
  • add_indicator(name, function, *args): Add technical indicator
  • validate(): 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 signals
  • buy(size=1.0, **kwargs): Place buy order
  • sell(size=1.0, **kwargs): Place sell order
  • close(): 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:

  1. Basic strategy structure
  2. Technical indicators
  3. Entry/exit signals
  4. Risk management
  5. 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

  1. 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()
  1. 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()
  1. 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

  1. 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()
  1. 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

⬆ back to top

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

algame_mrimadha-0.1.0.tar.gz (31.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

algame_MRIMADHA-0.1.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

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

Hashes for algame_mrimadha-0.1.0.tar.gz
Algorithm Hash digest
SHA256 696fd471f3f25cddce9a1260fd9496a6cd65e19284744de160d1ad54c172df2c
MD5 74140a44d14fa596ba0965351343356d
BLAKE2b-256 e6f81b14954896766c3445a4a42ff094d935ea1ec7e6ebfafcfa279cd7f0dcee

See more details on using hashes here.

File details

Details for the file algame_MRIMADHA-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for algame_MRIMADHA-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cb2ffccc354460e34b85bb11975a596c7e52cb9e58a400d66a7222c0e405f70f
MD5 28f833f1fd90bd5fdd5664bbe66c509c
BLAKE2b-256 814c5cc7c138eb1c9d5a85197428d6d350cfc6b2634aef12fcb11dcc30ce6c65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page