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