| Overall Statistics |
|
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 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 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import *
from QuantConnect import *
from QuantConnect.Algorithm import QCAlgorithm
from QuantConnect.Indicators.CandlestickPatterns import Engulfing
from datetime import timedelta
class Watchlist(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 5, 17) # Start Date
self.SetEndDate(2023, 5, 27) # End Date
self.SetCash(100000) # Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverse(self.CoarseFilter)
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Cash)
self.previous_day_data = {}
self.SetWarmUp(2, Resolution.Daily)
self.previousBar = None
self.filtered_symbols = set()
self.patterns = {}
self.engulfingNOW = set()
self.consolidatorToSymbol = {}
def CoarseFilter(self, coarse):
CoarseFilterResult = sorted(
[x for x in coarse if x.Price < 30 and x.MarketCap < 1.5e9],
key=lambda x: x.DollarVolume,
reverse=True)[:50]
return [x.Symbol for x in CoarseFilterResult]
def OnSecuritiesChanged(self, changes):
for security in changes.AddedSecurities:
symbol = security.Symbol
if symbol not in self.patterns:
engulfing = Engulfing() # create new instance of the method
self.patterns[symbol] = engulfing # if pattern occurs, add to class definition
consolidator = QuoteBarConsolidator(1)
consolidator.DataConsolidated += self.consolidation_handler
self.consolidatorToSymbol[consolidator] = symbol
self.SubscriptionManager.AddConsolidator(symbol, consolidator)
self.RegisterIndicator(symbol, engulfing, consolidator)
# stocks are added if there was an engulfing pattern present at all
def consolidation_handler(self, sender, consolidated):
symbol = self.consolidatorToSymbol.get(sender, None)
pattern_value = self.patterns[symbol].Current.Value
if self.patterns[symbol].IsReady:
if self.patterns[symbol].Current.Value != 0:
self.engulfingNOW.add(symbol)
self.Log(f"{symbol} Engulfing value: {pattern_value}")
def OnData(self, data):
for symbol in self.engulfingNOW:
if symbol in data and data[symbol] is not None:
history_daily = self.History(symbol, 15, Resolution.Daily)
history_minute = self.History(symbol, 2, Resolution.Minute)
if not history_daily.empty and 'volume' in history_daily.columns and \
not history_minute.empty and 'close' in history_minute.columns:
volume_ratio = history_daily['volume'].iloc[-1] / history_daily['volume'].iloc[-2]
percent_change = (history_minute['close'].iloc[-1] - history_minute['close'].iloc[-2]) / history_minute['close'].iloc[-2] * 100
# Execute trade logic based on volume and price change criteria
if volume_ratio >= 5 and percent_change >= 20:
self.filtered_symbols.add(symbol)
for symbol in self.filtered_symbols:
self.TradeLogic(symbol)
def TradeLogic(self, symbol):
if not self.Portfolio[symbol].Invested:
self.SetHoldings(symbol, 0.1)
self.Log(f"Buying {symbol.Value} based on conditions.")
else:
self.Log(f"Already invested in {symbol.Value}, skipping.")
holding = self.Portfolio[symbol]
if holding.Invested:
current_price = self.Securities[symbol].Price
stop_loss_price = holding.AveragePrice * 0.95
trailing_stop_price = holding.AveragePrice * 0.9
if current_price < stop_loss_price or current_price < trailing_stop_price:
self.Liquidate(symbol)
self.Debug(f"Liquidated {symbol.Value} due to stop loss or trailing stop criteria.")