TCP | Market Session | Session Analyzer📌 TCP | Market Session Indicator | Crypto Version
A powerful, real-time market session visualization tool tailored for crypto traders. Track the heartbeat of Asia, Europe, and US trading hours directly on your chart with live session boxes, behavioral analysis, liquidity grab detection, and countdown timers. Know when the action starts, how the market behaves, and where the traps lie.
🔰 Introduction:
Trade the Right Hours with the Right Tools
Time matters in trading. Most significant moves happen during key sessions—and knowing when and how each session unfolds can give you a sharp edge. The TCP Market Session Indicator, developed by Trade City Pro (TCP), puts professional session tracking and behavioral insights at your fingertips.
Whether you're a scalper or swing trader, this indicator gives you the timing context to enter and exit trades with greater confidence and clarity.
🕒 Core Features
• Live Session Boxes :
Highlight active ranges during Asia, Europe, and US sessions with dynamic high/low updates.
• Session Start/End Labels :
Know exactly when each session begins and ends plotted clearly on your chart with context.
• Session Behavior Analysis :
At the end of each session, the indicator classifies the price action as:
- Trend Up
- Trend Down
- Consolidation
- Manipulation
• Liquidity Grab Detection: Automatically detects possible stop hunts (fake breakouts) and marks them on the chart with precision filters (volume, ATR, reversal).
• Session Countdown Table: A live dashboard showing:
- Current active session
- Time left in session
- Upcoming session and how many minutes until it starts
- Utility time converter (e.g. 90 min = 01:30)
• Vertical Session Lines: Visualize past and upcoming session boundaries with customizable history and future range.
• Multi-Day Support: Draw session ranges for previous, current, and future days for better backtesting and forecasting.
⚙️ Settings Panel
Customize everything to fit your trading style and schedule:
• Session Time Settings:
Set the opening and closing time for each session manually using UTC-based minute inputs.
→ For example, enter Asia Start: 0, Asia End: 480 for 00:00–08:00 UTC.
This gives full flexibility to adjust session hours to match your preferred market behavior.
• Enable or Disable Elements:
Toggle the visibility of each session (Asia, Europe, US), as well as:
- Session Boxes
- Countdown Table
- Session Lines
- Liquidity Grab Labels
• Timezone Selection:
Choose between using UTC or your chart’s local timezone for session calculations.
• Customization Options:
Select number of past and future days to draw session data
Adjust vertical line transparency
Fine-tune label offset and spacing for clean layout
📊 Smart Session Boxes
Each session box tracks high, low, open, and close in real time, providing visual clarity on market structure. Once a session ends, the box closes, and the behavior type is saved and labeled ideal for spotting patterns across sessions.
• Asia: Green Box
• Europe: Orange Box
• US: Blue Box
💡 Why Use This Tool?
• Perfect Timing: Don’t get chopped in low-liquidity hours. Focus on sessions where volume and volatility align.
• Pattern Recognition: Study how price behaves session-to-session to build better strategies.
• Trap Detection: Spot manipulation moves (liquidity grabs) early and avoid common retail pitfalls.
• Macro Session Mapping: Use as a foundational layer to align trades with market structure and news cycles.
🔍 Example Use Case
You're watching BTC at 12:45 UTC. The indicator tells you:
The Asia session just ended (label shows “Asia Session End: Trend Up”)
Europe session starts in 15 minutes
A liquidity grab just triggered at the previous high—label confirmed
Now you know who’s active, what the market just did, and what’s about to start—all in one glance.
✅ Why Traders Trust It
• Visual & Intuitive: Fully chart-based, no clutter, no guessing
• Crypto-Focused: Designed specifically for 24/7 crypto markets (not outdated forex models)
• Non-Repainting: All labels and boxes stay as printed—no tricks
• Reliable: Tested across multiple exchanges, pairs, and timeframes
🧩 Built by Trade City Pro (TCP)
The TCP Market Session Indicator is part of a suite of professional tools used by over 150,000 traders. It’s coded in Pine Script v6 for full compatibility with TradingView’s latest capabilities.
🔗 Resources
• Tutorial: Learn how to analyze sessions like a pro in our TradingView guide:
"TradeCityPro Academy: Session Mapping & Liquidity Traps"
• More Tools: Explore our full library of indicators on
Komut dosyalarını "TradingView+手机版" için ara
FuTech : Earnings (All 269 Fundamental Metrics of Tradingview)FuTech : Earnings Indicator
The FuTech : Earnings Indicator is a revolutionary tool, offering the most comprehensive integration of all 269 fundamental financial metrics available from the TradingView platform.
This groundbreaking indicator is designed to empower financial researchers, traders, investors, and analysts with an unmatched depth of data, enabling superior analysis and decision-making.
Overview
"FuTech : Earnings Indicator" is the first-ever indicator to provide a holistic comparison of fundamental financial metrics for any stock, covering quarterly, yearly, and trailing twelve months (TTM) periods.
This tool brings together key financial data from income statements, balance sheets, cash flows, and other critical metrics found in company annual reports.
It also incorporates additional unique features like per-employee data, R&D expenses, and capital expenditures (CapEx), which are typically hidden within dense financial statements of Annual Reports.
---
Key Features and Capabilities
1. Comprehensive Financial Metrics
- "FuTech : Earnings Indicator" offers access to all 269 fundamental metrics available on TradingView platform. This includes widely used data such as revenue, profit margins, and EPS, alongside more niche metrics like R&D expenditure, employee efficiency, and financial scores developed by renowned analysts.
- Users can explore income statement data (e.g., net income, gross profit), balance sheet items (e.g., total assets, liabilities), cash flow metrics, and other financial statistics such as Altman Score, per employee expenses etc. in unparalleled detail.
2. Comparison Across Time Periods
- "FuTech : Earnings Indicator" allows users to analyze data for:
- Quarterly periods (e.g., Q1, Q2, Q3, Q4).
- Yearly comparisons for a broad historical view.
- TTM analysis to observe the most recent trends and developments.
- Users can select a minimum of 4 periods up to an unlimited range for detailed comparisons in both quarter.
3. Dynamic Data Display
- Users can select up to 5 key metrics alongside the stock price column to focus their analysis on the most relevant data points.
- Highlighting with green and red symbols offers an intuitive and visual representation:
- Green : Positive trends or improvements.
- Red : Negative trends or deteriorations.
4. Automated Averages
- "FuTech : Earnings Indicator" automatically calculates averages of selected metrics across the chosen periods. This feature helps users quickly identify performance trends and smooth out anomalies, enabling faster and more reliable research.
5. Designed for Research Excellence
- FuTech serves a wide audience, including:
- Corporate finance professionals who need a deep dive into financial metrics.
- Individual investors seeking robust tools for investment analysis.
- Broking companies and equity research analysts performing stock analysis.
- Traders looking to incorporate fundamental metrics into their strategies.
- Technical analysts seeking a better understanding of price behavior in relation to fundamentals.
- Fundamental research aspirants who want an edge in their learning process.
6. Unmatched Detail for Deeper Insights
- By pulling all 269 Financial metrics from the TradingView, "FuTech : Earnings Indicator" enables:
- Cross-comparison of a stock’s performance with its historical benchmarks.
- Evaluation of rare data like R&D expenses, CapEx trends, and employee efficiency ratios for enhanced investment insights.
- This ensures users can study stocks in greater depth than ever before.
7. Enhanced Usability
- Simple to use and visually appealing, "FuTech : Earnings Indicator" is designed with researchers in mind.
- Its intuitive interface ensures even novice users can navigate the wealth of data without feeling overwhelmed.
Applications of FuTech : Earnings Indicator
FuTech : Earnings Indicator is incredibly versatile and has applications in diverse fields of financial research and trading:
1. Corporate Finance
- Professionals in corporate finance can leverage "FuTech : Earnings Indicator" to benchmark company performance, study efficiency ratios, and evaluate financial health across various metrics.
2. Investors and Traders
- Long-term investors can use the tool to study the fundamental strengths of a stock before making buy-and-hold decisions.
- Traders can incorporate "FuTech : Earnings Indicator" into their analysis to align comprehensive fundamental trends with their targeted technical signals.
3. Equity Research Analysts
- Analysts can streamline their workflows by quickly identifying trends, outliers, and averages across large datasets.
4. Education and Research
- "FuTech : Earnings Indicator" is ideal for students and aspiring financial analysts who want a practical tool for understanding real-world data.
How FuTech : Earnings Indicator Stands Out
1. First-Ever Integration of All Financial Metrics
- It's an exclusive tool which offers the ability to explore all 269 financial metrics available on TradingView for a single stock research in-depth for quarters, years or TTM periods.
2. Period Customization
- Users have complete flexibility to select and analyze data across any range of time periods, allowing for customized insights tailored to specific research goals.
3. Data Visualization
- The intuitive use of color-coded symbols (green for positive trends, red for negative) makes complex data easy to interpret at a glance.
4. Actionable Insights
- The automated average calculations provide actionable insights for making informed decisions without manual computations.
5. Unique Metrics
- Metrics such as research and development costs, CapEx, and per-employee efficiency data offer unique angles that aren’t typically available in traditional analysis tools.
Why to Use FuTech : Earnings Indicator ?
1. Boost Your Research Power
- With FuTech, you can unlock a world of data that gives you the edge in analyzing stocks. Whether you’re a seasoned analyst or a beginner, this tool offers something for everyone.
2. Save Time and Effort
- The automated features and intuitive interface eliminate the need for time-consuming manual calculations and formatting.
3. Make Better Decisions
- "FuTech : Earnings Indicator's" detailed comparison capabilities and insightful visual aids allow for more accurate assessments of a stock’s performance and potential.
4. Broad Appeal
- From individual investors to financial institutions, FuTech is a valuable tool for anyone in the world of finance.
---
Conclusion
- The FuTech : Earnings Indicator is a must-have for anyone serious about financial analysis.
- It combines the depth of all 269 fundamental metrics with intuitive tools for comparison, visualization, and calculation.
- Designed for ease of use and powerful insights, FuTech : Earnings Indicator is set to transform the way financial data is analyzed and understood.
Thank you !
Jai Swaminarayan Dasna Das !
He Hari ! Bas Ek Tu Raji Tha !
ProfitTrailer Example TradingView Signals [v2019-01-31]ProfitTrailer Example TradingView Signal
This script provides an example of a TradingView Signal for use with ProfitTrailer's
new SIGNALS functionality and it's new TradingView integration capability.
This signals script implements a simple Moving Average Cross strategy
that works on any chart timeframe.
It allows you to pick the Price source i.e. Open, Close (default), etc.
You are able to choose between EMA (default) or SMA moving average
calculations.
You can define the fast and slow period lengths for use within the
moving average calculations.
If you get some value out of this indicator please consider making
a small donation to my favourite charity the Save the Childrens Fund.
Every donation will make a difference to the lives of children.
All donations over $2 are tax deductable. You can donate here:
savethechildrenfundraising.org.au
Copyright (c) 2019, Grant Cause aka CryptoCoyns
Best strategy for TradingView (fake)Hello everyone! I want to show you this strategy so you don't fall for the tricks of scammers. On TradingView, you can write an algorithm (probably more than one) that will show any profit you want: from 1% to 100,000% in one year (maybe more)! This can be done, for example, using the built-in linebreak () function and several conditions for opening long and short.
I am sure that sometimes scammers show up on TradingView showing their incredible strategies. Will a smart person sell a profitable quick strategy? When a lot of people start using the quick strategy, it stops working. Therefore, no smart person would sell you a quick strategy. It is acceptable to sell slow strategies: several transactions per month - this does not greatly affect the market.
So, don't fall for the tricks of scammers, write quick strategies yourself.
About this strategy, I can say that the linebreak () function does not work correctly in it. Accordingly, the lines are not drawn correctly on the chart. They are drawn in such a way as to show the maximum profit. I watched this algorithm on a 1m timeframe - no lines are drawn in real time. This is a fake!
Advanced Dynamic Swing Anchored VWAP (Adaptive, Smart Pivots)🔹 Overview
The Advanced Dynamic Swing Anchored VWAP is a powerful trading tool that automatically anchors VWAP to detected swing highs and lows, while adapting dynamically to market volatility using ATR-based tracking.
Unlike static VWAP lines, this adaptive version provides smarter trend tracking, real-time pivot detection, and swing labeling (HH, HL, LH, LL) to help traders identify market structure shifts with precision.
✨ Key Features
✅ Swing Pivot Detection – Automatic detection of swing highs & lows based on your chosen period.
✅ Adaptive ATR Tracking – VWAP responsiveness adjusts dynamically with volatility.
✅ Smart Labels – Marks pivots with HH, HL, LH, LL to track market structure.
✅ Trend-Based Coloring – VWAP changes color based on bullish or bearish direction.
✅ Alerts – Get notified instantly on new swing pivots or trend shifts.
✅ Multi-Market Ready – Works across Forex, Crypto, Stocks, and Indices.
🔍 How to Use
Identify Trend Direction – Green VWAP line = bullish swings; Red = bearish swings.
Watch Pivots – HH/HL indicate bullish structure, while LH/LL indicate bearish structure.
Combine With Confirmation – Best used with RSI, MACD, or Price Action for confluence.
Set Alerts – Never miss a trend shift with built-in TradingView alerts.
🎯 Best For
Swing traders looking for precision pivot detection.
Trend-following traders using VWAP-based support/resistance.
Scalpers who need adaptive VWAP levels that adjust to volatility.
Multi-asset traders (Crypto, Forex, Stocks, Futures).
📈 Why This Indicator?
The standard VWAP is static. Anchored VWAP requires manual anchoring. This advanced version automates the process, adapts to volatility, and visually shows pivots for smarter entries and exits.
By combining anchored VWAP logic with adaptive ATR filtering, this tool gives a next-gen trading edge for both discretionary and systematic traders.
$ADD LevelsThis Pine Script is designed to track and visualize the NYSE Advance-Decline Line (ADD). The Advance-Decline Line is a popular market breadth indicator, showing the difference between advancing and declining stocks on the NYSE. It’s often used to gauge overall market sentiment and strength.
1. //@version=5
This line tells TradingView to use Pine Script v5, the latest and most powerful version of Pine.
2. indicator(" USI:ADD Levels", overlay=false)
• This creates a new indicator called ” USI:ADD Levels”.
• overlay=false means it will appear in a separate pane, not on the main price chart.
3. add = request.security(...)
This fetches real-time data from the symbol USI:ADD (Advance-Decline Line) using a 1-minute timeframe. You can change the timeframe if needed.
add_symbol = input.symbol(" USI:ADD ", "Market Breadth Symbol")
add = request.security(add_symbol, "1", close)
4. Key Thresholds
These define the market sentiment zones:
Zone. Value. Meaning
Overbought +1500 Extremely bullish
Bullish +1000 Generally bullish trend
Neutral ±500 Choppy, unclear market
Bearish -1000 Generally bearish trend
Oversold -1500 Extremely bearish
5. Plot the ADD Line hline(...)
Draws static lines at +1500, +1000, +500, -500, -1000, -1500 for reference so you can visually assess where ADD stands.
6. Horizontal Threshold Lines bgcolor(...)
• Green background if ADD > +1500 → extremely bullish.
• Red background if ADD < -1500 → extremely bearish.
7. Background Highlights alertcondition(...)
• Green background if ADD > +1500 → extremely bullish.
• Red background if ADD < -1500 → extremely bearish.
8. Alert Conditions. alertcondition(...)
Lets you create automatic alerts for:
• USI:ADD being very high or low.
• Crosses above +1000 (bullish trigger).
• Crosses below -1000 (bearish trigger).
You can use these to trigger trades or monitor sentiment shifts.
Summary: When to Use It
• Use this script in a market breadth dashboard.
• Combine it with price action and volume analysis.
• Monitor for ADD crosses to signal potential market reversals or momentum.
Volume Profile & Smart Money Explorer🔍 Volume Profile & Smart Money Explorer: Decode Institutional Footprints
Master the art of institutional trading with this sophisticated volume analysis tool. Track smart money movements, identify peak liquidity windows, and align your trades with major market participants.
🌟 Key Features:
📊 Triple-Layer Volume Analysis
• Total Volume Patterns
• Directional Volume Split (Up/Down)
• Institutional Flow Detection
• Real-time Smart Money Tracking
• Historical Pattern Recognition
⚡ Smart Money Detection
• Institutional Trade Identification
• Large Block Order Tracking
• Smart Money Concentration Periods
• Whale Activity Alerts
• Volume Threshold Analysis
📈 Advanced Profiling
• Hourly Volume Distribution
• Directional Bias Analysis
• Liquidity Heat Maps
• Volume Pattern Recognition
• Custom Threshold Settings
🎯 Strategic Applications:
Institutional Trading:
• Track Big Player Movements
• Identify Accumulation/Distribution
• Follow Smart Money Flow
• Detect Institutional Trading Windows
• Monitor Block Orders
Risk Management:
• Identify High Liquidity Windows
• Avoid Thin Market Periods
• Optimize Position Sizing
• Track Market Participation
• Monitor Volume Quality
Market Analysis:
• Volume Pattern Recognition
• Smart Money Flow Analysis
• Liquidity Window Identification
• Institutional Activity Cycles
• Market Depth Analysis
💡 Perfect For:
• Professional Traders
• Volume Profile Traders
• Institutional Traders
• Risk Managers
• Algorithmic Traders
• Smart Money Followers
• Day Traders
• Swing Traders
📊 Key Metrics:
• Normalized Volume Profiles
• Institutional Thresholds
• Directional Volume Split
• Smart Money Concentration
• Historical Patterns
• Real-time Analysis
⚡ Trading Edge:
• Trade with Institution Flow
• Identify Optimal Entry Points
• Recognize Distribution Patterns
• Follow Smart Money Positioning
• Avoid Thin Markets
• Capitalize on Peak Liquidity
🎓 Educational Value:
• Understand Market Structure
• Learn Volume Analysis
• Master Institutional Patterns
• Develop Market Intuition
• Track Smart Money Flow
🛠️ Customization:
• Adjustable Time Windows
• Flexible Volume Thresholds
• Multiple Timeframe Analysis
• Custom Alert Settings
• Visual Preference Options
Whether you're tracking institutional flows in crypto markets or following smart money in traditional markets, the Volume Profile & Smart Money Explorer provides the deep insights needed to trade alongside the biggest players.
Transform your trading from retail guesswork to institutional precision. Know exactly when and where smart money moves, and position yourself ahead of major market shifts.
#VolumeProfile #SmartMoney #InstitutionalTrading #MarketAnalysis #TradingView #VolumeAnalysis #CryptoTrading #ForexTrading #TechnicalAnalysis #Trading #PriceAction #MarketStructure #OrderFlow #Liquidity #RiskManagement #TradingStrategy #DayTrading #SwingTrading #AlgoTrading #QuantitativeTrading
Highest High, Lowest Low, Midpoint for Selected Days [kiyarash]Highest High, Lowest Low, and Midpoint for Selected Days Indicator
This custom TradingView indicator allows you to visualize the highest high, lowest low, and the midpoint (average of the highest high and lowest low) over a custom-defined period. You can choose a starting date and specify how many days ahead you want to track the highest and lowest values. This is useful for identifying key levels in a trend and potential support or resistance zones.
How to Use:
Set the Starting Date:
In the settings, input the starting date from which you want to begin tracking the price range. This will be the reference point for your analysis.
Choose the Number of Days to Track:
Specify how many days you want to analyze from the selected starting date. For example, if you want to see the highest high and lowest low over the next 3 days, enter "3" in the settings.
Visualizing the Levels:
The indicator will automatically calculate the highest price and the lowest price over the selected period and draw three lines:
Red Line: Represents the Highest High within the selected period.
Green Line: Represents the Lowest Low within the selected period.
Blue Line: Represents the Midpoint, which is the average of the Highest High and Lowest Low.
Interpretation:
Highest High is a key resistance level, indicating the highest price reached within the specified period.
Lowest Low is a key support level, showing the lowest price during the same period.
Midpoint provides a reference for the average price, often acting as a neutral level between support and resistance.
This tool can help traders to quickly assess potential market ranges, identify breakout or breakdown points, and make informed decisions based on recent price action.
How to Apply:
Add the indicator to your chart.
Adjust the settings to choose your desired starting date and the number of days you want to analyze.
Observe the drawn lines for the Highest High, Lowest Low, and Midpoint levels, and use them to assist in your trading decisions.
Bar Replay Fix - Smooth Candle Transition for TradingViewThe Bar Replay Fix indicator addresses a known issue in TradingView’s Bar Replay mode, where the last completed candle is incorrectly drawn when switching from a lower timeframe to a higher one. This issue can create confusion during analysis, especially when replaying historical price action.
Key Features:
Accurate Candle Rendering: Ensures that candles are displayed correctly in Bar Replay mode by referencing and plotting the previous candle data.
Customizable Appearance: Configure the candle body, wick, and border colors for bullish, bearish, and doji candles to match your chart theme.
Seamless Integration: Works invisibly in the background to provide a smoother and more reliable replay experience.
Use Cases:
Enhance your backtesting accuracy by eliminating incorrect candle rendering during Bar Replay.
Maintain consistency in candle visualization when transitioning between timeframes in Replay mode.
Disclaimer: This indicator is specifically designed to resolve a visual issue in Bar Replay mode and does not provide any trading signals or analysis recommendations.
Markov Chain Trend IndicatorOverview
The Markov Chain Trend Indicator utilizes the principles of Markov Chain processes to analyze stock price movements and predict future trends. By calculating the probabilities of transitioning between different market states (Uptrend, Downtrend, and Sideways), this indicator provides traders with valuable insights into market dynamics.
Key Features
State Identification: Differentiates between Uptrend, Downtrend, and Sideways states based on price movements.
Transition Probability Calculation: Calculates the probability of transitioning from one state to another using historical data.
Real-time Dashboard: Displays the probabilities of each state on the chart, helping traders make informed decisions.
Background Color Coding: Visually represents the current market state with background colors for easy interpretation.
Concepts Underlying the Calculations
Markov Chains: A stochastic process where the probability of moving to the next state depends only on the current state, not on the sequence of events that preceded it.
Logarithmic Returns: Used to normalize price changes and identify states based on significant movements.
Transition Matrices: Utilized to store and calculate the probabilities of moving from one state to another.
How It Works
The indicator first calculates the logarithmic returns of the stock price to identify significant movements. Based on these returns, it determines the current state (Uptrend, Downtrend, or Sideways). It then updates the transition matrices to keep track of how often the price moves from one state to another. Using these matrices, the indicator calculates the probabilities of transitioning to each state and displays this information on the chart.
How Traders Can Use It
Traders can use the Markov Chain Trend Indicator to:
Identify Market Trends: Quickly determine if the market is in an uptrend, downtrend, or sideways state.
Predict Future Movements: Use the transition probabilities to forecast potential market movements and make informed trading decisions.
Enhance Trading Strategies: Combine with other technical indicators to refine entry and exit points based on predicted trends.
Example Usage Instructions
Add the Markov Chain Trend Indicator to your TradingView chart.
Observe the background color to quickly identify the current market state:
Green for Uptrend, Red for Downtrend, Gray for Sideways
Check the dashboard label to see the probabilities of transitioning to each state.
Use these probabilities to anticipate market movements and adjust your trading strategy accordingly.
Combine the indicator with other technical analysis tools for more robust decision-making.
Gaps (modified TradingView standard indicator)Based on standard TradingView "Gaps" indicator, but modified so that the gaps are displayed until fully closed (not jus paritally like the original indicator).
MarketGod for Tradingview(strategy)Fully Open Source Tv Market God Strategy. Good Luck
Strategy Description
MarketGod can be applied to any market, with any time-frame associated to it. The signals relay the alert at the close of the period, and the painted alert is then available to users to see on the chart or even set notifications for via tradingview's alert system. We recommend that users implement marketgod on their preferred time frames for trading, which for us is the 1h, 4h, 6h, 1D and above TFs.
MarketGod Versioning
The versions included with this release are the following
MarketGod v1
MarketGod v2
MarketGod v3
MarketGod v4
MarketGod v5
MarketGod v6
MarketGod v7
MarketGod v8
MarketGodx²
Ichimoku God
Suggested Uses
• MarketGod will inevitably produce false positives. We've taken steps to reduce this but we highly suggest you add this as a component of your strategy, not an end all be all
• That said, please do not feel the need to fire a trade based solely on a marketgod signal, or to every signal it fires.
• MarketGod users should backtest their strategy using OHLC candles for best results
• Heikin Ashi candles were recomended in the past, and we have eliminated the need for them, meaning that traditional candlestick inputs will yield the highest results.
• MarketGod will always give stronger alerts on higher TF's. If the 1-Day has fired a given signal and the 30 min or similar fire the opposite signal, know that the overall trend is still likely downward. Same concept applies to all timeframes on this tool.
Adjusting the Filter Settings
This tool has a noise filter for users to adjust.
The filter is a percentage based calculation, between significant points in time. The filter ranges between .5 and 25, with .5 increments
• For lower TFs ( IE Intraday), keep the filter set between .5-5
• Mid-TFs (4H,6H,12H,1D), the recommended range is between 5.5-10
• Higher TFs (3D and Higher), look for approx 11-20 range
Customizations
Customize the indicator by adjusting the colors in the style pane. Additionally, users can change the plots into labels with the price of close added to them, or a few other label text options, listed in the 'inputs' panel, below the filter adjustments. Users can also opt to turn the strategy orders as well, as this version will have them printed.
Strategy Performance Interpretation
Its important to understand the only metric that should be relevant is not the win %, as many may initially think. Alternatively, the only metric that matters in the end is your take home profit... meaning the profit one fees and taxes are accounted for. In our example here, the % brought back since the beginning of our window of 2018 is around 47% for $10,000 initial capital and 10% traded per position. Many are ignorant to the take home profit aspect as they focus solely on the winning %, which is ultimately incorrect approach to trading as a whole. as long as we maintain +30% (our goal minimum), the outcome being in the green, is our goal.
PineGIF - Display Gifs & Images In Tradingview [LuxAlgo]Pinescript is not designed to create or display images, let alone gifs, but it's very fun to try, and that's what this script does. This script allows the user to display three different gifs. In this post, we explain how we managed to display images/gif's using pinescript tables.
1. Image Pre-Processing
Due to pinescript limitations, we can't possibly display images with an excessively high resolution. As such we targeted pixel art as a primary image source. We used a pixel art gif of the magnificent Octocat (the mascot for the source-code hosting service GitHub) for our first try.
We first extract each frame from the gif and resize them to a 50x50 resolution which returns frames made of 2500 pixels. This process was done using python.
Getting Individual Pixels RGBA Values
Python can easily return a matrix containing each pixel's rgba value. For convenience, we converted the rgba values to hex.
We then create a simple code allowing us to return a pinescript array containing the 2500 pixel hex colors. We do this process for each frame.
2. Defining Table Cell Color
In the code, each frame is its own array. We create a new table with dimensions equal to len(frame1)^2 (we assume height = width).
The color of a cell is defined by the color of the image pixel at the same exact location. When a new bar is created, we do this exact process using a different frame which ultimately allows a new frame to be displayed.
3. Playing The GIFs
By default, the script will play the gif of the Tradingview cloud logo raining. In order to play the gif, simply use the replay mode. The replay speed allows the user to determine the frame rate (0.1 for the raining cloud and Nyan cat works best, 0.5 for Octocat).
We included the frames of the Octocat and Nyan cat gifs in the script.
4. Some Other Cool Images
Displaying static images is possible and involves the same process described above.
An original idea of the lizard, implemented by the wizard.
HTF Candlestick Patterns [TradingView] vX by DGTCandlesticks are graphical representations of price movements for a given period of time. They are commonly formed by the opening, high, low, and closing prices of a financial instrument. They have their origins in the centuries-old Japanese rice trade and have made their way into modern day price charting.
It’s important to note that candlestick patterns aren’t necessarily a buy or sell signal by themselves. They are instead a way to look at market structure and a potential indication of an upcoming opportunity. It is always useful to look at candlestick patterns in context like any other market analysis tool and candlestick patterns are most useful when used in combination with other techniques. There are countless candlestick patterns that traders can use to identify areas of interest on a chart, where some candlestick patterns may provide insights into the balance between buyers and sellers, others may indicate a reversal, continuation, or indecision.
Reversal patterns are quite useful when used in context. Reversal patterns should form at the bottom of a downtrend or at the top of an uptrend. Otherwise, they are not a reversal patterns, but continuation patterns. Most reversal patterns require confirmation such as price move in the direction of reversal accompanied by appropriate trading volume. The reversal patterns can further be confirmed through other means of traditional technical analysis—like trend lines, momentum, oscillators, or volume indicators—to reaffirm buying or selling pressure. The patterns themselves do not guarantee that the trend will reverse. Investors should always confirm reversal by the subsequent price action before initiating a trade.
This study implements some of the most commonly used candlestick patterns in a context with directional movement indicator. On request users can adjust the strong trend threshold from dialog box, eighter can disabled correlation with directional movement indicator. To add additional sight to analysis the simple moving averages of 20, 50, 100 and 200 periods are added (configurable)
You may add additional indicators of your choice. Colored DMI, BB Cloud or Price Distance to its MAs may help
Enjoy it!
Disclaimer: The script is for informational and educational purposes only. Use of the script does not constitutes professional and/or financial advice. You alone the sole responsibility of evaluating the script output and risks associated with the use of the script. In exchange for using the script, you agree not to hold dgtrd tradingview user liable for any possible claim for damages arising from any decision you make based on use of the script
FREE TRADINGVIEW FOR TIMEFRAMESWhen doing i.e the 3 minute timeframe turn on the closest timeframe available for you or the candles and wicks will be fucked up.
So if you're doing the 5 hour timeframe candles turn on the 4hr chart on your main chart.
To View the candles in full screen double click the windows with the candlesticks
If you don't have TradingView premium and want to look at custom timeframes you can use this.
For the ticker/coin/pair you want to show enter it like this:
For stocks, only the ticker i.e: MSFT, APPL
For Crypto, "Exchange:ticker" i.e: BITFINEX:BTCUSD, BINANCE:AGIBTC, BITMEX:ADAM19
When setting up the timeframe write i.e:
For minutes/hourly: 5, 240 (4 hour), 360 (6 hour)
For daily/weekly/monthly: 1D, 2W, 3M
When doing i.e the 3 minute timeframe turn on the closest timeframe available for you or the candles and wicks will be fucked up.
So if you're doing the 5 hour timeframe candles turn on the 4hr chart on your main chart.
TRADING VIEW INDICATOR - PINE TUTORIAL 5After a long gap, I have written the 5th tutorial for the pine script. You can find the others below, if you read through all of these you should be good to do your own writing.
This script mimics the Trading View Indicator . For example this one below.
www.tradingview.com
It shows the net result of the 28 indicator, either as buy or sell. I have worked hard to make sure it matches the trading view results but I am not in hundred percent agreement with tradingView on SMA, EMA and Ichimoku indicator.
There are many commented plots because I needed to check separately if each indicator is working correctly.
Someone else wrote this code but they did not make it public. It took me about 3 weeks to write this and to be honest it could be cleaner and better commented.
If you find any mistake please let me know. I hope it will be useful in your learning.
Data Gap DetectionThis simple script checks for data gaps in an intra-day TradingView chart. I have found that BitMEX 1-minute data is coming in rather holey lately, so I wrote this just to see how prevalent the problem is. It should work on any intra-day timeframe, not just 1-minute.
V1: initial release.
R.E.Signal V2.0: Improved Tim West inspired codeHi, this is version 2.0 of the Range Expansion Signal indicator, now including inside and outside bars.
I'm looking forward to tradingview to include other price feeds, since I'd love to trade FX from this site.
Cheers,
Ivan.
Correlation Heatmap█ OVERVIEW
This indicator creates a correlation matrix for a user-specified list of symbols based on their time-aligned weekly or monthly price returns. It calculates the Pearson correlation coefficient for each possible symbol pair, and it displays the results in a symmetric table with heatmap-colored cells. This format provides an intuitive view of the linear relationships between various symbols' price movements over a specific time range.
█ CONCEPTS
Correlation
Correlation typically refers to an observable statistical relationship between two datasets. In a financial time series context, it usually represents the extent to which sampled values from a pair of datasets, such as two series of price returns, vary jointly over time. More specifically, in this context, correlation describes the strength and direction of the relationship between the samples from both series.
If two separate time series tend to rise and fall together proportionally, they might be highly correlated. Likewise, if the series often vary in opposite directions, they might have a strong anticorrelation . If the two series do not exhibit a clear relationship, they might be uncorrelated .
Traders frequently analyze asset correlations to help optimize portfolios, assess market behaviors, identify potential risks, and support trading decisions. For instance, correlation often plays a key role in diversification . When two instruments exhibit a strong correlation in their returns, it might indicate that buying or selling both carries elevated unsystematic risk . Therefore, traders often aim to create balanced portfolios of relatively uncorrelated or anticorrelated assets to help promote investment diversity and potentially offset some of the risks.
When using correlation analysis to support investment decisions, it is crucial to understand the following caveats:
• Correlation does not imply causation . Two assets might vary jointly over an analyzed range, resulting in high correlation or anticorrelation in their returns, but that does not indicate that either instrument directly influences the other. Joint variability between assets might occur because of shared sensitivities to external factors, such as interest rates or global sentiment, or it might be entirely coincidental. In other words, correlation does not provide sufficient information to identify cause-and-effect relationships.
• Correlation does not predict the future relationship between two assets. It only reflects the estimated strength and direction of the relationship between the current analyzed samples. Financial time series are ever-changing. A strong trend between two assets can weaken or reverse in the future.
Correlation coefficient
A correlation coefficient is a numeric measure of correlation. Several coefficients exist, each quantifying different types of relationships between two datasets. The most common and widely known measure is the Pearson product-moment correlation coefficient , also known as the Pearson correlation coefficient or Pearson's r . Usually, when the term "correlation coefficient" is used without context, it refers to this correlation measure.
The Pearson correlation coefficient quantifies the strength and direction of the linear relationship between two variables. In other words, it indicates how consistently variables' values move together or in opposite directions in a proportional, linear manner. Its formula is as follows:
𝑟(𝑥, 𝑦) = cov(𝑥, 𝑦) / (𝜎𝑥 * 𝜎𝑦)
Where:
• 𝑥 is the first variable, and 𝑦 is the second variable.
• cov(𝑥, 𝑦) is the covariance between 𝑥 and 𝑦.
• 𝜎𝑥 is the standard deviation of 𝑥.
• 𝜎𝑦 is the standard deviation of 𝑦.
In essence, the correlation coefficient measures the covariance between two variables, normalized by the product of their standard deviations. The coefficient's value ranges from -1 to 1, allowing a more straightforward interpretation of the relationship between two datasets than what covariance alone provides:
• A value of 1 indicates a perfect positive correlation over the analyzed sample. As one variable's value changes, the other variable's value changes proportionally in the same direction .
• A value of -1 indicates a perfect negative correlation (anticorrelation). As one variable's value increases, the other variable's value decreases proportionally.
• A value of 0 indicates no linear relationship between the variables over the analyzed sample.
Aligning returns across instruments
In a financial time series, each data point (i.e., bar) in a sample represents information collected in periodic intervals. For instance, on a "1D" chart, bars form at specific times as successive days elapse.
However, the times of the data points for a symbol's standard dataset depend on its active sessions , and sessions vary across instrument types. For example, the daily session for NYSE stocks is 09:30 - 16:00 UTC-4/-5 on weekdays, Forex instruments have 24-hour sessions that span from 17:00 UTC-4/-5 on one weekday to 17:00 on the next, and new daily sessions for cryptocurrencies start at 00:00 UTC every day because crypto markets are consistently open.
Therefore, comparing the standard datasets for different asset types to identify correlations presents a challenge. If two symbols' datasets have bars that form at unaligned times, their correlation coefficient does not accurately describe their relationship. When calculating correlations between the returns for two assets, both datasets must maintain consistent time alignment in their values and cover identical ranges for meaningful results.
To address the issue of time alignment across instruments, this indicator requests confirmed weekly or monthly data from spread tickers constructed from the chart's ticker and another specified ticker. The datasets for spreads are derived from lower-timeframe data to ensure the values from all symbols come from aligned points in time, allowing a fair comparison between different instrument types. Additionally, each spread ticker ID includes necessary modifiers, such as extended hours and adjustments.
In this indicator, we use the following process to retrieve time-aligned returns for correlation calculations:
1. Request the current and previous prices from a spread representing the sum of the chart symbol and another symbol ( "chartSymbol + anotherSymbol" ).
2. Request the prices from another spread representing the difference between the two symbols ( "chartSymbol - anotherSymbol" ).
3. Calculate half of the difference between the values from both spreads ( 0.5 * (requestedSum - requestedDifference) ). The results represent the symbol's prices at times aligned with the sample points on the current chart.
4. Calculate the arithmetic return of the retrieved prices: (currentPrice - previousPrice) / previousPrice
5. Repeat steps 1-4 for each symbol requiring analysis.
It's crucial to note that because this process retrieves prices for a symbol at times consistent with periodic points on the current chart, the values can represent prices from before or after the closing time of the symbol's usual session.
Additionally, note that the maximum number of weeks or months in the correlation calculations depends on the chart's range and the largest time range common to all the requested symbols. To maximize the amount of data available for the calculations, we recommend setting the chart to use a daily or higher timeframe and specifying a chart symbol that covers a sufficient time range for your needs.
█ FEATURES
This indicator analyzes the correlations between several pairs of user-specified symbols to provide a structured, intuitive view of the relationships in their returns. Below are the indicator's key features:
Requesting a list of securities
The "Symbol list" text box in the indicator's "Settings/Inputs" tab accepts a comma-separated list of symbols or ticker identifiers with optional spaces (e.g., "XOM, MSFT, BITSTAMP:BTCUSD"). The indicator dynamically requests returns for each symbol in the list, then calculates the correlation between each pair of return series for its heatmap display.
Each item in the list must represent a valid symbol or ticker ID. If the list includes an invalid symbol, the script raises a runtime error.
To specify a broker/exchange for a symbol, include its name as a prefix with a colon in the "EXCHANGE:SYMBOL" format. If a symbol in the list does not specify an exchange prefix, the indicator selects the most commonly used exchange when requesting the data.
Note that the number of symbols allowed in the list depends on the user's plan. Users with non-professional plans can compare up to 20 symbols with this indicator, and users with professional plans can compare up to 32 symbols.
Timeframe and data length selection
The "Returns timeframe" input specifies whether the indicator uses weekly or monthly returns in its calculations. By default, its value is "1M", meaning the indicator analyzes monthly returns. Note that this script requires a chart timeframe lower than or equal to "1M". If the chart uses a higher timeframe, it causes a runtime error.
To customize the length of the data used in the correlation calculations, use the "Max periods" input. When enabled, the indicator limits the calculation window to the number of periods specified in the input field. Otherwise, it uses the chart's time range as the limit. The top-left corner of the table shows the number of confirmed weeks or months used in the calculations.
It's important to note that the number of confirmed periods in the correlation calculations is limited to the largest time range common to all the requested datasets, because a meaningful correlation matrix requires analyzing each symbol's returns under the same market conditions. Therefore, the correlation matrix can show different results for the same symbol pair if another listed symbol restricts the aligned data to a shorter time range.
Heatmap display
This indicator displays the correlations for each symbol pair in a heatmap-styled table representing a symmetric correlation matrix. Each row and column corresponds to a specific symbol, and the cells at their intersections correspond to symbol pairs . For example, the cell at the "AAPL" row and "MSFT" column shows the weekly or monthly correlation between those two symbols' returns. Likewise, the cell at the "MSFT" row and "AAPL" column shows the same value.
Note that the main diagonal cells in the display, where the row and column refer to the same symbol, all show a value of 1 because any series of non-na data is always perfectly correlated with itself.
The background of each correlation cell uses a gradient color based on the correlation value. By default, the gradient uses blue hues for positive correlation, orange hues for negative correlation, and white for no correlation. The intensity of each blue or orange hue corresponds to the strength of the measured correlation or anticorrelation. Users can customize the gradient's base colors using the inputs in the "Color gradient" section of the "Settings/Inputs" tab.
█ FOR Pine Script® CODERS
• This script uses the `getArrayFromString()` function from our ValueAtTime library to process the input list of symbols. The function splits the "string" value by its commas, then constructs an array of non-empty strings without leading or trailing whitespaces. Additionally, it uses the str.upper() function to convert each symbol's characters to uppercase.
• The script's `getAlignedReturns()` function requests time-aligned prices with two request.security() calls that use spread tickers based on the chart's symbol and another symbol. Then, it calculates the arithmetic return using the `changePercent()` function from the ta library. The `collectReturns()` function uses `getAlignedReturns()` within a loop and stores the data from each call within a matrix . The script calls the `arrayCorrelation()` function on pairs of rows from the returned matrix to calculate the correlation values.
• For consistency, the `getAlignedReturns()` function includes extended hours and dividend adjustment modifiers in its data requests. Additionally, it includes other settings inherited from the chart's context, such as "settlement-as-close" preferences.
• A Pine script can execute up to 40 or 64 unique `request.*()` function calls, depending on the user's plan. The maximum number of symbols this script compares is half the plan's limit, because `getAlignedReturns()` uses two request.security() calls.
• This script can use the request.security() function within a loop because all scripts in Pine v6 enable dynamic requests by default. Refer to the Dynamic requests section of the Other timeframes and data page to learn more about this feature, and see our v6 migration guide to learn what's new in Pine v6.
• The script's table uses two distinct color.from_gradient() calls in a switch structure to determine the cell colors for positive and negative correlation values. One call calculates the color for values from -1 to 0 based on the first and second input colors, and the other calculates the colors for values from 0 to 1 based on the second and third input colors.
Look first. Then leap.
ValueAtTime█ OVERVIEW
This library is a Pine Script® programming tool for accessing historical values in a time series using UNIX timestamps . Its data structure and functions index values by time, allowing scripts to retrieve past values based on absolute timestamps or relative time offsets instead of relying on bar index offsets.
█ CONCEPTS
UNIX timestamps
In Pine Script®, a UNIX timestamp is an integer representing the number of milliseconds elapsed since January 1, 1970, at 00:00:00 UTC (the UNIX Epoch ). The timestamp is a unique, absolute representation of a specific point in time. Unlike a calendar date and time, a UNIX timestamp's meaning does not change relative to any time zone .
This library's functions process series values and corresponding UNIX timestamps in pairs , offering a simplified way to identify values that occur at or near distinct points in time instead of on specific bars.
Storing and retrieving time-value pairs
This library's `Data` type defines the structure for collecting time and value information in pairs. Objects of the `Data` type contain the following two fields:
• `times` – An array of "int" UNIX timestamps for each recorded value.
• `values` – An array of "float" values for each saved timestamp.
Each index in both arrays refers to a specific time-value pair. For instance, the `times` and `values` elements at index 0 represent the first saved timestamp and corresponding value. The library functions that maintain `Data` objects queue up to one time-value pair per bar into the object's arrays, where the saved timestamp represents the bar's opening time .
Because the `times` array contains a distinct UNIX timestamp for each item in the `values` array, it serves as a custom mapping for retrieving saved values. All the library functions that return information from a `Data` object use this simple two-step process to identify a value based on time:
1. Perform a binary search on the `times` array to find the earliest saved timestamp closest to the specified time or offset and get the element's index.
2. Access the element from the `values` array at the retrieved index, returning the stored value corresponding to the found timestamp.
Value search methods
There are several techniques programmers can use to identify historical values from corresponding timestamps. This library's functions include three different search methods to locate and retrieve values based on absolute times or relative time offsets:
Timestamp search
Find the value with the earliest saved timestamp closest to a specified timestamp.
Millisecond offset search
Find the value with the earliest saved timestamp closest to a specified number of milliseconds behind the current bar's opening time. This search method provides a time-based alternative to retrieving historical values at specific bar offsets.
Period offset search
Locate the value with the earliest saved timestamp closest to a defined period offset behind the current bar's opening time. The function calculates the span of the offset based on a period string . The "string" must contain one of the following unit tokens:
• "D" for days
• "W" for weeks
• "M" for months
• "Y" for years
• "YTD" for year-to-date, meaning the time elapsed since the beginning of the bar's opening year in the exchange time zone.
The period string can include a multiplier prefix for all supported units except "YTD" (e.g., "2W" for two weeks).
Note that the precise span covered by the "M", "Y", and "YTD" units varies across time. The "1M" period can cover 28, 29, 30, or 31 days, depending on the bar's opening month and year in the exchange time zone. The "1Y" period covers 365 or 366 days, depending on leap years. The "YTD" period's span changes with each new bar, because it always measures the time from the start of the current bar's opening year.
█ CALCULATIONS AND USE
This library's functions offer a flexible, structured approach to retrieving historical values at or near specific timestamps, millisecond offsets, or period offsets for different analytical needs.
See below for explanations of the exported functions and how to use them.
Retrieving single values
The library includes three functions that retrieve a single stored value using timestamp, millisecond offset, or period offset search methods:
• `valueAtTime()` – Locates the saved value with the earliest timestamp closest to a specified timestamp.
• `valueAtTimeOffset()` – Finds the saved value with the earliest timestamp closest to the specified number of milliseconds behind the current bar's opening time.
• `valueAtPeriodOffset()` – Finds the saved value with the earliest timestamp closest to the period-based offset behind the current bar's opening time.
Each function has two overloads for advanced and simple use cases. The first overload searches for a value in a user-specified `Data` object created by the `collectData()` function (see below). It returns a tuple containing the found value and the corresponding timestamp.
The second overload maintains a `Data` object internally to store and retrieve values for a specified `source` series. This overload returns a tuple containing the historical `source` value, the corresponding timestamp, and the current bar's `source` value, making it helpful for comparing past and present values from requested contexts.
Retrieving multiple values
The library includes the following functions to retrieve values from multiple historical points in time, facilitating calculations and comparisons with values retrieved across several intervals:
• `getDataAtTimes()` – Locates a past `source` value for each item in a `timestamps` array. Each retrieved value's timestamp represents the earliest time closest to one of the specified timestamps.
• `getDataAtTimeOffsets()` – Finds a past `source` value for each item in a `timeOffsets` array. Each retrieved value's timestamp represents the earliest time closest to one of the specified millisecond offsets behind the current bar's opening time.
• `getDataAtPeriodOffsets()` – Finds a past value for each item in a `periods` array. Each retrieved value's timestamp represents the earliest time closest to one of the specified period offsets behind the current bar's opening time.
Each function returns a tuple with arrays containing the found `source` values and their corresponding timestamps. In addition, the tuple includes the current `source` value and the symbol's description, which also makes these functions helpful for multi-interval comparisons using data from requested contexts.
Processing period inputs
When writing scripts that retrieve historical values based on several user-specified period offsets, the most concise approach is to create a single text input that allows users to list each period, then process the "string" list into an array for use in the `getDataAtPeriodOffsets()` function.
This library includes a `getArrayFromString()` function to provide a simple way to process strings containing comma-separated lists of periods. The function splits the specified `str` by its commas and returns an array containing every non-empty item in the list with surrounding whitespaces removed. View the example code to see how we use this function to process the value of a text area input .
Calculating period offset times
Because the exact amount of time covered by a specified period offset can vary, it is often helpful to verify the resulting times when using the `valueAtPeriodOffset()` or `getDataAtPeriodOffsets()` functions to ensure the calculations work as intended for your use case.
The library's `periodToTimestamp()` function calculates an offset timestamp from a given period and reference time. With this function, programmers can verify the time offsets in a period-based data search and use the calculated offset times in additional operations.
For periods with "D" or "W" units, the function calculates the time offset based on the absolute number of milliseconds the period covers (e.g., `86400000` for "1D"). For periods with "M", "Y", or "YTD" units, the function calculates an offset time based on the reference time's calendar date in the exchange time zone.
Collecting data
All the `getDataAt*()` functions, and the second overloads of the `valueAt*()` functions, collect and maintain data internally, meaning scripts do not require a separate `Data` object when using them. However, the first overloads of the `valueAt*()` functions do not collect data, because they retrieve values from a user-specified `Data` object.
For cases where a script requires a separate `Data` object for use with these overloads or other custom routines, this library exports the `collectData()` function. This function queues each bar's `source` value and opening timestamp into a `Data` object and returns the object's ID.
This function is particularly useful when searching for values from a specific series more than once. For instance, instead of using multiple calls to the second overloads of `valueAt*()` functions with the same `source` argument, programmers can call `collectData()` to store each bar's `source` and opening timestamp, then use the returned `Data` object's ID in calls to the first `valueAt*()` overloads to reduce memory usage.
The `collectData()` function and all the functions that collect data internally include two optional parameters for limiting the saved time-value pairs to a sliding window: `timeOffsetLimit` and `timeframeLimit`. When either has a non-na argument, the function restricts the collected data to the maximum number of recent bars covered by the specified millisecond- and timeframe-based intervals.
NOTE : All calls to the functions that collect data for a `source` series can execute up to once per bar or realtime tick, because each stored value requires a unique corresponding timestamp. Therefore, scripts cannot call these functions iteratively within a loop . If a call to these functions executes more than once inside a loop's scope, it causes a runtime error.
█ EXAMPLE CODE
The example code at the end of the script demonstrates one possible use case for this library's functions. The code retrieves historical price data at user-specified period offsets, calculates price returns for each period from the retrieved data, and then populates a table with the results.
The example code's process is as follows:
1. Input a list of periods – The user specifies a comma-separated list of period strings in the script's "Period list" input (e.g., "1W, 1M, 3M, 1Y, YTD"). Each item in the input list represents a period offset from the latest bar's opening time.
2. Process the period list – The example calls `getArrayFromString()` on the first bar to split the input list by its commas and construct an array of period strings.
3. Request historical data – The code uses a call to `getDataAtPeriodOffsets()` as the `expression` argument in a request.security() call to retrieve the closing prices of "1D" bars for each period included in the processed `periods` array.
4. Display information in a table – On the latest bar, the code uses the retrieved data to calculate price returns over each specified period, then populates a two-row table with the results. The cells for each return percentage are color-coded based on the magnitude and direction of the price change. The cells also include tooltips showing the compared daily bar's opening date in the exchange time zone.
█ NOTES
• This library's architecture relies on a user-defined type (UDT) for its data storage format. UDTs are blueprints from which scripts create objects , i.e., composite structures with fields containing independent values or references of any supported type.
• The library functions search through a `Data` object's `times` array using the array.binary_search_leftmost() function, which is more efficient than looping through collected data to identify matching timestamps. Note that this built-in works only for arrays with elements sorted in ascending order .
• Each function that collects data from a `source` series updates the values and times stored in a local `Data` object's arrays. If a single call to these functions were to execute in a loop , it would store multiple values with an identical timestamp, which can cause erroneous search behavior. To prevent looped calls to these functions, the library uses the `checkCall()` helper function in their scopes. This function maintains a counter that increases by one each time it executes on a confirmed bar. If the count exceeds the total number of bars, indicating the call executes more than once in a loop, it raises a runtime error .
• Typically, when requesting higher-timeframe data with request.security() while using barmerge.lookahead_on as the `lookahead` argument, the `expression` argument should be offset with the history-referencing operator to prevent lookahead bias on historical bars. However, the call in this script's example code enables lookahead without offsetting the `expression` because the script displays results only on the last historical bar and all realtime bars, where there is no future data to leak into the past. This call ensures the displayed results use the latest data available from the context on realtime bars.
Look first. Then leap.
█ EXPORTED TYPES
Data
A structure for storing successive timestamps and corresponding values from a dataset.
Fields:
times (array) : An "int" array containing a UNIX timestamp for each value in the `values` array.
values (array) : A "float" array containing values corresponding to the timestamps in the `times` array.
█ EXPORTED FUNCTIONS
getArrayFromString(str)
Splits a "string" into an array of substrings using the comma (`,`) as the delimiter. The function trims surrounding whitespace characters from each substring, and it excludes empty substrings from the result.
Parameters:
str (series string) : The "string" to split into an array based on its commas.
Returns: (array) An array of trimmed substrings from the specified `str`.
periodToTimestamp(period, referenceTime)
Calculates a UNIX timestamp representing the point offset behind a reference time by the amount of time within the specified `period`.
Parameters:
period (series string) : The period string, which determines the time offset of the returned timestamp. The specified argument must contain a unit and an optional multiplier (e.g., "1Y", "3M", "2W", "YTD"). Supported units are:
- "Y" for years.
- "M" for months.
- "W" for weeks.
- "D" for days.
- "YTD" (Year-to-date) for the span from the start of the `referenceTime` value's year in the exchange time zone. An argument with this unit cannot contain a multiplier.
referenceTime (series int) : The millisecond UNIX timestamp from which to calculate the offset time.
Returns: (int) A millisecond UNIX timestamp representing the offset time point behind the `referenceTime`.
collectData(source, timeOffsetLimit, timeframeLimit)
Collects `source` and `time` data successively across bars. The function stores the information within a `Data` object for use in other exported functions/methods, such as `valueAtTimeOffset()` and `valueAtPeriodOffset()`. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
source (series float) : The source series to collect. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: (Data) A `Data` object containing collected `source` values and corresponding timestamps over the allowed time range.
method valueAtTime(data, timestamp)
(Overload 1 of 2) Retrieves value and time data from a `Data` object's fields at the index of the earliest timestamp closest to the specified `timestamp`. Callable as a method or a function.
Parameters:
data (series Data) : The `Data` object containing the collected time and value data.
timestamp (series int) : The millisecond UNIX timestamp to search. The function returns data for the earliest saved timestamp that is closest to the value.
Returns: ( ) A tuple containing the following data from the `Data` object:
- The stored value corresponding to the identified timestamp ("float").
- The earliest saved timestamp that is closest to the specified `timestamp` ("int").
valueAtTime(source, timestamp, timeOffsetLimit, timeframeLimit)
(Overload 2 of 2) Retrieves `source` and time information for the earliest bar whose opening timestamp is closest to the specified `timestamp`. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
source (series float) : The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timestamp (series int) : The millisecond UNIX timestamp to search. The function returns data for the earliest bar whose timestamp is closest to the value.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : (simple string) Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple containing the following data:
- The `source` value corresponding to the identified timestamp ("float").
- The earliest bar's timestamp that is closest to the specified `timestamp` ("int").
- The current bar's `source` value ("float").
method valueAtTimeOffset(data, timeOffset)
(Overload 1 of 2) Retrieves value and time data from a `Data` object's fields at the index of the earliest saved timestamp closest to `timeOffset` milliseconds behind the current bar's opening time. Callable as a method or a function.
Parameters:
data (series Data) : The `Data` object containing the collected time and value data.
timeOffset (series int) : The millisecond offset behind the bar's opening time. The function returns data for the earliest saved timestamp that is closest to the calculated offset time.
Returns: ( ) A tuple containing the following data from the `Data` object:
- The stored value corresponding to the identified timestamp ("float").
- The earliest saved timestamp that is closest to `timeOffset` milliseconds before the current bar's opening time ("int").
valueAtTimeOffset(source, timeOffset, timeOffsetLimit, timeframeLimit)
(Overload 2 of 2) Retrieves `source` and time information for the earliest bar whose opening timestamp is closest to `timeOffset` milliseconds behind the current bar's opening time. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
source (series float) : The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timeOffset (series int) : The millisecond offset behind the bar's opening time. The function returns data for the earliest bar's timestamp that is closest to the calculated offset time.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple containing the following data:
- The `source` value corresponding to the identified timestamp ("float").
- The earliest bar's timestamp that is closest to `timeOffset` milliseconds before the current bar's opening time ("int").
- The current bar's `source` value ("float").
method valueAtPeriodOffset(data, period)
(Overload 1 of 2) Retrieves value and time data from a `Data` object's fields at the index of the earliest timestamp closest to a calculated offset behind the current bar's opening time. The calculated offset represents the amount of time covered by the specified `period`. Callable as a method or a function.
Parameters:
data (series Data) : The `Data` object containing the collected time and value data.
period (series string) : The period string, which determines the calculated time offset. The specified argument must contain a unit and an optional multiplier (e.g., "1Y", "3M", "2W", "YTD"). Supported units are:
- "Y" for years.
- "M" for months.
- "W" for weeks.
- "D" for days.
- "YTD" (Year-to-date) for the span from the start of the current bar's year in the exchange time zone. An argument with this unit cannot contain a multiplier.
Returns: ( ) A tuple containing the following data from the `Data` object:
- The stored value corresponding to the identified timestamp ("float").
- The earliest saved timestamp that is closest to the calculated offset behind the bar's opening time ("int").
valueAtPeriodOffset(source, period, timeOffsetLimit, timeframeLimit)
(Overload 2 of 2) Retrieves `source` and time information for the earliest bar whose opening timestamp is closest to a calculated offset behind the current bar's opening time. The calculated offset represents the amount of time covered by the specified `period`. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
source (series float) : The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
period (series string) : The period string, which determines the calculated time offset. The specified argument must contain a unit and an optional multiplier (e.g., "1Y", "3M", "2W", "YTD"). Supported units are:
- "Y" for years.
- "M" for months.
- "W" for weeks.
- "D" for days.
- "YTD" (Year-to-date) for the span from the start of the current bar's year in the exchange time zone. An argument with this unit cannot contain a multiplier.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple containing the following data:
- The `source` value corresponding to the identified timestamp ("float").
- The earliest bar's timestamp that is closest to the calculated offset behind the current bar's opening time ("int").
- The current bar's `source` value ("float").
getDataAtTimes(timestamps, source, timeOffsetLimit, timeframeLimit)
Retrieves `source` and time information for each bar whose opening timestamp is the earliest one closest to one of the UNIX timestamps specified in the `timestamps` array. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
timestamps (array) : An array of "int" values representing UNIX timestamps. The function retrieves `source` and time data for each element in this array.
source (series float) : The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple of the following data:
- An array containing a `source` value for each identified timestamp (array).
- An array containing an identified timestamp for each item in the `timestamps` array (array).
- The current bar's `source` value ("float").
- The symbol's description from `syminfo.description` ("string").
getDataAtTimeOffsets(timeOffsets, source, timeOffsetLimit, timeframeLimit)
Retrieves `source` and time information for each bar whose opening timestamp is the earliest one closest to one of the time offsets specified in the `timeOffsets` array. Each offset in the array represents the absolute number of milliseconds behind the current bar's opening time. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
timeOffsets (array) : An array of "int" values representing the millisecond time offsets used in the search. The function retrieves `source` and time data for each element in this array. For example, the array ` ` specifies that the function returns data for the timestamps closest to one day and one week behind the current bar's opening time.
source (float) : (series float) The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple of the following data:
- An array containing a `source` value for each identified timestamp (array).
- An array containing an identified timestamp for each offset specified in the `timeOffsets` array (array).
- The current bar's `source` value ("float").
- The symbol's description from `syminfo.description` ("string").
getDataAtPeriodOffsets(periods, source, timeOffsetLimit, timeframeLimit)
Retrieves `source` and time information for each bar whose opening timestamp is the earliest one closest to a calculated offset behind the current bar's opening time. Each calculated offset represents the amount of time covered by a period specified in the `periods` array. Any call to this function cannot execute more than once per bar or realtime tick.
Parameters:
periods (array) : An array of period strings, which determines the time offsets used in the search. The function retrieves `source` and time data for each element in this array. For example, the array ` ` specifies that the function returns data for the timestamps closest to one day, week, and month behind the current bar's opening time. Each "string" in the array must contain a unit and an optional multiplier. Supported units are:
- "Y" for years.
- "M" for months.
- "W" for weeks.
- "D" for days.
- "YTD" (Year-to-date) for the span from the start of the current bar's year in the exchange time zone. An argument with this unit cannot contain a multiplier.
source (float) : (series float) The source series to analyze. The function stores each value in the series with an associated timestamp representing its corresponding bar's opening time.
timeOffsetLimit (simple int) : Optional. A time offset (range) in milliseconds. If specified, the function limits the collected data to the maximum number of bars covered by the range, with a minimum of one bar. If the call includes a non-empty `timeframeLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
timeframeLimit (simple string) : Optional. A valid timeframe string. If specified and not empty, the function limits the collected data to the maximum number of bars covered by the timeframe, with a minimum of one bar. If the call includes a non-na `timeOffsetLimit` value, the function limits the data using the largest number of bars covered by the two ranges. The default is `na`.
Returns: ( ) A tuple of the following data:
- An array containing a `source` value for each identified timestamp (array).
- An array containing an identified timestamp for each period specified in the `periods` array (array).
- The current bar's `source` value ("float").
- The symbol's description from `syminfo.description` ("string").
Ticker Tape█ OVERVIEW
This indicator creates a dynamic, scrolling display of multiple securities' latest prices and daily changes, similar to the ticker tapes on financial news channels and the Ticker Tape Widget . It shows realtime market information for a user-specified list of symbols along the bottom of the main chart pane.
█ CONCEPTS
Ticker tape
Traditionally, a ticker tape was a continuous, narrow strip of paper that displayed stock prices, trade volumes, and other financial and security information. Invented by Edward A. Calahan in 1867, ticker tapes were the earliest method for electronically transmitting live stock market data.
A machine known as a "stock ticker" received stock information via telegraph, printing abbreviated company names, transaction prices, and other information in a linear sequence on the paper as new data came in. The term "ticker" in the name comes from the "tick" sound the machine made as it printed stock information. The printed tape provided a running record of trading activity, allowing market participants to stay informed on recent market conditions without needing to be on the exchange floor.
In modern times, electronic displays have replaced physical ticker tapes. However, the term "ticker" remains persistent in today's financial lexicon. Nowadays, ticker symbols and digital tickers appear on financial news networks, trading platforms, and brokerage/exchange websites, offering live updates on market information. Modern electronic displays, thankfully, do not rely on telegraph updates to operate.
█ FEATURES
Requesting a list of securities
The "Symbol list" text box in the indicator's "Settings/Inputs" tab allows users to list up to 40 symbols or ticker Identifiers. The indicator dynamically requests and displays information for each one. To add symbols to the list, enter their names separated by commas . For example: "BITSTAMP:BTCUSD, TSLA, MSFT".
Each item in the comma-separated list must represent a valid symbol or ticker ID. If the list includes an invalid symbol, the script will raise a runtime error.
To specify a broker/exchange for a symbol, include its name as a prefix with a colon in the "EXCHANGE:SYMBOL" format. If a symbol in the list does not specify an exchange prefix, the indicator selects the most commonly used exchange when requesting the data.
Realtime updates
This indicator requests symbol descriptions, current market prices, daily price changes, and daily change percentages for each ticker from the user-specified list of symbols or ticker identifiers. It receives updated information for each security after new realtime ticks on the current chart.
After a new realtime price update, the indicator updates the values shown in the tape display and their colors.
The color of the percentages in the tape depends on the change in price from the previous day . The text is green when the daily change is positive, red when the value is negative, and gray when the value is 0.
The color of each displayed price depends on the change in value from the last recorded update, not the change over a daily period. For example, if a security's price increases in the latest update, the ticker tape shows that price with green text, even if the current price is below the previous day's closing price. This behavior allows users to monitor realtime directional changes in the requested securities.
NOTE: Pine scripts execute on realtime bars when new ticks are available in the chart's data feed. If no new updates are available from the chart's realtime feed, it may cause a delay in the data the indicator receives.
Ticker motion
This indicator's tape display shows a list of security information that incrementally scrolls horizontally from right to left after new chart updates, providing a dynamic visual stream of current market data. The scrolling effect works by using a counter that increments across successive intervals after realtime ticks to control the offset of each listed security. Users can set the initial scroll offset with the "Offset" input in the "Settings/Inputs" tab.
The scrolling rate of the ticker tape display depends on the realtime ticks available from the chart's data feed. Using the indicator on a chart with frequent realtime updates results in smoother scrolling. If no new realtime ticks are available in the chart's feed, the ticker tape does not move. Users can also deactivate the scrolling feature by toggling the "Running" input in the indicator's settings.
█ FOR Pine Script™ CODERS
• This script utilizes dynamic requests to iteratively fetch information from multiple contexts using a single request.security() instance in the code. Previously, `request.*()` functions were not allowed within the local scopes of loops or conditional structures, and most `request.*()` function parameters, excluding `expression`, required arguments of a simple or weaker qualified type. The new `dynamic_requests` parameter in script declaration statements enables more flexibility in how scripts can use `request.*()` calls. When its value is `true`, all `request.*()` functions can accept series arguments for the parameters that define their requested contexts, and `request.*()` functions can execute within local scopes. See the Dynamic requests section of the Pine Script™ User Manual to learn more.
• Scripts can execute up to 40 unique `request.*()` function calls. A `request.*()` call is unique only if the script does not already call the same function with the same arguments. See this section of the User Manual's Limitations page for more information.
• This script converts a comma-separated "string" list of symbols or ticker IDs into an array . It then loops through this array, dynamically requesting data from each symbol's context and storing the results within a collection of custom `Tape` objects . Each `Tape` instance holds information about a symbol, which the script uses to populate the table that displays the ticker tape.
• This script uses the varip keyword to declare variables and `Tape` fields that update across ticks on unconfirmed bars without rolling back. This behavior allows the script to color the tape's text based on the latest price movements and change the locations of the table cells after realtime updates without reverting. See the `varip` section of the User Manual to learn more about using this keyword.
• Typically, when requesting higher-timeframe data with request.security() using barmerge.lookahead_on as the `lookahead` argument, the `expression` argument should use the history-referencing operator to offset the series, preventing lookahead bias on historical bars. However, the request.security() call in this script uses barmerge.lookahead_on without offsetting the `expression` because the script only displays results for the latest historical bar and all realtime bars, where there is no future information to leak into the past. Instead, using this call on those bars ensures each request fetches the most recent data available from each context.
• The request.security() instance in this script includes a `calc_bars_count` argument to specify that each request retrieves only a minimal number of bars from the end of each symbol's historical data feed. The script does not need to request all the historical data for each symbol because it only shows results on the last chart bar that do not depend on the entire time series. In this case, reducing the retrieved bars in each request helps minimize resource usage without impacting the calculated results.
Look first. Then leap.
RiskMetrics█ OVERVIEW
This library is a tool for Pine programmers that provides functions for calculating risk-adjusted performance metrics on periodic price returns. The calculations used by this library's functions closely mirror those the Broker Emulator uses to calculate strategy performance metrics (e.g., Sharpe and Sortino ratios) without depending on strategy-specific functionality.
█ CONCEPTS
Returns, risk, and volatility
The return on an investment is the relative gain or loss over a period, often expressed as a percentage. Investment returns can originate from several sources, including capital gains, dividends, and interest income. Many investors seek the highest returns possible in the quest for profit. However, prudent investing and trading entails evaluating such returns against the associated risks (i.e., the uncertainty of returns and the potential for financial losses) for a clearer perspective on overall performance and sustainability.
One way investors and analysts assess the risk of an investment is by analyzing its volatility , i.e., the statistical dispersion of historical returns. Investors often use volatility in risk estimation because it provides a quantifiable way to gauge the expected extent of fluctuation in returns. Elevated volatility implies heightened uncertainty in the market, which suggests higher expected risk. Conversely, low volatility implies relatively stable returns with relatively minimal fluctuations, thus suggesting lower expected risk. Several risk-adjusted performance metrics utilize volatility in their calculations for this reason.
Risk-free rate
The risk-free rate represents the rate of return on a hypothetical investment carrying no risk of financial loss. This theoretical rate provides a benchmark for comparing the returns on a risky investment and evaluating whether its excess returns justify the risks. If an investment's returns are at or below the theoretical risk-free rate or the risk premium is below a desired amount, it may suggest that the returns do not compensate for the extra risk, which might be a call to reassess the investment.
Since the risk-free rate is a theoretical concept, investors often utilize proxies for the rate in practice, such as Treasury bills and other government bonds. Conventionally, analysts consider such instruments "risk-free" for a domestic holder, as they are a form of government obligation with a low perceived likelihood of default.
The average yield on short-term Treasury bills, influenced by economic conditions, monetary policies, and inflation expectations, has historically hovered around 2-3% over the long term. This range also aligns with central banks' inflation targets. As such, one may interpret a value within this range as a minimum proxy for the risk-free rate, as it may correspond to the minimum rate required to maintain purchasing power over time.
The built-in Sharpe and Sortino ratios that strategies calculate and display in the Performance Summary tab use a default risk-free rate of 2%, and the metrics in this library's example code use the same default rate. Users can adjust this value to fit their analysis needs.
Risk-adjusted performance
Risk-adjusted performance metrics gauge the effectiveness of an investment by considering its returns relative to the perceived risk. They aim to provide a more well-rounded picture of performance by factoring in the level of risk taken to achieve returns. Investors can utilize such metrics to help determine whether the returns from an investment justify the risks and make informed decisions.
The two most commonly used risk-adjusted performance metrics are the Sharpe ratio and the Sortino ratio.
1. Sharpe ratio
The Sharpe ratio , developed by Nobel laureate William F. Sharpe, measures the performance of an investment compared to a theoretically risk-free asset, adjusted for the investment risk. The ratio uses the following formula:
Sharpe Ratio = (𝑅𝑎 − 𝑅𝑓) / 𝜎𝑎
Where:
• 𝑅𝑎 = Average return of the investment
• 𝑅𝑓 = Theoretical risk-free rate of return
• 𝜎𝑎 = Standard deviation of the investment's returns (volatility)
A higher Sharpe ratio indicates a more favorable risk-adjusted return, as it signifies that the investment produced higher excess returns per unit of increase in total perceived risk.
2. Sortino ratio
The Sortino ratio is a modified form of the Sharpe ratio that only considers downside volatility , i.e., the volatility of returns below the theoretical risk-free benchmark. Although it shares close similarities with the Sharpe ratio, it can produce very different values, especially when the returns do not have a symmetrical distribution, since it does not penalize upside and downside volatility equally. The ratio uses the following formula:
Sortino Ratio = (𝑅𝑎 − 𝑅𝑓) / 𝜎𝑑
Where:
• 𝑅𝑎 = Average return of the investment
• 𝑅𝑓 = Theoretical risk-free rate of return
• 𝜎𝑑 = Downside deviation (standard deviation of negative excess returns, or downside volatility)
The Sortino ratio offers an alternative perspective on an investment's return-generating efficiency since it does not consider upside volatility in its calculation. A higher Sortino ratio signifies that the investment produced higher excess returns per unit of increase in perceived downside risk.
█ CALCULATIONS
Return period detection
Calculating risk-adjusted performance metrics requires collecting returns across several periods of a given size. Analysts may use different period sizes based on the context and their preferences. However, two widely used standards are monthly or daily periods, depending on the available data and the investment's duration. The built-in ratios displayed in the Strategy Tester utilize returns from either monthly or daily periods in their calculations based on the following logic:
• Use monthly returns if the history of closed trades spans at least two months.
• Use daily returns if the trades span at least two days but less than two months.
• Do not calculate the ratios if the trade data spans fewer than two days.
This library's `detectPeriod()` function applies related logic to available chart data rather than trade data to determine which period is appropriate:
• It returns true if the chart's data spans at least two months, indicating that it's sufficient to use monthly periods.
• It returns false if the chart's data spans at least two days but not two months, suggesting the use of daily periods.
• It returns na if the length of the chart's data covers less than two days, signifying that the data is insufficient for meaningful ratio calculations.
It's important to note that programmers should only call `detectPeriod()` from a script's global scope or within the outermost scope of a function called from the global scope, as it requires the time value from the first bar to accurately measure the amount of time covered by the chart's data.
Collecting periodic returns
This library's `getPeriodicReturns()` function tracks price return data within monthly or daily periods and stores the periodic values in an array . It uses a `detectPeriod()` call as the condition to determine whether each element in the array represents the return over a monthly or daily period.
The `getPeriodicReturns()` function has two overloads. The first overload requires two arguments and outputs an array of monthly or daily returns for use in the `sharpe()` and `sortino()` methods. To calculate these returns:
1. The `percentChange` argument should be a series that represents percentage gains or losses. The values can be bar-to-bar return percentages on the chart timeframe or percentages requested from a higher timeframe.
2. The function compounds all non-na `percentChange` values within each monthly or daily period to calculate the period's total return percentage. When the `percentChange` represents returns from a higher timeframe, ensure the requested data includes gaps to avoid compounding redundant values.
3. After a period ends, the function queues the compounded return into the array , removing the oldest element from the array when its size exceeds the `maxPeriods` argument.
The resulting array represents the sequence of closed returns over up to `maxPeriods` months or days, depending on the available data.
The second overload of the function includes an additional `benchmark` parameter. Unlike the first overload, this version tracks and collects differences between the `percentChange` and the specified `benchmark` values. The resulting array represents the sequence of excess returns over up to `maxPeriods` months or days. Passing this array to the `sharpe()` and `sortino()` methods calculates generalized Information ratios , which represent the risk-adjustment performance of a sequence of returns compared to a risky benchmark instead of a risk-free rate. For consistency, ensure the non-na times of the `benchmark` values align with the times of the `percentChange` values.
Ratio methods
This library's `sharpe()` and `sortino()` methods respectively calculate the Sharpe and Sortino ratios based on an array of returns compared to a specified annual benchmark. Both methods adjust the annual benchmark based on the number of periods per year to suit the frequency of the returns:
• If the method call does not include a `periodsPerYear` argument, it uses `detectPeriod()` to determine whether the returns represent monthly or daily values based on the chart's history. If monthly, the method divides the `annualBenchmark` value by 12. If daily, it divides the value by 365.
• If the method call does specify a `periodsPerYear` argument, the argument's value supersedes the automatic calculation, facilitating custom benchmark adjustments, such as dividing by 252 when analyzing collected daily stock returns.
When the array passed to these methods represents a sequence of excess returns , such as the result from the second overload of `getPeriodicReturns()`, use an `annualBenchmark` value of 0 to avoid comparing those excess returns to a separate rate.
By default, these methods only calculate the ratios on the last available bar to minimize their resource usage. Users can override this behavior with the `forceCalc` parameter. When the value is true , the method calculates the ratio on each call if sufficient data is available, regardless of the bar index.
Look first. Then leap.
█ FUNCTIONS & METHODS
This library contains the following functions:
detectPeriod()
Determines whether the chart data has sufficient coverage to use monthly or daily returns
for risk metric calculations.
Returns: (bool) `true` if the period spans more than two months, `false` if it otherwise spans more
than two days, and `na` if the data is insufficient.
getPeriodicReturns(percentChange, maxPeriods)
(Overload 1 of 2) Tracks periodic return percentages and queues them into an array for ratio
calculations. The span of the chart's historical data determines whether the function uses
daily or monthly periods in its calculations. If the chart spans more than two months,
it uses "1M" periods. Otherwise, if the chart spans more than two days, it uses "1D"
periods. If the chart covers less than two days, it does not store changes.
Parameters:
percentChange (float) : (series float) The change percentage. The function compounds non-na values from each
chart bar within monthly or daily periods to calculate the periodic changes.
maxPeriods (simple int) : (simple int) The maximum number of periodic returns to store in the returned array.
Returns: (array) An array containing the overall percentage changes for each period, limited
to the maximum specified by `maxPeriods`.
getPeriodicReturns(percentChange, benchmark, maxPeriods)
(Overload 2 of 2) Tracks periodic excess return percentages and queues the values into an
array. The span of the chart's historical data determines whether the function uses
daily or monthly periods in its calculations. If the chart spans more than two months,
it uses "1M" periods. Otherwise, if the chart spans more than two days, it uses "1D"
periods. If the chart covers less than two days, it does not store changes.
Parameters:
percentChange (float) : (series float) The change percentage. The function compounds non-na values from each
chart bar within monthly or daily periods to calculate the periodic changes.
benchmark (float) : (series float) The benchmark percentage to compare against `percentChange` values.
The function compounds non-na values from each bar within monthly or
daily periods and subtracts the results from the compounded `percentChange` values to
calculate the excess returns. For consistency, ensure this series has a similar history
length to the `percentChange` with aligned non-na value times.
maxPeriods (simple int) : (simple int) The maximum number of periodic excess returns to store in the returned array.
Returns: (array) An array containing monthly or daily excess returns, limited
to the maximum specified by `maxPeriods`.
method sharpeRatio(returnsArray, annualBenchmark, forceCalc, periodsPerYear)
Calculates the Sharpe ratio for an array of periodic returns.
Callable as a method or a function.
Namespace types: array
Parameters:
returnsArray (array) : (array) An array of periodic return percentages, e.g., returns over monthly or
daily periods.
annualBenchmark (float) : (series float) The annual rate of return to compare against `returnsArray` values. When
`periodsPerYear` is `na`, the function divides this value by 12 to calculate a
monthly benchmark if the chart's data spans at least two months or 365 for a daily
benchmark if the data otherwise spans at least two days. If `periodsPerYear`
has a specified value, the function divides the rate by that value instead.
forceCalc (bool) : (series bool) If `true`, calculates the ratio on every call. Otherwise, ratio calculation
only occurs on the last available bar. Optional. The default is `false`.
periodsPerYear (simple int) : (simple int) If specified, divides the annual rate by this value instead of the value
determined by the time span of the chart's data.
Returns: (float) The Sharpe ratio, which estimates the excess return per unit of total volatility.
method sortinoRatio(returnsArray, annualBenchmark, forceCalc, periodsPerYear)
Calculates the Sortino ratio for an array of periodic returns.
Callable as a method or a function.
Namespace types: array
Parameters:
returnsArray (array) : (array) An array of periodic return percentages, e.g., returns over monthly or
daily periods.
annualBenchmark (float) : (series float) The annual rate of return to compare against `returnsArray` values. When
`periodsPerYear` is `na`, the function divides this value by 12 to calculate a
monthly benchmark if the chart's data spans at least two months or 365 for a daily
benchmark if the data otherwise spans at least two days. If `periodsPerYear`
has a specified value, the function divides the rate by that value instead.
forceCalc (bool) : (series bool) If `true`, calculates the ratio on every call. Otherwise, ratio calculation
only occurs on the last available bar. Optional. The default is `false`.
periodsPerYear (simple int) : (simple int) If specified, divides the annual rate by this value instead of the value
determined by the time span of the chart's data.
Returns: (float) The Sortino ratio, which estimates the excess return per unit of downside
volatility.
Visible Fibonacci█ OVERVIEW
This indicator displays Fibonacci retracement and extension levels on the price chart using data within the chart's visible range, providing traders with an automated alternative to our well-known drawing tool .
█ CONCEPTS
Fibonacci sequence and the Golden ratio
The Fibonacci sequence is a sequence of numbers where each term is the sum of the previous two terms. In his book Liber Abaci , Fibonacci used this sequence to estimate the growth of rabbit populations. Although most commonly associated with Fibonacci, this numeric sequence appeared in Indian mathematics as early as 200 BC. As this sequence approaches infinity, the ratio of the last element to the preceding approaches the Golden ratio (1.618033...), a well-known metallic ratio theoretically observed in many natural and synthetic systems. Many traders believe that the Fibonacci sequence and the Golden ratio carry significance in the financial markets.
Fibonacci retracements and extensions
Fibonacci retracements and extensions are extremely popular in technical analysis. They are created by connecting two extreme points, typically pivot points, by a trend line and multiplying the range between them by the ratios of steps in the Fibonacci sequence, or more precisely, powers of the Golden Ratio, to produce estimated levels of support and resistance. The ratios used for retracement multipliers are typically the Golden ratio raised to the power of 0, -0.5, -1, -2, and -3, or 1, 0.786, 0.618, 0.382, and 0.236, respectively. It is also common to see traders use a retracement ratio of 0.5. The ratios used for extension multipliers are typically the Golden ratio raised to the power of 0.5, 1, 2, and 3, or 1.272, 1.618, 2.618, and 4.236, respectively. Traders often combine these retracement and extension ratios with others they deem significant for a more personalized output.
Zig Zag
Zig Zag is a popular indicator that filters out minor price fluctuations to denoise data and emphasize trends. Traders commonly use Zig Zag for trend confirmation, identifying potential support and resistance, and pattern detection. It is formed by identifying significant local high and low points in alternating order and connecting them with straight lines, omitting all other data points from their output. There are several ways to calculate the Zig Zag's data points and the conditions by which its direction changes. This script uses the highest and lowest values over a specified length to estimate the locations of pivots. The Zig Zag reverses its direction when a new high or low emerges in the opposite direction. Additionally, enabling the "Detect additional pivots" option in the script settings will locate extra pivots when the number of bars in which no new pivot occurs exceeds the Zig Zag length.
Visible Fibonacci
This script uses the chart's visible bars to calculate and display an automated Fibonacci retracement tool with extreme points based on either of two calculation methods:
• Visible Chart Range: This method uses the highest and lowest points from the visible chart range for Fibonacci level calculation.
• Visible Zig Zag: This method uses historical pivots from a Zig Zag indicator for level calculation. The "nth Last Pivot" input in the script settings controls how many pivots back from the last visible one will be used to calculate the Fibonacci levels.
As traders pan and zoom on their charts, the script dynamically recalculates its values explicitly using the bars within the visible range.
Note that levels drawn outside the range between the high and low points may affect the scale of the chart. To prevent this, select the "Scale price chart only" option in the chart settings.
█ FOR Pine Script™ CODERS
• This script utilizes functions from the VisibleChart library by our resident PineCoders . The library exploits the chart.left_visible_bar_time and chart.right_visible_bar_time variables, which return the opening time of the leftmost and rightmost bars on the chart. They are only two of many new built-ins in the `chart.*` namespace. See this blog post for more information, or look them up by typing "chart." in the Pine Script™ Reference Manual .
• This script's architecture utilizes user-defined types (UDTs) to create custom objects which are the equivalent of variables containing multiple parts, each able to hold independent values of different types . The recently added feature was announced in this blog post.
Look first. Then leap.