Follow the example
Choose a step to follow the example. Opening a request lets you review it; it does not submit a job or change your account.
Read the signal and every leg
Read the entry condition, requested allocation and each leg’s strike and expiration selectors in the saved rules below.
- Entry
- Saved candidate: Price(SPY) < SMA(SPY,50,Day) AND zero matching option positions
- Position sizing
- Saved candidate: One strategy unit; leg ratios apply. Buying power, collateral and liquidity can restrict orders.
- Signal exit
- Saved candidate: Price(SPY) >= SMA(SPY,50,Day); close whole matching spread at 14 or fewer DTE
- Starting capital
- Saved candidate: $10000.00
The plain-language purpose matches the saved rules below. Keep the rule, purchase size and exit together when creating your version.
Choose the lines to compare
Completed historical backtest
Explore the completed 2024 simulation below. Compare its recorded return and drawdown with the plotted benchmarks, then follow the captured fills. The original history, fees and execution assumptions remain available below.
The exact stored history shown here, with its source's period, comparisons and limits. Opening the walkthrough does not rerun it.
Preview the same rules in Aurora
Open the reviewed request, check its selectors and exits, and keep automated trading off. Review any test cost separately before submission.
An inspectable draft of this example. Historical synthetic pricing is visible, not a promise of available live quotes or identical execution.
Inspect a captured opening and close
These Filled orders show one captured position from the run. Its recorded opening and closing cash flows sum to $-487.82 after commissions. Inspect every leg and ratio; the engine's closed-trade count can count option legs rather than whole spread round trips.
Follow this position's Filled events by contract, side and time. Compare opening and closing premiums, quantities and commissions to understand its P&L. This example comes from the captured excerpt of the most recent 50 Filled orders.
Scroll sideways to compare all columns. Select a heading to sort.
| 2024-12-18 21:00:00 | SPY250117P00586000 | Buy to open | 1 | $11.0660 | $0.65 |
| 2024-12-18 21:00:00 | SPY250117P00557000 | Sell to open | 1 | $4.4239 | $0.65 |
| 2024-12-24 18:00:00 | SPY250117P00557000 | Buy to close | 1 | $0.7297 | $0.65 |
| 2024-12-24 18:00:00 | SPY250117P00586000 | Sell to close | 1 | $2.5195 | $0.65 |
No matching rows. Clear the filter to see all records.
The algorithm and its purpose
The rules below trade SPY options. The completed 2024 backtest includes the portfolio curve, contract-resolution records and any recorded fills.
Scroll sideways to compare all columns. Select a heading to sort.
| Entry | Price(SPY) < SMA(SPY,50,Day) AND zero matching option positions |
| Position sizing | One strategy unit; leg ratios apply. Buying power, collateral and liquidity can restrict orders. |
| Signal exit | Price(SPY) >= SMA(SPY,50,Day); close whole matching spread at 14 or fewer DTE |
| Starting capital | $10000.00 |
| Spread type | vertical |
| Execution | Market; $0.65 commission per option contract, default 0.5 half-spread fraction plus applicable liquidity impact. |
No matching rows. Clear the filter to see all records.
Contract selectors and ratios
Strike distances are percentages of the underlying price, not fixed market strikes or delta targets. Positive distance means out of the money: a higher strike for calls and a lower strike for puts. Negative distance means in the money; zero targets at the money (ATM). Days to expiration (DTE) measures the time remaining until a contract expires. Nearest expiration must lie within each leg's DTE range. Inspect the resolved contracts rather than assuming the authored offsets produce exact strike widths.
All option legs use the same requested expiry window. Verify actual shared expiration and the resulting quantities in the contract-resolution and fill records.
Scroll sideways to compare all columns. Select a heading to sort.
| 1 | long | put | 0% | 1 | 30 to 45 DTE |
| 2 | short | put | 5% | 1 | 30 to 45 DTE |
No matching rows. Clear the filter to see all records.
Create the exact inactive draft
Ask Aurora to build the rules above, review the preview, then save the draft while keeping automated trading off. A chat draft is inspected in Portfolio > Drafts or Aurora; the native Strategies editor belongs to a paper or live portfolio.
In an inactive native portfolio, use Open Options Position, choose the matching structure preset and verify each leg above. Under Allocation, set Type Contracts and Amount 1. Add the entry conditions, including zero matching option positions. Add both Close Options Position rules separately, matching SPY and the spread type with close scope spread and quantity all. A preset adds contract legs; it does not supply the complete entry or exit algorithm.
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.
Create and backtest with Python
Use the Python SDK instead of Aurora
Python SDK 1.42.0. Save the runner below as run_bear_put_spread.py.
Install and download
python3 -m pip install nexustrade==1.42.0
export NEXUSTRADE_API_KEY="YOUR_API_KEY"
curl --fail --output bear_put_spread.py https://nexustrade.io/seo/strategy-examples/bear-put-spread.py
Create, test and inspect
from bear_put_spread import create_bear_put_spread, backtest_bear_put_spread
book = create_bear_put_spread()
completed = backtest_bear_put_spread()
print(completed["result"])
Run
python3 run_bear_put_spread.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_bear_put_spread():
asset = nt.stock_asset("SPY")
return nt.portfolio(
"Public SEO example - Bear put spread",
[
nt.strategy(
"Open Bear put spread",
((nt.Price(asset) < nt.SMA(asset, 50, "Day")) & (nt.OptionPositionCount("SPY", "put", "long", "vertical") == nt.Value(0))),
nt.open_option(
builder=nt.options_builder(
legs=[
nt.leg(
option_type="put",
direction="long",
min_days_to_expiration=30,
max_days_to_expiration=45,
preference="nearest",
distance=0,
ratio=1
),
nt.leg(
option_type="put",
direction="short",
min_days_to_expiration=30,
max_days_to_expiration=45,
preference="nearest",
distance=5,
ratio=1
)
],
underlying_symbol="SPY",
spread_type="vertical"
),
allocation={'type': 'contracts', 'amount': 1}
)
),
nt.strategy(
"Close when signal invalidates",
(nt.Price(asset) >= nt.SMA(asset, 50, "Day")),
nt.close_option(
underlyings=['SPY'],
spread_type="vertical",
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="vertical",
close_scope="spread",
quantity={'type': 'all'},
triggers=[nt.dte_trigger(max_dte=14)]
)
),
],
initial_value=10000,
supports_fractional_shares=False,
alerts_enabled=False,
dividend_policy='cash',
)
def backtest_bear_put_spread(client=None):
client = client or nt.NexusTradeClient.from_environment()
operation = client.create_backtest(
nt.backtest(
create_bear_put_spread(),
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-bear-put-spread-2024-spy-v1",
)
return client.wait_for_backtest(operation["id"])
# Build locally: book = create_bear_put_spread()
# Run and inspect: completed = backtest_bear_put_spread(); 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-bear-put-spread.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 bear-put-spread.ts https://nexustrade.io/seo/strategy-examples/bear-put-spread.ts
Create, test and inspect
import { createBearPutSpread, backtestBearPutSpread } from "./bear-put-spread";
async function main() {
const book = createBearPutSpread();
const completed = await backtestBearPutSpread();
console.log(completed.result);
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
Run
npx tsx run-bear-put-spread.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 createBearPutSpread() {
const asset = nt.stockAsset("SPY");
return nt.portfolio(
"Public SEO example - Bear put spread",
[
nt.strategy(
"Open Bear put spread",
nt.and(
nt.lt(nt.Price(asset), nt.SMA(asset, 50, "Day")),
nt.eq(nt.OptionPositionCount("SPY", "put", "long", "vertical"), nt.Value(0))
),
nt.openOption({ builder: nt.optionsBuilder({ legs: [nt.leg({ optionType: "put", direction: "long", minDaysToExpiration: 30, maxDaysToExpiration: 45, preference: "nearest", distance: 0, ratio: 1 }), nt.leg({ optionType: "put", direction: "short", minDaysToExpiration: 30, maxDaysToExpiration: 45, preference: "nearest", distance: 5, ratio: 1 })], underlyingSymbol: "SPY", spreadType: "vertical" }), allocation: {"type": "contracts", "amount": 1} })
),
nt.strategy(
"Close when signal invalidates",
nt.gte(nt.Price(asset), nt.SMA(asset, 50, "Day")),
nt.closeOption({ underlyings: ["SPY"], spreadType: "vertical", closeScope: "spread", quantity: {"type": "all"} })
),
nt.strategy(
"Close at 14 DTE",
nt.gt(nt.Value(1), nt.Value(0)),
nt.closeOption({ underlyings: ["SPY"], spreadType: "vertical", closeScope: "spread", quantity: {"type": "all"}, triggers: [nt.dteTrigger({ maxDte: 14 })] })
),
],
{ initialValue: 10000, supportsFractionalShares: false, alertsEnabled: false, dividendPolicy: "cash" }
);
}
export async function backtestBearPutSpread(client = new nt.NexusTradeClient()) {
const operation = await client.createBacktest(
nt.backtest(createBearPutSpread(), {
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-bear-put-spread-2024-spy-v1" }
);
if (typeof operation.id !== "string") throw new Error("Missing backtest ID");
return client.waitForBacktest(operation.id);
}
// Build locally: const book = createBearPutSpread();
// Run and inspect: const completed = await backtestBearPutSpread(); console.log(completed.result);
Completed historical backtest
This exact saved candidate completed its fixed 2024 Day simulation on 2026-10-10. Starting capital was $10000.00. The request enabled detailed events and cash dividends. The curve below contains all 519 exported history points.
The SPY comparison invests the full starting balance, reinvests dividends and applies no strategy commission. This strategy requests one spread unit with its declared fees. Use the cash, position value and collateral history to explore how each deploys capital.
Scroll sideways to compare all columns. Select a heading to sort.
| Status | COMPLETE |
| Requested period | 2024-01-01 through 2024-12-31 |
| Starting capital | $10000.00 |
| Modeled return | -13.34% |
| Reported maximum drawdown | 23.74% |
| Full-capital SPY comparator return | 25.30% |
| Recorded commissions | $22.10 |
| Engine closed-trade count | 16 |
| Peak reserved collateral | $892.00 |
| Median reserved collateral while holding positions | $596.00 |
| Pricing contract version | 8 |
| Observed / synthetic half-spread calls | 42 / 26 |
| Unknown-timing quote accesses | 2505 |
| Missing-current-quote checks | 0 |
| Rejected fill groups / marks | 0 / 0 |
| Stale basket / single-option marks | 0 / 0 |
No matching rows. Clear the filter to see all records.
Inspect the candidate book
This is the indicative selected-candidate snapshot from the opening size decision. Compare the selected symbols and ratios with the actual Filled orders. Use the candidate bid, ask and mid to follow the sizing calculation, then compare the recorded execution premium.
Scroll sideways to compare all columns. Select a heading to sort.
| SPY250117P00586000 | $586.00 | 2025-01-17 | 30 | $11.02 | $11.08 | $11.05 | 1 | 949; sessionVolume |
| SPY250117P00557000 | $557.00 | 2025-01-17 | 30 | $4.40 | $4.52 | $4.46 | 1 | 98; sessionVolume |
No matching rows. Clear the filter to see all records.
{
"modelVersion": 2,
"enforced": true,
"chosenIndex": 0,
"path": "targetKept",
"reason": "target size limit 24 covers 1",
"requestedQuantity": 1,
"quantity": 1,
"sizingChain": [
{
"kind": "allocationImplied",
"bound": 1,
"quantity": 1,
"binding": true
},
{
"kind": "buyingPowerCap",
"bound": 13,
"quantity": 1,
"binding": false
},
{
"kind": "volumeLimit",
"bound": 24,
"quantity": 1,
"binding": false
},
{
"kind": "finalPriceRecap",
"bound": 1,
"quantity": 1,
"binding": false
}
],
"pricing": {
"mid": 15.510000000000002,
"halfSpread": 0.08999999999999986,
"participation": 0.01020408163265306,
"impactCost": 0.7034756477055026
}
}Inspect a contract-resolution audit
This is the latest retained resolution attempt, which can belong to a different position than the matched trade above. Its outcome, capital and risk codes explain what the resolver accepted or rejected at that decision. Follow the resulting Order events to see its fill status.
{
"time": "2024-12-27T14:31:00.000Z",
"status": "success",
"reason": null,
"riskAudit": {
"rulesetVersion": 1,
"outcome": "allowed",
"longSharesAvailable": 0,
"unhedgedShortCallContractsPerSpread": 0,
"buyingPowerEffective": 8210.239390131885,
"allocationRequested": 1,
"allocation": {
"type": "contracts",
"amount": 1
},
"portfolioValue": 8210.239390131885,
"underlyingPrice": 597.5399780273438,
"maxLossPerUnit": 595.9999999999999,
"finalContractQuantity": 1,
"collateralReserved": 595.9999999999999,
"committedCostBefore": 0
}
}Inspect the largest decline in the exported history
The exported grid's largest peak-to-trough decline was 23.70%, from $10759.84 at 2024-04-19T20:00:00.000Z to $8210.24 at 2024-12-24T18:00:00.000Z. The engine reported maximum drawdown of 23.74%. Compare the history snapshots with the reported statistic and inspect the events around this period.
Scroll sideways to compare all columns. Select a heading to sort.
| 2024-04-19T20:00:00.000Z | $9398.84 | $1361.00 | $554.00 |
| 2024-12-24T18:00:00.000Z | $8210.24 | $0.00 | $0.00 |
No matching rows. Clear the filter to see all records.
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.
Download the result and explore the events
Download the exact strategy inputs, completed result, full history, pricing counters and captured events. You can use these records to follow the strategy from its signal to its closing fill. Detailed events remain available in the product for 3 days; this saved example stays readable.
Explore this strategy further
Inspect matched quantities, actual strike widths, expirations and all close orders. For sold options, review collateral and exercise or assignment exposure separately from premium income. A condition firing can emit zero close orders; look at its evaluation and the Filled-order records.
Try another date range or change one rule, then compare the new backtest with this saved 2024 result. Inspect which trades and periods explain the difference.
No comments yet.