Overall Statistics |
Total Trades 12 Average Win 0.20% Average Loss -0.27% Compounding Annual Return -6.139% Drawdown 3.100% Expectancy 0.093 Net Profit -0.810% Sharpe Ratio -1.265 Probabilistic Sharpe Ratio 17.242% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 0.75 Alpha -0.064 Beta -0.058 Annual Standard Deviation 0.049 Annual Variance 0.002 Information Ratio -0.193 Tracking Error 0.203 Treynor Ratio 1.084 Total Fees $6.00 |
using QuantConnect.Securities.Option; namespace QuantConnect.Algorithm.CSharp { public class BullCallSpreadAlgorithm : QCAlgorithm { private Equity equity; private Option option; private Symbol optionSymbol; public override void Initialize() { SetStartDate(2018, 1, 1); SetEndDate(2019, 11, 27); SetCash(100000); equity = AddEquity("SPY", Resolution.Minute); option = AddOption("SPY", Resolution.Minute); optionSymbol = option.Symbol; Debug("Init option symbol " + optionSymbol.ToString() + " equity symbol " + equity.Symbol.ToString()); option.SetFilter(u => u.IncludeWeeklys().Strikes(-4, 4) .Expiration(TimeSpan.FromDays(1) /*TimeSpan.Zero*/, TimeSpan.FromDays(7))); option.PriceModel = OptionPriceModels.CrankNicolsonFD(); // set the warm-up period for the pricing model SetWarmup(TimeSpan.FromDays(4)); SetBenchmark(equity.Symbol); equity.FeeModel = new ConstantFeeModel(0); option.FeeModel = new ConstantFeeModel(0); } public override void OnData(Slice slice) { if(IsWarmingUp) return; OptionChain chain; if (slice.OptionChains.TryGetValue(optionSymbol, out chain)) { OptionContracts contracts = chain.Contracts; if (contracts == null || contracts.Count == 0) return; // if there is no securities in portfolio, trade the options if (!Portfolio.Invested) { TradeOptions(chain); } } } private void TradeOptions(OptionChain chain) { // sorted the optionchain by expiration date and choose the furthest date var lastExpiry = chain.OrderByDescending(x => x.Expiry).First().Expiry; var farthestCallChain = chain.Where(x=> x.Expiry == lastExpiry && x.Right == OptionRight.Call); var orderedCallChain = farthestCallChain.OrderBy(x => x.Strike); Log(Time + " Chains count " + chain.Contracts.Count + " last Expiry " + lastExpiry.ToShortDateString() + " count " + farthestCallChain.Count()); // call option contract with lower strike var call_low = orderedCallChain.First(); // call option contract with higher strike var call_high = orderedCallChain.Last(); Buy(call_low.Symbol, 1); Sell(call_high.Symbol ,1); } public override void OnOrderEvent(OrderEvent orderEvent) { Log(Time + " " + orderEvent); } } }