The Paranoid-Schizophrenic Kalman For ThinkOrSwim

whoDAT

Member
Plus
We've all been there. Trading is a psychosis. I get paranoid if a trade loses and change my direction. I get schizophrenic and change just for change's sake. What if that is a strategy???

On SPX, with the inputs (Close, 0.5, 7, 3, 1). 1 day time frame.
Chart shows it up 15% in 90 days (win rate 87%), 25% in last year (win rate 68%).
This assumes you're always in the market, long or short.
When looking at prior years, the study is breakeven to not great. Although I haven't analyzed the best inputs.

Enjoy!

Screenshot 2026-02-09 112641.png


Since Gemini helped me make the the study, I'll let them describe the technical bits.

This study, titled The Paranoid-Schizophrenic Kalman, is a sophisticated trend-following system that uses adaptive signal processing to navigate market volatility. At its core, it employs a Kalman Filter, a mathematical algorithm often used in aerospace and navigation, to "denoise" price action. Unlike a standard moving average, the Kalman engine dynamically adjusts its responsiveness based on the signal's error rate, providing a smoother, more accurate representation of the trend (the Cyan/Magenta Signal Line) while reducing the lag typically found in traditional indicators.

What makes this study unique is its "Logic-Flip" State Machine. Rather than strictly buying when the trend is up, the engine monitors its own performance in real-time. If a trade results in a loss or exceeds a specific time limit (MaxBarsBeforeFlip), the system assumes the current market regime has shifted and "inverts" its logic. In "Standard" mode, it follows the trend; in "Inverted" mode, it contrarian-trades against the trend. This self-correcting DNA allows the study to automatically pivot between trend-following and mean-reversion strategies based on historical success, aiming to stay on the right side of shifting market cycles.


Key Components​

ComponentTechnical Function
Kalman EngineUses a recursive state-space model to filter price noise and track the "true" trend with minimal lag.
State MachineA logic gate that tracks entry prices, bar counts, and wins/losses to dictate the next move.
Logic FlipAn adaptive mechanism that toggles the strategy between Standard (Trend) and Inverted (Counter-Trend) modes.
Profit EngineA real-time accounting module that calculates cumulative P/L and per-trade performance.


Code:
# THE CRAZY TRAIN AKA PARANOIA-SCHIZOPHERENIA
# APPLIED TO A KALMAN TREND
# -----------------------------------------------
input src = close;
input KalmanGain = 0.5;
input Signal_Length = 70;
input MaxBarsBeforeFlip = 40;
input UnitsTraded = 1;

# --- 1. KALMAN ENGINE ---
rec Kalman_Estimate;
rec Kalman_Error;
def Prev_Est = if IsNaN(Kalman_Estimate[1]) then src else Kalman_Estimate[1];
def Prev_Err = if IsNaN(Kalman_Error[1]) then 1 else Kalman_Error[1] + 0.1;
def K_Gain = Prev_Err / (Prev_Err + KalmanGain);
Kalman_Estimate = Prev_Est + K_Gain * (src - Prev_Est);
Kalman_Error = (1 - K_Gain) * Prev_Err;

plot SignalLine = Average(Kalman_Estimate, Signal_Length);
SignalLine.AssignValueColor(if SignalLine > SignalLine[1] then Color.CYAN else Color.MAGENTA);
SignalLine.SetLineWeight(3);

# --- 2. TREND DETECTION ---
def curlUp = SignalLine > SignalLine[1] and SignalLine[1] <= SignalLine[2];
def curlDown = SignalLine < SignalLine[1] and SignalLine[1] >= SignalLine[2];

# --- 3. THE STATE MACHINE ---
rec CurrentPosition;    
rec IsInverted;    
rec EntryPrice;
rec BarsInTrade;

# Step A: Did the previous trade close?
def tradeClosed = CurrentPosition[1] != 0 and (curlUp or curlDown or BarsInTrade[1] >= MaxBarsBeforeFlip);
def lastTradeProfit = if tradeClosed then (if CurrentPosition[1] == 1 then close - EntryPrice[1] else EntryPrice[1] - close) else 0;
def wasLoss = tradeClosed and lastTradeProfit < 0;

# Step B: Update Logic DNA (Flip on Loss or Time)
IsInverted = if BarNumber() <= Signal_Length then 1
             else if wasLoss or (BarsInTrade[1] >= MaxBarsBeforeFlip) then !IsInverted[1]
             else IsInverted[1];

# Step C: Determine Position
if (BarNumber() < Signal_Length) {
    CurrentPosition = 0;
    EntryPrice = close;
    BarsInTrade = 0;
} else {
    if (tradeClosed or CurrentPosition[1] == 0) {
        CurrentPosition = if IsInverted then (if SignalLine > SignalLine[1] then -1 else 1)
                                        else (if SignalLine > SignalLine[1] then 1 else -1);
        EntryPrice = close;
        BarsInTrade = 1;
    } else {
        CurrentPosition = CurrentPosition[1];
        EntryPrice = EntryPrice[1];
        BarsInTrade = BarsInTrade[1] + 1;
    }
}

# --- 4. PROFIT ENGINE & TRADE COUNTER ---
# We define isNewOrder based on the final state machine output
def isNewOrder = CurrentPosition != CurrentPosition[1] and CurrentPosition != 0;

# FIXED COUNTER: Only increments when a New Order signal is triggered
rec TradeCount = CompoundValue(1, if isNewOrder then TradeCount[1] + 1 else TradeCount[1], 0);

def barPips = if CurrentPosition[1] == 1 then close - close[1] else if CurrentPosition[1] == -1 then close[1] - close else 0;
rec totalCash = CompoundValue(1, totalCash[1] + (barPips * UnitsTraded), 0);

rec tradeAccumulator;
if isNewOrder {
    tradeAccumulator = 0; # Reset for new trade
} else {
    tradeAccumulator = tradeAccumulator[1] + (barPips * UnitsTraded);
}

# --- 5. VISUALS ---
# Note: The bubble shows the P/L of the trade that just CLOSED
AddChartBubble(isNewOrder and BarNumber() > Signal_Length, if CurrentPosition == 1 then low else high,
    AsDollars(tradeAccumulator[1]),
    if tradeAccumulator[1] >= 0 then Color.GREEN else Color.RED,
    if CurrentPosition == 1 then 0 else 1);

AddLabel(yes, "Logic: " + (if IsInverted then "INVERTED" else "STANDARD"), if IsInverted then Color.YELLOW else Color.WHITE);
AddLabel(yes, "Total Trades: " + TradeCount, Color.WHITE);
AddLabel(yes, "Session P/L: " + AsDollars(totalCash), if totalCash > 0 then Color.GREEN else Color.RED);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
1655 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top