| Overall Statistics |
|
Total Trades 30 Average Win 0.27% Average Loss -0.44% Compounding Annual Return -1.420% Drawdown 3.800% Expectancy -0.516 Net Profit -0.231% Sharpe Ratio -0.132 Probabilistic Sharpe Ratio 31.160% Loss Rate 70% Win Rate 30% Profit-Loss Ratio 0.61 Alpha -0.034 Beta 0.563 Annual Standard Deviation 0.072 Annual Variance 0.005 Information Ratio -0.883 Tracking Error 0.059 Treynor Ratio -0.017 Total Fees $33.36 |
using System.Collections.Concurrent;
namespace QuantConnect.Algorithm.CSharp
{
public class LogOverflow : QCAlgorithm
{
// variables
public int _lastMonth = -1;
Random rnd = new Random();
public ConcurrentDictionary<Symbol, SelectionData> stateData = new ConcurrentDictionary<Symbol, SelectionData>();
public ConcurrentDictionary<Symbol, SelectionData> longCandidatesData = new ConcurrentDictionary<Symbol, SelectionData>();
public Dictionary<Symbol, decimal> splitFactorBySymbol = new Dictionary<Symbol, decimal>();
// parameters
public int[] rebalanceMonths = new int[]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
public static int upperMarketPercentile = 90;
public static int lowerMarketPercentile = 68;
public class SelectionData
{
public SelectionData(){}
}
public override void Initialize()
{
SetStartDate(2014, 1, 1);
SetEndDate(2014, 3, 1);
SetCash(100000);
UniverseSettings.Resolution = Resolution.Daily;
SetSecurityInitializer(x => x.SetDataNormalizationMode(DataNormalizationMode.Adjusted));
AddUniverse(CoarseFilter, FineFilter);
}
public IEnumerable<Symbol> CoarseFilter(IEnumerable<CoarseFundamental> coarse)
{
if (Time.Month == _lastMonth)
{
return Universe.Unchanged;
}
_lastMonth = Time.Month;
if(!rebalanceMonths.Contains(Time.Month))
{
return Universe.Unchanged;
}
var list = (from c in coarse
where c.HasFundamentalData
select c).ToList();
splitFactorBySymbol.Clear();
splitFactorBySymbol = list.GroupBy(x => x.Symbol).Select(x => x.First()).ToDictionary(x => x.Symbol, x => x.SplitFactor);
return list.Select(x => x.Symbol);
}
public IEnumerable<Symbol> FineFilter(IEnumerable<FineFundamental> fine)
{
// market Cap calculation
var marketCapList = (from f in fine
let marketCap = (decimal)(f.EarningReports.BasicAverageShares.ThreeMonths * f.Price * splitFactorBySymbol[f.Symbol])
orderby marketCap
select marketCap).ToList();
var lowerCap = (decimal) marketCapList[(int)((decimal)(marketCapList.Count-1)/100 * lowerMarketPercentile)];
var upperCap = (decimal) marketCapList[(int)((decimal)(marketCapList.Count-1)/100 * upperMarketPercentile)];
var SmB = (from f in fine
let marketCap = (decimal)(f.EarningReports.BasicAverageShares.ThreeMonths * f.Price * splitFactorBySymbol[f.Symbol])
where marketCap > lowerCap
where marketCap <= upperCap
select f.Symbol).ToList();
return SmB;
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if(changes.AddedSecurities.Count > 0)
{
for(int i=0; i < changes.AddedSecurities.Count; i++)
{
var addedSymbol = changes.AddedSecurities[i].Symbol;
stateData.TryAdd(addedSymbol, new SelectionData());
}
}
if(changes.RemovedSecurities.Count > 0)
{
for(int i=0; i < changes.RemovedSecurities.Count; i++)
{
var temp = new SelectionData();
stateData.TryRemove(changes.RemovedSecurities[i].Symbol, out temp);
}
}
foreach(var kvp in stateData)
{
// This line causes log messages
var bars = History(kvp.Key, 131, Resolution.Daily);
// This line causes log messages
}
var tempDictionary = stateData.OrderBy(x => rnd.Next(stateData.Count)).Take(10).ToDictionary(x => x.Key, x => x.Value);
longCandidatesData = new ConcurrentDictionary<Symbol, SelectionData>(tempDictionary);
foreach(var symbol in Portfolio.Where(x => x.Value.Invested).Select(x => x.Key))
{
if(!longCandidatesData.Keys.Contains(symbol))
{
Liquidate(symbol);
}
}
foreach(var kvp in longCandidatesData)
{
var symbol = kvp.Key;
if(!Portfolio[symbol].Invested)
{
SetHoldings(symbol, 0.05m);
}
}
}
public override void OnData(Slice data)
{
}
}
}