Overall Statistics |
Total Trades 230 Average Win 0% Average Loss -0.51% Compounding Annual Return -44.468% Drawdown 55.700% Expectancy -1 Net Profit -44.825% Sharpe Ratio -0.816 Probabilistic Sharpe Ratio 2.605% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.091 Beta -1.141 Annual Standard Deviation 0.469 Annual Variance 0.22 Information Ratio -1.472 Tracking Error 0.542 Treynor Ratio 0.335 Total Fees $230.00 Estimated Strategy Capacity $550000.00 Lowest Capacity Asset IBM R735QTJ8XC9X |
using System; using System.Drawing; namespace QuantConnect.Algorithm.CSharp { public class CasualYellowGreenLemur : QCAlgorithm { string Symbol = "IBM"; //##### just move tp calculation in here for better flow static decimal st = 0.01m; decimal tp = st*2; decimal close = 0.0m; string type = "Buy"; int numberOfOrders =0; //##### set up for checking EMA meet TP2 criteria bool activateEMACheck = false; decimal filledQuantity; decimal filledPrice; private ExponentialMovingAverage slow; private ExponentialMovingAverage fast; private ExponentialMovingAverage ema; private OrderTicket _limitTicket; private OrderTicket _limitTicket2; private OrderTicket _stopMarketTicket; //##### you will not need int limitPrice, int StopMarketOrder, the RollingWindow, list of orders and decimal TP2 public override void Initialize() { SetStartDate(2020, 7, 4); SetEndDate(2021, 7, 6); SetCash(10000); AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute); fast = EMA(Symbol, 72, Resolution.Minute); slow = EMA(Symbol, 89, Resolution.Minute); ema = EMA(Symbol, 9, Resolution.Minute); Schedule.On(DateRules.On(EndDate), TimeRules.At(15, 0), SpecificTime); //##### warm up your indicator SetWarmUp(89); } public void SpecificTime() { Liquidate(Symbol); Debug("liquidated on the last day"); } public override void OnData(Slice data) { // ##### please check if the data slice contains the trade bar you need if (IsWarmingUp || !data.Bars.ContainsKey(Symbol)) return; var chart = Portfolio[Symbol]; close = data.Bars[Symbol].Close; //we call check on EMA to trigger TP2 first as it would be less expensive than conditions of numberOfOrders==0 if(numberOfOrders == 1 && activateEMACheck){ Checking(filledQuantity, filledPrice); } else if (chart.Price >= slow && numberOfOrders == 0) { type= "BUY"; Log("BUY >> " + Securities[Symbol].Price); _stopMarketTicket = StopMarketOrder(Symbol, -10, close-close * st); //##### 10 -> -10 (selling if stop hit), and do you mean stop price like this? otherwise it'll be filled right away _limitTicket = LimitOrder(Symbol, 10, close+close * tp); numberOfOrders = 1; Log("1st Stoploss >>" + _stopMarketTicket); Log("TP1 >>" + _limitTicket); } //##### avoid check again else if (chart.Price <= fast && numberOfOrders ==0) { type= "SELL"; Log("SELL >> " + Securities[Symbol].Price); _stopMarketTicket = StopMarketOrder(Symbol, 10, close+close * st); _limitTicket = LimitOrder(Symbol, -10, close-close * tp); //##### 10 -> -10 (selling) numberOfOrders = 1; Log("1st Stoploss >>" + _stopMarketTicket); Log("TP1 >>" + _limitTicket); } } public override void OnOrderEvent(OrderEvent orderEvent) { //##### no need to check filled in here if (numberOfOrders == 0) return; //##### Use swtich, break for speed to save from "if" check loop switch(numberOfOrders){ case 1:{ ///TP2 //##### do you mean fully filled order? as we have partially filled event also such that your qty might not be as desired if(_limitTicket.OrderId == orderEvent.OrderId && orderEvent.Status == OrderStatus.Filled){ //##### buy on below 9ema, sell the opposite way, you'll need to check if this is a buy/sell order //##### the original if condiiton will only run at this instance, it won't wait your ema conditions later, you'll need to specify a function to do so activateEMACheck = true; filledQuantity = orderEvent.FillQuantity; filledPrice = orderEvent.FillPrice; } //##### explicitly check if stop loss is hit else if(_stopMarketTicket.OrderId == orderEvent.OrderId && orderEvent.Status == OrderStatus.Filled){ Log(" **Hit stop loss: Resetting the Orders **"); //##### this will cancel all open orders Transactions.CancelOpenOrders(); numberOfOrders = 0; activateEMACheck = false; } } break; case 2: { //TP3 goes here //##### check additional order from TP1 if(_limitTicket2.OrderId == orderEvent.OrderId && orderEvent.Status == OrderStatus.Filled) { Log(" ** Hit TP2: Resetting the Orders **"); numberOfOrders = 0; } else if(_stopMarketTicket.OrderId == orderEvent.OrderId && orderEvent.Status == OrderStatus.Filled) { Log(" **Hit stop loss for TP2: Resetting the Orders **"); Transactions.CancelOpenOrders(); numberOfOrders = 0; } } break; default: { Log(" **Orders >=3 **"); Transactions.CancelOpenOrders(); numberOfOrders = 0; } break; } } private void Checking(decimal fillQuantity, decimal fillPrice){ var e = ema.Current.Value; //##### retrieve last window by .Current.Value var currentprice = Securities[Symbol].Price; if((currentprice < e && fillQuantity > 0m) || (currentprice > e && fillQuantity < 0m)){ Log(type + " >> " + currentprice); var qty = fillQuantity * 0.5m; _limitTicket2 = LimitOrder(Symbol, qty, close); //##### price should be same as close in here //##### you can just update the stop price in the first stop order var response = _stopMarketTicket.Update(new UpdateOrderFields() { StopPrice = fillPrice, Quantity = fillQuantity + qty //##### sum of 1st and 2nd limit orders' quantities }); //##### Check response with the OrderResponse, you may discard if not needed if (response.IsSuccess) { Debug("adjust stop price successfully"); } numberOfOrders = 2; Log("STOP >>" + _stopMarketTicket); Log("TP2 >>" + _limitTicket2); activateEMACheck = false; } } } }