Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
10000
End Equity
10000
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.371
Tracking Error
0.15
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Algorithm.Selection;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;   
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion


namespace QuantConnect.Algorithm.CSharp
{
    public class OptionsTradingBot : QCAlgorithm
    {
        #region Class Variables
        //public TradeManager _tradeManager = null;
        public List<TradeBar> _spyHistory;
        public readonly string[] _tickers = { "SPY" };
        //public readonly string[] _tickers = { "SPY", "QQQ", "DIA", "IWM", "XLK", "XLY","XLC", "XLU","XLF","XLV","XLE","XLI" };
        public List<string> _logMessages = new List<string>();
        //public List<TradeInfo> _tradeHistory = new List<TradeInfo>();
        //public List<TradeInfo> _tuesdayTrades { get; set; }
        public decimal _tuesdayMarketDirection { get; set; }
        public readonly decimal _spreadPrice = 0.50m;
        public readonly decimal _targetRoi = 0.94m;
        public readonly decimal _stopLoss = 0.50m;
        public readonly decimal _maxLoss = 0.65m;
        public readonly int _dteMinCall = 20;
        public readonly int _dteMaxCall = 30;
        public readonly int _dteMinPut = 20;
        public readonly int _dteMaxPut = 30;
        public readonly int _rsiPeriod = 14;
        public readonly decimal _vixThreshold = 17m;
        public readonly decimal _minAllocation = 0.05m;
        public readonly decimal _maxAllocation = 0.30m;
        public decimal _currentAllocation;

        public Symbol _vixSymbol;
        public Symbol _spySymbol;
        public Dictionary<string, ExponentialMovingAverage> _ema8 = new Dictionary<string, ExponentialMovingAverage>();
        public Dictionary<string, ExponentialMovingAverage> _ema21 = new Dictionary<string, ExponentialMovingAverage>();
        public Dictionary<string, ExponentialMovingAverage> _ema34 = new Dictionary<string, ExponentialMovingAverage>();

        public Dictionary<string, ExponentialMovingAverage> _ema50 = new Dictionary<string, ExponentialMovingAverage>();
        public Dictionary<string, ExponentialMovingAverage> _ema200 = new Dictionary<string, ExponentialMovingAverage>();
        public Dictionary<string, RollingWindow<IndicatorDataPoint>> _shortTermEmaHistory = new Dictionary<string, RollingWindow<IndicatorDataPoint>>();
        public Dictionary<string, RollingWindow<IndicatorDataPoint>> _longTermEmaHistory = new Dictionary<string, RollingWindow<IndicatorDataPoint>>();

        public Dictionary<string, Symbol> _options = new Dictionary<string, Symbol>();
        public Dictionary<string, Symbol> _underlyings = new Dictionary<string, Symbol>();
        public Dictionary<string, RelativeStrengthIndex> _rsiIndicators = new Dictionary<string, RelativeStrengthIndex>();
        public Dictionary<string, BollingerBands> _bollingerBands = new Dictionary<string, BollingerBands>();
        public Dictionary<string, KeltnerChannels> _keltnerChannels = new Dictionary<string, KeltnerChannels>();
        public Dictionary<string, RollingWindow<IndicatorDataPoint>> _rsiHistory = new Dictionary<string, RollingWindow<IndicatorDataPoint>>();
        public Dictionary<Symbol, RollingWindow<TradeBar>> _priceHistory = new Dictionary<Symbol, RollingWindow<TradeBar>>();

        public Dictionary<string, AverageDirectionalIndex> _adxIndicators = new Dictionary<string, AverageDirectionalIndex>(); // ADX Indicators
        public DateTime _lastVixUpdate;
        //public VIXData _vixData;
        public SimpleMovingAverage _vixSma;

        public int _winningTrades;
        public int _losingTrades;
        public DateTime _lastWeekCheck;
        public int _spreadsOpenedThisWeek;
        public int _maxSpreadsPerWeek;
        public int _consecutiveWeeksWithoutTrades;
        public bool _isTuesdayOrFriday;

        private readonly object _tradeLock = new object();

        //public List<TradeInfo> _trades;
        //public List<BaseTradeAlgorithm> _tradeAlgorithms = new List<BaseTradeAlgorithm>();
        public Dictionary<Symbol, AverageTrueRange> _atrIndicators;
        public Dictionary<string, RollingWindow<IndicatorDataPoint>> _rsiRollingWindows;

        public decimal _availableFundsForTrading;
        //public PerformanceManagement _performanceManager;
        Resolution _resolution = Resolution.Daily;
        public bool _useVixCheck = false;
        public bool _enableLogging = true;
        public int _loggingVerbosity = 5;
        #endregion

        public OptionsTradingBot()
        {
            //_tuesdayTrades = new List<TradeInfo>();
            _atrIndicators = new Dictionary<Symbol, AverageTrueRange>();
            _rsiRollingWindows = new Dictionary<string, RollingWindow<IndicatorDataPoint>>();
            //_tradeManager = new TradeManager(this);
            //_performanceManager = new PerformanceManagement(this, _maxAllocation, _minAllocation, _maxAllocation);
            _lastWeekCheck = Time.AddDays(-8);

        }

        private bool IsMarketOpen()
        {
            var securityExchangeHours = Securities["SPY"].Exchange.Hours;
            var isOpenNow = securityExchangeHours.IsOpen(Time, extendedMarketHours: false);
            return isOpenNow;
        }

        public override void Initialize()
        {
            try
            {
                //SetWarmUp(30*24, Resolution.Hour); // Days * hour per day
                SetStartDate(2022, 1, 1);
                //SetEndDate(2022, 1, 20);
                SetCash(10000);
                SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
                //SetSecurityInitializer(new MRTSecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));
                UniverseSettings.MinimumTimeInUniverse = TimeSpan.FromDays(35);

                _currentAllocation = .15m;
                //_vixData = new VIXData(this);
                _vixSma = new SimpleMovingAverage(10); // 10-period SMA for VIX

                //LoadTradesFromStore();
                //_trades = new List<TradeInfo>();
                //_tradeManager = new TradeManager(this);

                foreach (var ticker in _tickers)
                {
                    var equity = AddEquity(ticker, Resolution.Hour);
                    equity.SetDataNormalizationMode(DataNormalizationMode.Raw);

                    // Add option chain for the ticker
                    var option = AddOption(ticker, Resolution.Minute);
                    option.PriceModel = OptionPriceModels.BjerksundStensland();
                    option.EnableGreekApproximation = true;
                    option.SetFilter(universe => universe
                    .IncludeWeeklys()
                    .Strikes(-5, 5)
                    .Expiration(TimeSpan.FromDays(_dteMinPut), TimeSpan.FromDays(_dteMaxCall)));
                    AddOptionContract(option.Symbol, Resolution.Minute);

                    _options[ticker] = option.Symbol;
                    _underlyings[ticker] = equity.Symbol;

                    // Initialize indicators
                    var atr = ATR(equity.Symbol, 14, MovingAverageType.Simple, _resolution);
                    _atrIndicators[equity.Symbol] = atr;

                    var rsi = RSI(ticker, _rsiPeriod, MovingAverageType.Wilders, _resolution);
                    _rsiIndicators[ticker] = rsi;
                    _rsiRollingWindows[ticker] = new RollingWindow<IndicatorDataPoint>(35);

                    var historydepth = ticker == "SPY" ? 200 : 35;
                    var history = History<TradeBar>(ticker, historydepth, _resolution);
                    _ema8[ticker] = EMA(ticker, 8, _resolution);
                    _ema21[ticker] = EMA(ticker, 21, _resolution);
                    _ema34[ticker] = EMA(ticker, 34, _resolution);
                    _ema50["SPY"] = EMA("SPY", 50, _resolution);
                    _ema200["SPY"] = EMA("SPY", 200, _resolution);

                    _shortTermEmaHistory[ticker] = new RollingWindow<IndicatorDataPoint>(3); // Store last 5 periods
                    _longTermEmaHistory[ticker] = new RollingWindow<IndicatorDataPoint>(3); // Store last 5 periods

                    _bollingerBands[ticker] = BB(ticker, 20, 2, MovingAverageType.Simple, _resolution);
                    _keltnerChannels[ticker] = KCH(ticker, 20, 1.5m, MovingAverageType.Simple, _resolution);

                    // Initialize ADX and add to dictionary
                    var adx = ADX(ticker, 7, _resolution);
                    _adxIndicators[ticker] = adx;

                    // Initialize RollingWindow for TradeBars
                    _priceHistory[equity.Symbol] = new RollingWindow<TradeBar>(35);

                    if (history.Count() == 0)
                    {
                        //LogHelper.LogWarning(this, $"No historical data available for {ticker}. RSI will not be initialized.");
                    }
                    else
                    {
                        if (ticker == "SPY")
                        {
                            SetBenchmark(equity.Symbol);
                            _spySymbol = equity.Symbol;
                            _spyHistory = history.ToList();
                        }

                        //Warm up indicators from History Request
                        foreach (var bar in history)
                        {
                            _ema8[ticker].Update(bar.Time, bar.Close);
                            _ema21[ticker].Update(bar.Time, bar.Close);
                            _ema34[ticker].Update(bar.Time, bar.Close);
                            _bollingerBands[ticker].Update(bar.Time, bar.Close);
                            _keltnerChannels[ticker].Update(bar);
                            _adxIndicators[ticker].Update(bar);
                            _shortTermEmaHistory[ticker].Add(new IndicatorDataPoint(bar.EndTime, _ema8[ticker].Current.Value));
                            _longTermEmaHistory[ticker].Add(new IndicatorDataPoint(bar.EndTime, _ema34[ticker].Current.Value));
                            _rsiRollingWindows[ticker].Add(new IndicatorDataPoint(bar.EndTime, _ema34[ticker].Current.Value));

                            if (ticker == "SPY")
                            {
                                _ema50[ticker].Update(bar.Time, bar.Close);
                                _ema200[ticker].Update(bar.Time, bar.Close);
                            }
                        }
                    }
                }

            }
            catch (Exception e)
            {
                //LogHelper.LogError(this, $"Exception during Initialize(): {e.Message}");
            }
        }
    }
}