Overall Statistics
Total Orders
10001
Average Win
0.01%
Average Loss
0%
Compounding Annual Return
0.073%
Drawdown
0.000%
Expectancy
0
Start Equity
1000.00
End Equity
1000.07
Net Profit
0.007%
Sharpe Ratio
-11.615
Sortino Ratio
-16.796
Probabilistic Sharpe Ratio
17.938%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.001
Beta
-0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-16.477
Tracking Error
1.131
Treynor Ratio
13.213
Total Fees
$0.40
Estimated Strategy Capacity
$400000000.00
Lowest Capacity Asset
BTCUSDT E3
Portfolio Turnover
0.57%
from AlgorithmImports import *
from datetime import timedelta, datetime

class SquareBlackOwlet(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2021, 1, 1)
        self.set_end_date(2022, 1, 1)
        self.set_cash(1000)
        self.set_brokerage_model(BrokerageName.BITFINEX, AccountType.MARGIN)
        self._btc = self.add_crypto("BTCUSDT", Resolution.MINUTE).symbol

        self._window = 11
        self._lag = 31
        self._bb_50 = BollingerBands(period=self._window, k=1.96, moving_average_type=MovingAverageType.SIMPLE)


        self._consolidator = TradeBarConsolidator(timedelta(minutes=5))
        self.subscription_manager.add_consolidator(self._btc, self._consolidator)
        self.register_indicator(self._btc, self._bb_50, self._consolidator)
        self._consolidator.data_consolidated += self.on_consolidated_bar
        self.set_warm_up(timedelta(minutes = 5*self._window))
        
        self.entry_ticket = None
        self.entry_time = datetime.min
        self.money = 100.0

    def on_consolidated_bar(self, sender, bar: TradeBar) -> None:
        if not self._bb_50.IsReady:
            return
        
        precio = bar.close
        lower_band = self._bb_50.lower_band.current.value
        upper_band = self._bb_50.upper_band.current.value
        

        if not self.portfolio.invested:
            self.log(f"precio: {precio}")
            self.log(f"No hay inversiones")
            if precio < lower_band:
                self.log(f"Intentando compra market_order: precio btc: {precio}, cantidad: {self.money}, inversion: {self.money/precio}")
                self.entry_ticket = self.market_order(self._btc, self.money / precio)
   
                self.entry_time = self.time + timedelta(minutes=self._lag*5)
                self.log(f"Orden de entrada creada: {self.entry_ticket}")
                
            elif precio > upper_band:
                self.log(f"Intentando venta market_order: precio btc: {precio}, cantidad: {self.money}, inversion: {self.money/precio}")
                self.entry_ticket = self.market_order(self._btc,-self.money / precio)

                self.entry_time = self.time + timedelta(minutes=self._lag*5)
                self.log(f"Orden de entrada creada: {self.entry_ticket}")
        
        if self.portfolio.invested and self.entry_time <= self.time: #self.transactions.get_open_orders(self._btc)
            self.log("Ordenes pendientes por cerrar despues de 31 velas")
            current_quantity = abs(self.portfolio[self._btc].quantity)
            
            if current_quantity >= 0.00004:  # Verificar tamaño mínimo
                self.liquidate(self._btc)
            else:
                self.log(f"No se puede liquidar - cantidad {current_quantity} es menor que el mínimo 0.00004. Forzando cierre.")
                self.set_holdings(self._btc, 0)


    def on_order_event(self, order_event : OrderEvent):  
        self.log(f"[OrderEvent] {order_event}")