# Momentum Tide [Thinkorswim Port]
# Core math conversion from TradingView version
input lenBaseline = 50;
input lenSmooth = 8;
input atrLen = 15;
input neutralBand = 0.08;
input slopeScaler = 1.8;
input showBaseline = yes;
input showTri = yes;
# === Core Trend Math ===
def baseline = ExpAverage(close, lenBaseline);
def atrValue = Average(TrueRange(high, close, low), atrLen);
# Prevent divide-by-zero
def safeATR = Max(atrValue * slopeScaler, TickSize());
def rawDeviation = (close - baseline) / safeATR;
def signal = ExpAverage(rawDeviation, lenSmooth);
# --- TanhSafe conversion ---
def capped = Max(Min(signal, 20), -20);
def e2 = Exp(2 * capped);
def clamped = (e2 - 1) / (e2 + 1);
# Trend state
def state =
if clamped > neutralBand then 1
else if clamped < -neutralBand then -1
else 0;
def strength = AbsValue(clamped);
# === Colors ===
DefineGlobalColor("Bull", CreateColor(31, 222, 185));
DefineGlobalColor("Bear", CreateColor(214, 24, 104));
DefineGlobalColor("Neutral", CreateColor(120, 128, 138));
def isBull = state == 1;
def isBear = state == -1;
# === Baseline Plot ===
plot Base = if showBaseline then baseline else Double.NaN;
Base.AssignValueColor(
if isBull then GlobalColor("Bull")
else if isBear then GlobalColor("Bear")
else GlobalColor("Neutral")
);
Base.SetLineWeight(2);
# === Bar Coloring ===
AssignPriceColor(
if isBull then GlobalColor("Bull")
else if isBear then GlobalColor("Bear")
else GlobalColor("Neutral")
);
# === Flip Markers ===
def lastState = state[1];
def isGreenFlip = state == 1 and lastState != 1;
def isRedFlip = state == -1 and lastState != -1;
plot UpFlip = if showTri and isGreenFlip then low else Double.NaN;
UpFlip.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpFlip.SetDefaultColor(GlobalColor("Bull"));
UpFlip.SetLineWeight(2);
plot DownFlip = if showTri and isRedFlip then high else Double.NaN;
DownFlip.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownFlip.SetDefaultColor(GlobalColor("Bear"));
DownFlip.SetLineWeight(2);