Paste this complete indicator into Pine Editor. It displays the six calculated prices and the four episode outcomes in a table, independent of the chart symbol. Expected outputs are the two tables above. The script is an arithmetic audit: it does not select market pivots, read a manual Fib spiral, draw the full curve or place trades. Pine scripts cannot access manual chart drawing objects.
Complete source. The log unit is fixed at ln(1.05). Invalid units, reversed anchor times and non-positive log prices return na; bars outside the selected branch return na.Pine Script v6
//@version=6
indicator("Frozen spiral arithmetic fixtures", overlay = true)
// Counterclockwise golden-log model, not the native Fib spiral drawing.
// Solve only the increasing-x branch beta in [270, 360] degrees.
spiralPrice(float t, float ta, float pa, float tb, float pb, float h, float v, float q, bool logPrice) =>
float result = na
bool valid = tb > ta and h > 0 and v > 0 and q > 1
valid := valid and (not logPrice or (pa > 0 and pb > 0))
if valid
float unit = logPrice ? math.log(1.05) : v
float x = (tb - ta) / h
float y = logPrice ? math.log(pb / pa) / unit : (pb - pa) / unit
float radius = math.sqrt(x * x + y * y)
float alpha = math.atan(y / x)
float k = 2.0 * math.log(q) / math.pi
float endTime = ta + h * radius * math.exp(k * (2.0 * math.pi - alpha))
if t >= ta and t <= endTime
float lo = 1.5 * math.pi
float hi = 2.0 * math.pi
for i = 0 to 59
float beta = (lo + hi) / 2.0
float r = radius * math.exp(k * (beta - alpha))
float candidate = ta + h * r * math.cos(beta)
if candidate < t
lo := beta
else
hi := beta
float beta = (lo + hi) / 2.0
float yy = radius * math.exp(k * (beta - alpha)) * math.sin(beta)
result := logPrice ? pa * math.exp(unit * yy) : pa + unit * yy
result
outcome(float level, float lowPrice, float highPrice, float touchClose, float close1, float close2) =>
string result = "No contact"
if not na(level) and lowPrice <= level and level <= highPrice
result := "Expired"
if close1 <= touchClose - 2
result := "Failure"
else if close1 >= touchClose + 2
result := "Rebound"
else if close2 <= touchClose - 2
result := "Failure"
else if close2 >= touchClose + 2
result := "Rebound"
result
float phi = (1.0 + math.sqrt(5.0)) / 2.0
float base = spiralPrice(20, 0, 100, 10, 105, 10, 5, phi, false)
var table audit = table.new(position.top_right, 2, 12, border_width = 1)
if barstate.islast
names = array.from("Base", "A bar = 2", "B price = 106", "H = 20", "q = 1.5", "Log price")
values = array.from(base, spiralPrice(20, 2, 100, 10, 105, 10, 5, phi, false), spiralPrice(20, 0, 100, 10, 106, 10, 5, phi, false), spiralPrice(20, 0, 100, 10, 105, 20, 5, phi, false), spiralPrice(20, 0, 100, 10, 105, 10, 5, 1.5, false), spiralPrice(20, 0, 100, 10, 105, 10, 5, phi, true))
table.cell(audit, 0, 0, "Synthetic specification")
table.cell(audit, 1, 0, "Price at bar 20")
for i = 0 to 5
table.cell(audit, 0, i + 1, array.get(names, i))
table.cell(audit, 1, i + 1, str.tostring(array.get(values, i), "#.0000"))
table.cell(audit, 0, 7, "Synthetic episode")
table.cell(audit, 1, 7, "Fixed-rule outcome")
results = array.from(outcome(base, 75, 76, 75.5, 76.5, 78), outcome(base, 75, 76, 75.5, 73, 79), outcome(base, 77, 78, 77.5, 78, 80), outcome(base, 75, 76, 75.5, 76, 75.8))
for i = 0 to 3
table.cell(audit, 0, i + 8, "Episode " + str.tostring(i + 1))
table.cell(audit, 1, i + 8, array.get(results, i))