Skip to content

Legend101Zz/Algame-MRIMADHA

Repository files navigation

🎮 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/Legend101Zz/Algame-MRIMADHA.git

Development Setup

Quick Start for Developers

  1. Clone the repository:
git clone https://github.com/Legend101Zz/Algame-MRIMADHA.git
cd Algame-MRIMADHA
  1. Create and activate a virtual environment:
# Windows
python -m venv venv
venv\Scripts\activate

# Linux/Mac
python -m venv venv
source venv/bin/activate
  1. Run the development setup script:
python scripts/dev_setup.py

Running the Package

After setup, you can:

  1. Start the GUI:
python -m algame
  1. Run the quick start example:
python examples/quickstart.py
  1. Run tests:
pytest tests/

Project Structure

algame-MRIMADHA/
├── src/
│   └── algame/          # Main package directory
├── tests/               # Test files
├── examples/            # Example scripts
├── scripts/             # Development scripts
├── docs/                # Documentation
└── requirements/        # Requirement files

Contributing

  1. Create a new branch for your feature/fix:
git checkout -b feature-name
  1. Make your changes and run tests:
pytest tests/
  1. Submit a pull request to the main repository.

Common Development Tasks

  • Run specific test module:
pytest tests/core/test_engine.py
  • Run with coverage report:
pytest --cov=algame tests/
  • Start GUI in debug mode:
python -m algame --debug
  • Build documentation:
cd docs
make html

Troubleshooting Development Setup

If you encounter issues:

  1. Make sure you're in the virtual environment
  2. Try removing and reinstalling dependencies:
pip uninstall algame-mrimadha
pip install -e .
  1. Check the logs in ~/.algame/logs/

For more help, please open an issue on GitHub.

🏃‍♂️ 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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages