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;
			
		}
		
		
        
    }
    
}