Overall Statistics |
Total Trades 10 Average Win 0.73% Average Loss -1.10% Compounding Annual Return -57.717% Drawdown 0.900% Expectancy -0.169 Net Profit -0.705% Sharpe Ratio -9.386 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 0.66 Alpha 0.085 Beta -0.261 Annual Standard Deviation 0.047 Annual Variance 0.002 Information Ratio -11.277 Tracking Error 0.22 Treynor Ratio 1.706 Total Fees $2.50 |
/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System.Collections.Generic; using System.Linq; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Data; using QuantConnect.Data.Market; using QuantConnect.Orders; using QuantConnect.Securities.Option; using System.Collections.Generic; namespace QuantConnect.Algorithm.CSharp { /// <summary> /// In this algorithm we demonstrate how to define a universe /// as a combination of use the coarse fundamental data and fine fundamental data /// </summary> public class CoarseFineFundamentalComboAlgorithm : QCAlgorithm { private const int NumberOfSymbolsCoarse = 5; private const int NumberOfSymbolsFine = 2; // initialize our changes to nothing private SecurityChanges _changes = SecurityChanges.None; public override void Initialize() { UniverseSettings.Resolution = Resolution.Daily; SetStartDate(2016, 03, 01); SetEndDate(2016, 03, 03); SetCash(10000); // this add universe method accepts two parameters: // - coarse selection function: accepts an IEnumerable<CoarseFundamental> and returns an IEnumerable<Symbol> // - fine selection function: accepts an IEnumerable<FineFundamental> and returns an IEnumerable<Symbol> AddUniverse(CoarseSelectionFunction, FineSelectionFunction); } // sort the data by daily dollar volume and take the top 'NumberOfSymbolsCoarse' public IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse) { // select only symbols with fundamental data and sort descending by daily dollar volume var sortedByDollarVolume = coarse .Where(x => x.HasFundamentalData) .OrderByDescending(x => x.DollarVolume); // take the top entries from our sorted collection var top5 = sortedByDollarVolume.Take(15); // we need to return only the symbol objects return top5.Select(x => x.Symbol); } // sort the data by P/E ratio and take the top 'NumberOfSymbolsFine' public IEnumerable<Symbol> FineSelectionFunction(IEnumerable<FineFundamental> fine) { // Only return SPY for testing purposes return fine.Where(x=> x.Symbol.Value == "SPY").Select(x => x.Symbol); return fine.Where(x => // More than 7 days after earnings report Time >= x.EarningReports.FileDate.AddDays(-7) && Time >= x.EarningReports.FileDate.AddDays(0) && // Invalid FileDate x.EarningReports.FileDate != new DateTime()) .Take(5) .Select(x => x.Symbol); } public override void OnData(Slice data) { foreach (var kvp in data.OptionChains) { var symbol = kvp.Key; var chain = kvp.Value; var atmStraddle = chain .OrderBy(x => Math.Abs(chain.Underlying.Price - x.Strike)) .ThenByDescending(x => x.Expiry) .FirstOrDefault(); if (atmStraddle != null && !Portfolio.Invested) { Buy(OptionStrategies.Straddle(symbol, atmStraddle.Strike, atmStraddle.Expiry), 1); Log("Bought Straddle: " + symbol); } } } // this event fires whenever we have changes to our universe public override void OnSecuritiesChanged(SecurityChanges changes) { // Liquidate removed securities foreach (var security in changes.RemovedSecurities) { if (security.Invested) { Liquidate(security.Symbol); } } // Add option for every added security foreach (var security in changes.AddedSecurities) { if (security is Option) continue; var option = AddOption(security.Symbol); option.SetFilter(-2, 2, TimeSpan.Zero, TimeSpan.FromDays(45)); } } } }