Skip to content

Create new strategy (Alpha)

Ciocanel Razvan edited this page Jun 25, 2024 · 1 revision

Base Alpha Model Parameters

When creating a new strategy that inherits from the Base alpha model, you can customize its behavior by overriding the default parameters. Here's an explanation of key parameters and how to use them:

Scheduling Parameters

  • scheduleStartTime: Time to start opening new positions (default: 9:30 AM)
  • scheduleStopTime: Time to stop opening new positions (default: None)
  • scheduleFrequency: How often to check for new positions (default: 5 minutes)
  • minimumTradeScheduleDistance: Minimum time between consecutive trades (default: 1 day)

Position Management

  • maxActivePositions: Maximum number of open positions at any time (default: 1)
  • maxOrderQuantity: Maximum quantity for scaling positions (default: 1)
  • validateQuantity: Whether to validate order quantity against maxOrderQuantity (default: True)

Option Selection

  • dte: Target Days to Expiration (default: 0)
  • dteWindow: Range around target DTE to consider (default: 0)
  • dteThreshold: DTE threshold for closing positions (default: 21)
  • useFurthestExpiry: Whether to use the furthest available expiration (default: True)
  • dynamicDTESelection: Whether to consider last closed position's DTE (default: False)

Option Chain Filtering

  • nStrikesLeft: Number of strikes to consider below ATM (default: 200)
  • nStrikesRight: Number of strikes to consider above ATM (default: 200)

Order Execution

  • slippage: Slippage for limit orders (default: 0.0)
  • useLimitOrders: Whether to use limit orders (default: True)
  • limitOrderRelativePriceAdjustment: Adjustment factor for limit order prices (default: 0)
  • limitOrderExpiration: How long limit orders remain active (default: 8 hours)

Premium Targeting

  • targetPremiumPct: Target premium as percentage of portfolio (default: None)
  • targetPremium: Fixed dollar amount for target premium (default: None)
  • minPremium: Minimum acceptable premium (default: None)
  • maxPremium: Maximum acceptable premium (default: None)

Profit Management

  • profitTargetMethod: Method for calculating profit target (default: "Premium")
  • profitTarget: Profit target factor (default: 0.6)

Strategy-Specific Parameters

  • delta: Delta for option selection (default: 10)
  • wingSize: Wing size for spreads (default: 10)
  • putDelta, callDelta: Deltas for Iron Condor (default: 10)
  • netDelta: Net delta for strategies like Straddles (default: None)

Example: SPXic Strategy

Here's how you might set up a custom SPX Iron Condor strategy (copy from this strategy):

class SPXic(Base):
    PARAMETERS = {
        "scheduleStartTime": time(9, 31, 0),
        "scheduleFrequency": timedelta(minutes=30),
        "maxActivePositions": 1,
        "dte": 45,
        "dteWindow": 5,
        "dteThreshold": 21,
        "useFurthestExpiry": False,
        "nStrikesLeft": 50,
        "nStrikesRight": 50,
        "useLimitOrders": True,
        "limitOrderRelativePriceAdjustment": 0.1,
        "targetPremiumPct": 0.01,
        "profitTargetMethod": "Premium",
        "profitTarget": 0.5,
        "putDelta": 16,
        "callDelta": 16,
        "putWingSize": 5,
        "callWingSize": 5,
    }

    def init(self, context):
        super().__init__(context)
        # You can change the name here
        self.name = "SPXic"
        self.nameTag = "SPXic"
        self.ticker = "SPX"
        self.context.structure.AddUnderlying(self, self.ticker)
        self.logger.debug(f"{self.__class__.__name__} -> __init__ -> AddUnderlying")

    def getOrder(self, chain, data):
        if data.ContainsKey(self.underlyingSymbol):
            trade_times = [time(hour, minute, 0) for hour in range(9, 15) for minute in range(0, 60, 30) if not (hour == 15 and minute > 0)]
            # Remove the microsecond from the current time
            current_time = self.context.Time.time().replace(microsecond=0)
            if current_time not in trade_times:
                return None
            call =  self.order.getSpreadOrder(
                chain,
                'call',
                fromPrice=self.minPremium,
                toPrice=self.maxPremium,
                wingSize=self.callWingSize,
                sell=True
            )
            put = self.order.getSpreadOrder(
                chain,
                'put',
                fromPrice=self.minPremium,
                toPrice=self.maxPremium,
                wingSize=self.putWingSize,
                sell=True
            )
            if call is not None and put is not None:
                return [call, put]
            else:
                return None
        else:
            return None

This setup creates an SPX Iron Condor strategy that trades once every 30 minutes, targeting 45 DTE options, with a 16 delta for both puts and calls, and 5-point wings. It aims for a premium of 1% of the portfolio and a 50% profit target.