Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe 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.407
Tracking Error
0.102
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;

namespace QuantConnect.Algorithm.CSharp
{
    public class SellATMOptionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
    {
        private Symbol _optionSymbol;
        private Option _option;
        private readonly LocalOrderCollection _dailyOrders = new LocalOrderCollection();
        
        public override void Initialize()
        {
            SetStartDate(2020, 01, 01);
            SetEndDate(2020, 01, 30);
            SetCash(1000000);

            //SetWarmUp(TimeSpan.FromSeconds(5));

            _option = AddOption("TSLA", Resolution.Minute);
            _optionSymbol = _option.Symbol;

            //Set option contracts filter with the expiration date.
            //_option.SetFilter(-2,2,0 ,1);
            _option.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(10));

        }

        public override void OnData(Slice slice)
        {
            //For each day the trading should start from 09:01AM NY TIME. Default timezone is TimeZones.NewYork.
            if (Time.Hour < 9 && Time.Minute < 1) return;

            if (Portfolio.Invested) return;

            if (_dailyOrders.DoesOrderPlacedForTheDay(slice.Time)) return;
            
            foreach (var sliceOptionChain in slice.OptionChains)
            {
                if (sliceOptionChain.Key != _optionSymbol) continue;

                OptionChain optionChain = sliceOptionChain.Value;

                // find a nearest ATM call contract
                var contract = optionChain
                    .Where(x => x.Right == OptionRight.Call &&
                    optionChain.Underlying.Price - x.Strike ==  0.0m)
                    .OrderBy(x => x.Expiry)
                    .FirstOrDefault();

                if (contract != null)
                {
                    var orderTicket = StopLimitOrder(contract.Symbol, -2,  100, 100);
                   _dailyOrders.Add(new LocalOrder(slice.Time, contract.Symbol, orderTicket));
                    Debug($"StopLimitOrder Placed On:{Time.ToLongDateString()}, symbol : {contract.ToString()} at Strike Price: {contract.Strike}, Underlying Price: {contract.UnderlyingLastPrice}, Qty: 1, Direction: SELL");
                }
            }

        }

        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            //if(orderEvent.Status == OrderStatus.Filled)
            //{
                Debug($"Order : {orderEvent.Symbol.ToString()} is {orderEvent.Status} at Price: {orderEvent.FillPrice}, Qty: {orderEvent.FillQuantity}, Direction: {orderEvent.Direction}");
            //}
        }
        

        #region Implementation of IRegressionAlgorithmDefinition

        /// <summary>
        /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
        /// </summary>
        public bool CanRunLocally { get; } = true;

        /// <summary>
        /// This is used by the regression test system to indicate which languages this algorithm is written in.
        /// </summary>
        public Language[] Languages { get; } = { Language.CSharp };

        /// <summary>
        /// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
        /// </summary>
        public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
        {
            {"Total Trades", "2"},
            {"Average Win", "0%"},
            {"Average Loss", "0%"},
            {"Compounding Annual Return", "0%"},
            {"Drawdown", "0%"},
            {"Expectancy", "0"},
            {"Net Profit", "0%"},
            {"Sharpe 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", "$2.00"},
            {"Estimated Strategy Capacity", "$6300000.00"},
            {"Lowest Capacity Asset", "GOOCV W723A0UB7HTY|GOOCV VP83T1ZUHROL"},
            {"Fitness Score", "0"},
            {"Kelly Criterion Estimate", "0"},
            {"Kelly Criterion Probability Value", "0"},
            {"Sortino Ratio", "0"},
            {"Return Over Maximum Drawdown", "0"},
            {"Portfolio Turnover", "0"},
            {"Total Insights Generated", "0"},
            {"Total Insights Closed", "0"},
            {"Total Insights Analysis Completed", "0"},
            {"Long Insight Count", "0"},
            {"Short Insight Count", "0"},
            {"Long/Short Ratio", "100%"},
            {"Estimated Monthly Alpha Value", "$0"},
            {"Total Accumulated Estimated Alpha Value", "$0"},
            {"Mean Population Estimated Insight Value", "$0"},
            {"Mean Population Direction", "0%"},
            {"Mean Population Magnitude", "0%"},
            {"Rolling Averaged Population Direction", "0%"},
            {"Rolling Averaged Population Magnitude", "0%"},
            {"OrderListHash", "38553a7723601f345ea373858ad7be0d"}
        };

        #endregion

    }

    
    public class LocalOrderCollection : List<LocalOrder>
    {
        public bool DoesOrderPlacedForTheDay(DateTime dateTime)
        {
            var existingTrade = this.FirstOrDefault(t => t.TradeDateTime.Date.Equals(dateTime.Date));
            return existingTrade != null;
        }
    }
    
    public class LocalOrder
    {
        public LocalOrder(DateTime tradeDateTime, Symbol optionContract, OrderTicket orderTicket)
        {
            TradeDateTime = tradeDateTime;
            OptionContract = optionContract;
            OrderTicket = orderTicket;
        }

        public DateTime TradeDateTime { get; }
        public Symbol OptionContract { get; }
        
        public OrderTicket OrderTicket { get; }

    }
    
}