Overall Statistics |
Total Trades 37 Average Win 0.08% Average Loss -0.01% Compounding Annual Return -2.711% Drawdown 1.600% Expectancy 3.261 Net Profit -0.308% Sharpe Ratio -0.451 Probabilistic Sharpe Ratio 30.007% Loss Rate 67% Win Rate 33% Profit-Loss Ratio 11.78 Alpha 0.038 Beta 0.119 Annual Standard Deviation 0.046 Annual Variance 0.002 Information Ratio 1.857 Tracking Error 0.254 Treynor Ratio -0.177 Total Fees $37.00 |
namespace QuantConnect.Algorithm.CSharp { using System.Collections.Concurrent; using Newtonsoft.Json; public class DoubleVolumeBuyAtClose : QCAlgorithm { private int stocksInBackTest = 100; private int datesOfBackTest = 40; public int startingCash = 10000; private string scheduleSymbol = "SPY"; public int counter = 0; private int serialized = 0; private readonly ConcurrentDictionary<Symbol, RollingWindow<decimal>> historicalVolumes = new ConcurrentDictionary<Symbol, RollingWindow<decimal>>(); private List<Symbol> dailySymbols = new List<Symbol>(); public override void Initialize() { var endDate = new DateTime(2020, 3, 6); //Friday SetStartDate(endDate.AddDays(datesOfBackTest * -1)); SetEndDate(endDate); SetCash(startingCash); AddUniverse(CoarseSelectionFilter); UniverseSettings.Resolution = Resolution.Minute; var spy = this.AddEquity(scheduleSymbol).Symbol; AddUniverse(CoarseSelectionFilter); //SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Cash); UniverseSettings.Resolution = Resolution.Minute; Schedule.On(DateRules.EveryDay(spy), TimeRules.BeforeMarketClose(spy, 10), BeforeClose); } public void BeforeClose() { foreach(var selection in dailySymbols) { if (!historicalVolumes.ContainsKey(selection)) { var history = History(selection, 20, Resolution.Daily); historicalVolumes[selection] = new RollingWindow<decimal>(20); foreach(var h in history) { historicalVolumes[selection].Add(h.Volume); } } var window = historicalVolumes[selection]; if (window.IsReady) { var sec = this.Securities[selection]; var average = window.Skip(1).Average(f=>f); var resolution = sec.Resolution; var open = sec.Open; var current = sec.Price; var volume = sec.Volume; if ((average * 3) < volume && open < current) { var h = History(selection, 30, Resolution.Daily); var averageSpan = h.Select(f=> Math.Abs(f.Open - f.Close)).Average(); var takeProfit = sec.Price + averageSpan; var stopLosss = sec.Price - averageSpan; var position = Math.Ceiling((averageSpan * 4) / sec.Price) ; MarketOrder(sec.Symbol, position); StopLimitOrder(sec.Symbol, position * -1, stopLosss, takeProfit); } } window.Add(this.Securities[selection].Volume); } } public IEnumerable<Symbol> CoarseSelectionFilter(IEnumerable<CoarseFundamental> universe) { universe = universe.Where(f=> f.Price > 100 && f.DollarVolume > 10000000 && f.Price < 600).Take(stocksInBackTest); dailySymbols = universe.Select(f=>f.Symbol).ToList(); return dailySymbols; } } }