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
-6.563
Tracking Error
0.077
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
    #region imports
from AlgorithmImports import *
#endregion
from AlgorithmImports import *
import pytz

# Your New Python File
class DualThrustAlphaModel(AlphaModel):

    def __init__(self,
                 ph,
                 range_period,
                 resolution = Resolution.HOUR,
                 bars_to_consolidate = 1):

        self.ph = ph
        # period the range is calculated over
        self.range_period = range_period
        # initialize with empty dict.
        self._symbol_data_by_symbol = {}
        # time for bars we make the calculations on
        resolution_in_time_span =  Extensions.to_time_span(resolution)
        self.consolidator_time_span = Time.multiply(resolution_in_time_span, bars_to_consolidate)

        self.period = timedelta(minutes=60)

    def update(self, algorithm, data):
        insights = []

        for symbol, symbol_data in self._symbol_data_by_symbol.items():
            if not symbol_data.is_ready: #or symbol_data.insight_close_time_utc > algorithm.utc_time:
                continue

            holding = algorithm.portfolio[symbol]
            #price = algorithm.securities[symbol].price 

            if symbol_data.wvf > symbol_data.rangehigh: #or symbol_data.wvf > (symbol_data.std_wvf * 2):
                symbol_data.insight_close_time_utc = self.period
                insights.append(Insight.price(symbol, symbol_data.insight_close_time_utc, InsightDirection.UP))
                algorithm.debug(f"wvf: {symbol_data.wvf}")
                algorithm.debug(f"rangehigh: {symbol_data.rangehigh}")

        return insights

    def on_securities_changed(self, algorithm, changes):
        # added
        for symbol in [x.symbol for x in changes.added_securities]:
            if symbol not in self._symbol_data_by_symbol:
                # add symbol/symbol_data pair to collection
                symbol_data = self.SymbolData(algorithm, symbol, self.ph, self.range_period, self.consolidator_time_span)
                self._symbol_data_by_symbol[symbol] = symbol_data

        # removed
        for symbol in [x.symbol for x in changes.removed_securities]:
            symbol_data = self._symbol_data_by_symbol.pop(symbol, None)
            if symbol_data is None:
                algorithm.error("Unable to remove data from collection: DualThrustAlphaModel")
            else:
                # unsubscribe consolidator from data updates
                algorithm.subscription_manager.remove_consolidator(symbol, symbol_data.get_consolidator())

    class SymbolData:
    
        def __init__(self, algorithm, symbol, ph, range_period, consolidator_resolution):

            self.symbol = symbol
            self.range_window = RollingWindow[TradeBar](range_period)
            self.consolidator = TradeBarConsolidator(consolidator_resolution)
            algorithm.subscription_manager.add_consolidator(symbol, self.consolidator)
            self.wvf_window_rangehigh = RollingWindow[float](50)
            self.wvf_window_std = RollingWindow[float](20)
            self.rangehigh = 0
            self.wvf = 0
            self.std_wvf = 0
            self.insight_close_time_utc = datetime.min.replace(tzinfo=pytz.UTC)

            def on_data_consolidated(sender, consolidated):

                self.range_window.add(consolidated)

                if self.range_window.is_ready:
                    hh = max([x.high for x in self.range_window])
                    hc = max([x.close for x in self.range_window])
                    lc = min([x.close for x in self.range_window])
                    ll = min([x.low for x in self.range_window])

                    self.wvf = ((hc - consolidated.low)/hc) * 100

                    self.wvf_window_rangehigh.add(self.wvf)
                    self.wvf_window_std.add(self.wvf)
                    
                    self.rangehigh = max([x for x in self.wvf_window_rangehigh]) * ph

            self.consolidator.data_consolidated += on_data_consolidated

            history = algorithm.history[TradeBar](symbol, 100, Resolution.HOUR)
            for bar in history:
                self.consolidator.update(bar)

        # Returns the interior consolidator
        def get_consolidator(self):
            return self.consolidator
        
        @property
        def is_ready(self):
            return self.range_window.is_ready
from AlgorithmImports import *
from VIXAlpha import *

class SELLPUTFRAMEWORK(QCAlgorithm):

    def initialize(self):

        # -- STRATEGY INPUT PARAMETERS --
        self.ph = 0.85
        self.range_period = 22
        #self.bbl = 20
        #self.lb = 50
        
        #self.mult = 2.0
        self.consolidator_bars = 20
        #self.wvf = None

        # set leverage
        self.leverage = 3
        self.yoy_return = 0.6

        # Settings
        self.universe_settings.resolution = Resolution.HOUR
        self.set_start_date(2024,5,1)
        self.set_cash(100000)

        # Warming up
        resolution_in_time_span =  Extensions.to_time_span(self.universe_settings.resolution)
        warm_up_time_span = Time.multiply(resolution_in_time_span, self.consolidator_bars)
        self.set_warm_up(warm_up_time_span)

        # Universe Selection
        tickers = ['TQQQ']
        symbols = [Symbol.create(ticker, SecurityType.EQUITY, Market.USA) for ticker in tickers]
        self.set_universe_selection(ManualUniverseSelectionModel(symbols))

        # Alpha Model
        #self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(hours = 1)))
        self.set_alpha(DualThrustAlphaModel(self.ph, self.range_period, self.universe_settings.resolution, self.consolidator_bars))
        

        ## Portfolio Construction
        self.set_portfolio_construction(NullPortfolioConstructionModel())

        ## Execution
        self.set_execution(ImmediateExecutionModel())

        ## Risk Management
        self.set_risk_management(NullRiskManagementModel())

    def on_order_event(self, order_event):
        if order_event.status == OrderStatus.FILLED:
            self.debug("Purchased Stock: {0}".format(order_event.symbol))