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 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 |
namespace QuantConnect { /* * Basic Template Algorithm * * The underlying QCAlgorithm class has many methods which enable you to use QuantConnect. * We have explained some of these here, but the full base class can be found at: * https://github.com/QuantConnect/Lean/tree/master/Algorithm */ public class BasicTemplateAlgorithm : QCAlgorithm { public String StockTicker = "SPY"; public Symbol OptionSymbol; private const decimal GoalRate = 0.25M; private const decimal GoalFactor = 1 + GoalRate; public RollingWindow<Decimal> PercentChangeH = new RollingWindow<Decimal>(1); public Decimal PercentChange; public RateOfChangePercent PercentChangeI; private string OrderTrackingDebugStr = ""; public int OrderQuantity (decimal cash, decimal price) { return (int) Math.Floor(cash / price); } bool HasOrderOrHolding = false; public override void Initialize() { // backtest parameters SetStartDate(2016, 07, 1); SetEndDate(DateTime.Now); // cash allocation SetCash(3000); // request specific equities // including forex. Options and futures in beta. var equity = AddEquity(StockTicker, Resolution.Daily); //AddForex("EURUSD", Resolution.Minute); // Must add option universe filter var option = AddOption(StockTicker, Resolution.Daily); OptionSymbol = option.Symbol; option.SetFilter(universe => from symbol in universe // default is monthly expirations only .Expiration(TimeSpan.FromDays(30), TimeSpan.FromDays(60)) where symbol.ID.OptionRight == OptionRight.Call where Math.Abs(symbol.ID.StrikePrice - universe.Underlying.Price) < 10 select symbol); // use the underlying equity as the benchmark SetBenchmark(equity.Symbol); PercentChangeI = ROCP(StockTicker, 1, Resolution.Daily); } /* * New data arrives here. * The "Slice" data represents a slice of time, it has all the data you need for a moment. */ public override void OnData(Slice data) { if (!PercentChangeI.IsReady) return; PercentChangeH.Add(PercentChangeI); PercentChange = PercentChangeH[0]; Plot("Daily", PercentChangeI); ExecuteShort(data); ExecuteLong(data); } public void ExecuteLong(Slice slice) { if (HasOrderOrHolding) { return; } // We already have a position if ((PercentChange < -0.02m) && (PercentChange > -0.125m) // -2.5 to -12.5% ) { OptionChain chain; if (slice.OptionChains.TryGetValue(OptionSymbol, out chain)) { var contract = ( from optionContract in chain.OrderByDescending(x => x.Strike) select optionContract ).FirstOrDefault(); if (contract != null) { HasOrderOrHolding = true; MarketOrder(contract.Symbol, OrderQuantity(Portfolio.Cash, contract.AskPrice) ); } } } } public void ExecuteShort(Slice slice) { foreach (var security_option in Securities) { if ((security_option.Value.Symbol.SecurityType == SecurityType.Option) && (security_option.Value.Invested)) { Decimal midPrice = MidPrice(security_option.Value.BidPrice, security_option.Value.AskPrice); var currentGoal = ((security_option.Value.Holdings.AveragePrice * security_option.Value.Holdings.AbsoluteQuantity * 100) * GoalFactor) + security_option.Value.Holdings.TotalFees; var currentValue = (midPrice * security_option.Value.Holdings.AbsoluteQuantity * 100); Plot("Plotter", "HoldingGoal", currentGoal); Plot("Plotter", "HoldingValue", currentValue); OrderTrackingDebugStr = String.Format("{0} - POSITION IN {1} {2:0.00} {3} {4:MM/dd/yy} -- Cost {5:0.00} -- Will exit at {6:0.00} and current value={7:0.00}", Time.ToString(), security_option.Value.Symbol.Underlying, security_option.Value.Symbol.ID.StrikePrice, security_option.Value.Symbol.ID.OptionRight, security_option.Value.Symbol.ID.Date, security_option.Value.Holdings.AbsoluteHoldingsCost, currentGoal, currentValue ); if (currentValue >= currentGoal) { HasOrderOrHolding = false; Liquidate(); } } } } private void ShowOrderTracking() { if (HasOrderOrHolding) Debug(OrderTrackingDebugStr); } private Decimal MidPrice(Decimal Low, Decimal High) { return Math.Round(((High - Low) / 2) + Low, 2); } } }