Overall Statistics
Total Orders
6
Average Win
0%
Average Loss
-4.07%
Compounding Annual Return
-11.747%
Drawdown
9.100%
Expectancy
-1
Start Equity
100000
End Equity
95918.85
Net Profit
-4.081%
Sharpe Ratio
-1.67
Sortino Ratio
-2.271
Probabilistic Sharpe Ratio
8.495%
Loss Rate
100%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.097
Beta
-0.758
Annual Standard Deviation
0.081
Annual Variance
0.007
Information Ratio
-0.992
Tracking Error
0.187
Treynor Ratio
0.178
Total Fees
$3.00
Estimated Strategy Capacity
$35000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
1.89%
Drawdown Recovery
0
# region imports
from AlgorithmImports import *
# endregion

class OneCancelOtherExampleAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)

        equity = self.add_equity("SPY")
        equity.ema = self.ema("SPY", 14, Resolution.DAILY)
        equity.has_OCO = False

    def on_data(self, data: Slice):
        equity = self.securities["SPY"]
        if equity.has_OCO:
            return
        bar = data.bars.get("SPY")
        if not bar:
            return;
        # If the price is above the EMA, we will buy 75% of the portfolio value
        # and place the OCO orders to sell it.
        # Otherwise, we will short 75% of the portfolio value
        # and place OCO orders to rebuy.
        ema = equity.ema.current.value
        price = bar.close
        weight =  0.75 if ema > price else -.75
        stop_price = bar.close * (.95 if ema > price else 1.05)
        limit_price = bar.close * (1.05 if ema > price else .95)

        quantity = self.calculate_order_quantity("SPY", weight)
        self.market_order("SPY", quantity)
        equity.stop_çoss = self.stop_market_order("SPY", -quantity, stop_price)
        equity.take_profit = self.limit_order("SPY", -quantity, limit_price)
        equity.has_OCO = True
    
    def on_order_event(self, order_event):
        if order_event.status == OrderStatus.FILLED:
            equity = self.securities[order_event.symbol]
            match order_event.ticket.order_type:
                case OrderType.STOP_MARKET:
                    equity.take_profit.cancel()
                    equity.has_OCO = False
                case OrderType.LIMIT:
                    equity.stop_loss.Cancel()
                    equity.has_OCO = False