| Overall Statistics |
|
Total Orders 24310 Average Win 0.01% Average Loss -0.01% Compounding Annual Return 350.800% Drawdown 47.900% Expectancy -0.029 Net Profit 4.212% Sharpe Ratio 498.161 Sortino Ratio 1896.866 Probabilistic Sharpe Ratio 55.296% Loss Rate 53% Win Rate 47% Profit-Loss Ratio 1.07 Alpha 2134.872 Beta 6.264 Annual Standard Deviation 4.316 Annual Variance 18.626 Information Ratio 565.068 Tracking Error 3.8 Treynor Ratio 343.24 Total Fees â‚®0.00 Estimated Strategy Capacity â‚®1000.00 Lowest Capacity Asset SOLUSDT 2UZ Portfolio Turnover 1081.14% |
from datetime import timedelta
from AlgorithmImports import *
class Chakh(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2024, 1, 1)
self.SetEndDate(2024, 1, 10)
self.SetAccountCurrency("USDT", 10000)
self.SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin)
crypto = self.AddCrypto('SOLUSDT', Resolution.Minute, Market.Bybit)
crypto.SetFeeModel(ConstantFeeModel(0))
self.symbol = crypto.Symbol
self.lotsize = crypto.SymbolProperties.LotSize
self.take_profit = 120
self.percentile = 0.95
self.trade_bar_window = RollingWindow[TradeBar](60)
self.necessary_down_window = RollingWindow[float](60)
self.percentile_down_window = RollingWindow[float](60)
self.Consolidate(self.symbol, timedelta(minutes=1), self.trade_bar_window_consolidation_handler)
def OnData(self, data: Slice):
if not self.trade_bar_window.IsReady:
return
# set long limit orders
long_order_price = round(self.Securities[self.symbol].Price * (1 - self.percentile_down_window[0]), 2)
order_properties = BybitOrderProperties()
order_properties.TimeInForce = TimeInForce.GoodTilDate(self.Time + timedelta(minutes=2))
size = 50 / long_order_price
self.LimitOrder(self.symbol, size, long_order_price, 'limit long', order_properties)
def trade_bar_window_consolidation_handler(self, bar: TradeBar):
self.trade_bar_window.Add(bar)
self.necessary_down_window.Add((1 - bar.Low / bar.Open))
l = list(sorted(self.necessary_down_window))
self.percentile_down_window.Add(l[int(self.percentile * len(l))])
def OnOrderEvent(self, orderEvent: OrderEvent):
if orderEvent.Status != OrderStatus.Filled:
return
if orderEvent.Direction == OrderDirection.Buy:
# set take profit via limit sell order
size = orderEvent.FillQuantity
take_profit_price = round(orderEvent.LimitPrice * (1 + self.percentile_down_window[0] * self.take_profit / 100), 2)
self.LimitOrder(self.symbol, -size, take_profit_price, 'take profit long')