| Feature | Iron Butterfly | Iron Condor |
|---|---|---|
| Short Strikes | Both at ATM (same strike) | Different strikes (OTM) |
| Net Credit | Higher | Lower |
| Profit Zone | Narrower | Wider |
| Probability of Profit | Lower | Higher |
| Max Profit Likelihood | Only at exact ATM price | Between short strikes |
| Best For | Low volatility, pinned price | Range bound markets |
| File | Purpose | API Environment |
|---|---|---|
ib.json |
Entry flow β Opens new positions | Paper |
liquidation_flow.json |
Closes positions manually or scheduled | Live |
monitoring_flow.json |
Auto-monitors P&L, exits on thresholds | Live |
trade_history_flow.json |
Calculates historical P&L | Live |
Trigger: Monday 9:35 AM (cron) or Manual
Trigger: Thursday 2:40 PM (cron) or Manual
Trigger: Every 5 minutes (repeating inject)
Trigger: Manual
Fetches last 30 days of closed orders, matches entry/exit pairs by expiry, and calculates realized P&L, win rate, and cumulative statistics.
// Set API Keys node
global.set("apiKeyP1", "YOUR_DATA_API_KEY"); // For market data
global.set("apiSecretP1", "YOUR_DATA_SECRET");
global.set("apiKeyP3", "YOUR_PAPER_TRADING_KEY"); // For paper trading
global.set("apiSecretP3", "YOUR_PAPER_SECRET");
// Strategy Configuration
global.set("underlying", "SPY");
global.set("quantity", 1); // Number of contracts per leg
global.set("wingWidth", 10); // Distance from ATM to long strikes
For liquidation_flow.json, monitoring_flow.json, and trade_history_flow.json:
global.set("apiKeyLive", "YOUR_LIVE_API_KEY");
global.set("apiSecretLive", "YOUR_LIVE_SECRET");
| Key Name | Purpose | Environment |
|---|---|---|
apiKeyP1 / apiSecretP1 |
Market data (snapshots, Greeks) | data.alpaca.markets |
apiKeyP3 / apiSecretP3 |
Paper trading orders | paper-api.alpaca.markets |
apiKeyLive / apiSecretLive |
Live trading orders | api.alpaca.markets |
| Endpoint | Purpose |
|---|---|
/v2/stocks/SPY/snapshot |
Get SPY price |
/v1beta1/options/snapshots |
Get options prices/Greeks |
/v2/orders (paper) |
Submit paper orders |
/v2/orders (live) |
Submit live orders |
/v2/positions |
Get open positions |
{
"order_class": "mleg",
"type": "market",
"time_in_force": "day",
"qty": "5",
"legs": [
{
"symbol": "SPY250117P00580000",
"side": "buy",
"ratio_qty": "1"
},
{
"symbol": "SPY250117P00590000",
"side": "sell",
"ratio_qty": "1"
},
{
"symbol": "SPY250117C00590000",
"side": "sell",
"ratio_qty": "1"
},
{
"symbol": "SPY250117C00600000",
"side": "buy",
"ratio_qty": "1"
}
]
}
qty at order level = number of spreads (actual contracts per leg)ratio_qty at leg level = ratio between legs (always "1" for butterfly)ratio_qty replaced the deprecated ratio fieldSPY250117P00580000
β β β β
β β β βββ Strike Γ 1000 (8 digits, padded with zeros)
β β βββββ Option type (P=Put, C=Call)
β βββββββββββ Expiry (YYMMDD)
βββββββββββββββ Underlying symbol
Why Thursday?
| Condition | Threshold | Rationale |
|---|---|---|
| Profit Target | P&L β₯ 50% | Secure profits before potential reversal |
| Max Profit | P&L β₯ 90% | Close when near max, avoid pin risk |
| Stop Loss | P&L β€ β80% | Limit losses on breakout moves |
Click "Manual Liquidation Trigger" in the liquidation flow to close immediately.
// Net Credit = Premium received - Premium paid
netCreditReceived = shortCredit - longCost;
// Max Risk = Wing Width Γ 100 - Net Credit
maxRisk = (wingWidth * 100 * quantity) - netCreditReceived;
// Return on Capital (ROC)
returnOnCapital = (realizedPnL / maxRisk) * 100;
// Return on Credit
returnOnCredit = (realizedPnL / netCreditReceived) * 100;
// Annualized Return
annualizedReturn = (returnOnCapital / tradeDays) * 252;
{
"summary": {
"completedTrades": 5,
"totalPnL": "+$234.50",
"winCount": 4,
"lossCount": 1,
"winRate": "80.0%",
"avgPnLPerTrade": "+$46.90"
}
}
SPY Price: $590.25
ATM Strike: $590
Wing Width: 10
Position:
- Buy 1x SPY 250117 P580 @ $0.80
- Sell 1x SPY 250117 P590 @ $2.50
- Sell 1x SPY 250117 C590 @ $2.50
- Buy 1x SPY 250117 C600 @ $0.80
Net Credit: $3.40
Max Profit: $340
Max Loss: $660
SPY Price: $589.50
Close Cost: ~$1.80
Realized P&L:
$3.40 - $1.80 = $1.60
Γ 100 = $160 profit
ROC: $160 / $660 = 24.2%
Cause: No open positions or wrong API keys
Fix: Verify live API keys are set and positions exist
Cause: Using ratio instead of ratio_qty
Fix: Use "ratio_qty": "1" (string, not number)
Cause: Missing qty at order level
Fix: Include "qty": "N" at order level with actual quantity
Cause: Global variables not set
Fix: Run the "Initialize API Keys" inject node first
Cause: Multiple butterflies with different expiries
Fix: Flow groups by expiry and submits separate orders
node.warn() output in function nodesus_option asset class filterOptions trading involves significant risk. This automation is provided as-is without warranty. Always monitor your positions and ensure you understand the risks involved. Past performance does not guarantee future results.
Deploy Iron Butterfly and other strategies with MachineTrader's low-code platform.
Start Free Trial