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