AGAIG 0DTE Buy or Sell Iron Fly for Profit
An 11:30 AM entry, math-driven instead of eyeballed. The indicator pulls implied volatility and time left to close, then solves for the exact strike distance matching your target probability of touch — no guessing where to set wings.
Why 11:30? Opening volatility has settled, but there's still enough time value left to make selling premium worthwhile.
Why probability of touch, not just the expected move? The raw one-sigma "market maker move" tells you where price usually lands, but it's not tied to your risk tolerance. Setting wings by touch probability lets you choose that directly — 25% on the sell side buys real room before a wing gets tested, versus the ~32% you'd get from a plain one-sigma wing by default.
Two-sided. Toggle Sell (short iron fly, collect credit, profit if price stays inside) or Buy (long iron fly, pay debit, profit if price reaches a wing) — same math, opposite intent, each with its own target probability.
Built-in GTC calculator. Enter your actual fill, get the exact limit price for a 35% profit target. No mental math mid-session.
The edge is discipline. A hard 35% target plus a defined late-day exit turns a probability edge into consistent, bankable results — instead of letting winners ride into risk.
Caveats:
Standard options math, not a proprietary signal — a calculator, not a crystal ball
Assumes constant vol, no drift; real markets have skew and fat tails, especially on news days
Built for same-day (0DTE) expirations only — SPY, QQQ, SPX, etc.
Track your fills before sizing up
Note: I frequently trade today’s data using tomorrow’s expirations at the same entry/exits and try to obtain profit targets today. I added Label Location/Size.
Iron Fly Buy Chart Look:
Iron Fly Sell Chart Look:
Iron Fly Input and Options Change Mode:
Indicator Link: http://tos.mx/!WFokeZFu
An 11:30 AM entry, math-driven instead of eyeballed. The indicator pulls implied volatility and time left to close, then solves for the exact strike distance matching your target probability of touch — no guessing where to set wings.
Why 11:30? Opening volatility has settled, but there's still enough time value left to make selling premium worthwhile.
Why probability of touch, not just the expected move? The raw one-sigma "market maker move" tells you where price usually lands, but it's not tied to your risk tolerance. Setting wings by touch probability lets you choose that directly — 25% on the sell side buys real room before a wing gets tested, versus the ~32% you'd get from a plain one-sigma wing by default.
Two-sided. Toggle Sell (short iron fly, collect credit, profit if price stays inside) or Buy (long iron fly, pay debit, profit if price reaches a wing) — same math, opposite intent, each with its own target probability.
Built-in GTC calculator. Enter your actual fill, get the exact limit price for a 35% profit target. No mental math mid-session.
The edge is discipline. A hard 35% target plus a defined late-day exit turns a probability edge into consistent, bankable results — instead of letting winners ride into risk.
Caveats:
Standard options math, not a proprietary signal — a calculator, not a crystal ball
Assumes constant vol, no drift; real markets have skew and fat tails, especially on news days
Built for same-day (0DTE) expirations only — SPY, QQQ, SPX, etc.
Track your fills before sizing up
Note: I frequently trade today’s data using tomorrow’s expirations at the same entry/exits and try to obtain profit targets today. I added Label Location/Size.
Iron Fly Buy Chart Look:
Iron Fly Sell Chart Look:
Iron Fly Input and Options Change Mode:
Indicator Link: http://tos.mx/!WFokeZFu
Code:
#
# AGAIG 0 DTE Iron Fly for Profit - Buy or Sell
# Sell (Short Iron Fly) / Buy (Long Iron Fly) toggle with GTC profit-target calculator
# ---------------------------------------------------------------------------
declare upper;
input tradeMode = {default SellIronFly, BuyIronFly};
input sellTargetPOT = 0.25; # target wing touch prob when SELLING (lower = safer)
input buyTargetPOT = 0.70; # target wing touch prob when BUYING (higher = more attainable)
input entryHour = 11;
input entryMinute = 30;
input marketCloseHour = 16;
input marketCloseMinute = 0;
input useRawMMMforSellWings = no; # yes = size sell wings off raw 1-sigma MMM instead of sellTargetPOT
input strikeIncrement = 1.0;
input tradingDayMinutes = 390;
input tradingDaysPerYear = 252;
input manualIV = 0.0;
input showAlternateBand = yes;
input openingCreditOrDebit = 0.0; # enter your ACTUAL fill price per share once opened (credit for Sell, debit for Buy)
input profitTargetPct = 0.50; # GTC target as % of credit (Sell) or % gain on debit (Buy)
input LabelSize = FontSize.Small;
input LabelLocation = Location.Bottom_LEFT;
script InvNorm {
input p = 0.5;
def a1 = -39.6968303;
def a2 = 220.9460984;
def a3 = -275.9285104;
def a4 = 138.3577519;
def a5 = -30.66479807;
def a6 = 2.506628277;
def b1 = -54.4760988;
def b2 = 161.5858369;
def b3 = -155.6989799;
def b4 = 66.80131189;
def b5 = -13.28068155;
def c1 = -0.007784894;
def c2 = -0.322396458;
def c3 = -2.400758277;
def c4 = -2.549732539;
def c5 = 4.374664141;
def c6 = 2.938163983;
def d1 = 0.007784696;
def d2 = 0.322467129;
def d3 = 2.445134137;
def d4 = 3.754408662;
def p_low = 0.02425;
def p_high = 1 - p_low;
def q_low = Sqrt(-2 * Log(p));
def result_low = (((((c1 * q_low + c2) * q_low + c3) * q_low + c4) * q_low + c5) * q_low + c6) /
((((d1 * q_low + d2) * q_low + d3) * q_low + d4) * q_low + 1);
def q_mid = p - 0.5;
def r_mid = q_mid * q_mid;
def result_mid = (((((a1 * r_mid + a2) * r_mid + a3) * r_mid + a4) * r_mid + a5) * r_mid + a6) * q_mid /
(((((b1 * r_mid + b2) * r_mid + b3) * r_mid + b4) * r_mid + b5) * r_mid + 1);
def q_high = Sqrt(-2 * Log(1 - p));
def result_high = -(((((c1 * q_high + c2) * q_high + c3) * q_high + c4) * q_high + c5) * q_high + c6) /
((((d1 * q_high + d2) * q_high + d3) * q_high + d4) * q_high + 1);
plot result = if p < p_low then result_low else if p <= p_high then result_mid else result_high;
}
script NormCDF {
input x = 0.0;
def ax = AbsValue(x);
def t = 1 / (1 + 0.2316419 * ax);
def dd = 0.3989423 * Exp(-ax * ax / 2);
def poly = t * (0.319381530 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429))));
def prob = 1 - dd * poly;
plot result = if x >= 0 then prob else 1 - prob;
}
def isEntryBar = SecondsFromTime(entryHour * 100 + entryMinute) >= 0 and
SecondsFromTime(entryHour * 100 + entryMinute) < GetAggregationPeriod() / 1000;
def newDay = GetDay() != GetDay()[1];
def entryPrice = if isEntryBar then close
else if newDay then Double.NaN
else entryPrice[1];
def entryIVraw = if manualIV > 0 then manualIV else impVolatility();
def entryIV = if isEntryBar then entryIVraw
else if newDay then Double.NaN
else entryIV[1];
def minutesRemaining = (marketCloseHour * 60 + marketCloseMinute) - (entryHour * 60 + entryMinute);
def tYears = (minutesRemaining / tradingDayMinutes) / tradingDaysPerYear;
def isSellMode = tradeMode == tradeMode.SellIronFly;
def zOneSigma = 1.0;
def sigmaFactor = Exp(zOneSigma * entryIV * Sqrt(tYears));
def upperMMMraw = entryPrice * sigmaFactor;
def lowerMMMraw = entryPrice / sigmaFactor;
def upperMMMstrike = Round(upperMMMraw / strikeIncrement, 0) * strikeIncrement;
def lowerMMMstrike = Round(lowerMMMraw / strikeIncrement, 0) * strikeIncrement;
# --- Sell mode wings (short iron fly - want LOW touch prob) ----------------
def zSell = InvNorm(1 - sellTargetPOT / 2);
def sellPotFactor = Exp(zSell * entryIV * Sqrt(tYears));
def sellUpperRaw = entryPrice * sellPotFactor;
def sellLowerRaw = entryPrice / sellPotFactor;
def sellWingUpper = Round(sellUpperRaw / strikeIncrement, 0) * strikeIncrement;
def sellWingLower = Round(sellLowerRaw / strikeIncrement, 0) * strikeIncrement;
def sellWingUpperFinal = if useRawMMMforSellWings then upperMMMstrike else sellWingUpper;
def sellWingLowerFinal = if useRawMMMforSellWings then lowerMMMstrike else sellWingLower;
def sellAltUpper = if useRawMMMforSellWings then sellWingUpper else upperMMMstrike;
def sellAltLower = if useRawMMMforSellWings then sellWingLower else lowerMMMstrike;
def sellWingDistX = AbsValue(Log(sellWingUpperFinal / entryPrice)) / (entryIV * Sqrt(tYears));
def sellEstPOT = 2 * NormCDF(-sellWingDistX);
# --- Buy mode wings (long/reverse iron fly - want HIGH touch prob) ---------
def zBuy = InvNorm(1 - buyTargetPOT / 2);
def buyPotFactor = Exp(zBuy * entryIV * Sqrt(tYears));
def buyUpperRaw = entryPrice * buyPotFactor;
def buyLowerRaw = entryPrice / buyPotFactor;
def buyWingUpper = Round(buyUpperRaw / strikeIncrement, 0) * strikeIncrement;
def buyWingLower = Round(buyLowerRaw / strikeIncrement, 0) * strikeIncrement;
def buyWingDistX = AbsValue(Log(buyWingUpper / entryPrice)) / (entryIV * Sqrt(tYears));
def buyEstPOT = 2 * NormCDF(-buyWingDistX);
def atmStrike = Round(entryPrice / strikeIncrement, 0) * strikeIncrement;
# --- GTC profit target based on manually entered fill price -----------------
def gtcSellTarget = openingCreditOrDebit * (1 - profitTargetPct); # buy-to-close limit
def gtcBuyTarget = openingCreditOrDebit * (1 + profitTargetPct); # sell-to-close limit
# --- Plots -------------------------------------------------------------------
plot Center = entryPrice;
Center.SetDefaultColor(Color.WHITE);
Center.SetStyle(Curve.SHORT_DASH);
Center.SetLineWeight(2);
Center.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
plot WingUpper = if isSellMode then sellWingUpperFinal else buyWingUpper;
WingUpper.SetDefaultColor(if isSellMode then Color.RED else Color.GREEN);
WingUpper.SetLineWeight(2);
WingUpper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
plot WingLower = if isSellMode then sellWingLowerFinal else buyWingLower;
WingLower.SetDefaultColor(if isSellMode then Color.RED else Color.GREEN);
WingLower.SetLineWeight(2);
WingLower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
plot AltUpper = if isSellMode and showAlternateBand then sellAltUpper else Double.NaN;
AltUpper.SetDefaultColor(Color.GRAY);
AltUpper.SetStyle(Curve.SHORT_DASH);
AltUpper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
plot AltLower = if isSellMode and showAlternateBand then sellAltLower else Double.NaN;
AltLower.SetDefaultColor(Color.GRAY);
AltLower.SetStyle(Curve.SHORT_DASH);
AltLower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
# --- Labels ------------------------------------------------------------------
AddLabel(isEntryBar, "ENTRY WINDOW NOW", Color.YELLOW, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice), "Body (ATM): " + atmStrike, Color.WHITE, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice) and isSellMode,
"SELL Iron Fly wings @ ~" + AsPercent(sellTargetPOT) + " POT: " + sellWingLowerFinal + " / " + sellWingUpperFinal, Color.RED, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice) and isSellMode,
"Est. touch prob: " + AsPercent(sellEstPOT), Color.CYAN, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice) and isSellMode and showAlternateBand,
"Ref band: " + sellAltLower + " / " + sellAltUpper, Color.GRAY, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice) and !isSellMode,
"BUY (Long) Iron Fly wings @ ~" + AsPercent(buyTargetPOT) + " POT: " + buyWingLower + " / " + buyWingUpper, Color.GREEN, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice) and !isSellMode,
"Est. touch prob: " + AsPercent(buyEstPOT), Color.CYAN, LabelLocation, LabelSize);
AddLabel(!IsNaN(entryPrice), "IV used: " + AsPercent(entryIV), Color.CYAN, LabelLocation, LabelSize);
AddLabel(openingCreditOrDebit > 0 and isSellMode,
"GTC Buy-to-Close @ " + AsDollars(gtcSellTarget) + " (" + AsPercent(profitTargetPct) + " of credit)", Color.YELLOW, LabelLocation, LabelSize);
AddLabel(openingCreditOrDebit > 0 and !isSellMode,
"GTC Sell-to-Close @ " + AsDollars(gtcBuyTarget) + " (" + AsPercent(profitTargetPct) + " gain on debit)", Color.YELLOW, LabelLocation, LabelSize);
input exitCheckHour = 15;
input exitCheckMinute = 55;
def isExitCheckBar = SecondsFromTime(exitCheckHour * 100 + exitCheckMinute) >= 0 and
SecondsFromTime(exitCheckHour * 100 + exitCheckMinute) < GetAggregationPeriod() / 1000;
AddLabel(isExitCheckBar, "3:55 CHECK: If GTC not filled, consider closing at market (0DTE only)", Color.ORANGE);
Alert(isExitCheckBar, "0DTE 3:55 exit check - close if GTC not hit", Alert.BAR, Sound.Bell);
# --- Alert ---------------------------------------------------------------
Alert(isEntryBar, "0DTE Entry window - mode: " + (if isSellMode then "SELL IronFly" else "BUY IronFly"), Alert.BAR, Sound.Ring);
Last edited by a moderator: