Overall Statistics
Total Trades
207
Average Win
0.01%
Average Loss
-0.01%
Compounding Annual Return
0.257%
Drawdown
0.300%
Expectancy
0.317
Net Profit
0.254%
Sharpe Ratio
0.796
Probabilistic Sharpe Ratio
40.364%
Loss Rate
53%
Win Rate
47%
Profit-Loss Ratio
1.83
Alpha
0.001
Beta
0.003
Annual Standard Deviation
0.002
Annual Variance
0
Information Ratio
-2.125
Tracking Error
0.125
Treynor Ratio
0.539
Total Fees
$0.00
Estimated Strategy Capacity
$700000.00
Lowest Capacity Asset
BTCUSD E3
class BTCTradingBot(QCAlgorithm):
        
    def Initialize(self):
        
        self.SetStartDate(2020, 7, 1)
        self.SetCash(1000000)
        
        self.tick = self.AddCrypto("BTCUSD", Resolution.Hour, Market.Bitfinex).Symbol
        self.btc_money_flow = self.MFI(self.tick, 3, Resolution.Hour)
        self.SetWarmUp(3)
        
        self.close_price_history = RollingWindow[float](4)
        
        self.trailing_sl_short = None
        self.trailing_sl_long = None
     
    def OnData(self, data):
               
        if not data.ContainsKey(self.tick) or self.IsWarmingUp: return
        
        self.close_price_history.Add(data[self.tick].Close)
        previous_close = self.close_price_history[0]
        
        # avoid entry when there is other orders/positions active, such that it will not mess up the variable storing orders
        if self.trailing_sl_short is None and self.trailing_sl_long is None and (self.btc_money_flow.Current.Value >= 100) and (previous_close > self.close_price_history[1]):        
            self.MarketOrder(self.tick, -0.1)        # SHORT ORDER
            self.trailing_sl_short = self.StopMarketOrder(self.tick, 0.1, self.Securities[self.tick].Close * 1.003)
            self.trailing_sl_short_close = self.Securities[self.tick].Close
            
        if self.trailing_sl_short is not None and self.trailing_sl_short_close > previous_close:
            updateSettings = UpdateOrderFields()
            updateSettings.StopPrice = self.Securities[self.tick].Close * 1.003
            self.trailing_sl_short.Update(updateSettings)
            self.trailing_sl_short_close = self.Securities[self.tick].Close        # update for trailing sl
                
        if self.trailing_sl_short is not None and self.trailing_sl_short.Status == OrderStatus.Filled:
            self.trailing_sl_short = None
            self.MarketOrder(self.tick, 0.1)            # LONG ORDER
            self.trailing_sl_long = self.StopMarketOrder(self.tick, -0.1, self.Securities[self.tick].Close * 0.995)
            self.trailing_sl_long_close = self.Securities[self.tick].Close
                
        if self.trailing_sl_long is not None and self.trailing_sl_long_close < previous_close:
            updateSettings = UpdateOrderFields()
            updateSettings.StopPrice = self.Securities[self.tick].Close * 0.995
            self.trailing_sl_long.Update(updateSettings)
            self.trailing_sl_long_close = self.Securities[self.tick].Close        # update for trailing sl
            
        if self.trailing_sl_long is not None and self.trailing_sl_long.Status == OrderStatus.Filled:
            self.trailing_sl_long = None