| Overall Statistics |
|
Total Trades 226 Average Win 0.01% Average Loss -0.01% Compounding Annual Return 50.132% Drawdown 1.600% Expectancy -0.296 Net Profit 7.385% Sharpe Ratio 5.93 Probabilistic Sharpe Ratio 98.098% Loss Rate 59% Win Rate 41% Profit-Loss Ratio 0.71 Alpha 0.054 Beta 1.014 Annual Standard Deviation 0.074 Annual Variance 0.006 Information Ratio 1.334 Tracking Error 0.044 Treynor Ratio 0.434 Total Fees $237.05 Estimated Strategy Capacity $9100000.00 |
using System.Reflection;
namespace QuantConnect
{
public partial class BootCampTask : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2016, 12, 28);
SetEndDate(2017, 3, 1);
SetCash(100000);
UniverseSettings.Resolution = Resolution.Hour;
SetUniverseSelection(new MyUniverseSelectionModel());
SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(1), 0.025, null));
SetPortfolioConstruction(new SectorWeightingPortfolioConstructionModel(Resolution.Daily));
SetExecution(new ImmediateExecutionModel());
}
}
public class MyUniverseSelectionModel : FundamentalUniverseSelectionModel
{
public MyUniverseSelectionModel()
: base(true)
{
}
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
{
return
(from c in coarse
where c.HasFundamentalData && c.Price > 0
orderby c.DollarVolume descending
select c.Symbol).Take(100);
}
public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
{
var technology = new List<FineFundamental>();
technology.AddRange(
(from f in fine
where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology
orderby f.MarketCap descending select f).Take(3)
);
var financialServices = new List<FineFundamental>();
financialServices.AddRange(
(from f in fine
where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices
orderby f.MarketCap descending select f).Take(2)
);
var consumerDefensive = new List<FineFundamental>();
consumerDefensive.AddRange(
(from f in fine
where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive
orderby f.MarketCap descending select f).Take(1)
);
var selection = new List<Symbol>();
selection.AddRange(technology.Select(f=> f.Symbol));
selection.AddRange(financialServices.Select(f=> f.Symbol));
selection.AddRange(consumerDefensive.Select(f=> f.Symbol));
return selection;
}
}
public class SectorWeightingPortfolioConstructionModel : EqualWeightingPortfolioConstructionModel
{
private readonly Dictionary<int, List<Symbol>> symbolBySectorCode = new Dictionary<int, List<Symbol>>();
private readonly Dictionary<Insight, double> result = new Dictionary<Insight, double>();
private decimal sectorBuyingPower = 0;
public SectorWeightingPortfolioConstructionModel(Resolution resolution)
: base(resolution)
{
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
foreach (var security in changes.AddedSecurities)
{
//1. When new assets are added to the universe, save the Morningstar Sector Code for each security to the variable sectorCode
var sectorCode = security.Fundamentals?.AssetClassification?.MorningstarSectorCode;
//2. If there is a sectorCode and it is not in the symbolBySectorCode dictionary, save the values as a list
// and append the security symbol as the value in the symbolBySectorCode dictionary
if (sectorCode.HasValue)
{
if (!symbolBySectorCode.ContainsKey(sectorCode.Value))
{
symbolBySectorCode[sectorCode.Value] = new List<Symbol>();
}
// If a sectorCode exists in the mapping, Add the security Symbol to the dictionary
symbolBySectorCode[sectorCode.Value].Add(security.Symbol);
}
}
foreach (var security in changes.RemovedSecurities)
{
//3. For securities that are removed, save their MorningStar sector code to sectorCode
var sectorCode = security.Fundamentals?.AssetClassification?.MorningstarSectorCode;
//4. If the saved sectorCode is in the symbolBySectorCode dictionary, remove the sectorCode.
// If the saved symbol is a value in the symbolBySectorCode dictionary, remove the symbol
if (sectorCode.HasValue)
{
symbolBySectorCode[sectorCode.Value].Remove(security.Symbol);
}
}
// We use the super() function to avoid using the base class name explicity
base.OnSecuritiesChanged(algorithm, changes);
}
}
}