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

class CommodityMomentumAlphaModel(AlphaModel):

    def __init__(self):
        self.commodity_symbol = None
        self.commodity_ppo = None
        self.last_update_time = datetime.min
        self.consolidator = None
        self.high_threshold = 0.1  # Example threshold for high positive PPO
        self.low_threshold = -0.1  # Example threshold for high negative PPO
        self.insights = []  # Store insights
        self.min = 1  # Consolidate minute data into 1-minute bars
        self.ppo_values = []  # List to store PPO values

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

        # Only update once every minute
        if (algorithm.Time - self.last_update_time).total_seconds() < 60 * self.min:
            return insights
        self.last_update_time = algorithm.Time

        # Add the commodity future, e.g., Crude Oil WTI
        if self.commodity_symbol is None:
            future = algorithm.AddFuture(Futures.Energies.CrudeOilWTI, Resolution.Minute)
            self.commodity_symbol = future.Symbol

            # Consolidate minute data into 1-minute bars
            self.consolidator = TradeBarConsolidator(timedelta(minutes=self.min))
            algorithm.SubscriptionManager.AddConsolidator(self.commodity_symbol, self.consolidator)

            # Register the PPO indicator to the 1-minute consolidated data
            self.commodity_ppo = PercentagePriceOscillator(10, 20, MovingAverageType.SIMPLE)
            algorithm.RegisterIndicator(self.commodity_symbol, self.commodity_ppo, self.consolidator)

        # Update the PPO with the latest data
        if self.commodity_ppo.IsReady:
            ppo_value = self.commodity_ppo.Current.Value
            self.ppo_values.append(ppo_value)
            algorithm.Plot("PPO", "Value", ppo_value)

            # Generate insights based on the PPO value and defined thresholds
            if ppo_value > self.high_threshold:
                insights.append(Insight.Price(self.commodity_symbol, timedelta(minutes=self.min), InsightDirection.Up))
            elif ppo_value < self.low_threshold:
                insights.append(Insight.Price(self.commodity_symbol, timedelta(minutes=self.min), InsightDirection.Down))
            else:
                insights.append(Insight.Price(self.commodity_symbol, timedelta(minutes=self.min), InsightDirection.Flat))

        self.insights = insights
        return insights

    def OnSecuritiesChanged(self, algorithm, changes):
        for security in changes.RemovedSecurities:
            if security.Symbol == self.commodity_symbol:
                algorithm.SubscriptionManager.RemoveConsolidator(security.Symbol, self.consolidator)
                self.commodity_symbol = None

        for security in changes.AddedSecurities:
            if security.Symbol == self.commodity_symbol:
                self._register_indicator(algorithm, security)

    def _register_indicator(self, algorithm, security):
        security.consolidator = TradeBarConsolidator(timedelta(minutes=10))
        algorithm.SubscriptionManager.AddConsolidator(security.Symbol, security.consolidator)
        algorithm.RegisterIndicator(security.Symbol, security.indicator, security.consolidator)

    def OnEndOfAlgorithm(self):
        # Optional: Save PPO values to a file (in a way that works with QuantConnect environment)
        ppo_df = pd.DataFrame(self.ppo_values, columns=['PPO'])
        algorithm.Log("PPO values saved at the end of algorithm")
# region imports
from AlgorithmImports import *
from CommodityMomentumAlphaModel import CommodityMomentumAlphaModel
# endregion

class PensiveBlackFrog(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 1, 1)
        self.set_cash(100000)
   

        self.future = self.AddFuture(Futures.Energies.CrudeOilWTI,Resolution.MINUTE)
        self.future.SetFilter(0, 180)  # Set filter for front month contracts
        # Set benchmark to Crude Oil price
        self.SetBenchmark(self.future.Symbol)

        # Set up ATR indicator for the consolidated data
        self.atrConsolidator = TradeBarConsolidator(timedelta(minutes=10))
        self.atr = self.ATR(self.future.Symbol, 14, MovingAverageType.Wilders)
        self.RegisterIndicator(self.future.Symbol, self.atr, self.atrConsolidator)
        self.SubscriptionManager.AddConsolidator(self.future.Symbol, self.atrConsolidator)



        # Set up the commodity momentum alpha model
        self.alpha_model = CommodityMomentumAlphaModel()
        self.AddAlpha(self.alpha_model)
         # Track positions to avoid overtrading
        self.currently_long = False
        self.SetWarmUp(timedelta(2))  # Warm up the algorithm with x days of data
   
    
       
      # Track positions to avoid overtrading
        self.currently_long = False
        self.currently_short = False
        self.SetWarmUp(timedelta(days=2))  # Warm up the algorithm with x days of data
   
        self.stopMarketOrderTicket = None
        self.takeProfitOrderTicket = None
        self.opening_bar = None
    

    def OnData(self, data: Slice):
        if self.IsWarmingUp:
            return

        for chain in data.FutureChains:
            contracts = sorted(chain.Value, key=lambda x: x.Expiry)
            if len(contracts) == 0:
                continue

            front_contract = contracts[0]
            future_symbol = front_contract.Symbol

            # Ensure we have data for the front contract
            if future_symbol not in data.Bars:
                continue

            last_close = data.Bars[future_symbol].Close
            atr_value = self.atr.Current.Value
            # self.Debug(f"ATR Value: {atr_value}")  # Debug the ATR value

            if self.alpha_model.insights:
                for insight in self.alpha_model.insights:
                    # self.Debug(f"Insight: {insight} - Last Close: {last_close} - ATR: {atr_value}")
                    pass





















            # if self.opening_bar is not None:
            #     if future_symbol in data.Bars:
            #         bar = data.Bars[future_symbol]
            #         last_close = bar.Close

            #         if last_close > self.opening_bar.High:
            #             # Check existing insights and position
            #             if self.alpha_model.insights:
            #                 for insight in self.alpha_model.insights:
            #                     if insight.Direction == InsightDirection.Up:
            #                         atr_value = self.atr.Current.Value
            #                         self.Debug(f"ATR Value: {atr_value}")

            #                         stop_loss_level = last_close - atr_value
            #                         take_profit_level = last_close + atr_value * 1.2

            #                         # Set holdings only if we don't already have a position
            #                         if not self.Portfolio[future_symbol].Invested:
            #                             self.SetHoldings(future_symbol, -0.1)
            #                             self.stop_loss_level = stop_loss_level
            #                             self.take_profit_level = take_profit_level
            #                             self.entry_price = last_close
            #                         else:
            #                             # Update stop loss and take profit levels
            #                             self.stop_loss_level = max(self.stop_loss_level, stop_loss_level)
            #                             self.take_profit_level = min(self.take_profit_level, take_profit_level)

            # # Exit conditions
            # if future_symbol in self.Portfolio and self.Portfolio[future_symbol].Invested:
            #     invested_symbol = self.Portfolio[future_symbol]

            #     if future_symbol in data.Bars:
            #         last_close = data.Bars[future_symbol].Close

            #         if last_close <= self.stop_loss_level or last_close >= self.take_profit_level:
            #             self.Liquidate(future_symbol)
            #             self.Debug(f"Exited position in {future_symbol} at {last_close} due to stop loss or take profit.")

            #         # Check if the insight direction has changed
            #         if not any(insight.Direction == InsightDirection.Up for insight in self.alpha_model.insights):
            #             self.Liquidate(future_symbol)
            #             self.Debug(f"Exited position in {future_symbol} due to change in insight direction.")