Overall Statistics |
Total Trades 447 Average Win 6.26% Average Loss -4.85% Compounding Annual Return 537.403% Drawdown 44.200% Expectancy 0.151 Net Profit 197.674% Sharpe Ratio 1.696 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.29 Alpha 1.755 Beta 2.266 Annual Standard Deviation 1.124 Annual Variance 1.262 Information Ratio 1.646 Tracking Error 1.118 Treynor Ratio 0.841 Total Fees $0.00 |
namespace QuantConnect { public class Hippopotamus : QCAlgorithm { [Parameter] public string symbol = "EURUSD"; [Parameter] public int ema = 20; [Parameter] public int minutes = 89; [Parameter] public int waitBars = 0; [Parameter] public decimal maxSpread = 0.0002M; [Parameter] public decimal maxMove = 0.002M; [Parameter] public decimal stopMargin = 0.0002M; [Parameter] public decimal tsCutoff = 0.00075M; [Parameter] public decimal slAfterPi = 0.0005M; [Parameter] public decimal takeProfit = 0.002M; [Parameter] public DateTime startDate = new DateTime(2014, 1, 1); [Parameter] public DateTime endDate = new DateTime(2014, 1, 2); static Resolution dataResolution = Resolution.Tick; ExponentialMovingAverage emaIndicator; OrderTicket order; TradeBar[] last3; bool[] rising; decimal stopLossPrice; decimal takeProfitPrice; decimal trailingStopPrice; decimal maxProfit; int barsSinceExit; public override void Initialize() { SetStartDate(startDate); SetEndDate(endDate); SetCash(10000); SetBrokerageModel(BrokerageName.OandaBrokerage); AddSecurity(SecurityType.Forex, symbol, dataResolution); SetWarmup(ema); var tickConsolidator = new TickConsolidator(TimeSpan.FromMinutes(minutes)); emaIndicator = new ExponentialMovingAverage(ema); RegisterIndicator(symbol, emaIndicator, tickConsolidator); tickConsolidator.DataConsolidated += OnTick; SubscriptionManager.AddConsolidator(symbol, tickConsolidator); last3 = new TradeBar[3]; rising = new bool[3]; trailingStopPrice = 0; barsSinceExit = 0; } public void OnTick(object sender, TradeBar bar) { TradeBar[] temp = new TradeBar[3]; barsSinceExit++; for (int i = 1; i < 3; i++) { temp[i - 1] = last3[i]; } last3 = temp; last3[2] = bar; if (last3[0] != null && last3[1] != null && last3[2] != null) { for (int i = 0; i < 3; i++) { if(last3[i].Open - last3[i].Close > 0) { rising[i] = false; } else { rising [i] = true; } } } temp = null; } public override void OnData(Slice data) { if (!data.ContainsKey(symbol)) return; if (IsWarmingUp) return; var tick = data[symbol][0]; double vol = 0; if (last3[2] != null) vol = Math.Abs((double)(last3[2].Open - last3[2].Close)); if (!Portfolio.HoldStock && !IsWarmingUp && tick.AskPrice - tick.BidPrice < maxSpread && last3[0] != null && last3[1] != null && last3[2] != null && vol > (double)maxSpread && vol < (double)maxMove && barsSinceExit > waitBars ) { if (rising[0] && rising[1] && rising[2] && last3[2].Close > emaIndicator ) { buy(); } else if (!rising[0] && !rising[1] && !rising[2] && last3[2].Close < emaIndicator ) { sell(); } } else if (Portfolio.HoldStock && !IsWarmingUp && tick.AskPrice - tick.BidPrice < maxSpread ) { Order orderObject = (Order)Transactions.GetOrderById(order); int quantity = (int)orderObject.Quantity; decimal price = orderObject.Price; if ((quantity < 0 && (tick.AskPrice > stopLossPrice || tick.AskPrice < takeProfitPrice)) || (quantity > 0 && (tick.BidPrice < stopLossPrice || tick.BidPrice > takeProfitPrice)) ) { close(symbol, quantity); } else if ((quantity < 0 && tick.AskPrice > emaIndicator) || (quantity > 0 && tick.BidPrice < emaIndicator) ) { //close(symbol, quantity); } else if (0==0) { } /*if (quantity < 0 && trailingStopPrice > tick.AskPrice + slAfterPi) trailingStopPrice = tick.AskPrice + slAfterPi; else if (quantity > 0 && trailingStopPrice < tick.BidPrice - slAfterPi) trailingStopPrice = tick.BidPrice - slAfterPi; if ((quantity < 0 && (tick.AskPrice > trailingStopPrice)) || (quantity > 0 && (tick.BidPrice < trailingStopPrice)) ) { close(symbol, quantity); }*/ } tick = null; } public override void OnOrderEvent(OrderEvent orderEvent) { //Notify var order = Transactions.GetOrderById(orderEvent.OrderId); Notify.Sms("8602808220", Time + " : " + order.Type + " : " + orderEvent); } public void buy() { if (!Portfolio.HoldStock) { int units = (int)(20 * (double)Portfolio.TotalPortfolioValue); order = Order(symbol, units); Order orderObject = (Order)Transactions.GetOrderById(order); if (orderObject != null) { decimal tradePrice = orderObject.Price; stopLossPrice = last3[0].Low - stopMargin; takeProfitPrice = tradePrice + Math.Abs(last3[0].Low + stopMargin - tradePrice); } } } public void sell() { if (!Portfolio.HoldStock) { int units = (int)(20 * (double)Portfolio.TotalPortfolioValue); order = Order(symbol, -1 * units); Order orderObject = (Order)Transactions.GetOrderById(order); if (orderObject != null) { decimal tradePrice = orderObject.Price; stopLossPrice = last3[0].High + stopMargin; takeProfitPrice = tradePrice - Math.Abs(last3[0].High + stopMargin - tradePrice); } } } public void close(string symbol, decimal quantity) { Order(symbol, -1 * quantity); barsSinceExit = 0; } } }