Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
100000
Net Profit
0%
Sharpe Ratio
0
Sortino Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-2.303
Tracking Error
0.085
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
from AlgorithmImports import *
from datetime import date
from typing import List
class SymbolData:
    def __init__(self, open_price: float, current_date: date):
        self.open_price = open_price
        self.bought_today = False
        self.entry_price = 0.0
        self.current_date = current_date
    def __repr__(self):
        return f"Open: {self.open_price}, Bought: {self.bought_today}, Entry: {self.entry_price}"
class GapUpBreakout(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2020, 12, 1)
        self.set_end_date(2020, 12, 15)
        self.set_cash(100000)
        # Add a coarse universe for stock selection
        self.add_universe(self.coarse_selection_function)
        self._symbol_data = {}
        self._previous_second = -1
    def coarse_selection_function(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        # Filter to fundamental data and limit to US exchanges
        return [
            c.symbol
            for c in coarse
            if c.has_fundamental_data
               and c.symbol.id.market in ("usa", "nys", "ase", "arca", "nasdaq")
        ]
    def on_data(self, data: Slice) -> None:
        # 1) Exit logic: take profit or stop loss
        for symbol, bar in data.bars.items():
            if symbol not in self._symbol_data:
                continue
            sd = self._symbol_data[symbol]
            if not sd.bought_today:
                continue
            current_price = bar.close
            if sd.entry_price > 0:
                # Using open price as reference
                take_profit_level = sd.open_price * 1.60
                stop_loss_level = sd.open_price * 0.90
                if current_price >= take_profit_level:
                    self.liquidate(symbol)
                    sd.bought_today = False
                    sd.entry_price = 0.0
                elif current_price <= stop_loss_level:
                    self.liquidate(symbol)
                    sd.bought_today = False
                    sd.entry_price = 0.0
        # 2) Entry logic once per second
        if self.time.second != self._previous_second:
            self._previous_second = self.time.second
            current_date = self.time.date()
            for symbol in self.active_securities.keys:
                # Ensure we have daily bars for this symbol
                if symbol not in data.bars:
                    continue
                bar = data.bars[symbol]
                current_open = bar.open
                current_close = bar.close
                # Get the previous day's close
                history = self.history(symbol, 2, Resolution.DAILY)
                if history.empty or history.shape[0] < 2:
                    continue
                prev_close = history["close"].iloc[-2]
                # If new day or symbol not known, consider it for tracking
                if (
                    symbol not in self._symbol_data
                    or self._symbol_data[symbol].current_date != current_date
                ):
                    # Check gap requirements
                    if current_open >= 2.75 and current_open >= prev_close * 1.10:
                        self._symbol_data[symbol] = SymbolData(current_open, current_date)
                else:
                    sd = self._symbol_data[symbol]
                    # Look for breakout from today's open
                    if not sd.bought_today and sd.open_price > 0.0:
                        breakout_level = sd.open_price * 1.20
                        if current_close > breakout_level:
                            qty = self.calculate_order_quantity(symbol, 0.01)
                            if qty != 0:
                                self.buy(symbol, qty)
                                sd.bought_today = True
                                sd.entry_price = current_close
    def on_end_of_day(self, symbol: Symbol) -> None:
        # Liquidate positions in the symbol passed at the end of day
        if symbol in self._symbol_data:
            sd = self._symbol_data[symbol]
            if sd.bought_today:
                self.liquidate(symbol)
                sd.bought_today = False
                sd.entry_price = 0.0