| Overall Statistics |
|
Total Trades 10001 Average Win 0.23% Average Loss -0.42% Compounding Annual Return -2.105% Drawdown 74.300% Expectancy -0.008 Net Profit -24.843% Sharpe Ratio 0.05 Probabilistic Sharpe Ratio 0.006% Loss Rate 36% Win Rate 64% Profit-Loss Ratio 0.55 Alpha -0.042 Beta 0.753 Annual Standard Deviation 0.245 Annual Variance 0.06 Information Ratio -0.286 Tracking Error 0.21 Treynor Ratio 0.016 Total Fees $17439.43 |
namespace QuantConnect
{
public partial class BootCampTask : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2002, 3, 1);
SetEndDate(2020, 05, 25);
SetCash(100000);
UniverseSettings.Resolution = Resolution.Hour;
AddUniverseSelection(new LiquidValueUniverseSelectionModel());
//1. Create an instance of the LongShortEYAlphaModelLongShortEYAlphaModel()
SetAlpha(new LongShortEYAlphaModel());
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
SetExecution(new ImmediateExecutionModel());
SetRiskManagement(new MaximumDrawdownPercentPerSecurity(0.02m));
}
}
public class LiquidValueUniverseSelectionModel : FundamentalUniverseSelectionModel
{
private int _lastMonth = -1;
public LiquidValueUniverseSelectionModel()
: base(true, null, null)
{
}
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
{
if (_lastMonth == algorithm.Time.Month)
{
return Universe.Unchanged;
}
_lastMonth = algorithm.Time.Month;
var sortedByDollarVolume = coarse
.Where(x => x.HasFundamentalData)
.OrderByDescending(x => x.DollarVolume);
return sortedByDollarVolume
.Take(5)
.Select(x => x.Symbol);
}
public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
{
var sortedByYields = fine.OrderByDescending(x => x.ValuationRatios.EarningYield);
var universe = sortedByYields.Take(2).Concat(sortedByYields.TakeLast(2));
return universe.Select(x => x.Symbol);
}
}
// Define the LongShortEYAlphaModel class
public class LongShortEYAlphaModel : AlphaModel
{
private int _lastMonth = -1;
private List<Security> _activeSecurities = new List<Security>();
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
//2. If statement to emit signals once a month
if(_lastMonth == algorithm.Time.Month){
return insights;
}
_lastMonth = algorithm.Time.Month;
//3. Use foreach to emit insights with insight directions
foreach (var security in _activeSecurities){
if (data.ContainsKey(security.Symbol)) {
var yield = security.Fundamentals.ValuationRatios.EarningYield;
var direction = (InsightDirection) Math.Sign(yield);
insights.Add(Insight.Price(security.Symbol, TimeSpan.FromDays(28), direction));
}
}
// based on whether earnings yield is greater or less than zero once a month
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) {
// Handle security changes in from your universe model.
foreach (var added in changes.AddedSecurities){
_activeSecurities.Add(added);
}
foreach (var removed in changes.RemovedSecurities){
_activeSecurities.Remove(removed);
}
}
}
}