| Overall Statistics |
|
Total Trades 10001 Average Win 0.05% Average Loss -0.05% Compounding Annual Return 7.162% Drawdown 9.500% Expectancy 0.040 Net Profit 17.310% Sharpe Ratio 0.666 Probabilistic Sharpe Ratio 27.778% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 1.06 Alpha 0.039 Beta 0.124 Annual Standard Deviation 0.088 Annual Variance 0.008 Information Ratio -0.607 Tracking Error 0.153 Treynor Ratio 0.469 Total Fees $12092.74 |
namespace QuantConnect
{
public partial class BootCampTask : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2002, 10, 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(100)
.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(10).Concat(sortedByYields.TakeLast(10));
return universe.Select(x => x.Symbol);
}
}
// Define the LongShortEYAlphaModel class
public class LongShortEYAlphaModel : AlphaModel
{
private int _lastMonth = -1;
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 algorithm.ActiveSecurities.Values){
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;
}
}
}