| Overall Statistics |
|
Total Trades 114 Average Win 0.16% Average Loss -0.16% Compounding Annual Return 0.111% Drawdown 2.400% Expectancy 0.114 Net Profit 1.034% Sharpe Ratio 0.183 Probabilistic Sharpe Ratio 0.271% Loss Rate 44% Win Rate 56% Profit-Loss Ratio 0.98 Alpha 0.001 Beta 0.002 Annual Standard Deviation 0.005 Annual Variance 0 Information Ratio -0.806 Tracking Error 0.135 Treynor Ratio 0.543 Total Fees $221.35 |
using System.Collections.Concurrent;
namespace QuantConnect.Algorithm.CSharp
{
public class QuantumVentralAutosequencers : QCAlgorithm
{
private readonly ConcurrentDictionary<Symbol, SelectionData> averages = new ConcurrentDictionary<Symbol, SelectionData>();
public override void Initialize()
{
SetStartDate(2010, 1, 1);
SetEndDate(2019, 4, 1);
SetCash(100000);
AddUniverse(CoarseSelectionFilter);
UniverseSettings.Resolution = Resolution.Minute;
}
public override void OnData(Slice data){
foreach(var symbol in averages.Keys){
if(data.ContainsKey(symbol)){
averages[symbol].window.Add(data.Bars[symbol]);
}
}
}
public IEnumerable<Symbol> CoarseSelectionFilter(IEnumerable<CoarseFundamental> universe)
{
var selected = new List<Symbol>();
universe = universe
.Where(x => x.Price > 10)
.OrderByDescending(x => x.DollarVolume).Take(10);
foreach (var coarse in universe)
{
var symbol = coarse.Symbol;
if (!averages.ContainsKey(symbol))
{
//1. Call history to get an array of 200 days of history data
var history = History(symbol, 200, Resolution.Daily);
//2. Adjust SelectionData to pass in the history result
averages[symbol] = new SelectionData(history);
}
averages[symbol].Update(Time, coarse.AdjustedPrice);
var window = averages[symbol].window;
if (!window.IsReady) continue;
decimal alpha = window[0].Open - window[1].Close;
decimal gapSize = 1/100*(window[1].High - window[1].Low);
if (averages[symbol].IsReady() && averages[symbol].Fast.Current.Value > averages[symbol].Slow.Current.Value)
{
if (alpha < -1*gapSize){
selected.Add(coarse.Symbol);
}
}
}
return selected.Take(10);
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
foreach (var security in changes.RemovedSecurities)
{
if (security.Invested)
{
Liquidate(security.Symbol);
}
SelectionData token;
averages.TryRemove(security.Symbol, out token);
}
foreach (var security in changes.AddedSecurities)
{
SetHoldings(security.Symbol, 0.10m);
}
}
}
public partial class SelectionData
{
public readonly ExponentialMovingAverage Fast;
public readonly ExponentialMovingAverage Slow;
public RollingWindow<TradeBar> window = new RollingWindow<TradeBar>(2);
public bool IsReady() {return Slow.IsReady && Fast.IsReady;}
//3. Update the constructor to accept an IEnumerable<TradeBar> history parameter
public SelectionData(IEnumerable<TradeBar> history)
{
Fast = new ExponentialMovingAverage(50);
Slow = new ExponentialMovingAverage(200);
//4. Loop over history data and pass the bar.EndTime and bar.Close values to Update()
foreach(var bar in history)
{
window.Add(bar);
Update(bar.EndTime, bar.Close);
}
}
public bool Update(DateTime time, decimal value)
{
Slow.Update(time, value);
Fast.Update(time, value);
return IsReady();
}
}
}