Algorithm Lab

Build, test, and deploy quantitative strategies

Explorer
mainv2.4.1
MomentumAlpha / main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># QuantAlgo Labs - Momentum Alpha Strategy
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Algorithm ID: algo_28451
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Last Modified: 2024-01-12 14:32:15 UTC
 
from quantalgo import Algorithm, Resolution, Universe
from quantalgo.indicators import RSI, MACD, SMA
from quantalgo.risk import PositionSizer, StopLoss
 
class MomentumAlpha(Algorithm):
class="text-[#a5d6a7]">"""
Momentum-based strategy that identifies breakout opportunities
using RSI divergence and MACD confirmation signals.
class="text-[#a5d6a7]">"""
def initialize(self):
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Strategy Configuration
self.set_start_date(2023, 1, 1)
self.set_end_date(2024, 1, 1)
self.set_cash(1_000_000)
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Universe Selection
self.universe = Universe.top_dollar_volume(500)
self.add_universe(self.universe)
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Technical Indicators
self.rsi_period = 14
self.rsi_overbought = 70
self.rsi_oversold = 30
self.macd_fast = 12
self.macd_slow = 26
self.macd_signal = 9
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Risk Parameters
self.position_size = 0.10 class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># 10% per position
self.max_positions = 10
self.stop_loss = 0.02 class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># 2% stop loss
self.take_profit = 0.06 class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># 6% take profit
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Initialize indicators dict
self.indicators = {}
self.log(class="text-[#a5d6a7]">"Momentum Alpha initialized successfully")
def on_securities_changed(self, changes):
for security in changes.added_securities:
symbol = security.symbol
self.indicators[symbol] = {
class="text-[#a5d6a7]">'rsi': RSI(symbol, self.rsi_period),
class="text-[#a5d6a7]">'macd': MACD(symbol, self.macd_fast, self.macd_slow, self.macd_signal),
class="text-[#a5d6a7]">'sma_50': SMA(symbol, 50),
class="text-[#a5d6a7]">'sma_200': SMA(symbol, 200),
}
def on_data(self, data):
for symbol in self.active_securities:
if not self._indicators_ready(symbol):
continue
indicators = self.indicators[symbol]
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Entry Logic
if self._check_entry_signal(symbol, indicators):
self._execute_entry(symbol, data[symbol].close)
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Exit Logic
if self.portfolio[symbol].invested:
self._check_exit_conditions(symbol, indicators, data[symbol].close)
def _check_entry_signal(self, symbol, indicators):
rsi = indicators[class="text-[#a5d6a7]">'rsi'].current.value
macd = indicators[class="text-[#a5d6a7]">'macd']
sma_50 = indicators[class="text-[#a5d6a7]">'sma_50'].current.value
sma_200 = indicators[class="text-[#a5d6a7]">'sma_200'].current.value
class=class="text-[#a5d6a7]">"text-muted-foreground/60 italic"># Bullish conditions
trend_up = sma_50 > sma_200
rsi_signal = rsi < self.rsi_oversold
macd_crossover = macd.signal.current.value > macd.current.value
return trend_up and rsi_signal and macd_crossover
def _execute_entry(self, symbol, price):
if len(self.portfolio.invested) >= self.max_positions:
return
quantity = PositionSizer.fixed_percent(
self.portfolio.cash,
price,
self.position_size
)
self.market_order(symbol, quantity)
self.log(fclass="text-[#a5d6a7]">"ENTRY: {symbol} @ {price:.2f}, qty: {quantity}")
 
[14:32:15]Algorithm initialized successfully
[14:32:15]Universe: Top 500 by dollar volume
[14:32:16]Starting backtest: 2023-01-01 to 2024-01-01
[14:32:18]Loaded 500 securities
[14:32:20]ENTRY: NVDA @ 485.00, qty: 150
[14:32:22]ENTRY: AAPL @ 178.25, qty: 200
[14:32:25]Position limit reached (10/10)
[14:32:28]EXIT: NVDA @ 512.30, P&L: +$4,095 (+5.63%)
[14:32:30]Processing date: 2023-06-15
[14:32:32]Insufficient data for TSLA indicators
[14:32:45]Backtest completed in 30.2s

Algorithm Settings

Configure runtime parameters

Backtest Period

Capital

Risk Management

10%
2%
6%
10

Data Resolution

Universe

Recent Backtests

2 min ago
+68.5%
1 hr ago
+42.3%
3 hr ago
Failed