Explore more topics
NexusTrade guide

Build and test a long call

Select an underlying, expiry and strike, then test a purchased call with a declared premium budget.

As of 2026-10-13

Jump to a section

TL;DR

Build a long call in four steps: describe it to Aurora, check the saved rules, backtest it, follow a trade. Start from the worked example below: copy its rules, then change the ticker, dates or exits and test your version. On SPY in 2024 it returned 31.16% against 25.30% for SPY, and its maximum drawdown was 13.27%.

How to build a long call

Animation: the long call strategy as built in the AI chat (Price(SPY) > SMA(SPY,50,Day); $1,000 dollars allocation; at or below SMA50; maxDte 14) is saved as 3 rules. Its legs (buy 1 call at ATM resolving to $472; nearest expiry 30 to 45 days out, Feb 2, 2024) appear on a strike line. Then the expiration payoff of the recorded long call (Buy the SPY $472 call, expiring Feb 2, 2024) draws as the SPY price sweeps from $455 to $497: max loss $865.44; no cap on profit as SPY rises; breakeven $480.65; per contract before commissions. Then the same position's profit or loss is drawn at each session close from Jan 2, 2024 to Jan 19, 2024, ending at +$1.51 after commissions.
The algorithmic strategy held this position from Jan 2 to Jan 19, 2024 in its backtest and made $1.51 after commissions.
Step 1 of 4

1. Describe it to Aurora

Open the prepared request. Aurora receives the exact rules shown here and checks them without saving a portfolio. Review its preview before choosing whether to save or test your own version.

What you should see

A preview of the rules and their validation result. Any invalid inputs are identified before you decide what to save.

Step 2 of 4

2. Check the saved rules

Start with the actual rules used in this example. Days to expiration means the days remaining until the option expires. The complete editor inputs and SDK functions are available below.

Underlying
SPY
Entry
Open when SPY’s price is above its 50-day simple moving average and no matching option position is open.
Purchased call
Buy the call with a strike nearest SPY’s price. Choose the nearest available expiry 30 to 45 days away; use one contract per strategy unit.
Premium allocation
Use a $1,000 allocation. Only whole contracts that fit the resolved cost may open.
Exit
Close all matching option legs when SPY falls to its 50-day average or below, or when 14 or fewer days remain until expiration.
Starting capital
$10,000.00
What you should see

The entry decides when to open. The leg selectors choose contracts. The allocation sets size, and the exit decides when to close. Keep these parts together in your draft.

Completed 2024 backtest14.2K9.6K2024-01-022024-12-31
Options strategy 2024-12-31, 21:00:00 UTC
13,116.2
Full-capital SPY buy and hold 2024-12-31, 21:00:00 UTC
12,530.29
Options strategyFull-capital SPY buy and holdHistorical simulation
Completed 2024 historical simulation. The plotted observations and comparison series are preserved.
Step 3 of 4

3. Backtest it

Compare the two recorded curves and the result below. SPY invests the full starting balance; this options candidate uses its saved allocation. Their fees and invested capital differ.

Candidate vs full-capital SPY
31.16% vs 25.30%
What you should see

The requested period was 2024-01-01 through 2024-12-31. The candidate’s largest reported decline was 13.27%, with $22.10 in recorded commissions. Quote coverage is not certified for strategy comparison; inspect the retained quote checks before comparing these strategies.

Step 4 of 4

4. Follow one trade

Buying to open purchases an option; selling to open writes it. Closing reverses that position. Multiply each premium below by 100 shares per contract and its quantity, then subtract the recorded fees to follow the cash flow.

Call · $472 strike
Jan 2, 2024 14:31 UTC: buy to open 1 at $8.6544 per share; $0.65 fee. Jan 19, 2024 14:31 UTC: sell to close 1 at $8.6825 per share; $0.65 fee.
What you should see

The first position opened on January 2 and closed on January 19, 2024, at 14 DTE. The time-exit close evaluation emitted 1 order. These are simulated Filled orders, not broker executions. The first position's P&L was $1.51 after recorded commissions, calculated from all its opening and closing premiums and quantities.

Four steps take a long call from an idea to a tested strategy. Each step uses the SPY worked example.

The rules that define it

Show the table · 7 rows, 2 columns
InputSaved example
UnderlyingSPY
EntryPrice > SMA(50, Day) AND matching OptionPositionCount = 0
Purchased callATM; nearest expiration 30 to 45 days away; ratio 1
Premium allocation$1,000 dollars; whole contracts must fit the resolved debit
CloseWhole matching position when price <= SMA50, or at 14 or fewer DTE
Order executionMarket; actual fills and fees are not shown by an authoring preview
Product readback3 saved rules; inactive paper example; zero positions; automated approval disabled

One purchased call

Inspect one purchased call

A long call uses a buy-to-open call leg. Set the underlying, expiration and strike rules in the options builder and choose a premium budget that fits the portfolio's buying power.

Expiration payoff

Inspect expiration payoff

Expiration payoff per underlying share is max(underlying price minus strike, 0) minus the premium paid. Breakeven is strike plus premium. Maximum loss is the premium plus fees, while time decay and volatility can change the option price before expiration.

Save it as a draft

Show how to save the draft

Use the prepared Aurora request in the walkthrough above. Check the resolved rules before saving: match the flat-position entry condition and both close rules with the saved table. The returned preview is the object to inspect.

Prompt
Create a chat portfolio named Public SEO example - Long call with $10,000 initial value. Do not deploy it or run a backtest. Underlying SPY. Open only when Price(SPY) > SMA(SPY,50,Day) and the number of matching long call custom option positions on SPY equals zero. Use a $1,000 dollars allocation. Buy one ATM call with ratio 1, nearest expiration between 30 and 45 DTE. Use spreadType custom. Add a close-all matching-spread rule when SPY price is at or below SMA50. Add a separate close-all matching-spread rule with maxDte 14. Create an undeployed research draft in this conversation and show its saved rules, selectors and returned identifier. Keep automated trading off.

Set the fields in the rule editor

Set the fields in the rule editor

A saved Aurora chat draft and a native paper portfolio have different inspection routes. Open Portfolio, choose Drafts, and preview your chat draft or open it in Aurora. The native strategies editor belongs to a paper or live portfolio; a chat draft ID is not a native editor ID. Keep an authoring example inactive while inspecting it.

In your inactive paper portfolio, choose Strategies and add or edit a rule. Select the Open Options Position action, then Long Call. Set Underlying Asset to SPY. The preset supplies ATM call selection; verify Min DTE 30, Max DTE 45, nearest expiration and each ratio 1. Under Allocation choose Type Dollars and Amount 1000.

Add the price/SMA50 and zero-position conditions to the opening rule. Add both Close Options Position rules separately. Saving an opening preset alone does not add these conditions or exits. The close rules match SPY and the configured spread type, and close all matching positions. Keep this example in its own draft; adding other matching SPY positions changes what those exits can close. Review the saved rules before any test.

Verify the implementation

Inspect verify the implementation

Check that the saved rule buys a call and that its expiry, strike selection and premium budget match your inputs. A completed test should identify which contract was selected on each signal. If the selector returns no contract or market data is missing, inspect those inputs and coverage before treating the absence of trades as a result. Backtest the exact selector rules rather than a hand-picked contract. Inspect the contracts selected on each signal and use paper trading to check orders before choosing a live broker.

Create and backtest with Python

Use the Python SDK instead of Aurora

Python SDK 1.42.0. Save the runner below as run_long_call.py.

Install and download

Shell
python3 -m pip install nexustrade==1.42.0
export NEXUSTRADE_API_KEY="YOUR_API_KEY"
curl --fail --output long_call.py https://nexustrade.io/seo/strategy-examples/long-call.py

Create, test and inspect

Python
from long_call import create_long_call, backtest_long_call

book = create_long_call()
completed = backtest_long_call()
print(completed["result"])

Run

Shell
python3 run_long_call.py

Python strategy and backtest functions

View complete Python SDK functions

The backtest function submits the 2024 test with SPY as its benchmark, records events and waits for the result. Use a new request key when changing rules, dates or fees.

Python
import nexustrade as nt


def create_long_call():
    asset = nt.stock_asset("SPY")
    return nt.portfolio(
        "Public SEO example - Long call",
        [
            nt.strategy(
                "Open Long call",
                ((nt.Price(asset) > nt.SMA(asset, 50, "Day")) & (nt.OptionPositionCount("SPY", "call", "long", "custom") == nt.Value(0))),
                nt.open_option(
                    builder=nt.options_builder(
                        legs=[nt.leg(option_type="call", direction="long", min_days_to_expiration=30, max_days_to_expiration=45, preference="nearest", distance=0, ratio=1)],
                        underlying_symbol="SPY",
                        spread_type="custom"
                    ),
                    allocation={'type': 'dollars', 'amount': 1000}
                )
            ),
            nt.strategy(
                "Close when trend breaks",
                (nt.Price(asset) <= nt.SMA(asset, 50, "Day")),
                nt.close_option(
                    underlyings=['SPY'],
                    spread_type="custom",
                    close_scope="spread",
                    quantity={'type': 'all'}
                )
            ),
            nt.strategy(
                "Close at 14 DTE",
                (nt.Value(1) > nt.Value(0)),
                nt.close_option(
                    underlyings=['SPY'],
                    spread_type="custom",
                    close_scope="spread",
                    quantity={'type': 'all'},
                    triggers=[nt.dte_trigger(max_dte=14)]
                )
            ),
        ],
        initial_value=10000,
        alerts_enabled=False,
    )


def backtest_long_call(client=None):
    client = client or nt.NexusTradeClient.from_environment()
    operation = client.create_backtest(
        nt.backtest(
            create_long_call(),
            start_date="2024-01-01", end_date="2024-12-31",
            interval="Day", baseline_symbol="SPY",
            initial_value=10000, generate_events=True,
            dividend_policy="cash",
            fee_config={"Stock": {"type": "percent", "amount": 0.1},
                        "Cryptocurrency": {"type": "percent", "amount": 0.7},
                        "Option": {"type": "dollars", "amount": 0.65}},
        ),
        idempotency_key="explore-long-call-2024-spy-v1",
    )
    return client.wait_for_backtest(operation["id"])


# Build locally: book = create_long_call()
# Run and inspect: completed = backtest_long_call(); print(completed["result"])

Create and backtest with TypeScript

Use the TypeScript SDK instead of Aurora

TypeScript SDK 1.42.0. Save the runner below as run-long-call.ts.

Install and download

Shell
npm install nexustrade@1.42.0
npm install --save-dev tsx
export NEXUSTRADE_API_KEY="YOUR_API_KEY"
curl --fail --output long-call.ts https://nexustrade.io/seo/strategy-examples/long-call.ts

Create, test and inspect

TypeScript
import { createLongCall, backtestLongCall } from "./long-call";

async function main() {
  const book = createLongCall();
  const completed = await backtestLongCall();
  console.log(completed.result);
}

main().catch((error: unknown) => {
  console.error(error);
  process.exitCode = 1;
});

Run

Shell
npx tsx run-long-call.ts

TypeScript strategy and backtest functions

View complete TypeScript SDK functions

The same rules, dates and fees are used in both SDKs. The backtest function keeps its request key across retries.

TypeScript
import * as nt from "nexustrade";

export function createLongCall() {
  const asset = nt.stockAsset("SPY");
  return nt.portfolio(
    "Public SEO example - Long call",
    [
      nt.strategy(
          "Open Long call",
          nt.and(
              nt.gt(nt.Price(asset), nt.SMA(asset, 50, "Day")),
              nt.eq(nt.OptionPositionCount("SPY", "call", "long", "custom"), nt.Value(0))
          ),
          nt.openOption({ builder: nt.optionsBuilder({ legs: [nt.leg({ optionType: "call", direction: "long", minDaysToExpiration: 30, maxDaysToExpiration: 45, preference: "nearest", distance: 0, ratio: 1 })], underlyingSymbol: "SPY", spreadType: "custom" }), allocation: {"type": "dollars", "amount": 1000} })
      ),
      nt.strategy(
          "Close when trend breaks",
          nt.lte(nt.Price(asset), nt.SMA(asset, 50, "Day")),
          nt.closeOption({ underlyings: ["SPY"], spreadType: "custom", closeScope: "spread", quantity: {"type": "all"} })
      ),
      nt.strategy(
          "Close at 14 DTE",
          nt.gt(nt.Value(1), nt.Value(0)),
          nt.closeOption({ underlyings: ["SPY"], spreadType: "custom", closeScope: "spread", quantity: {"type": "all"}, triggers: [nt.dteTrigger({ maxDte: 14 })] })
      ),
    ],
    { initialValue: 10000, alertsEnabled: false }
  );
}

export async function backtestLongCall(client = new nt.NexusTradeClient()) {
  const operation = await client.createBacktest(
    nt.backtest(createLongCall(), {
      startDate: "2024-01-01", endDate: "2024-12-31",
      interval: "Day", baselineSymbol: "SPY",
      initialValue: 10000, generateEvents: true,
      dividendPolicy: "cash",
      feeConfig: {
        Stock: { type: "percent", amount: 0.1 },
        Cryptocurrency: { type: "percent", amount: 0.7 },
        Option: { type: "dollars", amount: 0.65 },
      },
    }),
    { idempotencyKey: "explore-long-call-2024-spy-v1" }
  );
  if (typeof operation.id !== "string") throw new Error("Missing backtest ID");
  return client.waitForBacktest(operation.id);
}

// Build locally: const book = createLongCall();
// Run and inspect: const completed = await backtestLongCall(); console.log(completed.result);

Start from this example

The worked example below is a starting point for you to copy. Open its exact rules in Aurora, then change the ticker, dates, legs or exits and backtest your own version.

Worked example to copy: SPY, 2024

Completed 2024 backtest14.2K9.6K2024-01-022024-12-31
Options strategy 2024-12-31, 21:00:00 UTC
13,116.2
Full-capital SPY buy and hold 2024-12-31, 21:00:00 UTC
12,530.29
Options strategyFull-capital SPY buy and holdHistorical simulation
Return
31.16%
SPY buy and hold
25.30%
Max drawdown
13.27%
Closed option legs
17
Commissions
$22.10; $0.65 per option contract
Show the table · 15 rows, 2 columns

Scroll sideways to compare all columns. Select a heading to sort.

StatusCOMPLETE
Pricing contract version8
Requested period2024-01-01 through 2024-12-31
Modeled return31.16%
Candidate maximum drawdown13.27%
Full-capital SPY buy and hold25.30%
Recorded fees$22.10; $0.65 per option contract
Option slippage contract0.5 of half-spread
Observed / synthetic half-spread calls36 / 72
Unknown-timing quote accesses5542
Rejected fill groups / marks0 / 0
Closed trades17
First held-option snapshot2024-01-02T21:00:00.000Z
Missing-current-quote checks0
First recorded option holdingsSPY240202C00472000: quantity +1, call strike $472, expiry 2024-02-02

How the example did on SPY, 2024-01-01 to 2024-12-31, starting with $10,000.

One trade from the example

One position from the worked example, opened Jan 2, 2024 and closed Jan 19, 2024.

Long $472 call
+$2.81
Commissions
−$1.30
Net
+$1.51

Explain this options decision with Aurora

Ask Aurora to connect the recorded signal, contract choice, allocation and fills. It receives this page's captured decision and order fields, so you can follow its explanation back to each value.

Inspect the worked example's records

The example trade's fills

  1. 2024-01-02 14:31:00

    Contract

    SPY240202C00472000

    Action

    Buy to open

    Contracts

    1

    Premium per share

    $8.6544

    Fee

    $0.65

  2. 2024-01-19 14:31:00

    Contract

    SPY240202C00472000

    Action

    Sell to close

    Contracts

    1

    Premium per share

    $8.6825

    Fee

    $0.65

Recorded rows in source order; spacing does not represent elapsed time.

Show the table · 2 rows, 6 columns

Scroll sideways to compare all columns. Select a heading to sort.

2024-01-02 14:31:00SPY240202C00472000Buy to open1$8.6544$0.65
2024-01-19 14:31:00SPY240202C00472000Sell to close1$8.6825$0.65

Each premium is per share; one contract is 100 shares.

Inspect the selected contracts and sizing

The candidate snapshot shows the bid and ask used in the sizing decision. Every selected leg had the February 2 expiration, 31 DTE at entry and multiplier 100.

The liquidity model kept the target. Allocation allowed 1 unit; the volume limit allowed 2. The requested and sent quantities were both 1. The opening premium also includes modeled liquidity impact beyond the persisted half-spread fraction.

Show the table · 1 row, 6 columns

Scroll sideways to compare all columns. Select a heading to sort.

SPY240202C00472000$472.00$8.15$8.71$8.4311; trailingMedian5

Inspect an adverse period in the published history

The largest peak-to-trough decline in the exported 519-point history was 13.24%: $13235.24 on 2024-07-16 to $11483.00 on 2024-09-06. At the trough the exported position value was $0.00.

The engine reported maximum drawdown of 13.27%. That differs from the decline calculated over the exported history points. Explore the snapshots and events around this period to understand the change in portfolio value.

Show the table · 2 rows, 5 columns

Scroll sideways to compare all columns. Select a heading to sort.

2024-07-16 20:00:00$13235.24$11769.74$1465.50$12001.33
2024-09-06 20:00:00$11483.00$11483.00$0.00$11517.45

Plan a separate variant and later test

Review the optional next experiment

After reviewing the recorded example, use the prepared request above for the original rules. This optional plan covers a separate variant and a later test.

  1. Create one variant, then test unseen dates

    Ask: "Change only the timed close trigger from 14 DTE to 10 DTE. Show the rule diff and compare both candidates on the 2024 development period with every other setting fixed." After choosing, freeze the rules and select another test period you have not inspected. The displayed 2024 results already make 2024 a viewed development period. Keep any later revisions in a new research cycle.

Explore the backtest events

Show what to check in the events

Choose a fixed period and record the displayed research-token cost before submitting an options test. Daily options tests can cost research tokens. Keep the saved rules, date range, starting capital, interval, fees and result receipt together. Inspect selected symbols, expirations, strikes, quote coverage and actual opening/closing events before discussing returns.

If no contract fits the selectors or $1,000 budget, no opening is expected. Missing quotes, an unresolved shared expiration or insufficient buying power require investigation. Explore the resolution and sizing events to understand how the rules were applied.

Continue exploring

Discussion

Sign in or create a free account to join the discussion.

No comments yet.

Aurora · AI research assistant

Try this in Aurora

Edit the request, then open it in Aurora. You choose when to send it.