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

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.
A preview of the rules and their validation result. Any invalid inputs are identified before you decide what to save.
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
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.
- 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
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%
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.
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.
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
| Input | Saved example |
|---|---|
| Underlying | SPY |
| Entry | Price > SMA(50, Day) AND matching OptionPositionCount = 0 |
| Purchased call | ATM; nearest expiration 30 to 45 days away; ratio 1 |
| Premium allocation | $1,000 dollars; whole contracts must fit the resolved debit |
| Close | Whole matching position when price <= SMA50, or at 14 or fewer DTE |
| Order execution | Market; actual fills and fees are not shown by an authoring preview |
| Product readback | 3 saved rules; inactive paper example; zero positions; automated approval disabled |
No matching rows. Clear the filter to see all records.
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.
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
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
from long_call import create_long_call, backtest_long_call
book = create_long_call()
completed = backtest_long_call()
print(completed["result"])
Run
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.
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
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
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
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.
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
- 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
- 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.
| Status | COMPLETE |
| Pricing contract version | 8 |
| Requested period | 2024-01-01 through 2024-12-31 |
| Modeled return | 31.16% |
| Candidate maximum drawdown | 13.27% |
| Full-capital SPY buy and hold | 25.30% |
| Recorded fees | $22.10; $0.65 per option contract |
| Option slippage contract | 0.5 of half-spread |
| Observed / synthetic half-spread calls | 36 / 72 |
| Unknown-timing quote accesses | 5542 |
| Rejected fill groups / marks | 0 / 0 |
| Closed trades | 17 |
| First held-option snapshot | 2024-01-02T21:00:00.000Z |
| Missing-current-quote checks | 0 |
| First recorded option holdings | SPY240202C00472000: quantity +1, call strike $472, expiry 2024-02-02 |
No matching rows. Clear the filter to see all records.
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
2024-01-02 14:31:00
ContractSPY240202C00472000
ActionBuy to open
Contracts1
Premium per share$8.6544
Fee$0.65
2024-01-19 14:31:00
ContractSPY240202C00472000
ActionSell to close
Contracts1
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:00 | SPY240202C00472000 | Buy to open | 1 | $8.6544 | $0.65 |
| 2024-01-19 14:31:00 | SPY240202C00472000 | Sell to close | 1 | $8.6825 | $0.65 |
No matching rows. Clear the filter to see all records.
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.43 | 11; trailingMedian5 |
No matching rows. Clear the filter to see all records.
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 |
No matching rows. Clear the filter to see all records.
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.
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.
No comments yet.