Overall Statistics
Total Trades
13
Average Win
0.39%
Average Loss
-0.05%
Compounding Annual Return
-47.122%
Drawdown
13.600%
Expectancy
3.034
Net Profit
-0.348%
Sharpe Ratio
497.724
Probabilistic Sharpe Ratio
0%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
7.07
Alpha
151.49
Beta
4.083
Annual Standard Deviation
0.316
Annual Variance
0.1
Information Ratio
653.376
Tracking Error
0.238
Treynor Ratio
38.479
Total Fees
$2646.45
from datetime import timedelta

#https://www.youtube.com/watch?v=AM52D58vGQk&t=231s

class ParticleMultidimensionalInterceptor(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 4)
        self.SetEndDate(2021, 1, 5)
        self.SetCash(100000)
        self.btcusd = self.AddCrypto("BTCUSD", Resolution.Minute, Market.GDAX)
        self.symbol = self.btcusd.Symbol
        
        self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
        
        ema_period = 200
        rsi_period = 14
        self.risk_reward = 2
        self.previous_bar = None
        
        self.ema = ExponentialMovingAverage(ema_period)
        self.rsi = self.RSI(self.symbol, rsi_period,  MovingAverageType.Simple, Resolution.Minute)
            
        self.RegisterIndicator(self.symbol, self.ema, Resolution.Minute)
        self.RegisterIndicator(self.symbol, self.rsi, Resolution.Minute)
        
        self.SetWarmup(ema_period)


    def OnData(self, data):
        
        self.Plot("EMA/Price", "EMA", self.ema.Current.Value)
        self.Plot("EMA/Price", "Price", data[self.symbol].Close)
        self.Plot("RSI", "RSI", self.rsi.Current.Value)
        
        # Wait until warmup period is over
        if not self.IsWarmingUp:
            
            engulfing = False
            if self.previous_bar is not None and self.previous_bar.Close < self.previous_bar.Open:
                if data[self.symbol].Close >= self.previous_bar.Open and data[self.symbol].Open <= self.previous_bar.Close:
                    engulfing = True
            
            # If all 3 indicators agree
            if data[self.symbol].Close > self.ema.Current.Value and self.rsi.Current.Value > 50 and engulfing:
                
                # Make sure we don't have any open positions
                if not self.Portfolio.Invested:
                    quantity = self.CalculateOrderQuantity(self.symbol, 1.0)
                    self.MarketOrder(self.symbol, quantity)
                    
                    # Set stop loss to the opening price
                    stopLoss = self.Securities[self.symbol].Open
                    
                    # Set profit target to x2 the risk delta
                    risk_delta = self.Securities[self.symbol].Close - stopLoss
                    target = self.Securities[self.symbol].Close + (risk_delta * 2)
                    
                    self.LimitOrder(self.symbol, -quantity, target, "Take Profit")
                    self.StopMarketOrder(self.symbol, -quantity, stopLoss, "Stop Loss")
                    
        self.previous_bar = data[self.symbol]
                    
    def OnOrderEvent(self, orderEvent):
        
        order = self.Transactions.GetOrderById(orderEvent.OrderId)
        
        if order.Status == OrderStatus.Filled:
            if order.Type == OrderType.Limit or order.Type == OrderType.Limit:
                self.Transactions.CancelOpenOrders(order.Symbol)
                
        if order.Status == OrderStatus.Canceled:
            self.Log(str(orderEvent))