trading-strategy-development
Trading Strategy Development
Quick Start
When creating or modifying a trading strategy:
- Use the standard strategy class structure
- Implement entry/exit logic with proper risk management
- Add position tracking and state management
- Include structured logging with
[ENTRY],[EXIT],[REJECTED],[POSITION],[METRICS]tags - Configure strategy parameters for backtesting
Strategy Structure Template
#!/usr/bin/env python3
"""
Strategy Name - Brief Description
"""
import os
import time
import logging
import pandas as pd
import numpy as np
import requests
from datetime import datetime
from pathlib import Path
# Configuration
SYMBOL = "REPLACE_ME" # Injected by strategy manager
API_HOST = os.getenv('OPENALGO_HOST', 'http://127.0.0.1:5001')
API_KEY = os.getenv('OPENALGO_APIKEY', 'demo_key')
# Strategy Parameters
PARAMS = {
'risk_per_trade': 0.02, # 2% of capital
'stop_loss_pct': 1.5,
'take_profit_pct': 3.0,
# Add strategy-specific parameters
}
# Setup Logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(f"Strategy_{SYMBOL}")
class StrategyName:
def __init__(self, symbol, params):
self.symbol = symbol
self.params = params
self.position = 0
self.data = pd.DataFrame()
self.entry_price = 0.0
def fetch_data(self):
"""Fetch market data from OpenAlgo API"""
# Implementation here
pass
def calculate_indicators(self):
"""Calculate technical indicators"""
# RSI, MACD, ADX, ATR, VWAP, etc.
pass
def check_signals(self):
"""Check entry and exit conditions"""
if self.data.empty:
return
current = self.data.iloc[-1]
prev = self.data.iloc[-2]
# Entry Logic
if self.position == 0:
if self._entry_conditions_met(current, prev):
self.entry("BUY", current['close'])
# Exit Logic
elif self.position != 0:
if self._exit_conditions_met(current, prev):
self.exit("SELL", current['close'])
def entry(self, side, price):
"""Execute entry signal"""
logger.info(f"[ENTRY] {side} {self.symbol} at {price:.2f}")
# Place order via API
self.position = 1 if side == "BUY" else -1
self.entry_price = price
def exit(self, side, price):
"""Execute exit signal"""
pnl = self._calculate_pnl(price)
logger.info(f"[EXIT] {side} {self.symbol} at {price:.2f} | PnL: {pnl:.2f}")
self.position = 0
self.entry_price = 0.0
def run(self):
"""Main strategy loop"""
logger.info(f"Starting strategy for {self.symbol}")
while True:
self.fetch_data()
self.calculate_indicators()
self.check_signals()
time.sleep(60) # Check every minute
Common Patterns
Entry Conditions
Momentum Strategy:
if (current['adx'] > 25 and
current['rsi'] > 50 and
current['close'] > prev['close'] and
current['volume'] > prev['volume'] * 1.2):
self.entry("BUY", current['close'])
Mean Reversion Strategy:
if (current['rsi'] < 30 and
current['close'] < current['lower_bb'] and
current['close'] < current['vwap']):
self.entry("BUY", current['close'])
Breakout Strategy:
if (current['close'] > current['resistance'] and
current['volume'] > current['avg_volume'] * 1.5 and
current['adx'] > 20):
self.entry("BUY", current['close'])
Exit Conditions
Stop Loss:
if self.position > 0:
stop_loss = self.entry_price * (1 - self.params['stop_loss_pct'] / 100)
if current['close'] < stop_loss:
self.exit("SELL", current['close'])
Take Profit:
if self.position > 0:
take_profit = self.entry_price * (1 + self.params['take_profit_pct'] / 100)
if current['close'] > take_profit:
self.exit("SELL", current['close'])
Trailing Stop:
if self.position > 0:
trailing_stop = current['close'] - (2 * current['atr'])
if trailing_stop > self.entry_price:
self.exit("SELL", current['close'])
Technical Indicators
RSI:
delta = df['close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
df['rsi'] = 100 - (100 / (1 + rs))
ATR:
high_low = df['high'] - df['low']
high_close = np.abs(df['high'] - df['close'].shift())
low_close = np.abs(df['low'] - df['close'].shift())
ranges = pd.concat([high_low, high_close, low_close], axis=1)
true_range = np.max(ranges, axis=1)
df['atr'] = true_range.rolling(window=14).mean()
VWAP (Intraday):
df['tp'] = (df['high'] + df['low'] + df['close']) / 3
df['pv'] = df['tp'] * df['volume']
df['cum_pv'] = df.groupby(df['datetime'].dt.date)['pv'].cumsum()
df['cum_vol'] = df.groupby(df['datetime'].dt.date)['volume'].cumsum()
df['vwap'] = df['cum_pv'] / df['cum_vol']
Risk Management
Position Sizing
def calculate_position_size(self, entry_price, stop_loss_price):
"""Calculate position size based on risk per trade"""
risk_amount = ACCOUNT_SIZE * self.params['risk_per_trade']
risk_per_unit = abs(entry_price - stop_loss_price)
if risk_per_unit == 0:
return 0
quantity = int(risk_amount / risk_per_unit)
return max(quantity, 1) # Minimum 1 unit
Portfolio Heat Limits
def check_portfolio_heat(self):
"""Check total portfolio risk exposure"""
total_risk = sum(self._calculate_position_risk(pos) for pos in self.positions)
max_heat = ACCOUNT_SIZE * 0.02 # 2% max portfolio heat
if total_risk >= max_heat:
logger.warning("[REJECTED] Portfolio heat limit reached")
return False
return True
Time-Based Exits
from datetime import time
import pytz
def is_market_closing_soon(self):
"""Check if market is closing soon (exit before 15:15 IST)"""
ist = pytz.timezone('Asia/Kolkata')
now = datetime.now(ist).time()
return now >= time(15, 15) # Exit 15 minutes before market close
Logging Standards
Use structured logging tags:
[ENTRY]- Entry signal generated[EXIT]- Exit signal generated[REJECTED]- Signal rejected (risk limits, filters, etc.)[POSITION]- Position update[METRICS]- Performance metrics
Example:
logger.info(f"[ENTRY] BUY {self.symbol} @ {price:.2f} | RSI={rsi:.1f} ADX={adx:.1f}")
logger.info(f"[EXIT] SELL {self.symbol} @ {price:.2f} | PnL={pnl:.2f}")
logger.warning(f"[REJECTED] Entry blocked: Portfolio heat limit")
logger.info(f"[METRICS] Win Rate: {win_rate:.1f}% | Profit Factor: {pf:.2f}")
Strategy Types
Equity Strategies
- Location:
openalgo/strategies/scripts/ - Examples:
advanced_equity_strategy.py,sector_momentum_strategy.py - Focus: NSE stocks, sector rotation, momentum
Options Strategies
- Location:
openalgo/strategies/scripts/ - Examples:
advanced_options_ranker.py - Focus: IV rank, Greeks, spread strategies, delta neutrality
- Use port 5002 (Dhan broker)
MCX Strategies
- Location:
openalgo/strategies/scripts/ - Examples:
mcx_commodity_momentum_strategy.py,mcx_advanced_strategy.py - Focus: Commodities, futures, global arbitrage
Common Issues
Strategies Not Placing Orders
Check:
- Entry conditions are too strict (relax filters)
- Risk limits blocking entries (check portfolio heat)
- Market hours validation (ensure market is open)
- API connectivity (verify OpenAlgo server is running)
Position Tracking Issues
Use PositionManager from trading_utils.py:
from openalgo.strategies.utils.trading_utils import PositionManager
pm = PositionManager(symbol)
if not pm.has_position():
pm.update_position(qty, price, 'BUY')
Testing
Before deploying:
- Test with paper trading mode
- Verify entry/exit logic with historical data
- Check risk management limits
- Validate logging output
- Test API connectivity
Additional Resources
- Strategy examples:
openalgo/strategies/scripts/ - Utility functions:
openalgo/strategies/utils/trading_utils.py - Backtest framework:
openalgo/strategies/utils/simple_backtest_engine.py - Integration guide:
openalgo/strategies/AITRAPP_INTEGRATION_GUIDE.md
More from sayujks0071/antidhan
risk-management
Implement and review risk controls, position sizing, portfolio heat limits, stop losses, and risk monitoring. Use when implementing risk management, reviewing risk controls, calculating position sizes, or analyzing portfolio risk exposure.
7trading-operations
Daily trading operations, monitoring, troubleshooting, deployment, and system health checks. Use when starting trading sessions, monitoring strategies, troubleshooting issues, checking system status, or deploying strategies.
7pr-49-review
Reviews pull request #49 for OpenAlgo observability changes, focusing on risks, security, and test coverage. Use when analyzing PR #49 or when the user asks about the local observability stack changes.
6log-monitoring
Monitor current logs in real-time, track log file sizes, watch for new entries, and check log health across system and strategy logs. Use when monitoring live logs, checking log status, watching for errors, or tracking log file growth.
6plan-based-skill-builder
Builds Cursor skills from plan documents by analyzing workflows, extracting key instructions, and creating structured skill files. Use when creating skills from restart plans, deployment plans, prioritization plans, retest plans, or any structured plan documents.
6backtesting-analysis
Run backtests, analyze strategy performance, compare strategies, and generate ranking reports. Use when backtesting strategies, analyzing performance metrics, comparing strategy variants, or generating backtest reports.
6