using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Data;
using System.Linq;
namespace QuantConnect.Algorithm.CSharp
{
public class BasicTemplateAlgorithm : QCAlgorithm
{
int myUniverseCount = 0;
private const int Count = 50; //NUMBER OF STOCKS FOR UNIVERSE TO SELECT
private SecurityChanges _changes = SecurityChanges.None;
private static readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>();
private class SelectionData
{
public readonly StandardDeviation mySTD;
public SelectionData(QCAlgorithm algorithm, Symbol symbol)
{
mySTD = new StandardDeviation(20);
algorithm.AddSecurity(SecurityType.Equity, symbol);
var history = algorithm.History(symbol, 20);
algorithm.RemoveSecurity(symbol);
foreach (TradeBar tradeBar in history)
{
mySTD.Update(tradeBar.EndTime, tradeBar.Close);
}
}
public decimal mySTDValue(decimal price)
{
return mySTD / price;
}
public bool Update(DateTime time, decimal value)
{
return mySTD.Update(time, value);
}
}
public override void Initialize()
{
SetStartDate(2015, 12, 01);
//SetEndDate(2009, 6, 1);
SetCash(25000);
UniverseSettings.Resolution = Resolution.Minute;
SetWarmup(TimeSpan.FromMinutes(20));
AddUniverse(coarse =>
{
var topVolume = from cf in coarse
where cf.Volume >= 100000
select cf;
return (from cf in topVolume
let avg = _averages.GetOrAdd(cf.Symbol, sym => new SelectionData(this, cf.Symbol))
where avg.Update(cf.EndTime, cf.Price)
orderby avg.mySTDValue(cf.Price) descending
select cf.Symbol).Take(Count);
});
}
public void OnData(TradeBars data)
{
_changes = SecurityChanges.None;
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
_changes = changes;
}
}
}