Overall Statistics |
Total Trades 18 Average Win 13.03% Average Loss -2.36% Compounding Annual Return 101.936% Drawdown 51.300% Expectancy 3.885 Net Profit 78.181% Sharpe Ratio 2.323 Loss Rate 25% Win Rate 75% Profit-Loss Ratio 5.51 Alpha -0.015 Beta 37.999 Annual Standard Deviation 0.219 Annual Variance 0.048 Information Ratio 2.26 Tracking Error 0.219 Treynor Ratio 0.013 Total Fees $63.36 |
namespace QuantConnect.Algorithm.CSharp { public class ARCryptoTemplateAlgorithm : QCAlgorithm { // USER variables private string ticker = "BTCUSD"; private int startingCash = 2000; private int maxPosition = 1000; private int minPosition = 500; private decimal usd; // PROGRAM variables public decimal price; public decimal holding; // the # of eth that we hold in the portfolio public string baseSymbol; // "ETH" Stochastic sto; Resolution res = Resolution.Tick; RollingWindow<IndicatorDataPoint> stochKWin; RollingWindow<IndicatorDataPoint> stochDWin; Stochastic sto2; RollingWindow<IndicatorDataPoint> stochKWin2; RollingWindow<IndicatorDataPoint> stochDWin2; MovingAverageConvergenceDivergence macd; RollingWindow<IndicatorDataPoint> macdWin; MomersionIndicator momersion; public override void Initialize() { SetStartDate(2017, 3, 8); //Set Start Date SetEndDate(2018, 1, 1); //Set End Date SetCash(startingCash); //Set Strategy Cash var crypto = AddCrypto(ticker, res); baseSymbol = crypto.BaseCurrencySymbol; SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash); DefaultOrderProperties = new GDAXOrderProperties { PostOnly = true }; Chart tradePlotter = new Chart("Trades"); tradePlotter.AddSeries(new Series("BUY", SeriesType.Scatter, index:0)); tradePlotter.AddSeries(new Series("SELL", SeriesType.Scatter, index:0)); AddChart(tradePlotter); Chart stoPlotter = new Chart("Sto", ChartType.Stacked); stoPlotter.AddSeries(new Series("K", SeriesType.Line, index:0)); //stoPlotter.AddSeries(new Series("D", SeriesType.Line, index:0)); AddChart(stoPlotter); var consolidator = new TickConsolidator(3000); consolidator.DataConsolidated += consHandler; SubscriptionManager.AddConsolidator(ticker, consolidator); sto = new Stochastic(ticker, 10, 8, 3); RegisterIndicator(ticker, sto, consolidator); sto.StochK.Updated += (sender, updated) => stochKWin.Add(updated); sto.StochD.Updated += (sender, updated) => stochDWin.Add(updated); stochKWin = new RollingWindow<IndicatorDataPoint>(5); stochDWin = new RollingWindow<IndicatorDataPoint>(5); macd = new MovingAverageConvergenceDivergence(ticker, 3,8,9, MovingAverageType.Exponential); RegisterIndicator(ticker, macd, consolidator, x => x.Value); macd.Signal.Updated += (sender, updated) => macdWin.Add(updated); macdWin = new RollingWindow<IndicatorDataPoint>(5); // momersion = MOMERSION(ticker, 12,26); // RegisterIndicator(ticker, momersion, consolidator, x => x.Value); //--- minutely data consolidator var consolidator2 = new TickConsolidator(TimeSpan.FromMinutes(60)); consolidator2.DataConsolidated += (sender, data) => { Log($"###### Time = {data.EndTime}");}; SubscriptionManager.AddConsolidator(ticker, consolidator2); sto2 = new Stochastic(ticker, 14, 10, 5); RegisterIndicator(ticker, sto2, consolidator2); sto2.StochK.Updated += (sender, updated) => stochKWin2.Add(updated); sto2.StochD.Updated += (sender, updated) => stochDWin2.Add(updated); stochKWin2 = new RollingWindow<IndicatorDataPoint>(5); stochDWin2 = new RollingWindow<IndicatorDataPoint>(5); } //public override void OnData(Slice data) public void consHandler(object sender, TradeBar data) { //price = data[ticker].Price; price = data.Price; usd = Portfolio.CashBook["USD"].Amount; Plot("Sto", "K", stochKWin[0]); //Plot("Sto", "D", stochDWin[0]); if (!stochKWin.IsReady && !stochDWin.IsReady && !macdWin.IsReady && !stochKWin2.IsReady && !stochDWin2.IsReady) {return;} Log($"{price} at {data.EndTime}, K= {stochKWin[0].Value}, K2= {stochKWin2[0].Value}, MACD= {macdWin[0].Value}"); if (!Portfolio.Invested && usd > minPosition) { if (stochKWin[0].Value >= 20 && (stochKWin[1].Value < 20 || stochKWin[2].Value < 20 || stochKWin[3].Value < 20 ) && stochKWin[0].Value>stochDWin[0].Value && stochKWin2[0].Value >= 20 && stochKWin2[0].Value>stochDWin2[0].Value)//&& macdWin[0].Value>macdWin[1].Value) { decimal quantity = Math.Round(Math.Min(usd, maxPosition)/price,2); LimitOrder(ticker, quantity, Math.Round((price - 0.01m),2)); Plot("Trades", "BUY", price); } } if (Portfolio.Invested) { if (stochKWin[0] < 80 && stochKWin[1]>=80 && stochKWin[0] < stochDWin[0] && stochKWin2[0] < 80 && stochKWin2[1]>=80 && stochKWin2[0] < stochDWin2[0]) { holding = Portfolio.CashBook[baseSymbol].Amount; MarketOrder(ticker, -holding); Plot("Trades", "SELL", price); } } } public override void OnOrderEvent(OrderEvent orderEvent){ Log(orderEvent.ToString()); } } }