algame-MRIMADHA 0.1.0
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.
License: MIT
Requires Python: >=3.8

# 🎮 Algame-MRIMADHA

<div align="center">

![Algame Logo](resources/logo.png)

[![PyPI version](https://badge.fury.io/py/algame-mrimadha.svg)](https://badge.fury.io/py/algame-mrimadha)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![Documentation Status](https://readthedocs.org/projects/algame-mrimadha/badge/?version=latest)](https://algame-mrimadha.readthedocs.io/)

**📈 A Modern Algorithmic Trading & Backtesting Framework**

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

[Installation](#installation) • [Quick Start](#quick-start) • [Documentation](https://algame-mrimadha.readthedocs.io/) • [Examples](examples/) • [Contributing](CONTRIBUTING.md)

</div>

---

## 🌟 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

```bash
pip install algame-mrimadha
```

Development Version:
```bash
pip install git+https://github.com/mrigesh/algame-mrimadha.git
```

---

## 🏃‍♂️ Quick Start

### Code Your First Strategy
```python
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
```python
from algame.gui import start_app

start_app()
```

![GUI Screenshot](resources/gui_main.png)

---

## ✨ Key Features

### 🎯 Multi-Everything Support

#### Multi-Asset Trading
```python
# 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
```python
# 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
```python
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
```python
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](resources/strategy_builder.png)

#### Template-Based Development
```python
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:

```python
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

```python
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](resources/analysis_dashboard.png)

---

## 📘 Documentation

# API Reference

## Core APIs

### Engine API

The engine API provides the core backtesting functionality.

#### EngineManager

```python
from algame.core import EngineManager

manager = EngineManager(config=None)
```

**Methods:**

- `run_backtest(strategy, data, parameters=None)`: Run a backtest
  ```python
  results = manager.run_backtest(
      strategy=MyStrategy,
      data=market_data,
      parameters={'sma_period': 20}
  )
  ```

- `optimize_strategy(strategy, parameter_space, **kwargs)`: Optimize strategy parameters
  ```python
  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

```python
from algame.core.data import DataManager

manager = DataManager()
```

**Methods:**

- `get_data(symbol, source='yahoo', **kwargs)`: Load market data
  ```python
  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
  ```python
  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.

```python
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

```python
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

```python
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

```python
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

```python
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`:

```python
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

```python
# 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

```python
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:
```python
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()
```

2. Indicator Crossovers:
```python
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()
```

3. Multiple Conditions:
```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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

```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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:
```python
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
```python
# ❌ 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()
```

2. Survivorship Bias
```python
# ❌ 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](https://github.com/Legend101Zz)
- **Dharuva Thakur** - *Core Developer* - [GitHub](https://github.com/Dharuva)
- **Maanas Sood** - *Core Developer* - [GitHub](https://github.com/maanasood)

---

## 📜 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

---

<div align="center">

Made with ❤️ by traders who code

[⬆ back to top](#)

</div>