Swing Point Volume Z-ScoreSWING POINT VOLUME Z-SCORE INDICATOR
A volume analysis tool that identifies statistical volume spikes at swing points with optional higher timeframe confirmation.
This indicator uses Leviathan's method of swing detection. All credit to him for his amazing work (and any mistakes mine). I was also inspired by Trading Riot, who's Capitulation indicator gave me the idea to create this one.
WHAT IT DOES
This indicator combines three analytical approaches:
- Volume Z-score calculation to measure volume significance statistically
- Automatic swing point detection (higher highs, lower lows, etc.)
- Optional higher timeframe volume confirmation
The Z-score measures how many standard deviations current volume is from the average, helping identify when volume activity is genuinely elevated rather than relying on visual assessment.
VISUAL SYSTEM
The indicator uses a color-coded approach for quick assessment:
GREEN - Normal Activity (Z-Score 1.0-2.0)
Above-average volume levels
ORANGE - Elevated Activity (Z-Score 2.0-3.0)
High volume activity that may indicate increased interest
RED - Potential Institutional Activity (Z-Score 3.0+)
Very high volume levels that could suggest significant market participation
HIGHER TIMEFRAME CONFIRMATION
When enabled, the indicator checks volume on a higher timeframe:
- Checkmark symbol indicates HTF volume also shows elevation
- X symbol indicates HTF volume doesn't confirm
- Auto-selects appropriate higher timeframe or allows manual selection
KEY FEATURES
Statistical Approach: Uses Z-score methodology rather than arbitrary volume thresholds
Adaptive Thresholds: Can adjust based on market volatility conditions
Swing Focus: Concentrates analysis on structurally important price levels
Volume Trends: Shows whether volume is accelerating or decelerating
Success Tracking: Monitors how often HTF confirmation proves effective
DISPLAY OPTIONS
Basic Mode: Essential features with clean interface
Advanced Mode: Additional customization and analytics
Label Sizing: Four size options to fit different screen setups
Table Position: Moveable info table with transparency control
Custom Colors: Adjustable for different chart themes
PRACTICAL APPLICATIONS
May help identify:
- Volume spikes at support/resistance levels
- Potential accumulation or distribution zones
- Breakout confirmation with volume backing
- Areas where larger market participants might be active
Works on all liquid markets and timeframes, though generally more effective on 15-minute charts and higher.
USAGE NOTES
This is an analytical tool that highlights statistically significant volume events. It should be used as part of a broader analysis approach rather than as a standalone trading system.
The indicator works best when combined with:
- Price action analysis
- Support and resistance identification
- Trend analysis
- Proper risk management
Default settings are designed to work well across most instruments, but users can adjust parameters based on their specific needs and trading style.
TECHNICAL DETAILS
Built with Pine Script v5
Compatible with all TradingView subscription levels
Open source code available for review and learning
Works on stocks, forex, crypto, futures, and other liquid instruments
The statistical approach helps remove some subjectivity from volume analysis, though like all technical indicators, it should be used thoughtfully as part of a complete trading plan.
Indicadores e estratégias
Bitcoin Expectile Model [LuxAlgo]The Bitcoin Expectile Model is a novel approach to forecasting Bitcoin, inspired by the popular Bitcoin Quantile Model by PlanC. By fitting multiple Expectile regressions to the price, we highlight zones of corrections or accumulations throughout the Bitcoin price evolution.
While we strongly recommend using this model with the Bitcoin All Time History Index INDEX:BTCUSD on the 3 days or weekly timeframe using a logarithmic scale, this model can be applied to any asset using the daily timeframe or superior.
Please note that here on TradingView, this model was solely designed to be used on the Bitcoin 1W chart, however, it can be experimented on other assets or timeframes if of interest.
🔶 USAGE
The Bitcoin Expectile Model can be applied similarly to models used for Bitcoin, highlighting lower areas of possible accumulation (support) and higher areas that allow for the anticipation of potential corrections (resistance).
By default, this model fits 7 individual Expectiles Log-Log Regressions to the price, each with their respective expectile ( tau ) values (here multiplied by 100 for the user's convenience). Higher tau values will return a fit closer to the higher highs made by the price of the asset, while lower ones will return fits closer to the lower prices observed over time.
Each zone is color-coded and has a specific interpretation. The green zone is a buy zone for long-term investing, purple is an anomaly zone for market bottoms that over-extend, while red is considered the distribution zone.
The fits can be extrapolated, helping to chart a course for the possible evolution of Bitcoin prices. Users can select the end of the forecast as a date using the "Forecast End" setting.
While the model is made for Bitcoin using a log scale, other assets showing a tendency to have a trend evolving in a single direction can be used. See the chart above on QQQ weekly using a linear scale as an example.
The Start Date can also allow fitting the model more locally, rather than over a large range of prices. This can be useful to identify potential shorter-term support/resistance areas.
🔶 DETAILS
🔹 On Quantile and Expectile Regressions
Quantile and Expectile regressions are similar; both return extremities that can be used to locate and predict prices where tops/bottoms could be more likely to occur.
The main difference lies in what we are trying to minimize, which, for Quantile regression, is commonly known as Quantile loss (or pinball loss), and for Expectile regression, simply Expectile loss.
You may refer to external material to go more in-depth about these loss functions; however, while they are similar and involve weighting specific prices more than others relative to our parameter tau, Quantile regression involves minimizing a weighted mean absolute error, while Expectile regression minimizes a weighted squared error.
The squared error here allows us to compute Expectile regression more easily compared to Quantile regression, using Iteratively reweighted least squares. For Quantile regression, a more elaborate method is needed.
In terms of comparison, Quantile regression is more robust, and easier to interpret, with quantiles being related to specific probabilities involving the underlying cumulative distribution function of the dataset; on the other expectiles are harder to interpret.
🔹 Trimming & Alterations
It is common to observe certain models ignoring very early Bitcoin price ranges. By default, we start our fit at the date 2010-07-16 to align with existing models.
By default, the model uses the number of time units (days, weeks...etc) elapsed since the beginning of history + 1 (to avoid NaN with log) as independent variable, however the Bitcoin All Time History Index INDEX:BTCUSD do not include the genesis block, as such users can correct for this by enabling the "Correct for Genesis block" setting, which will add the amount of missed bars from the Genesis block to the start oh the chart history.
🔶 SETTINGS
Start Date: Starting interval of the dataset used for the fit.
Correct for genesis block: When enabled, offset the X axis by the number of bars between the Bitcoin genesis block time and the chart starting time.
🔹 Expectiles
Toggle: Enable fit for the specified expectile. Disabling one fit will make the script faster to compute.
Expectile: Expectile (tau) value multiplied by 100 used for the fit. Higher values will produce fits that are located near price tops.
🔹 Forecast
Forecast End: Time at which the forecast stops.
🔹 Model Fit
Iterations Number: Number of iterations performed during the reweighted least squares process, with lower values leading to less accurate fits, while higher values will take more time to compute.
Fork: BigBeluga TargetTrend with Bounded Box & Potential LabelFork of BigBeluga's TargetTrend indicator with bounding boxes of trend legs with max favorable excursion label added.
nkh Multi-TF S/RThis script create a specific marking for each time frame, change pivot to adjust mark.
nkh.
VWAP Multi-TimeframeThis is a multi-timeframe VWAP indicator that provides volume weighted average price calculations for the following time periods:
15min
30min
1H
2H
4H
6H
8H
12H
1D
1W
1M
3M
6M
1Y
You can use the lower timeframes for short term trend control areas and use the longer timeframes for long term trend control areas. Trade in the direction of the trend and watch for price reactions that you can trade when price gets close to or touches any of these levels.
This indicator will provide a data plot value of 1 for bullish when price is above all VWAPs that are turned on, -1 for bearish when price is below all VWAPs that are turned on and 0 for neutral when price is not above or below all VWAPs. Use this 1, -1, 0 value as a filter on your signal generating indicators so that you can prevent signals from coming in unless they are in the same direction as the VWAP trend.
Features
Trend direction value of 1, -1 or 0 to send to external indicators so you can filter your signal generating indicators using the VWAP trend.
Trend table that shows you whether price is above or below all of the major VWAPs. This includes the daily, weekly, monthly and yearly VWAPs.
Trend coloring between each VWAP and the close price of each candle so you can easily identify the trend direction.
Customization
Set the source value to use for all of the VWAP calculations. The default is HLC3.
Turn on or off each VWAP.
Change the color of each VWAP line.
Change the thickness of each VWAP line.
Turn on or off labels for each VWAP or turn all labels on or off at once.
Change the offset length from the current bar to the label text.
Change the label text color.
Turn on or off trend coloring for each VWAP.
Change the color for up trends and down trends.
Turn on or off the trend direction display table.
Change the location of the trend direction display table.
Adjust the background and text colors on the trend direction display table.
How To Use The Trend Direction Filtering Feature
The indicator will provide a data plot value of 1 for bullish when price is above all of the VWAPs that are turned on, a value of -1 for bearish when price is below all of the VWAPS that are turned on and a value of 0 for neutral when price is above and below some of the VWAPs that are turned on.
The name of the value to use with your external indicators will show up as: VWAP Multi-Timeframe: Trend Direction To Send To External Indicators
Make sure to use that as your source on your external indicators to get the correct values.
This 1, -1 or 0 value can then be used by another external indicator to tell the indicator what is allowed to do. For instance if you have another indicator that provides buy and sell signals, you can use this trend direction value to prevent your other indicator from giving a sell signal when the VWAP trend is bullish or prevent your other indicator from giving a buy signal when the VWAP trend is bearish.
You will need to program your other indicators to use this trend filtering feature, but this indicator is already set up with this filtering code so you can use it with any other indicator that you choose to filter(if you know how to customize pine script).
Markets You Can Use This Indicator On
This indicator uses volume and price to calculate values, so it will work on any chart that provides volume and price data.
Momentum_EMABand📢 Reposting Notice
I am reposting this script because my earlier submission was hidden due to description requirements under TradingView’s House Rules. This updated version fully explains the originality, the reason for combining these indicators, and how they work together. Follow me for future updates and refinements.
🆕 Momentum EMA Band, Rule-Based System
Momentum EMA Band is not just a mashup — it is a purpose-built trading tool for intraday traders and scalpers that integrates three complementary technical concepts into a single rules-based breakout & retest framework.
Originality comes from the specific sequence and interaction of these three filters:
Supertrend → Sets directional bias.
EMA Band breakout with retest logic → Times precise entries.
ADX filter → Confirms momentum strength and avoids noise.
This system is designed to filter out weak setups and false breakouts that standalone indicators often fail to avoid.
🔧 How the Indicator Works — Combined Logic
1️⃣ EMA Price Band — Dynamic Zone Visualization
Plots upper & lower EMA bands (default: 9-period EMA).
Green Band → Price above upper EMA = bullish momentum
Red Band → Price below lower EMA = bearish pressure
Yellow Band → Price within band = neutral zone
Acts as a consolidation zone and breakout trigger level.
2️⃣ Supertrend Overlay — Reliable Trend Confirmation
ATR-based Supertrend adapts to volatility:
Green Line = Uptrend bias
Red Line = Downtrend bias
Ensures trades align with the prevailing trend.
3️⃣ ADX-Based No-Trade Zone — Choppy Market Filter
Manual ADX calculation (default: length 14).
If ADX < threshold (default: 20) and price is inside EMA Band → gray background marks low-momentum zones.
🧩 Why This Mashup Works
Supertrend confirms trend direction.
EMA Band breakout & retest validates the breakout’s strength.
ADX ensures the market has enough trend momentum.
When all align, entries are higher probability and whipsaws are reduced.
📈 Example Trade Walkthrough
Scenario: 5-minute chart, ADX threshold = 20.
Supertrend turns green → trend bias is bullish.
Price consolidates inside the yellow EMA Band.
ADX rises above 20 → trend momentum confirmed.
Price closes above the green EMA Band after retesting the band as support.
Entry triggered on candle close, stop below band, target based on risk-reward.
Exit when Supertrend flips red or ADX momentum drops.
This sequence prevents premature entries, keeps trades aligned with trend, and avoids ranging markets.
🎯 Key Features
✅ Multi-layered confirmation for precision trading
✅ Built-in no-trade zone filter
✅ Fully customizable parameters
✅ Clean visuals for quick decision-making
⚠ Disclaimer: This is Version 1. Educational purposes only. Always use with risk management.
Crude Oil Option Auto Hedge made by govindits help for crudeoil option trading and you can easily decide
Clean Pivot Lines with AlertsTechnical Overview
This Script is designed for detecting untouched pivot highs and lows. It draws horizontal levels only when those pivots remain unviolated within a configurable lookback window and removes them automatically upon price breaches or sweeps.
Key components include:
Pivot detection logic : Utilizes ta.pivothigh()/ta.pivotlow() (or equivalent via request.security for HTF) with parameterized pivotLength to ensure flexibility and adaptability to different timeframes.
Cleanliness filtering : Checks lookbackBars prior to line creation to skip levels already violated, ensuring only uncontaminated pivots are used.
Dynamic level tracking : Stores active levels in arrays (highLines, lowLines) for continuous real-time monitoring.
Violation logic : Detects both close-based breaks (breakAbove/breakBelow) and wick-based sweeps (sweepAbove/sweepBelow), triggering alerts and automatic teardown.
Periodic housekeeping : Every N (10) confirmed bars, re-verifies “clean” status and removes silently invalidated levels—maintaining chart hygiene and avoiding stale overlays.
Customization options : Supports pivot timeframe override, colors, line width/style, lookback length, and alert toggling.
Utility
This overlay script provides a disciplined workflow for drawing meaningful support/resistance levels, filtering out contaminated pivot points, and signaling validations (breaks/sweeps) with alerts. Its modular design and HTF support facilitate integration into systematic workflows, offering far more utility than mere static pivot plots.
Usage Instructions
1. Adjust `pivot_timeframe`, `pivot_length`, and `lookback_bars` to suit your strategy timeframe and volatility structure.
2. Customize visual parameters as required.
3. Enable alerts to receive in-platform messages upon pivot violations.
4. Use HTF override only if analyzing multi-timeframe pivot behavior; otherwise, leave empty to default to chart timeframe.
Performance & Limitations
- Pivot lines confirmation lags by `pivot_length` bars; real-time signals may be delayed.
- Excessive active lines may impact performance on low-TF charts.
- The “clean” logic is contingent on the `lookback_bars` parameter; choose sufficiently high values to avoid false cleanliness.
- Alerts distinguish between closes beyond and wick-only breaches to aid strategic nuance.
All-Time High/Low Levels with Dynamic Price Zones📈 All-Time High/Low Levels with Dynamic Price Zones — AlertBlake
🧠 Overview:
This powerful indicator automatically identifies and draws the All-Time High (AT.H) and All-Time Low (AT.L) on your chart, providing a clear visual framework for price action analysis. It also calculates and displays the Midpoint (50%), Upper Quartile (75%), and Lower Quartile (25%) levels, creating a dynamic grid that helps traders pinpoint key psychological levels, support/resistance zones, and potential breakout or reversal areas.
✨ Features:
Auto-Detection of All-Time High and Low:
Tracks the highest and lowest prices in the full visible historical range of the chart.
Automatically updates as new highs or lows are created.
Dynamic Level Calculation:
Midpoint (50%): Halfway between AT.H and AT.L.
25% Level: 25% between AT.L and AT.H.
75% Level: 75% between AT.L and AT.H.
Each level is clearly labeled with its corresponding value.
Labels are positioned to the right of the price for easy reading.
Color-Coded Lines (customizable)
FIBO SWING mfi by julzALGOOVERVIEW
FIBO SWING mfi by julzALGO blends MFI → RSI → Least‑Squares smoothing to flag overbought/oversold swings and continuously plot Fibonacci retracements from the rolling high/low of the last 200 bars. It’s built to spot momentum shifts while giving you a clean, always‑current fib map of the recent market range.
CORE PRINCIPLES
Hybrid Momentum Signal
Uses MFI to integrate price and volume.
Applies RSI to MFI for momentum clarity.
Smooths the result with Least Squares regression to reduce noise.
Swing Identification
Marks potential swing highs when momentum is overbought.
Marks potential swing lows when momentum is oversold.
Fixed-Window Fibonacci Mapping
Always calculates fib levels from the highest high and lowest low of the last 200 bars.
This keeps fib zones consistent, independent of swing point detection.
Visual Clarity & Non-Repainting Logic
Clean labels for OB/OS zones.
Lines and levels update only as new bars confirm changes.
Adaptability
Works on any market and timeframe.
Adjustable momentum length, OB/OS thresholds, and smoothing.
HOW IT WORKS
Computes Money Flow Index (MFI) from price & volume.
Applies RSI to the MFI for clearer OB/OS momentum.
Smooths the hybrid with a Least Squares (linear regression) filter.
Swing labels appear when OB/OS conditions are met (green = swing low, red = swing high).
Fibonacci retracements are always drawn from the highest high and lowest low of the last 200 bars (rolling window), independent of swing labels.
HOW TO USE
Watch for OB/OS flips to mark potential swing highs/lows.
Use the 200‑bar fib grid as your active map of pullback levels and reaction zones.
Combine fib reactions with your price action/volume cues for confirmation.
Works across markets and timeframes.
SETTINGS
Length – Period for both MFI and RSI.
OB/OS Levels – Overbought/oversold thresholds (default 70/30).
Smooth – Least‑Squares smoothing length.
Fibonacci Window – Fixed at 200 bars in this version (changeable in code via fibLen).
NOTES
Logic is non‑repainting aside from standard bar/label confirmation.
Increase Length on very low timeframes to reduce noise.
Swing labels help context; fibs are always based on the most recent 200‑bar high/low range.
SUMMARY
FIBO SWING mfi by julzALGO is a momentum-plus-price action tool that merges MFI → RSI → smoothing to identify overbought/oversold swings and automatically plot Fibonacci retracements based on the rolling high/low of the last 200 bars.
It’s designed to help traders quickly see potential reversal points and pullback zones, offering visual confluence between momentum shifts and fixed-window price structure.
DISCLAIMER
For educational purposes only. Not financial advice. Trade responsibly with proper risk management.
Nifty Smart Zones & Breakout Bars(5min TF only) by Chaitu50cNifty Smart Zones & Breakout Bars is a purpose-built intraday trading tool, tested extensively on Nifty50 and recommended for Nifty50 use only.
All default settings are optimised specifically for Nifty50 on the 5-minute timeframe for maximum accuracy and clarity.
Why Last Bar of the Session Matters
The last candle of a trading session often represents the final battle between buyers and sellers for that day.
It encapsulates closing sentiment, influenced by end-of-day positioning, profit booking, and institutional activity.
The high and low of this bar frequently act as strong intraday support/resistance in the following sessions.
Price often reacts around these levels, especially when combined with volume surges.
Core Features
Session Last-Candle Zones
Plots a horizontal box at the high and low of the last candle in each session.
Boxes extend to the right to track carry-over levels into new sessions.
Uses a stateless approach — past zones reappear if relevant.
Smart Suppression System
When more than your Base Sessions (No Suppression) are shown, newer zones overlapping or within a proximity distance (in points) of older zones are hidden.
Older zones take priority, reducing chart clutter while keeping critical levels.
Breakout Bar Coloring
Highlights breakout bars in four categories:
Up Break (1-bar)
Down Break (1-bar)
Up Break (2-bar)
Down Break (2-bar)
Breakouts use a break buffer (in ticks) to filter noise.
Toggle coloring on/off instantly.
Volume Context (User Tip)
For best use, pair with volume analysis.
High-volume breakouts from last-session zones have greater conviction and can signal sustained momentum.
Usage Recommendations
Instrument: Nifty50 only (tested & optimised).
Timeframe: 5-minute chart for best results.
Approach:
Watch for price interaction with the plotted last-session zones.
Combine zone breaks with bar color signals and volume spikes for higher-probability trades.
Use suppression to focus on key, non-redundant levels.
Why This Tool is Different
Unlike standard support/resistance plotting, this indicator focuses on session-closing levels, which are more reliable than arbitrary highs/lows because they capture the final market consensus for the session.
The proximity-based suppression ensures your chart stays clean, while breakout paints give instant visual cues for momentum shifts.
Drone Arrows with Supply & Demand (v6)A guided decision-making tool.
Here’s a conservative way to use it:
For Long Trades (Buy)
Check the Dashboard
At least 4–5 timeframes green (uptrend) is ideal.
Overall condition = “Strong Buy” preferred.
Look for a Green BUY Signal Arrow
Appears below the candle.
Price should be above the MA if the trend filter is on.
Ideally, volume is above threshold if volume filter is enabled.
Check Supply/Demand Zones
Avoid buying directly into a nearby supply zone overhead.
Best if you’re entering near/within a demand zone.
Confirm Market Structure
Higher highs & higher lows in recent price action.
Set Stop Loss & Targets
Use the plotted SL (ATR-based) or place just below nearest demand zone.
TP levels are plotted — aim for 1:2 or better reward-to-risk.
For Short Trades (Sell)
Check the Dashboard
At least 4–5 timeframes red (downtrend) is ideal.
Overall condition = “Strong Sell” preferred.
Look for a Red SELL Signal Arrow
Appears above the candle.
Price should be below the MA if the trend filter is on.
Ideally, volume is above threshold if volume filter is enabled.
Check Supply/Demand Zones
Avoid shorting into a nearby demand zone.
Best if you’re entering near/within a supply zone.
Confirm Market Structure
Lower highs & lower lows in recent price action.
Set Stop Loss & Targets
Use plotted SL (ATR-based) or just above nearest supply zone.
TP levels are plotted — aim for 1:2 or better reward-to-risk.
Extra Tips
Patience: This tool works best in trending markets. In choppy sideways ranges, expect more false signals.
Higher Timeframe Confluence: Even if trading M5/M15, align with H1 or H4 direction for better probabilities.
Zones as Dynamic S/R: The supply/demand boxes are great for trade entries/exits — watch how price reacts to them.
Cool Down Helps: The cooldown prevents overtrading but you can adjust it if you want faster signals.
Trend line Projection by julzALGOOVERVIEW
Trend Line Single draws two dynamic, forward-projecting trendlines from recent pivots:
Wick Lines – from swing highs/lows of candle wicks.
Body Lines – from swing highs/lows of candle bodies.
Both auto-extend to the right and can optionally shade the zone between wick and body lines, making it easy to spot reaction areas and structure shifts.
Includes automatic HH/LL/HL/LH pivot labeling.
HOW TO USE
Default Length = 8 works for most markets.
Shorter Length → more reactive lines, more frequent signals.
Longer Length → smoother structure, fewer but stronger signals.
Watch for price retests or breaks of wick/body bands.
Use shaded zones to quickly see where price is balancing between wick extremes and body closes.
FEATURES
Wick-based upper/lower trendlines from confirmed swing pivots.
Body-based upper/lower trendlines from confirmed body pivots.
Always-on right extension for forward projection.
Optional fill between wick and body lines to visualize “pressure zones.”
Automatic HH / LL / HL / LH labels for structure reading.
Non-repainting beyond standard pivot confirmation.
SETTINGS
Length – Pivot lookback/forward bars (default 8).
Wick Top / Bottom Color – Wick trendline colors.
Body Top / Bottom Color – Body trendline colors.
Fill Color – Transparency/color for the shaded zone.
PRINCIPLES
Wicks often mark liquidity grabs or extremes.
Bodies reflect actual settlement – good for fair value and consolidation zones.
Wick ≈ Body confluence can mark stronger S/R.
Break + Retest of a line can signal continuation or reversal—always confirm with your own system.
NOTES
Lines only appear after pivots confirm.
Works on all markets and timeframes.
For low-TF noise reduction, increase Length.
This tool is for discretionary analysis, not auto-trading.
SUMMARY
A lightweight, production-ready trendline tool that combines wick- and body-based structure, forward-projects them, optionally shades between them, and labels key pivots for instant structure reading.
DISCLAIMER
For educational purposes only. This is not financial advice. Trade at your own risk with proper management.
Market Structure (DeadCat)🌟 Market Structure (DeadCat) - Indicator Overview 🌟
The Market Structure (DeadCat) indicator plots swing highs and lows (HH, HL, LH, LL) using pivot points, helping you spot uptrends, downtrends, and potential reversals. Perfect for traders who use market structure.
🌟 Key Features 🌟
🔹 Swing Point Labels
HH (Higher High): Signals uptrend strength.
HL (Higher Low): Marks bullish support.
LH (Lower High): Hints at weakening uptrend or reversal.
LL (Lower Low): Confirms downtrend momentum.
🔹 Trend Detection
Uptrend: Tracks HH/HL for bullish momentum.
Downtrend: Tracks LH/LL for bearish momentum.
Waits for breaks of prior HH/HL or LH/LL to confirm new swing points, ensuring reliable signals. 🔄
🔹 Customizable Labels
Adjust label text color (default: black) to suit your chart. Supports up to 500 labels for a clean, focused view. 🖌️
🌟 Indicator Settings 🌟
Swing Length: Fixed at 20 bars (left) and 2 bars (right) for pivot detection.
Label Color: Customize text color for better visibility.
rsi 8 beta 2🔔 How to Use for Entry
BUY Entry when:
Yellow BUY arrow appears
GOLD bar > USD bar
Delta (strength difference) is positive
SELL Entry when:
Blue SELL arrow appears
USD bar > GOLD bar
Delta is negative
Exit either on the opposite arrow or when strength starts weakening.
Market Open Impulse [LuciTech]Market Open Impulse Strategy
The Market Open Impulse Strategy is designed to capture significant price movements that occur at market open (2:30 PM UK time). This strategy identifies impulsive candles with high volatility and enters trades based on the direction and strength of the initial market reaction.
How It Works:
The strategy activates exclusively at 2:30 PM UK time during market open sessions. It uses ATR-based volatility filtering to identify impulsive candles that exceed a configurable multiplier (default 1.5x ATR). Long entries are triggered when an impulsive candle closes above its midpoint and above the opening price, while short entries occur when an impulsive candle closes below its midpoint and below the opening price.
Risk management is handled through precise stop loss placement at the opposite extreme of the impulse candle (high for short positions, low for long positions). Take profit levels are calculated using a configurable risk-reward ratio with a default setting of 3:1. Position sizing is automatically calculated based on the percentage risk per trade, and an optional breakeven feature can move the stop loss to the entry price at specified profit levels.
The strategy incorporates time-based filtering to ensure trades only occur during the specified market open window. Visual indicators highlight qualifying impulsive candles and plot all entry and exit levels for clear trade management. The system offers flexible risk management with customizable risk percentage, risk-reward ratios, and breakeven settings, along with multiple stop loss calculation methods including both ATR-based and candle-based options.
Key Parameters:
Market open timing is fully configurable through hour and minute settings for strategy activation. The impulse ATR multiple sets the minimum volatility threshold required for trade qualification, with visual highlighting available for qualifying setups. Risk management parameters include the percentage of account equity to risk per trade, target profit multiples relative to initial risk, and the profit level threshold for breakeven stop loss adjustment. Users can choose between ATR-based or candle-based stop loss calculation methods and adjust technical parameters for volatility calculation including ATR length and smoothing methods.
Applications:
This strategy is particularly effective for trading market open volatility and momentum, capturing institutional order flow during key timing windows, executing short-term swing trades on significant price impulses, and trading markets with predictable opening patterns and consistent volatility characteristics.
KOBK Quantum Oscillator 383 SB## ⚡ **Core Technology**
- **Quantum Oscillator Integration**: Advanced momentum analysis using stealth algorithms
- **Flow Sync Filtering**: Intelligent trend confirmation technology
- **Zone Lock Protection**: Dynamic stop-loss placement based on market structure
- **Pulse Confirmation**: Entry timing optimization for maximum accuracy
## 📊 **Visual Components**
### **Main Chart Display**
- Clean directional signals (▲ Buy / ▼ Sell)
- Flow Sync Filter line for trend awareness
- Professional scanner information panel
- Real-time risk assessment data
### **Quantum Oscillator Panel**
- Dual-line momentum system with crossover signals
- Dynamic histogram showing market strength
- Color-coded momentum zones
- Equilibrium reference line
## 🎨 **Signal Intelligence**
- **Green Signals**: High-probability bullish entries
- **Red Signals**: High-probability bearish entries
- **Color-Coded Momentum**: Bright colors indicate strong moves, faded colors show weakening momentum
- **Background Highlighting**: Subtle visual confirmation of market conditions
## ⚙️ **Key Features**
- **Smart Risk Management**: Automatic stop-loss calculation based on market structure
- **Trend Confirmation**: Built-in filter prevents counter-trend trades
- **Scanner Compatibility**: Works with TradingView's screening tools
- **Real-Time Alerts**: Instant notifications for all signal types
- **Professional Interface**: Clean, uncluttered display designed for serious traders
## 🔒 **Important Usage Note**
**This system is designed as a COMPLETE trading solution and requires ALL components to function properly. The individual indicators are NOT intended for standalone use and will not provide accurate signals when used separately. Always use the complete KOBK ZENOSU TRAP system as intended.**
## 🎯 **Best For**
- Day traders seeking precise entry points
- Swing traders looking for trend confirmation
- Scanner users monitoring multiple markets
- Risk-conscious traders requiring built-in protection
free course 98304 24602// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) creativecommons.org
// best signal
//@version=5
indicator('free course 98304 24602', overlay = true, max_bars_back = 1500, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)
//--------------------------------------------------------------------------------------------------------------------}
// Settings
//---------------------------------------------------------------------------------------------------------------------{
disp = display.all - display.status_line
rpGR = 'Profile Generic Settings'
Showprofle = input.bool(true, 'Show Profile', group = 'Indicator option', display = disp)
rpLN = input.int(200, '  Lookback Length / Fixed Range', minval = 10, maxval = 1500, step = 10 , group = rpGR, display = disp)
rpLN := last_bar_index > rpLN ? rpLN - 1 : last_bar_index
vpSRC = input.string('Volume', '  Profile Source', options = , group = rpGR, display = disp)
vpGR = 'Profile Presentation Settings'
vpTP = 'displays total trading activity/money flow (common interest, both buying and selling trading activity/money flow) over a specified time period at specific price levels ' +
' - high traded node rows : high trading activity/money flow price levels - usually represents consolidation levels (value areas) ' +
' - average traded node rows : average trading activity/money flow price levels ' +
' - low traded node rows : low trading activity/money flow price levels - usually represents supply & demand levels or liquidity levels ' +
'row lengths, indicates the amount of the traded activity/money flow at specific price levels'
vpSH = input.bool(true, 'Volume/Money Flow Profile', group = vpGR, tooltip = vpTP, display = disp)
vpHVC = input.color(color.new(#ffeb3b, 50), '  High Traded Nodes', inline = 'VP1', group = vpGR)
vpHVT = input.int(53, 'Threshold %' , minval = 50, maxval = 99 , step = 1,inline = 'VP1', group = vpGR, tooltip = 'option range ', display = disp) / 100
vpAVC = input.color(color.new(#2962ff, 50), '  Average Traded Nodes', group = vpGR)
vpLVC = input.color(color.new(#f23645, 50), '  Low Traded Nodes', inline = 'VP2', group = vpGR)
vpLVT = input.int(37, 'Threshold %' , minval = 10, maxval = 40 , step = 1,inline = 'VP2', group = vpGR, tooltip = 'option range ', display = disp) / 100
spTP = 'displays the sentiment, the dominat party over a specified time period at the specific price levels ' +
' - bullish node rows : buying trading activity/money flow is higher ' +
' - barish node rows : selling trading activity/money flow is higher ' +
'row lengths, indicates the strength of the buyers/sellers at the specific price levels'
spSH = input.bool(false, 'Sentiment Profile', group = vpGR, tooltip = spTP)
spPTT = 'conditions used to calculate the up/down volume/money flow ' +
'* bar polarity up => if close > open down => if close <= open ' +
'* bar buying/selling pressure up => if (close - low) > (high - close) down => if (close - low) <= (high - close)'
spPT1 = 'Bar Polarity'
spPT2 = 'Bar Buying/Selling Pressure'
spPTY = input.string(spPT1, '  Sentiment Polarity Method', options = , group = vpGR, tooltip = spPTT, display = disp)
spBLC = input.color(color.new(#26a69a, 50), '  Bullish Nodes', inline = 'SP', group = vpGR)
spBRC = input.color(color.new(#ef5350, 50), 'Bearish Nodes', inline = 'SP', group = vpGR)
hmSH = input.bool(false, 'Profile Heatmap', group = vpGR, tooltip = 'tip : higher number of rows results with a better visuals')
hmSO1 = 'Volume/Money Flow Profile'
hmSRC = input.string(hmSO1, '  Heatmap Source', options = , group = vpGR, display = disp)
hmTR = input.int(73, '  Heatmap Transparency' , minval = 0, maxval = 100 , group = vpGR, display = disp)
othGR = 'Other Presentation Settings'
pcTP = 'displays the price level of the highest traded activity/money flow or the changes of the price levels with the highest traded activity/money flow'
rpPC = input.string('Last(Zone)', '  Level of Significance', options = , inline='PoC', group = othGR, tooltip = pcTP, display = disp)
vaSH = input.bool(false, 'Consolidation Zones', group = othGR, display = disp)
vaTH = input.int(25, '  Consolidation Threshold %' , minval = 0, maxval = 100, inline = 'va', group = othGR, display = disp) / 100
vaC = input.color(color.new(#2962ff, 73), '', inline = 'va', group = othGR)
spTT = 'displays the price zone of the highest bullish or bearish sentiment zone'
spPC = input.bool(false, 'Highest Sentiment Zone', inline = 'spP', group = othGR, tooltip = spTT)
rpPL = input.bool(false, 'Profile Price Levels', inline = 'BBe', group = othGR)
rpPLC = input.color(color.new(#00bcd4, 0), '', inline = 'BBe', group = othGR)
rpLS = input.string('Small', "", options= , inline = 'BBe', group = othGR, display = disp)
rpBG = input.bool(false, 'Profile Range Background Fill', inline = 'BG', group = othGR)
rpBGC = input.color(color.new(#00bcd4, 95), '', inline = 'BG', group = othGR)
otGR = 'Other Profile Settings'
rpNR = input.int(25, '  Number of Rows' , minval = 10, maxval = 100 ,step = 5, group = otGR, tooltip = 'option range ', display = disp)
rpW = input.int(13, '  Profile Width %', minval = 10, maxval = 50, group = otGR, tooltip = 'option range ', display = disp) / 100
vpLS = input.string('Auto', "  Profile Text Size", options= , group = otGR, display = disp)
vpHO = input.int(13, '  Profile Horizontal Offset', group = otGR, tooltip = 'option allows negative numbers as well, in case of a use the profiles will overlap with the price chart', display = disp)
//---------------------------------------------------------------------------------------------------------------------}
// User Defined Types
//---------------------------------------------------------------------------------------------------------------------{
// @type bar properties with their values
//
// @field o (float) open price of the bar
// @field h (float) high price of the bar
// @field l (float) low price of the bar
// @field c (float) close price of the bar
// @field v (float) volume of the bar
// @field i (int) index of the bar
type bar
float o = open
float h = high
float l = low
float c = close
float v = volume
int i = bar_index
int n = bar_index
int t = time
//---------------------------------------------------------------------------------------------------------------------}
// Variables
//---------------------------------------------------------------------------------------------------------------------{
bar b = bar.new()
rpVST = array.new_float(rpNR, 0.)
rpVSB = array.new_float(rpNR, 0.)
rpVSD = array.new_float(rpNR, 0.)
var dRP = array.new_box()
var pocPoints = array.new()
var polyline pocPolyline = na
var polyline spPolyline = na
var color llC = na
var color lsC = na
//---------------------------------------------------------------------------------------------------------------------}
// Functions/Methods
//---------------------------------------------------------------------------------------------------------------------{
// @function creates new label object and updates existing label objects
//
// @param details in Pine Scriptâ„¢ language reference manual
//
// @returns none, updated visual objects (labels)
f_drawLabelX(_x, _y, _text, _style, _textcolor, _size, _tooltip) =>
var lb = label.new(_x, _y, _text, xloc.bar_index, yloc.price, color(na), _style, _textcolor, _size, text.align_left, _tooltip)
lb.set_xy(_x, _y)
lb.set_text(_text)
lb.set_tooltip(_tooltip)
lb.set_textcolor(_textcolor)
// @function This function converts string to enumerated size
//
// @param _t custom string
//
// @returns enumerated size
f_gTS(_t) =>
switch _t
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal
'Auto' => size.auto
//---------------------------------------------------------------------------------------------------------------------}
// Calculations
//---------------------------------------------------------------------------------------------------------------------{
bull = spPTY == spPT1 ? b.c > b.o : (b.c - b.l) > (b.h - b.c)
nzV = nz(b.v)
rpS = f_gTS(rpLS)
vpS = f_gTS(vpLS)
var float pLST = na
var float pHST = na
if b.i == last_bar_index - rpLN
pLST := b.l
pHST := b.h
else if b.i > last_bar_index - rpLN
pLST := math.min(b.l, pLST)
pHST := math.max(b.h, pHST)
pSTP = (pHST - pLST) / rpNR
if barstate.islast and not na(nzV) and not timeframe.isseconds and rpLN > 0 and pSTP > 0 and nzV > 0
if dRP.size() > 0
for i = 0 to dRP.size() - 1
box.delete(dRP.shift())
if pocPoints.size() > 0
pocPoints.clear()
a_allPolylines = polyline.all
if array.size(a_allPolylines) > 0
for i = 0 to array.size(a_allPolylines) - 1
polyline.delete(a_allPolylines.get(i))
for bI = rpLN to 0
l = 0
for pLL = pLST to pHST - pSTP by pSTP
if b.h >= pLL and b.l < pLL + pSTP
vPOR = if b.l >= pLL and b.h > pLL + pSTP
(pLL + pSTP - b.l ) / (b.h - b.l )
else if b.h <= pLL + pSTP and b.l < pLL
(b.h - pLL) / (b.h - b.l )
else if (b.l >= pLL and b.h <= pLL + pSTP)
1
else
pSTP / (b.h - b.l )
if vpSRC == 'Money Flow'
rpVST.set(l, rpVST.get(l) + nzV * vPOR * (pLST + (l + .5) * pSTP) )
else
rpVST.set(l, rpVST.get(l) + nzV * vPOR )
if bull and spSH and Showprofle
if vpSRC == 'Money Flow'
rpVSB.set(l, rpVSB.get(l) + nzV * vPOR * (pLST + (l + .5) * pSTP))
else
rpVSB.set(l, rpVSB.get(l) + nzV * vPOR )
l += 1
if rpPC == 'Developing'
if bI == rpLN
pocPoints.push(chart.point.from_index(b.i , pLST + (rpVST.indexof(rpVST.max()) + .5) * pSTP))
else
pocPoints.push(chart.point.from_index(b.i , pLST + (rpVST.indexof(rpVST.max()) + .5) * pSTP))
if rpPC == 'Developing' and Showprofle
pocPolyline := polyline.new(pocPoints, false, false, xloc.bar_index, vpHVC, color(na), line.style_solid, 2)
if rpPC == 'Last(Zone)' and Showprofle or rpPC == 'Last(Line)' and Showprofle
pocPoints.push(chart.point.from_index(b.i , pLST + (rpVST.indexof(rpVST.max()) + .5) * pSTP))
pocPoints.push(chart.point.from_index(b.i, pLST + (rpVST.indexof(rpVST.max()) + .5) * pSTP))
pocPolyline := polyline.new(pocPoints, false, false, xloc.bar_index, vpHVC, color(na), rpPC == 'Last(Line)' ? line.style_solid : line.style_dotted, rpPC == 'Last(Line)' ? 2 : 1)
for l = 0 to rpNR - 1
bbp = 2 * rpVSB.get(l) - rpVST.get(l)
rpVSD.set(l, rpVSD.get(l) + bbp * (bbp > 0 ? 1 : -1) )
if vpSH and Showprofle or spSH and Showprofle
sBI = b.i + (spSH ? rpLN * rpW : 7) + int(rpLN * rpW / 3)
dRP.push(box.new(sBI - 1 + vpHO, pLST + (l + .1) * pSTP, sBI - int(rpLN * rpW / 3) + 1 + vpHO, pLST + (l + .9) * pSTP, #2962ff80, bgcolor = #2962ff10,
text = str.tostring(pLST + (l + .5) * pSTP, format.mintick), text_color = chart.fg_color, text_size = vpS ))
if rpBG and Showprofle
dRP.push(box.new(b.i - rpLN, pLST, b.i, pHST, rpBGC, bgcolor = rpBGC ))
if rpPL and Showprofle
f_drawLabelX(b.i, pHST, str.tostring(pHST, format.mintick), label.style_label_down, rpPLC, rpS,
'Profile High - ' + str.tostring(pHST, format.mintick) + ' %' + str.tostring((pHST - pLST) / pLST * 100, '#.##') + ' higher than the Profile Low ' +
'Total ' + (vpSRC == 'Volume' ? 'Volume : ' : 'Money Flow (' + syminfo.currency + ') : ') + str.tostring(rpVST.sum(), format.volume) +
' Number of bars : ' + str.tostring(rpLN + 1))
f_drawLabelX(b.i, pLST, str.tostring(pLST, format.mintick), label.style_label_up , rpPLC, rpS,
'Profile Low - ' + str.tostring(pLST, format.mintick) + ' %' + str.tostring((pHST - pLST) / pHST * 100, '#.##') + ' lower than the Profile High ' +
'Total ' + (vpSRC == 'Volume' ? 'Volume : ' : 'Money Flow (' + syminfo.currency + ') : ') + str.tostring(rpVST.sum(), format.volume) +
' Number of bars : ' + str.tostring(rpLN + 1))
for l = 0 to rpNR - 1
if dRP.size() < 500
vtLV = rpVST.get(l)
vtMX = rpVST.max()
LpM = vtLV / vtMX
vdMX = rpVSD.max()
DpM = rpVSD.get(l) / vdMX
llC := LpM > vpHVT ? color.from_gradient(LpM, vpHVT, 1, vpAVC, vpHVC) : color.from_gradient(LpM, 0, vpLVT, vpLVC, vpAVC)
bbp = 2 * rpVSB.get(l) - vtLV
lsC := bbp > 0 ? color.from_gradient(DpM, 0, .7, color.new(spBLC, 70 + int(hmTR / 4)), color.new(spBLC, 30 + int(hmTR / 4))) :
color.from_gradient(DpM, 0, .7, color.new(spBRC, 70 + int(hmTR / 4)), color.new(spBRC, 30 + int(hmTR / 4)))
if rpPC == 'Last(Zone)' and LpM == 1 and Showprofle
dRP.push(box.new(b.i , pLST + (rpVST.indexof(vtMX) + .0) * pSTP, b.i, pLST + (rpVST.indexof(vtMX) + 1.) * pSTP, vpHVC, bgcolor = color.new(vpHVC, 73) ))
if vaSH and LpM > vaTH and LpM < 1 and Showprofle
dRP.push(box.new(b.i , pLST + (l + .0) * pSTP, b.i, pLST + (l + 1.) * pSTP, color(na), bgcolor = vaC ))
if vaSH and rpPC != 'Last(Zone)' and LpM == 1 and Showprofle
dRP.push(box.new(b.i , pLST + (l + .0) * pSTP, b.i, pLST + (l + 1.) * pSTP, color(na), bgcolor = vaC ))
if spPC and DpM == 1 and Showprofle
spPolyline := polyline.new(array.from(chart.point.from_index(b.i , pLST + (rpVSD.indexof(vdMX) + .5) * pSTP), chart.point.from_index(b.i, pLST + (rpVSD.indexof(vdMX) + .5) * pSTP)), false, false, xloc.bar_index, lsC, color(na), line.style_dotted, 1)
dRP.push(box.new(b.i , pLST + (rpVSD.indexof(vdMX) + .0) * pSTP, b.i, pLST + (rpVSD.indexof(vdMX) + 1.) * pSTP, lsC, bgcolor = color.new(lsC, 73) ))
if vpSH and Showprofle
sBI = b.i + (spSH ? rpLN * rpW : 7) + int(rpLN * rpW / 3)
eBI = sBI + int(LpM * rpLN * rpW)
dRP.push(box.new(sBI + vpHO, pLST + (l + .1) * pSTP, eBI + vpHO, pLST + (l + .9) * pSTP, llC, bgcolor = llC,
text = str.tostring(vpSRC == 'Money Flow' ? array.get(rpVST, l) : array.get(rpVST, l) * (pLST + (l + .5) * pSTP), format.volume) + ' ' +
syminfo.currency + ' (' + str.tostring(math.abs(vtLV / rpVST.sum() * 100), '#.##') + '%)',
text_halign = text.align_left, text_color = chart.fg_color, text_size = vpS ))
if spSH and Showprofle
sBI = b.i + rpLN * rpW
eBI = sBI - int(DpM * rpLN * rpW)
dRP.push(box.new(sBI + vpHO, pLST + (l + .1) * pSTP, eBI + vpHO, pLST + (l + .9) * pSTP, lsC, bgcolor = lsC,
text = str.tostring(bbp, format.volume ) + (vpSRC == 'Money Flow' ? ' ' + syminfo.currency : '') +
' (' + str.tostring(math.abs(bbp / vtLV * 100), '#.##') + '%)',
text_halign = text.align_right, text_color = chart.fg_color, text_size = vpS ))
if hmSH and Showprofle
dRP.push(box.new(b.i , pLST + (l + .0) * pSTP, b.i, pLST + (l + 1.) * pSTP, hmSRC == hmSO1 ? color.new(llC, hmTR) : lsC, bgcolor = hmSRC == hmSO1 ? color.new(llC, hmTR) : lsC))
//---------------------------------------------------------------------------------------------------------------------}
//---------------------------------------------------------------------------------------------------------------------}
//---------------------------------------------------------------------------------------------------------------------}
//---------------------------------------------------------------------------------------------------------------------}
//---------------------------------------------------------------------------------------------------------------------}
//---------------------------------------------------------------------------------------------------------------------}
showRevBands = input.bool(true, "Show Reversal Bands", group='Indicator option')
lenRevBands = input.int(30, "Length", group="REVERSAL BANDS")
f_kc(src, len, sensitivity) =>
basis = ta.sma(src, len)
span = ta.atr(len)
= f_kc(close, lenRevBands, 3)
= f_kc(close, lenRevBands, 4)
= f_kc(close, lenRevBands, 5)
= f_kc(close, lenRevBands, 6)
cyan = #00DBFF, cyan30 = color.new(cyan, 100)
pink = #b2b5be, pink30 = color.new(pink, 100)
red = #b2b5be, red30 = color.new(red , 100)
up1 = plot(showRevBands ? upperKC1 : na, "Rev.Zone Upper 1", red30, display = display.none)
up2 = plot(showRevBands ? upperKC2 : na, "Rev.Zone Upper 2", red30, display = display.none)
up3 = plot(showRevBands ? upperKC3 : na, "Rev.Zone Upper 3", red30, display = display.none)
//plot(showRevBands ? upperKC4 : na, "Rev.Zone Upper 4", red30)
//plot(showRevBands ? lowerKC4 : na, "Rev.Zone Lower 4", cyan30)
dn1 = plot(showRevBands ? lowerKC3 : na, "Rev.Zone Lower 3", cyan30, display = display.none)
dn2 = plot(showRevBands ? lowerKC2 : na, "Rev.Zone Lower 2", cyan30, display = display.none)
dn3 = plot(showRevBands ? lowerKC1 : na, "Rev.Zone Lower 1", cyan30, display = display.none)
fill(up1, up2, color = color.new(#f23645, 80))
fill(up2, up3, color = color.new(#f23645, 50))
fill(dn1, dn2, color = color.new(#089981, 50))
fill(dn2, dn3, color = color.new(#089981, 80))
//---------------------------------------------------------------------------------------------------------------------}
//CONSTANTS & STRINGS & INPUTS
//---------------------------------------------------------------------------------------------------------------------{
BULLISH_LEG = 1
BEARISH_LEG = 0
BULLISH = +1
BEARISH = -1
GREEN = #089981
RED = #F23645
BLUE = #2157f3
GRAY = #878b94
MONO_BULLISH = #b2b5be
MONO_BEARISH = #5d606b
HISTORICAL = 'Historical'
PRESENT = 'Present'
COLORED = 'Colored'
MONOCHROME = 'Monochrome'
ALL = 'All'
BOS = 'BOS'
CHOCH = 'CHoCH'
TINY = size.tiny
SMALL = size.small
NORMAL = size.normal
ATR = 'Atr'
RANGE = 'Cumulative Mean Range'
CLOSE = 'Close'
HIGHLOW = 'High/Low'
SOLID = '⎯⎯⎯'
DASHED = '----'
DOTTED = '····'
SMART_GROUP = 'Smart Money Concepts'
INTERNAL_GROUP = 'Real Time Internal Structure'
SWING_GROUP = 'Real Time Swing Structure'
BLOCKS_GROUP = 'Order Blocks'
EQUAL_GROUP = 'EQH/EQL'
GAPS_GROUP = 'Fair Value Gaps'
LEVELS_GROUP = 'Highs & Lows MTF'
ZONES_GROUP = 'Premium & Discount Zones'
modeTooltip = 'Allows to display historical Structure or only the recent ones'
styleTooltip = 'Indicator color theme'
showTrendTooltip = 'Display additional candles with a color reflecting the current trend detected by structure'
showInternalsTooltip = 'Display internal market structure'
internalFilterConfluenceTooltip = 'Filter non significant internal structure breakouts'
showStructureTooltip = 'Display swing market Structure'
showSwingsTooltip = 'Display swing point as labels on the chart'
showHighLowSwingsTooltip = 'Highlight most recent strong and weak high/low points on the chart'
showInternalOrderBlocksTooltip = 'Display internal order blocks on the chart Number of internal order blocks to display on the chart'
showSwingOrderBlocksTooltip = 'Display swing order blocks on the chart Number of internal swing blocks to display on the chart'
orderBlockFilterTooltip = 'Method used to filter out volatile order blocks It is recommended to use the cumulative mean range method when a low amount of data is available'
orderBlockMitigationTooltip = 'Select what values to use for order block mitigation'
showEqualHighsLowsTooltip = 'Display equal highs and equal lows on the chart'
equalHighsLowsLengthTooltip = 'Number of bars used to confirm equal highs and equal lows'
equalHighsLowsThresholdTooltip = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows Lower values will return fewer but more pertinent results'
showPremiumDiscountZonesTooltip = 'Display premium, discount, and equilibrium zones on chart'
modeInput = input.string( HISTORICAL, 'Mode', group = SMART_GROUP, tooltip = modeTooltip, options = )
styleInput = input.string( COLORED, 'Style', group = SMART_GROUP, tooltip = styleTooltip,options = )
showTrendInput = input( false, 'Color Candles', group = SMART_GROUP, tooltip = showTrendTooltip)
showInternalsInput = input( true, 'Show Internal Structure', group = INTERNAL_GROUP, tooltip = showInternalsTooltip)
showInternalBullInput = input.string( ALL, 'Bullish Structure', group = INTERNAL_GROUP, inline = 'ibull', options = )
internalBullColorInput = input( GREEN, '', group = INTERNAL_GROUP, inline = 'ibull')
showInternalBearInput = input.string( ALL, 'Bearish Structure' , group = INTERNAL_GROUP, inline = 'ibear', options = )
internalBearColorInput = input( RED, '', group = INTERNAL_GROUP, inline = 'ibear')
internalFilterConfluenceInput = input( false, 'Confluence Filter', group = INTERNAL_GROUP, tooltip = internalFilterConfluenceTooltip)
internalStructureSize = input.string( TINY, 'Internal Label Size', group = INTERNAL_GROUP, options = )
showStructureInput = input( true, 'Show Swing Structure', group = SWING_GROUP, tooltip = showStructureTooltip)
showSwingBullInput = input.string( ALL, 'Bullish Structure', group = SWING_GROUP, inline = 'bull', options = )
swingBullColorInput = input( GREEN, '', group = SWING_GROUP, inline = 'bull')
showSwingBearInput = input.string( ALL, 'Bearish Structure', group = SWING_GROUP, inline = 'bear', options = )
swingBearColorInput = input( RED, '', group = SWING_GROUP, inline = 'bear')
swingStructureSize = input.string( SMALL, 'Swing Label Size', group = SWING_GROUP, options = )
showSwingsInput = input( false, 'Show Swings Points', group = SWING_GROUP, tooltip = showSwingsTooltip,inline = 'swings')
swingsLengthInput = input.int( 50, '', group = SWING_GROUP, minval = 10, inline = 'swings')
showHighLowSwingsInput = input( false, 'Show Strong/Weak High/Low',group = SWING_GROUP, tooltip = showHighLowSwingsTooltip)
orderBlockFilterInput = input.string( 'Atr', 'Order Block Filter', group = BLOCKS_GROUP, tooltip = orderBlockFilterTooltip, options = )
showEqualHighsLowsInput = input( false, 'Equal High/Low', group = EQUAL_GROUP, tooltip = showEqualHighsLowsTooltip)
equalHighsLowsLengthInput = input.int( 3, 'Bars Confirmation', group = EQUAL_GROUP, tooltip = equalHighsLowsLengthTooltip, minval = 1)
equalHighsLowsThresholdInput = input.float( 0.1, 'Threshold', group = EQUAL_GROUP, tooltip = equalHighsLowsThresholdTooltip, minval = 0, maxval = 0.5, step = 0.1)
equalHighsLowsSizeInput = input.string( TINY, 'Label Size', group = EQUAL_GROUP, options = )
showDailyLevelsInput = input( false, 'Daily', group = LEVELS_GROUP, inline = 'daily')
dailyLevelsStyleInput = input.string( SOLID, '', group = LEVELS_GROUP, inline = 'daily', options = )
dailyLevelsColorInput = input( BLUE, '', group = LEVELS_GROUP, inline = 'daily')
showWeeklyLevelsInput = input( false, 'Weekly', group = LEVELS_GROUP, inline = 'weekly')
weeklyLevelsStyleInput = input.string( SOLID, '', group = LEVELS_GROUP, inline = 'weekly', options = )
weeklyLevelsColorInput = input( BLUE, '', group = LEVELS_GROUP, inline = 'weekly')
showMonthlyLevelsInput = input( false, 'Monthly', group = LEVELS_GROUP, inline = 'monthly')
monthlyLevelsStyleInput = input.string( SOLID, '', group = LEVELS_GROUP, inline = 'monthly', options = )
monthlyLevelsColorInput = input( BLUE, '', group = LEVELS_GROUP, inline = 'monthly')
showPremiumDiscountZonesInput = input( false, 'Premium/Discount Zones', group = ZONES_GROUP , tooltip = showPremiumDiscountZonesTooltip)
premiumZoneColorInput = input.color( RED, 'Premium Zone', group = ZONES_GROUP)
equilibriumZoneColorInput = input.color( GRAY, 'Equilibrium Zone', group = ZONES_GROUP)
discountZoneColorInput = input.color( GREEN, 'Discount Zone', group = ZONES_GROUP)
//---------------------------------------------------------------------------------------------------------------------}
//DATA STRUCTURES & VARIABLES
//---------------------------------------------------------------------------------------------------------------------{
// @type UDT representing alerts as bool fields
// @field internalBullishBOS internal structure custom alert
// @field internalBearishBOS internal structure custom alert
// @field internalBullishCHoCH internal structure custom alert
// @field internalBearishCHoCH internal structure custom alert
// @field swingBullishBOS swing structure custom alert
// @field swingBearishBOS swing structure custom alert
// @field swingBullishCHoCH swing structure custom alert
// @field swingBearishCHoCH swing structure custom alert
// @field internalBullishOrderBlock internal order block custom alert
// @field internalBearishOrderBlock internal order block custom alert
// @field swingBullishOrderBlock swing order block custom alert
// @field swingBearishOrderBlock swing order block custom alert
// @field equalHighs equal high low custom alert
// @field equalLows equal high low custom alert
// @field bullishFairValueGap fair value gap custom alert
// @field bearishFairValueGap fair value gap custom alert
type alerts
bool internalBullishBOS = false
bool internalBearishBOS = false
bool internalBullishCHoCH = false
bool internalBearishCHoCH = false
bool swingBullishBOS = false
bool swingBearishBOS = false
bool swingBullishCHoCH = false
bool swingBearishCHoCH = false
bool internalBullishOrderBlock = false
bool internalBearishOrderBlock = false
bool swingBullishOrderBlock = false
bool swingBearishOrderBlock = false
bool equalHighs = false
bool equalLows = false
bool bullishFairValueGap = false
bool bearishFairValueGap = false
bool chochswing = false
bool chochplusswing = false
bool swingbos = false
bool chochplus = false
bool choch = false
bool bos = false
bool ob = false
bool swingob = false
bool obtouch = false
// @type UDT representing last swing extremes (top & bottom)
// @field top last top swing price
// @field bottom last bottom swing price
// @field barTime last swing bar time
// @field barIndex last swing bar index
// @field lastTopTime last top swing time
// @field lastBottomTime last bottom swing time
type trailingExtremes
float top
float bottom
int barTime
int barIndex
int lastTopTime
int lastBottomTime
// @type UDT representing trend bias
// @field bias BULLISH or BEARISH
type trend
int bias
// @type UDT representing Equal Highs Lows display
// @field l_ine displayed line
// @field l_abel displayed label
type equalDisplay
line l_ine = na
label l_abel = na
// @type UDT representing a pivot point (swing point)
// @field currentLevel current price level
// @field lastLevel last price level
// @field crossed true if price level is crossed
// @field barTime bar time
// @field barIndex bar index
type pivot
float currentLevel
float lastLevel
bool crossed
int barTime = time
int barIndex = bar_index
// @type UDT representing an order block
// @field barHigh bar high
// @field barLow bar low
// @field barTime bar time
// @field bias BULLISH or BEARISH
type orderBlock
float barHigh
float barLow
int barTime
int bias
// @variable current swing pivot high
var pivot swingHigh = pivot.new(na,na,false)
// @variable current swing pivot low
var pivot swingLow = pivot.new(na,na,false)
// @variable current internal pivot high
var pivot internalHigh = pivot.new(na,na,false)
// @variable current internal pivot low
var pivot internalLow = pivot.new(na,na,false)
// @variable current equal high pivot
var pivot equalHigh = pivot.new(na,na,false)
// @variable current equal low pivot
var pivot equalLow = pivot.new(na,na,false)
// @variable swing trend bias
var trend swingTrend = trend.new(0)
// @variable internal trend bias
var trend internalTrend = trend.new(0)
// @variable equal high display
var equalDisplay equalHighDisplay = equalDisplay.new()
// @variable equal low display
var equalDisplay equalLowDisplay = equalDisplay.new()
// @variable storage for parsed highs
var array parsedHighs = array.new()
// @variable storage for parsed lows
var array parsedLows = array.new()
// @variable storage for raw highs
var array highs = array.new()
// @variable storage for raw lows
var array lows = array.new()
// @variable storage for bar time values
var array times = array.new()
// @variable last trailing swing high and low
var trailingExtremes trailing = trailingExtremes.new()
// @variable color for swing bullish structures
var swingBullishColor = styleInput == MONOCHROME ? MONO_BULLISH : swingBullColorInput
// @variable color for swing bearish structures
var swingBearishColor = styleInput == MONOCHROME ? MONO_BEARISH : swingBearColorInput
// @variable color for premium zone
var premiumZoneColor = styleInput == MONOCHROME ? MONO_BEARISH : premiumZoneColorInput
// @variable color for discount zone
var discountZoneColor = styleInput == MONOCHROME ? MONO_BULLISH : discountZoneColorInput
// @variable bar index on current script iteration
varip int currentBarIndex = bar_index
// @variable bar index on last script iteration
varip int lastBarIndex = bar_index
// @variable alerts in current bar
alerts currentAlerts = alerts.new()
// @variable time at start of chart
var initialTime = time
// @variable default volatility measure
atrMeasure = ta.atr(200)
// @variable parsed volatility measure by user settings
volatilityMeasure = orderBlockFilterInput == ATR ? atrMeasure : ta.cum(ta.tr)/bar_index
// @variable true if current bar is a high volatility bar
highVolatilityBar = (high - low) >= (2 * volatilityMeasure)
// @variable parsed high
parsedHigh = highVolatilityBar ? low : high
// @variable parsed low
parsedLow = highVolatilityBar ? high : low
// we store current values into the arrays at each bar
parsedHighs.push(parsedHigh)
parsedLows.push(parsedLow)
highs.push(high)
lows.push(low)
times.push(time)
//---------------------------------------------------------------------------------------------------------------------}
//USER-DEFINED FUNCTIONS
//---------------------------------------------------------------------------------------------------------------------{
// @function Get the value of the current leg, it can be 0 (bearish) or 1 (bullish)
// @returns int
leg(int size) =>
var leg = 0
newLegHigh = high > ta.highest( size)
newLegLow = low < ta.lowest( size)
if newLegHigh
leg := BEARISH_LEG
else if newLegLow
leg := BULLISH_LEG
leg
// @function Identify whether the current value is the start of a new leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfNewLeg(int leg) => ta.change(leg) != 0
// @function Identify whether the current level is the start of a new bearish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBearishLeg(int leg) => ta.change(leg) == -1
// @function Identify whether the current level is the start of a new bullish leg (swing)
// @param leg (int) Current leg value
// @returns bool
startOfBullishLeg(int leg) => ta.change(leg) == +1
// @function create a new label
// @param labelTime bar time coordinate
// @param labelPrice price coordinate
// @param tag text to display
// @param labelColor text color
// @param labelStyle label style
// @returns label ID
drawLabel(int labelTime, float labelPrice, string tag, color labelColor, string labelStyle) =>
var label l_abel = na
if modeInput == PRESENT
l_abel.delete()
l_abel := label.new(chart.point.new(labelTime,na,labelPrice),tag,xloc.bar_time,color=color(na),textcolor=labelColor,style = labelStyle,size = size.small)
// @function create a new line and label representing an EQH or EQL
// @param p_ivot starting pivot
// @param level price level of current pivot
// @param size how many bars ago was the current pivot detected
// @param equalHigh true for EQH, false for EQL
// @returns label ID
drawEqualHighLow(pivot p_ivot, float level, int size, bool equalHigh) =>
equalDisplay e_qualDisplay = equalHigh ? equalHighDisplay : equalLowDisplay
string tag = 'EQL'
color equalColor = swingBullishColor
string labelStyle = label.style_label_up
if equalHigh
tag := 'EQH'
equalColor := swingBearishColor
labelStyle := label.style_label_down
if modeInput == PRESENT
line.delete( e_qualDisplay.l_ine)
label.delete( e_qualDisplay.l_abel)
e_qualDisplay.l_ine := line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel), chart.point.new(time ,na,level), xloc = xloc.bar_time, color = equalColor, style = line.style_dotted)
labelPosition = math.round(0.5*(p_ivot.barIndex + bar_index - size))
e_qualDisplay.l_abel := label.new(chart.point.new(na,labelPosition,level), tag, xloc.bar_index, color = color(na), textcolor = equalColor, style = labelStyle, size = equalHighsLowsSizeInput)
// @function store current structure and trailing swing points, and also display swing points and equal highs/lows
// @param size (int) structure size
// @param equalHighLow (bool) true for displaying current highs/lows
// @param internal (bool) true for getting internal structures
// @returns label ID
getCurrentStructure(int size,bool equalHighLow = false, bool internal = false) =>
currentLeg = leg(size)
newPivot = startOfNewLeg(currentLeg)
pivotLow = startOfBullishLeg(currentLeg)
pivotHigh = startOfBearishLeg(currentLeg)
if newPivot
if pivotLow
pivot p_ivot = equalHighLow ? equalLow : internal ? internalLow : swingLow
if equalHighLow and math.abs(p_ivot.currentLevel - low ) < equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot, low , size, false)
p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := low
p_ivot.crossed := false
p_ivot.barTime := time
p_ivot.barIndex := bar_index
if not equalHighLow and not internal
trailing.bottom := p_ivot.currentLevel
trailing.barTime := p_ivot.barTime
trailing.barIndex := p_ivot.barIndex
trailing.lastBottomTime := p_ivot.barTime
if showSwingsInput and not internal and not equalHighLow
drawLabel(time , p_ivot.currentLevel, p_ivot.currentLevel < p_ivot.lastLevel ? 'LL' : 'HL', swingBullishColor, label.style_label_up)
else
pivot p_ivot = equalHighLow ? equalHigh : internal ? internalHigh : swingHigh
if equalHighLow and math.abs(p_ivot.currentLevel - high ) < equalHighsLowsThresholdInput * atrMeasure
drawEqualHighLow(p_ivot,high ,size,true)
p_ivot.lastLevel := p_ivot.currentLevel
p_ivot.currentLevel := high
p_ivot.crossed := false
p_ivot.barTime := time
p_ivot.barIndex := bar_index
if not equalHighLow and not internal
trailing.top := p_ivot.currentLevel
trailing.barTime := p_ivot.barTime
trailing.barIndex := p_ivot.barIndex
trailing.lastTopTime := p_ivot.barTime
if showSwingsInput and not internal and not equalHighLow
drawLabel(time , p_ivot.currentLevel, p_ivot.currentLevel > p_ivot.lastLevel ? 'HH' : 'LH', swingBearishColor, label.style_label_down)
// @function draw line and label representing a structure
// @param p_ivot base pivot point
// @param tag test to display
// @param structureColor base color
// @param lineStyle line style
// @param labelStyle label style
// @param labelSize text size
// @returns label ID
drawStructure(pivot p_ivot, string tag, color structureColor, string lineStyle, string labelStyle, string labelSize) =>
var line l_ine = line.new(na,na,na,na,xloc = xloc.bar_time)
var label l_abel = label.new(na,na)
if modeInput == PRESENT
l_ine.delete()
l_abel.delete()
l_ine := line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel), chart.point.new(time,na,p_ivot.currentLevel), xloc.bar_time, color=structureColor, style=lineStyle)
l_abel := label.new(chart.point.new(na,math.round(0.5*(p_ivot.barIndex+bar_index)),p_ivot.currentLevel), tag, xloc.bar_index, color=color(na), textcolor=structureColor, style=labelStyle, size = labelSize)
// @function delete order blocks
// @param internal true for internal order blocks
// @returns orderBlock ID
// @function fetch and store order blocks
// @param p_ivot base pivot point
// @param internal true for internal order blocks
// @param bias BULLISH or BEARISH
// @returns void
// @function draw order blocks as boxes
// @param internal true for internal order blocks
// @returns void
// @function detect and draw structures, also detect and store order blocks
// @param internal true for internal structures or order blocks
// @returns void
displayStructure(bool internal = false) =>
var bullishBar = true
var bearishBar = true
if internalFilterConfluenceInput
bullishBar := high - math.max(close, open) > math.min(close, open - low)
bearishBar := high - math.max(close, open) < math.min(close, open - low)
pivot p_ivot = internal ? internalHigh : swingHigh
trend t_rend = internal ? internalTrend : swingTrend
lineStyle = internal ? line.style_dashed : line.style_solid
labelSize = internal ? internalStructureSize : swingStructureSize
extraCondition = internal ? internalHigh.currentLevel != swingHigh.currentLevel and bullishBar : true
bullishColor = styleInput == MONOCHROME ? MONO_BULLISH : internal ? internalBullColorInput : swingBullColorInput
if ta.crossover(close,p_ivot.currentLevel) and not p_ivot.crossed and extraCondition
string tag = t_rend.bias == BEARISH ? CHOCH : BOS
if internal
currentAlerts.internalBullishCHoCH := tag == CHOCH
currentAlerts.internalBullishBOS := tag == BOS
else
currentAlerts.swingBullishCHoCH := tag == CHOCH
currentAlerts.swingBullishBOS := tag == BOS
p_ivot.crossed := true
t_rend.bias := BULLISH
displayCondition = internal ? showInternalsInput and (showInternalBullInput == ALL or (showInternalBullInput == BOS and tag != CHOCH) or (showInternalBullInput == CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBullInput == ALL or (showSwingBullInput == BOS and tag != CHOCH) or (showSwingBullInput == CHOCH and tag == CHOCH))
if displayCondition
drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down,labelSize)
p_ivot := internal ? internalLow : swingLow
extraCondition := internal ? internalLow.currentLevel != swingLow.currentLevel and bearishBar : true
bearishColor = styleInput == MONOCHROME ? MONO_BEARISH : internal ? internalBearColorInput : swingBearColorInput
if ta.crossunder(close,p_ivot.currentLevel) and not p_ivot.crossed and extraCondition
string tag = t_rend.bias == BULLISH ? CHOCH : BOS
if internal
currentAlerts.internalBearishCHoCH := tag == CHOCH
currentAlerts.internalBearishBOS := tag == BOS
else
currentAlerts.swingBearishCHoCH := tag == CHOCH
currentAlerts.swingBearishBOS := tag == BOS
p_ivot.crossed := true
t_rend.bias := BEARISH
displayCondition = internal ? showInternalsInput and (showInternalBearInput == ALL or (showInternalBearInput == BOS and tag != CHOCH) or (showInternalBearInput == CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBearInput == ALL or (showSwingBearInput == BOS and tag != CHOCH) or (showSwingBearInput == CHOCH and tag == CHOCH))
if displayCondition
drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,labelSize)
// @function get line style from string
// @param style line style
// @returns string
getStyle(string style) =>
switch style
SOLID => line.style_solid
DASHED => line.style_dashed
DOTTED => line.style_dotted
// @function draw MultiTimeFrame levels
// @param timeframe base timeframe
// @param sameTimeframe true if chart timeframe is same as base timeframe
// @param style line style
// @param levelColor line and text color
// @returns void
drawLevels(string timeframe, bool sameTimeframe, string style, color levelColor) =>
= request.security(syminfo.tickerid, timeframe, [high , low , time , time],lookahead = barmerge.lookahead_on)
float parsedTop = sameTimeframe ? high : topLevel
float parsedBottom = sameTimeframe ? low : bottomLevel
int parsedLeftTime = sameTimeframe ? time : leftTime
int parsedRightTime = sameTimeframe ? time : rightTime
int parsedTopTime = time
int parsedBottomTime = time
if not sameTimeframe
int leftIndex = times.binary_search_rightmost(parsedLeftTime)
int rightIndex = times.binary_search_rightmost(parsedRightTime)
array timeArray = times.slice(leftIndex,rightIndex)
array topArray = highs.slice(leftIndex,rightIndex)
array bottomArray = lows.slice(leftIndex,rightIndex)
parsedTopTime := timeArray.size() > 0 ? timeArray.get(topArray.indexof(topArray.max())) : initialTime
parsedBottomTime := timeArray.size() > 0 ? timeArray.get(bottomArray.indexof(bottomArray.min())) : initialTime
var line topLine = line.new(na, na, na, na, xloc = xloc.bar_time, color = levelColor, style = getStyle(style))
var line bottomLine = line.new(na, na, na, na, xloc = xloc.bar_time, color = levelColor, style = getStyle(style))
var label topLabel = label.new(na, na, xloc = xloc.bar_time, text = str.format('P{0}H',timeframe), color=color(na), textcolor = levelColor, size = size.small, style = label.style_label_left)
var label bottomLabel = label.new(na, na, xloc = xloc.bar_time, text = str.format('P{0}L',timeframe), color=color(na), textcolor = levelColor, size = size.small, style = label.style_label_left)
topLine.set_first_point( chart.point.new(parsedTopTime,na,parsedTop))
topLine.set_second_point( chart.point.new(last_bar_time + 20 * (time-time ),na,parsedTop))
topLabel.set_point( chart.point.new(last_bar_time + 20 * (time-time ),na,parsedTop))
bottomLine.set_first_point( chart.point.new(parsedBottomTime,na,parsedBottom))
bottomLine.set_second_point(chart.point.new(last_bar_time + 20 * (time-time ),na,parsedBottom))
bottomLabel.set_point( chart.point.new(last_bar_time + 20 * (time-time ),na,parsedBottom))
// @function true if chart timeframe is higher than provided timeframe
// @param timeframe timeframe to check
// @returns bool
higherTimeframe(string timeframe) => timeframe.in_seconds() > timeframe.in_seconds(timeframe)
// @function update trailing swing points
// @returns int
updateTrailingExtremes() =>
trailing.top := math.max(high,trailing.top)
trailing.lastTopTime := trailing.top == high ? time : trailing.lastTopTime
trailing.bottom := math.min(low,trailing.bottom)
trailing.lastBottomTime := trailing.bottom == low ? time : trailing.lastBottomTime
// @function draw trailing swing points
// @returns void
drawHighLowSwings() =>
var line topLine = line.new(na, na, na, na, color = swingBearishColor, xloc = xloc.bar_time)
var line bottomLine = line.new(na, na, na, na, color = swingBullishColor, xloc = xloc.bar_time)
var label topLabel = label.new(na, na, color=color(na), textcolor = swingBearishColor, xloc = xloc.bar_time, style = label.style_label_down, size = size.tiny)
var label bottomLabel = label.new(na, na, color=color(na), textcolor = swingBullishColor, xloc = xloc.bar_time, style = label.style_label_up, size = size.tiny)
rightTimeBar = last_bar_time + 20 * (time - time )
topLine.set_first_point( chart.point.new(trailing.lastTopTime, na, trailing.top))
topLine.set_second_point( chart.point.new(rightTimeBar, na, trailing.top))
topLabel.set_point( chart.point.new(rightTimeBar, na, trailing.top))
topLabel.set_text( swingTrend.bias == BEARISH ? 'Strong High' : 'Weak High')
bottomLine.set_first_point( chart.point.new(trailing.lastBottomTime, na, trailing.bottom))
bottomLine.set_second_point(chart.point.new(rightTimeBar, na, trailing.bottom))
bottomLabel.set_point( chart.point.new(rightTimeBar, na, trailing.bottom))
bottomLabel.set_text( swingTrend.bias == BULLISH ? 'Strong Low' : 'Weak Low')
// @function draw a zone with a label and a box
// @param labelLevel price level for label
// @param labelIndex bar index for label
// @param top top price level for box
// @param bottom bottom price level for box
// @param tag text to display
// @param zoneColor base color
// @param style label style
// @returns void
drawZone(float labelLevel, int labelIndex, float top, float bottom, string tag, color zoneColor, string style) =>
var label l_abel = label.new(na,na,text = tag, color=color(na),textcolor = zoneColor, style = style, size = size.small)
var box b_ox = box.new(na,na,na,na,bgcolor = color.new(zoneColor,80),border_color = color(na), xloc = xloc.bar_time)
b_ox.set_top_left_point( chart.point.new(trailing.barTime,na,top))
b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,bottom))
l_abel.set_point( chart.point.new(na,labelIndex,labelLevel))
// @function draw premium/discount zones
// @returns void
drawPremiumDiscountZones() =>
drawZone(trailing.top, math.round(0.5*(trailing.barIndex + last_bar_index)), trailing.top, 0.95*trailing.top + 0.05*trailing.bottom, 'Premium', premiumZoneColor, label.style_label_down)
equilibriumLevel = math.avg(trailing.top, trailing.bottom)
drawZone(equilibriumLevel, last_bar_index, 0.525*trailing.top + 0.475*trailing.bottom, 0.525*trailing.bottom + 0.475*trailing.top, 'Equilibrium', equilibriumZoneColorInput, label.style_label_left)
drawZone(trailing.bottom, math.round(0.5*(trailing.barIndex + last_bar_index)), 0.95*trailing.bottom + 0.05*trailing.top, trailing.bottom, 'Discount', discountZoneColor, label.style_label_up)
//---------------------------------------------------------------------------------------------------------------------}
//MUTABLE VARIABLES & EXECUTION
//---------------------------------------------------------------------------------------------------------------------{
parsedOpen = showTrendInput ? open : na
candleColor = internalTrend.bias == BULLISH ? swingBullishColor : swingBearishColor
plotcandle(parsedOpen,high,low,close,color = candleColor, wickcolor = candleColor, bordercolor = candleColor)
if showHighLowSwingsInput or showPremiumDiscountZonesInput
updateTrailingExtremes()
if showHighLowSwingsInput
drawHighLowSwings()
if showPremiumDiscountZonesInput
drawPremiumDiscountZones()
getCurrentStructure(swingsLengthInput,false)
getCurrentStructure(5,false,true)
if showEqualHighsLowsInput
getCurrentStructure(equalHighsLowsLengthInput,true)
if showInternalsInput or showTrendInput
displayStructure(true)
if showStructureInput or showHighLowSwingsInput
displayStructure()
lastBarIndex := currentBarIndex
currentBarIndex := bar_index
newBar = currentBarIndex != lastBarIndex
if barstate.islastconfirmedhistory or (barstate.isrealtime and newBar)
if showDailyLevelsInput and not higherTimeframe('D')
drawLevels('D',timeframe.isdaily,dailyLevelsStyleInput,dailyLevelsColorInput)
if showWeeklyLevelsInput and not higherTimeframe('W')
drawLevels('W',timeframe.isweekly,weeklyLevelsStyleInput,weeklyLevelsColorInput)
if showMonthlyLevelsInput and not higherTimeframe('M')
drawLevels('M',timeframe.ismonthly,monthlyLevelsStyleInput,monthlyLevelsColorInput)
//---------------------------------------------------------------------------------------------------------------------}
//ALERTS
//---------------------------------------------------------------------------------------------------------------------{
alertcondition(currentAlerts.internalBullishBOS, 'Internal Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(currentAlerts.internalBullishCHoCH, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(currentAlerts.internalBearishBOS, 'Internal Bearish BOS', 'Internal Bearish BOS formed')
alertcondition(currentAlerts.internalBearishCHoCH, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed')
alertcondition(currentAlerts.swingBullishBOS, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(currentAlerts.swingBullishCHoCH, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(currentAlerts.swingBearishBOS, 'Bearish BOS', 'Bearish BOS formed')
alertcondition(currentAlerts.swingBearishCHoCH, 'Bearish CHoCH', 'Bearish CHoCH formed')
alertcondition(currentAlerts.equalHighs, 'Equal Highs', 'Equal highs detected')
alertcondition(currentAlerts.equalLows, 'Equal Lows', 'Equal lows detected')
//---------------------------------------------------------------------------------------------------------------------}
//-----------------------------------------------------------------------------
// Input Settings
//-----------------------------------------------------------------------------
i_3 = "FVGs represent price areas where a significant gap occurred between two trading sessions, indicating a potential continuation or reversal point."
//----------------------------------------
// Order Blocks
//----------------------------------------
var_ob_13 = (time - time ) / 100
//----------------------------------------
// Constants
color CLEAR = color.rgb(0, 0, 0, 100)
//----------------------------------------
// Fair Value Gaps (FVG)
//----------------------------------------
in_fvg_1 = input(true, "Fair Value Gaps (FVG)", group="Fair Value Gaps", inline="fvg_css", tooltip = i_3)
in_fvg_2 = input.timeframe("", "Timeframe", group="Fair Value Gaps", inline="tf")
in_fvg_op = input.int(defval=12, title="Opacity %", minval=0, maxval=100, group="Fair Value Gaps", inline="tf")
in_fvg_3 = input.float(2, "Max Width", minval=0, maxval=5.0, step=0.1, group="Fair Value Gaps", inline="width")
in_fvg_4 = input.bool(false, "Filter FVG", group="Fair Value Gaps", inline="width")
in_fvg_5 = input.string("Close", "Mitigation Method", options= , group="Fair Value Gaps", inline="mt")
in_fvg_6 = input.bool(true, "Fill", group="Fair Value Gaps", inline="mt")
in_fvg_7 = input.bool(false, "Shade", group="Fair Value Gaps", inline="mt")
in_fvg_8 = input.int(defval=8, title="Max FVG", minval=0, maxval=50, group="Fair Value Gaps", inline="OS")
in_fvg_9 = input.int(defval=17, title="Length", minval=0, maxval=100, group="Fair Value Gaps", inline="OS")
in_fvg_10 = input.bool(false, "Extend", group="Fair Value Gaps", inline="OS")
in_fvg_11 = input.color(color.new(#089981, 88), "", group="Fair Value Gaps", inline="fvg_css")
in_fvg_12 = input.color(color.new(#f23645, 88), "", group="Fair Value Gaps", inline="fvg_css")
mid_line_show = input.string("On", " Mid Line", , group="Fair Value Gaps", inline="mid")
in_fvg_13 = input.string("Solid", " Style", , group="Fair Value Gaps", inline="mid")
in_fvg_14 = input.color(#089981, "", group="Fair Value Gaps", inline="mid")
in_fvg_14_2 = input.color(#f23645, "", group="Fair Value Gaps", inline="mid")
in_fvg_16 = input.int(defval=1, title="Line Width", minval=1, maxval=5, group="Fair Value Gaps", inline="mid_w")
in_fvg_15 = input.bool(false, "Extend (Current)", group="Fair Value Gaps", inline="mid_w")
var_fvg_1 = color.new(color.green, 100)
var_fvg_2 = color.new(color.green, 90)
var_fvg_3 = true
var_fvg_4 = true
var_fvg_5 = color.white
var_fvg_6 = "HTF"
var_fvg_7 = 10
var_fvg_8 = 50
in_fvg_op := 100 - in_fvg_op
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
color transparent = #ffffff00
custom_func_1(res) =>
t = time(res)
not na(t) and (na(t ) or t > t )
custom_func_2(x, y, txt, css, dashed, down, lbl_size) =>
label.new(int(math.avg(x, bar_index)), y, txt, color=transparent, textcolor=css, style=down ? label.style_label_down : label.style_label_up, size=lbl_size)
line.new(x, y, bar_index, y, color=css, style=dashed ? line.style_dotted : line.style_solid)
custom_func_3(_cond, _count) =>
_barssince = bar_index - ta.valuewhen(_cond, bar_index, _count)
_barssince
// Swing Detection/Measurements
custom_func_4(length) =>
var prev = 0
prev := high > ta.highest(length) ? 0 : low < ta.lowest(length) ? 1 : prev
t = prev == 0 and prev != 0 ? high : 0
b = prev == 1 and prev != 1 ? low : 0
var variable_ms_1 = 0, var variable_ms_2 = 0
var variable_ms_3 = 0., var variable_ms_4 = 0, var variable_ms_5 = 0., var variable_ms_6 = 0
var variable_ms_7 = 0., var variable_ms_8 = 0, var variable_ms_9 = 0., var variable_ms_10 = 0
var variable_ms_11 = true, var variable_ms_12 = true
var variable_ms_13 = true, var variable_ms_14 = true
var variable_ms_15 = high, var variable_ms_16 = low
var up_trailing_x = 0, var down_trailing_x = 0
var high_text = "", var low_text = ""
variable_ms_17 = false
variable_ms_18 = false
// Functions
lineStyle(x) =>
switch x
"Solid" => line.style_solid
"Dashed" => line.style_dashed
"Dotted" => line.style_dotted
variable_ms_20 = ta.pivothigh(high, 10, 10)
variable_ms_21 = ta.pivotlow(low, 10, 10)
//-----------------------------------------------------------------------------
// Fair Value Gaps
//-----------------------------------------------------------------------------
// Global Data
var htfH = open
var htfL = open
if close > htfH
htfH := close
if close < htfL
htfL := close
// Security Data, used for HTF Bar Data reference
sClose = request.security(ticker.standard(syminfo.tickerid), in_fvg_2, close , barmerge.gaps_off, barmerge.lookahead_on)
sHighP2 = request.security(ticker.standard(syminfo.tickerid), in_fvg_2, high , barmerge.gaps_off, barmerge.lookahead_on)
sLowP2 = request.security(ticker.standard(syminfo.tickerid), in_fvg_2, low , barmerge.gaps_off, barmerge.lookahead_on)
sOpen = request.security(ticker.standard(syminfo.tickerid), in_fvg_2, open , barmerge.gaps_off, barmerge.lookahead_on)
sBar = request.security(ticker.standard(syminfo.tickerid), in_fvg_2, bar_index, barmerge.gaps_off, barmerge.lookahead_on)
// Array variables to hold data in memory
var variable_fvg_1 = array.new_box(0)
var variable_fvg_2 = array.new_box(0)
var variable_fvg_3 = array.new_box(0)
var variable_fvg_4 = array.new_box(0)
var variable_fvg_5 = array.new_line(0)
var variable_fvg_6 = array.new_line(0)
var variable_fvg_7 = array.new_line(0)
var variable_fvg_8 = array.new_line(0)
var variable_fvg_9 = array.new_line(0)
var variable_fvg_10 = array.new_line(0)
var variable_fvg_11 = array.new_label(0)
var variable_fvg_12 = array.new_label(0)
var variable_fvg_13 = color.new(color.white, 100)
var variable_fvg_14 = false
var variable_fvg_15 = false
variable_fvg_14 := false
variable_fvg_15 := false
// Functions
custom_func_5(_upperlimit, _lowerlimit, _midlimit, _bar, _boxholder, _boxholder_fill, _midholder, _highholder, _lowholder, _labelholder, _boxcolor, _mtfboxcolor, _htf, line_color_mid) =>
variable_fvg_16 = str.tostring(in_fvg_2)
offset = var_fvg_8
variable_fvg_17 = _mtfboxcolor
bg_color = color.new(_mtfboxcolor, in_fvg_op)
if _htf == false
variable_fvg_16 := str.tostring(timeframe.period)
offset := var_fvg_7
variable_fvg_17 := _boxcolor
array.push(_boxholder, box.new(_bar, _upperlimit, _bar + (var_ob_13) * in_fvg_9, _lowerlimit, border_color= na, bgcolor=in_fvg_6 ? bg_color : na, extend=in_fvg_10 ? extend.right : extend.none, xloc=xloc.bar_time, text="", text_color=#787b86, text_halign=text.align_right, text_size=size.small))
array.push(_boxholder_fill, box.new(_bar, _upperlimit, _bar + (var_ob_13) * in_fvg_9, _lowerlimit, border_color= na, bgcolor=in_fvg_6 ? bg_color : na, extend=in_fvg_10 ? extend.right : extend.none, xloc=xloc.bar_time))
array.push(_midholder, line.new(_bar, (_lowerlimit + _upperlimit) / 2.0, _bar + (var_ob_13) * in_fvg_9, _midlimit, color=mid_line_show == "On" ? line_color_mid : #363a4500, extend=in_fvg_10 ? extend.right : extend.none, style=lineStyle(in_fvg_13), width=in_fvg_16, xloc=xloc.bar_time))
array.push(_lowholder, line.new(_bar, _lowerlimit, _bar + (var_ob_13) * in_fvg_9, _lowerlimit, color=var_fvg_3 ? variable_fvg_17 : na, extend=in_fvg_10 ? extend.right : extend.none, width=1, xloc=xloc.bar_time))
array.push(_highholder, line.new(_bar, _upperlimit, _bar + (var_ob_13) * in_fvg_9, _upperlimit, color=var_fvg_3 ? variable_fvg_17 : na, extend=in_fvg_10 ? extend.right : extend.none, width=1, xloc=xloc.bar_time))
// Checks for gap between current candle and 2 previous candle (Fair Value Gap)
custom_func_6(_close, _high, _highp2, _low, _lowp2, _open, _bar, _htf) =>
gap = 0
thold_ = (ta.highest(_high, 300) - ta.lowest(_low, 300)) * math.max(in_fvg_3, 0.1) / 100.
if _open > _close // Red candle
if _lowp2 > _high
if not (in_fvg_4) or math.abs(_lowp2 - _high) > thold_
upperlimit = _high
lowerlimit = _lowp2
midlimit = lowerlimit + ((upperlimit - lowerlimit) / 2.)
gap := 1
if in_fvg_1
custom_func_5(upperlimit, lowerlimit, midlimit, _bar, variable_fvg_1, variable_fvg_3, variable_fvg_9, variable_fvg_5, variable_fvg_7, variable_fvg_11, var_fvg_1, in_fvg_12, _htf,in_fvg_14_2)
else
if _low > _highp2
if not (in_fvg_4) or math.abs(_low - _highp2) > thold_
upperlimit = _low
lowerlimit = _highp2
midlimit = lowerlimit + ((upperlimit - lowerlimit) / 2.)
gap := -1
if in_fvg_1
custom_func_5(upperlimit, lowerlimit, midlimit, _bar, variable_fvg_2, variable_fvg_4, variable_fvg_10, variable_fvg_6, variable_fvg_8, variable_fvg_12, var_fvg_2, in_fvg_11, _htf,in_fvg_14)
gap
// Removes the gap from its relevant array if it has been filled
custom_func_7(_currentgap, _currentgap_fill, _i, _boxholder, _boxholder_fill, _midholder, _highholder, _lowholder, _labelholder) =>
array.remove(_boxholder, _i)
array.remove(_boxholder_fill, _i)
currentmid = array.get(_midholder, _i)
currenthigh = array.get(_highholder, _i)
currentlow = array.get(_lowholder, _i)
array.remove(_midholder, _i)
array.remove(_highholder, _i)
array.remove(_lowholder, _i)
if var_fvg_4
line.delete(currentmid)
line.delete(currenthigh)
line.delete(currentlow)
else
line.set_extend(currentmid, extend.none)
line.set_x2(currentmid, time)
line.set_extend(currenthigh, extend.none)
line.set_x2(currenthigh, time)
line.set_extend(currentlow, extend.none)
line.set_x2(currentlow, time)
if var_fvg_4
box.delete(_currentgap)
box.delete(_currentgap_fill)
else
box.set_extend(_currentgap, extend.none)
box.set_right(_currentgap, time)
// Checks if gap has been filled either by 0.5 fill (var_fvg_3) or SHRINKS the gap to reflect the true value gap left
custom_func_8(_high, _low) =>
variable_fvg_19 = 0
if array.size(variable_fvg_1) > 0
for i = array.size(variable_fvg_1) - 1 to 0
if in_fvg_15
currentgap_fill = array.get(variable_fvg_3, i)
currentgap = array.get(variable_fvg_1, i)
cmid = array.get(variable_fvg_9, i)
chigh = array.get(variable_fvg_5, i)
clow = array.get(variable_fvg_7, i)
line.set_x2(cmid, timenow + (var_ob_13) * in_fvg_9)
line.set_x2(chigh, timenow + (var_ob_13) * in_fvg_9)
line.set_x2(clow, timenow + (var_ob_13) * in_fvg_9)
box.set_right(currentgap_fill, timenow + (var_ob_13) * in_fvg_9)
box.set_right(currentgap, timenow + (var_ob_13) * in_fvg_9)
if in_fvg_5 == "Touch"
currentgap_fill = array.get(variable_fvg_3, i)
currentgap = array.get(variable_fvg_1, i)
currentmid = array.get(variable_fvg_9, i)
currenthigh = array.get(variable_fvg_5, i)
currentlow = array.get(variable_fvg_7, i)
currenttop = box.get_top(currentgap)
if high > currenttop
variable_fvg_19 := 1
custom_func_7(currentgap, currentgap_fill, i, variable_fvg_1, variable_fvg_3, variable_fvg_9, variable_fvg_5, variable_fvg_7, variable_fvg_11)
if in_fvg_5 == "Wicks"
currentgap_fill = array.get(variable_fvg_3, i)
currentgap = array.get(variable_fvg_1, i)
currentmid = array.get(variable_fvg_9, i)
currenthigh = array.get(variable_fvg_5, i)
currentlow = array.get(variable_fvg_7, i)
currenttop = box.get_bottom(currentgap)
currentbottom = box.get_top(currentgap_fill)
if high > currentbottom and in_fvg_7
currentgap_f = array.get(variable_fvg_3, i)
cur_bottom = box.get_bottom(currentgap_f)
_bottom = box.get_bottom(currentgap)
if _bottom == cur_bottom
box.set_bottom(currentgap_f, high)
else
box.set_bottom(currentgap_f, math.max(cur_bottom, high))
box.set_bgcolor(currentgap_f, #787b865e)
if high > currenttop
variable_fvg_19 := 1
custom_func_7(currentgap, currentgap_fill, i, variable_fvg_1, variable_fvg_3, variable_fvg_9, variable_fvg_5, variable_fvg_7, variable_fvg_11)
if in_fvg_5 == "Close"
currentgap_fill = array.get(variable_fvg_3, i)
currentgap = array.get(variable_fvg_1, i
Prime NumbersPrime Numbers highlights prime numbers (no surprise there 😅), tokens and the recent "active" feature in "input".
🔸 CONCEPTS
🔹 What are Prime Numbers?
A prime number (or a prime) is a natural number greater than 1 that is not a product of two smaller natural numbers.
Wikipedia: Prime number
🔹 Prime Factorization
The fundamental theorem of arithmetic states that every integer larger than 1 can be written as a product of one or more primes. More strongly, this product is unique in the sense that any two prime factorizations of the same number will have the same number of copies of the same primes, although their ordering may differ. So, although there are many different ways of finding a factorization using an integer factorization algorithm, they all must produce the same result. Primes can thus be considered the "basic building blocks" of the natural numbers.
Wikipedia: Fundamental theorem of arithmetic
Math Is Fun: Prime Factorization
We divide a given number by Prime Numbers until only Primes remain.
Example:
24 / 2 = 12 | 24 / 3 = 8
12 / 3 = 4 | 8 / 2 = 4
4 / 2 = 2 | 4 / 2 = 2
|
24 = 2 x 3 x 2 | 24 = 3 x 2 x 2
or | or
24 = 2² x 3 | 24 = 2² x 3
In other words, every natural/integer number above 1 has a unique representation as a product of prime numbers, no matter how the number is divided. Only the order can change, but the factors (the basic elements) are always the same.
🔸 USAGE
The Prime Numbers publication contains two use cases:
Prime Factorization: performed on "close" prices, or a manual chosen number.
List Prime Numbers: shows a list of Prime Numbers.
The other two options are discussed in the DETAILS chapter:
Prime Factorization Without Arrays
Find Prime Numbers
🔹 Prime Factorization
Users can choose to perform Prime Factorization on close prices or a manually given number.
❗️ Note that this option only applies to close prices above 1, which are also rounded since Prime Factorization can only be performed on natural (integer) numbers above 1.
In the image below, the left example shows Prime Factorization performed on each close price for the latest 50 bars (which is set with "Run script only on 'Last x Bars'" -> 50).
The right example shows Prime Factorization performed on a manually given number, in this case "1,340,011". This is done only on the last bar.
When the "Source" option "close price" is chosen, one can toggle "Also current price", where both the historical and the latest current price are factored. If disabled, only historical prices are factored.
Note that, depending on the chosen options, only applicable settings are available, due to a recent feature, namely the parameter "active" in settings.
Setting the "Source" option to "Manual - Limited" will factorize any given number between 1 and 1,340,011, the latter being the highest value in the available arrays with primes.
Setting to "Manual - Not Limited" enables the user to enter a higher number. If all factors of the manual entered number are in the 1 - 1,340,011 range, these factors will be shown; however, if a factor is higher than 1,340,011, the calculation will stop, after which a warning is shown:
The calculated factors are displayed as a label where identical factors are simplified with an exponent notation in superscript.
For example 2 x 2 x 2 x 5 x 7 x 7 will be noted as 2³ x 5 x 7²
🔹 List Prime Numbers
The "List Prime Numbers" option enables users to enter a number, where the first found Prime Number is shown, together with the next x Prime Numbers ("Amount", max. 200)
The highest shown Prime Number is 1,340,011.
One can set the number of shown columns to customize the displayed numbers ("Max. columns", max. 20).
🔸 DETAILS
The Prime Numbers publication consists out of 4 parts:
Prime Factorization Without Arrays
Prime Factorization
List Prime Numbers
Find Prime Numbers
The usage of "Prime Factorization" and "List Prime Numbers" is explained above.
🔹 Prime Factorization Without Arrays
This option is only there to highlight a hurdle while performing Prime Factorization.
The basic method of Prime Factorization is to divide the base number by 2, 3, ... until the result is an integer number. Continue until the remaining number and its factors are all primes.
The division should be done by primes, but then you need to know which one is a prime.
In practice, one performs a loop from 2 to the base number.
Example:
Base_number = input.int(24)
arr = array.new()
n = Base_number
go = true
while go
for i = 2 to n
if n % i == 0
if n / i == 1
go := false
arr.push(i)
label.new(bar_index, high, str.tostring(arr))
else
arr.push(i)
n /= i
break
Small numbers won't cause issues, but when performing the calculations on, for example, 124,001 and a timeframe of, for example, 1 hour, the script will struggle and finally give a runtime error.
How to solve this?
If we use an array with only primes, we need fewer calculations since if we divide by a non-prime number, we have to divide further until all factors are primes.
I've filled arrays with prime numbers and made libraries of them. (see chapter "Find Prime Numbers" to know how these primes were found).
🔹 Tokens
A hurdle was to fill the libraries with as many prime numbers as possible.
Initially, the maximum token limit of a library was 80K.
Very recently, that limit was lifted to 100K. Kudos to the TradingView developers!
What are tokens?
Tokens are the smallest elements of a program that are meaningful to the compiler. They are also known as the fundamental building blocks of the program.
I have included a code block below the publication code (// - - - Educational (2) - - - ) which, if copied and made to a library, will contain exactly 100K tokens.
Adding more exported functions will throw a "too many tokens" error when saving the library. Subtracting 100K from the shown amount of tokens gives you the amount of used tokens for that particular function.
In that way, one can experiment with the impact of each code addition in terms of tokens.
For example adding the following code in the library:
export a() => a = array.from(1) will result in a 100,041 tokens error, in other words (100,041 - 100,000) that functions contains 41 tokens.
Some more examples, some are straightforward, others are not )
// adding these lines in one of the arrays results in x tokens
, 1 // 2 tokens
, 111, 111, 111 // 12 tokens
, 1111 // 5 tokens
, 111111111 // 10 tokens
, 1111111111111111111 // 20 tokens
, 1234567890123456789 // 20 tokens
, 1111111111111111111 + 1 // 20 tokens
, 1111111111111111111 + 8 // 20 tokens
, 1111111111111111111 + 9 // 20 tokens
, 1111111111111111111 * 1 // 20 tokens
, 1111111111111111111 * 9 // 21 tokens
, 9999999999999999999 // 21 tokens
, 1111111111111111111 * 10 // 21 tokens
, 11111111111111111110 // 21 tokens
//adding these functions to the library results in x tokens
export f() => 1 // 4 tokens
export f() => v = 1 // 4 tokens
export f() => var v = 1 // 4 tokens
export f() => var v = 1, v // 4 tokens
//adding these functions to the library results in x tokens
export a() => const arraya = array.from(1) // 42 tokens
export a() => arraya = array.from(1) // 42 tokens
export a() => a = array.from(1) // 41 tokens
export a() => array.from(1) // 32 tokens
export a() => a = array.new() // 44 tokens
export a() => a = array.new(), a.push(1) // 56 tokens
What if we could lower the amount of tokens, so we can export more Prime Numbers?
Look at this example:
829111, 829121, 829123, 829151, 829159, 829177, 829187, 829193
Eight numbers contain the same number 8291.
If we make a function that removes recurrent values, we get fewer tokens!
829111, 829121, 829123, 829151, 829159, 829177, 829187, 829193
//is transformed to:
829111, 21, 23, 51, 59, 77, 87, 93
The code block below the publication code (// - - - Educational (1) - - - ) shows how these values were reduced. With each step of 100, only the first Prime Number is shown fully.
This function could be enhanced even more to reduce recurrent thousands, tens of thousands, etc.
Using this technique enables us to export more Prime Numbers. The number of necessary libraries was reduced to half or less.
The reduced Prime Numbers are restored using the restoreValues() function, found in the library fikira/Primes_4.
🔹 Find Prime Numbers
This function is merely added to show how I filled arrays with Prime Numbers, which were, in turn, added to libraries (after reduction of recurrent values).
To know whether a number is a Prime Number, we divide the given number by values of the Primes array (Primes 2 -> max. 1,340,011). Once the division results in an integer, where the divisor is smaller than the dividend, the calculation stops since the given number is not a Prime.
When we perform these calculations in a loop, we can check whether a series of numbers is a Prime or not. Each time a number is proven not to be a Prime, the loop starts again with a higher number. Once all Primes of the array are used without the result being an integer, we have found a new Prime Number, which is added to the array.
Doing such calculations on one bar will result in a runtime error.
To solve this, the findPrimeNumbers() function remembers the index of the array. Once a limit has been reached on 1 bar (for example, the number of iterations), calculations will stop on that bar and restart on the next bar.
This spreads the workload over several bars, making it possible to continue these calculations without a runtime error.
The result is placed in log.info() , which can be copied and pasted into a hardcoded array of Prime Number values.
These settings adjust the amount of workload per bar:
Max Size: maximum size of Primes array.
Max Bars Runtime: maximum amount of bars where the function is called.
Max Numbers To Process Per Bar: maximum numbers to check on each bar, whether they are Prime Numbers.
Max Iterations Per Bar: maximum loop calculations per bar.
🔹 The End
❗️ The code and description is written without the help of an LLM, I've only used Grammarly to improve my description (without AI :) )
RS BTC 11-minute scalp is a strategy designed for BTC. I would appreciate your comments on what can be done to improve it.
Trend Strength
OVERVIEW
This script votes across five well-known techniques (EMA posture, price vs base EMA, DI/ADX, RSI around 50, and PPO histogram), aggregates them into a discrete score from −5 to +5, and paints the candles (body, wick, and border) at 11 levels to show market regime and conviction. A zero-centered momentum oscillator and a directional/neutral squeeze meter then tell you when volatility is coiling and how energy is likely to release.
Key Features
Transparent multi-vote engine
Five independent “votes” in {+1, 0, −1}:
EMA posture: EMA(fast) vs EMA(slow).
Price vs base EMA: close vs an intermediate EMA.
DI/ADX gate: if ADX > threshold, +DI vs −DI sets the sign.
RSI posture around 50: above/below soft bands (e.g., 56/44).
PPO histogram sign: PPO − Signal above/below zero.
Score = sum of the five votes ∈ (deep green → yellow → neutral → yellow → deep red).
Momentum oscillator (context only):
Zero-centered (~−6…+6), blending a normalized ROC, RSI distance from 50, and PPO histogram. Above/below zero = bullish/bearish tilt; slope = acceleration or fatigue. Optional volume tint (brighter when volume > SMA(volume, 20)). Volume does not change the score by default.
Two-key Squeeze with timing:
Compression: Bollinger Bands inside Keltner Channels (same lookback).
Flatness: oscillator near zero by a user tolerance (epsZero).
While both hold, a counter increments (your “coil timer”). Display it neutrally (mirrored band around zero) or directionally (above zero if osc ≥ 0, below if < 0). A release occurs when compression ends; optional arrows mark Up/Down depending on the oscillator sign at release.
USAGE
Read the color first.
+4/+5 (deep greens): broad bullish agreement → favor pullback entries with the trend.
−4/−5 (deep reds): broad bearish agreement → favor rally fades.
Around 0 (yellow/light yellow/fuchsia(neutral)): mixed/transition—lean on squeeze and oscillator for timing.
Use the oscillator as context.
Above/below zero confirms bias; a rising/falling slope hints at acceleration/deceleration. Divergence or repeated failures at zero warn of exhaustion.
Watch the squeeze meter.
The longer the counter builds, the more meaningful the expansion tends to be. Consider entries on release aligned with both candle color and oscillator sign; manage risk with ATR/swing structure.
Key settings to tune (why they matter):
EMA fast/slow: responsiveness vs stability.
ADX length & threshold: how strong a trend must be before DI votes count.
RSI length & bands: widen bands to reduce whipsaws around 50; tighten to be more sensitive.
PPO fast/slow/signal: sensitivity of momentum crossings.
Volatility window (volLen), BB/KC multipliers, epsZero: frequency of squeezes and strictness of “flat momentum.”
Display: neutral vs directional squeeze band; show/hide oscillator; optional volume coloring.
CONCLUSION
This tool is a clear, testable framework for reading trend and its strength. By aggregating five classic methods into a single discrete score and pairing it with a momentum-aware squeeze timer, it helps you act with context—trade with the trend when conviction is high, stand aside during transitions, and prepare for expansions rather than reacting late.
N波動検出インジケーター(基本版)Main Specifications – N-Wave Indicator
1. Pattern Detection
Automatically detects classic N-wave patterns (ABC-type price swings) based on pivot highs and lows.
Uses adjustable pivot length parameters to define swing points.
2. Wave Structure
Marks three key points: Start (A), Peak/Valley (B), and End (C).
Connects these points with lines to visualize the N-shape.
3. Labeling
Displays point labels A, B, C directly on the chart.
Color-coded for uptrend vs. downtrend waves.
4. Customizable Parameters
Pivot length: Determines how far back to look for highs/lows.
Minimum wave height: Filters out small price noise.
Label toggle: Show/hide wave labels.
Line style: Solid or dashed line for wave connections.
5. Trend Direction Analysis
Automatically identifies if the current N-wave is bullish (higher highs/higher lows) or bearish (lower highs/lower lows).
Optional background shading for trend direction.
6. Multi-Timeframe Support
Can detect N-wave patterns using higher timeframe data (e.g., H1 waves on a 5-min chart).
7. Alerts
Alerts when a new N-wave is completed.
Separate alerts for bullish and bearish N-wave formations.
8. Compatibility
Works on Forex, Stocks, Crypto across all timeframes.
Overlay on price chart (no separate window needed).
WaveTrend Dynamic (Lazy Bear Style)█ OVERVIEW
The WaveTrend Dynamic indicator (in the style of Lazy Bear) is an advanced tool based on the Exponential Smoothing Average (ESA), which adapts to the volatility and price of a financial instrument. It is more flexible than the classic WaveTrend but shares a similar concept of bands around a main oscillator line.
The indicator uses dynamic bands calculated as distances from the ESA, with their width adjustable via the "level" parameter. This allows it to be tailored to various markets, timeframes, and volatility conditions, making it easier to identify trends, reversal points, and buy/sell signals.
█ CONCEPTS
The WaveTrend Dynamic combines oscillator functions with trend analysis. Below, we explain the key components in a simple way, understandable even for beginner users.
Core Calculations
The indicator relies on the adaptive ESA and a few straightforward steps:
1 — ESA (Adaptive Average): Calculated as a smoothed average of the price (from high, low, and close, or HLC3) using the ESA Length parameter (default: 10). This number determines how many past candles are considered in the calculation. The ESA quickly responds to price changes, helping to track trends.
2 — Deviation (D): Measures how much the price deviates from the ESA, factoring in market volatility. This allows the indicator to adapt to different instruments.
3 — Price Distance Indicator (CI): Shows how far the price is from the ESA relative to market volatility. This forms the basis for the main indicator line, reacting to price movements.
4 — WT1 (WaveTrend 1): The main line, smoothing the Price Distance Indicator (CI) with the Average Length parameter (default: 21). It reflects the direction of price movement and momentum.
5 — WT2 (WaveTrend 2): A signal line that further smooths WT1 (with a period of 4). It helps confirm signals through crossovers with WT1.
6 — Bands (UpperBand and LowerBand): These form a dynamic channel around the ESA. Their width depends on the level parameter (default: 100). Wider bands result in fewer but more reliable signals. In the original WaveTrend, the oscillator bands use lower values, such as 50 or 60. To achieve classic oscillator signals (more frequent WT1/WT2 crossovers outside the bands), set the level to 50–60.
Trend Identification
The indicator identifies two types of trends:
• Major Trend: Determined by the position of WT1 relative to the ESA. When WT1 is above the ESA, it indicates a bullish trend. When below, it signals a bearish trend. Line and fill colors reflect this trend.
• Mini-Trend: Based on WT1 and WT2 crossovers. When the lines cross, they change to the same color, signaling short-term changes or reversal points. This is ideal for quick trading decisions.
Visuals and Effects
• WT1 and WT2 Lines: Scaled to price and displayed on the price chart for easier analysis.
• Fills: Between the bands (UpperBand/LowerBand) and between WT1/WT2, with a "wave" effect that adjusts transparency based on the trend (green for bullish, red for bearish).
• Signals: Three types—return-to-band, WT1/WT2 crossovers outside the bands, and crossovers inside the bands. Signals are displayed as triangles with different colors for buy and sell.
█ FEATURES
Detailed features of the indicator, aligned with the order of settings in the script:
• Basic Parameters: ESA Length — controls ESA smoothing; Average Length — affects WT1 responsiveness; level (WT Level) — adjusts band width for signal filtering.
• Display Elements: Options to show/hide ESA, bands, WT1/WT2; customizable colors for lines, fills, and the wave effect.
• Signals: Three signal groups (return-to-band, crossovers outside bands, crossovers inside bands) with display and color customization options.
█ HOW TO USE
1 — Add the indicator to your TradingView chart and adjust parameters: — Increase ESA Length and Average Length for low-volatility markets (e.g., stocks), or decrease for cryptocurrencies or forex. — Set level to 50–60 for classic WaveTrend signals with WT1/WT2 crossovers outside bands. The default value of 100 creates wider bands and fewer signals.
2 — Analyze trends: — Major trend (WT1 vs. ESA) shows the overall market direction. — Mini-trends (WT1/WT2 crossovers) help time short-term entries.
3 — Use signals: — Return-to-band: Buy at the lower band, sell at the upper band (mean-reversion). — Crossovers outside bands: Indicate strong momentum (with a lower level, e.g., 50). — Crossovers inside bands: Signal weaker trend changes.
4 — Combine with other tools: Use with volume, RSI, or support/resistance for better decisions. Test on historical data to optimize settings.