| 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);
}
}
}