Overall Statistics |
Total Trades 4382 Average Win 0.17% Average Loss -0.11% Compounding Annual Return 1.423% Drawdown 47.600% Expectancy 0.058 Net Profit 7.832% Sharpe Ratio 0.173 Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.52 Alpha 0.284 Beta -12.492 Annual Standard Deviation 0.221 Annual Variance 0.049 Information Ratio 0.084 Tracking Error 0.221 Treynor Ratio -0.003 Total Fees $6129.16 |
using MathNet.Numerics.Statistics; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Indicators; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; namespace QuantConnect.Algorithm.CSharp { public sealed class PETestAlgorithm : QCAlgorithm { private const int _numFine = 10; private const int _numCoarse = 400; private const decimal _target = 1m / _numFine; private SecurityChanges _changes = SecurityChanges.None; private readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>(); private class SelectionData { private static readonly Symbol _whoCares = "XXXXXXXXXXXXXXX"; private int _lastCoarseMonth = -1; private int _lastFineMonth = -1; public decimal CoarseRankingStat; public decimal FineRankingStat; public bool UpdateFineFundamental(FineFundamental fine) { if (_lastFineMonth < 0 || _lastFineMonth != fine.Time.Month) { _lastFineMonth = fine.Time.Month; decimal pe = fine.ValuationRatios.PERatio; if (pe == 0) FineRankingStat = -100000m; else if (pe > 0) FineRankingStat = -pe; else //pe < 0 FineRankingStat = 1m / pe; } return true; } public bool UpdateCoarseFundamental(CoarseFundamental coarse) { if (_lastCoarseMonth < 0 || _lastCoarseMonth != coarse.Time.Month) { _lastCoarseMonth = coarse.Time.Month; CoarseRankingStat = coarse.DollarVolume; } return true; } } /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { UniverseSettings.Resolution = Resolution.Daily; SetStartDate(2014, 01, 01); //SetEndDate(2015, 01, 01); SetCash(100 * 1000); AddUniverse(CoarseSelection, FineSelection); } private IEnumerable<Symbol> CoarseSelection(IEnumerable<CoarseFundamental> coarse) { var hasFundamental = coarse.Where(x => x.HasFundamentalData); return (from cf in hasFundamental let avg = _averages.GetOrAdd(cf.Symbol, sym => new SelectionData()) where avg.UpdateCoarseFundamental(cf) orderby avg.CoarseRankingStat descending select cf.Symbol).Take(_numCoarse); } private IEnumerable<Symbol> FineSelection(IEnumerable<FineFundamental> fine) { return (from f in fine let avg = _averages.GetOrAdd(f.Symbol, sym => new SelectionData()) where avg.UpdateFineFundamental(f) orderby avg.FineRankingStat descending select f.Symbol).Take(_numFine); } public void OnData(TradeBars data) { if (_changes == SecurityChanges.None) return; // liquidate securities removed from our universe foreach (var security in _changes.RemovedSecurities) { if (security.Invested) { Liquidate(security.Symbol); } } // we'll simply go long each security we added to the universe foreach (var security in _changes.AddedSecurities) { SetHoldings(security.Symbol, _target); } } public override void OnSecuritiesChanged(SecurityChanges changes) { _changes = changes; } } }