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