Overall Statistics |
Total Trades 71 Average Win 21.58% Average Loss -1.23% Compounding Annual Return 10.782% Drawdown 18.700% Expectancy 3.976 Net Profit 679.665% Sharpe Ratio 0.787 Loss Rate 73% Win Rate 27% Profit-Loss Ratio 17.55 Alpha 0.016 Beta 4.838 Annual Standard Deviation 0.142 Annual Variance 0.02 Information Ratio 0.648 Tracking Error 0.142 Treynor Ratio 0.023 Total Fees $1200.99 |
namespace QuantConnect.Algorithm.CSharp { /// <summary> /// This algorithm will go long when the 50 crosses above the 200 and will short /// when the 50 crosses back below the 200. /// </summary> public class MovingAverageCrossAlgorithm : QCAlgorithm { private string _symbol = "SPY"; private DateTime _previous; private SimpleMovingAverage _fast; private SimpleMovingAverage _slow; // private SimpleMovingAverage[] _ribbon; /// <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() { // set up our analysis span SetStartDate(1998, 01, 02); //SetEndDate(2017, 07, 01); SetCash(100000); // request SPY data with minute resolution AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute); // create a 50 day exponential moving average _fast = SMA(_symbol, 50, Resolution.Daily); // create a 200 day exponential moving average _slow = SMA(_symbol, 200, Resolution.Daily); // var ribbonCount = 4; // var ribbonInterval = 50; // _ribbon = Enumerable.Range(0, ribbonCount).Select(x => SMA(_symbol, (x + 1)*ribbonInterval, Resolution.Daily)).ToArray(); } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">TradeBars IDictionary object with your stock data</param> public void OnData(TradeBars data) { // a couple things to notice in this method: // 1. We never need to 'update' our indicators with the data, the engine takes care of this for us // 2. We can use indicators directly in math expressions // 3. We can easily plot many indicators at the same time // wait for our slow ema to fully initialize if (!_slow.IsReady) return; // only once per day if (_previous.Date == Time.Date) return; // define a small tolerance on our checks to avoid bouncing const decimal tolerance = 0.00015m; var holdings = Portfolio[_symbol].Quantity; var profitloss = Portfolio[_symbol].UnrealizedProfit; // we only want to go long if we're currently short or flat if (holdings <= 0) { // if the fast is greater than the slow, we'll go long if (_fast > _slow * (1 + tolerance)) { Log("BUY >> " + Securities[_symbol].Price); SetHoldings(_symbol, 1.0); } } // we only want to liquidate if we're currently long // if the fast is less than the slow we'll liquidate our long //if (_fast < _slow) if (holdings > 0 && _fast < _slow) { Log("SELL >> " + Securities[_symbol].Price); SetHoldings(_symbol, -1.0); //Liquidate(_symbol); } if (profitloss <= -2000) { //Log("SELL >> " + Securities[_symbol].Price); //SetHoldings(_symbol, -1.0); Liquidate(_symbol); } Plot(_symbol, "Price", data[_symbol].Price); // easily plot indicators, the series name will be the name of the indicator Plot(_symbol, _fast, _slow); //Plot("Ribbon", _ribbon); _previous = Time; } } }