Overall Statistics |
Total Trades 552 Average Win 2.15% Average Loss -1.81% Compounding Annual Return 8.748% Drawdown 15.700% Expectancy 0.252 Net Profit 223.831% Sharpe Ratio 0.734 Loss Rate 43% Win Rate 57% Profit-Loss Ratio 1.19 Alpha 0.074 Beta 0.002 Annual Standard Deviation 0.1 Annual Variance 0.01 Information Ratio 0.135 Tracking Error 0.21 Treynor Ratio 44.089 Total Fees $1331.16 |
namespace QuantConnect { /* * John Ehlers' MESA * (programmed by Jean-Paul van Brakel) */ public class BasicTemplateAlgorithm : QCAlgorithm { public string _ticker = "SPY"; // which stock ticker public static int MESA_length = 9; // indicator length public static decimal _limit = 0.85M; // threshold for anti-trend liquidation private readonly RollingWindow<double> Prices = new RollingWindow<double>(MESA_length); private Chart plotter; decimal _oldprice = 100000; decimal _price; decimal _oldsine; decimal _sine; decimal _lead; int _dir = 0; public override void Initialize() { //Start and End Date range for the backtest: SetStartDate(2000, 1, 1); SetEndDate(2014, 1, 1); SetCash(25000); AddSecurity(SecurityType.Equity, _ticker, Resolution.Daily); plotter = new Chart("MESA", ChartType.Overlay); plotter.AddSeries(new Series("MESA sine", SeriesType.Line)); plotter.AddSeries(new Series("MESA lead", SeriesType.Line)); AddChart(plotter); } public void OnData(TradeBars data) { Prices.Add((double)(data[_ticker].High + data[_ticker].Low)/2); _price = data[_ticker].Close; if (!Prices.IsReady) return; // MESA // ********************************************************************************************************* double realPart = 0; double imagPart = 0; for (int i = 0; i < MESA_length; i++) { double temp = Prices[i]; realPart = realPart + temp*Math.Cos(2*Math.PI*i/MESA_length); imagPart = imagPart + temp*Math.Sin(2*Math.PI*i/MESA_length); } double phase1 = 0; if (Math.Abs(realPart) > 0.001) { phase1 = Math.Atan(imagPart/realPart); } else { phase1 = (Math.PI / 2*Math.Sign(imagPart)); } double phase2 = 0; if (realPart < 0) { phase2 = phase1 + Math.PI; } else { phase2 = phase1; } double phase = 0; if (phase2 < 0) { phase = phase2 + 2*Math.PI; } else if (phase2 > 2*Math.PI) { phase = phase2 - 2*Math.PI; } else { phase = phase2; } _oldsine = _sine; _sine = (decimal) Math.Cos(phase); _lead = (decimal) Math.Cos(phase+Math.PI/4); int _old_dir = _dir; if (_lead < _sine && _dir != -1) { _dir = -1; } else if (_lead > _sine && _dir != 1) { _dir = 1; } // ********************************************************************************************************* // Update chart Plot("MESA", "MESA sine", _sine+90); Plot("MESA", "MESA lead", _lead+90); // Order logic / (simple) risk management decimal pps = ((_price - _oldprice)/_oldprice)*100; if (pps >= 4.5M || pps < -2.0M || _dir != _old_dir || // if P/L crosses boundaries (_sine < _limit && _sine > _oldsine && _dir == -1) || // if direction is wrong (_sine > _limit && _sine < _oldsine && _dir == 1)) { // if direction is wrong // End position Liquidate(_ticker); } if (!Portfolio.HoldStock) { int quantity = (int)Math.Floor(Portfolio.Cash / data[_ticker].Close); if (_dir != _old_dir) { if (quantity > 0) Order(_ticker, _dir*quantity); _oldprice = _price; } } } } }