Quick scan for cycles🙏🏻
The followup for
As I told before, ML based algorading is all about detecting any kind of non-randomness & exploiting it (cuz allegedly u cant trade randomness), and cycles are legit patterns that can be leveraged
But bro would u really apply Fourier / Wavelets / 'whatever else heavy' on every update of thousands of datasets, esp in real time on HFT / nearly HFT data? That's why this metric. It works much faster & eats hell of a less electicity, will do initial rough filtering of time series that might contain any kind of cyclic behaviour. And then, only on these filtered datasets u gonna put Periodograms / Autocorrelograms and see what's going there for real. Better to do it 10x times less a day on 10x less datasets, right?
I ended up with 2 methods / formulas, I called em 'type 0' and 'type 1':
- type 0: takes sum of abs deviations from drift line, scales it by max abs deviation from the same drift line;
- type 1: takes sum of abs deviations from drift line, scales it by range of non-abs deviations from the same drift line.
Finnaly I've chosen type 0 , both logically (sum of abs dev divided by max abs dev makes more sense) and experimentally. About that actually, here are both formulas put on sine waves with uniform noise:
^^ generated sine wave with uniform noise
^^ both formulas on that wave
^^ both formulas on real data
As you can see type 0 is less affected by noise and shows higher values on synthetic data, but I decided to put type 1 inside as well, in case my analysis was not complete and on real data type 1 can actually be better since it has a lil higher info gain / info content (still not sure). But I can assure u that out of all other ways I've designed & tested for quite a time I tell you, these 2 are really the only ones who got there.
Now about dem thresholds and how to use it.
Both type 0 and type 1 can be modelled with Beta distribution, and based on it and on some obvious & tho non mainstream statistical modelling techniques, I got these thresholds, so these are not optimized overfitted values, but natural ones. Each type has 3 thresholds (from lowest to highest):
- typical value (turned off by default). aka basis ;
- typical deviation from typical value, aka deviation ;
- maximum modelled deviation from typical value (idk whow to call it properly for now, this is my own R&D), aka extension .
So when the metric is above one of these thresholds (which one is up to you, you'll read about it in a sec), it means that there might be a strong enough periodic signal inside the data, and the data got to be put through proper spectral analysis tools to confirm / deny it.
If you look at the pictures above again, you'll see gray signal, that's uniform noise. Take a look at it and see where does it sit comparing to the thresholds. Now you just undertand that picking up a threshold is all about the amount of false positives you care to withstand.
If you take basis as threshold, you'll get tons of false positives (that's why it's even turned off by default), but you'll almost never miss a true positive. If you take deviation as threshold, it's gonna be kinda balanced approach. If you take extension as threshold, you gonna miss some cycles, and gonna get only the strongest ones.
More true positives -> more false positives, less false positives -> less true positives, can't go around that mane
Just to be clear again, I am not completely sure yet, but I def lean towards type 0 as metric, and deviation as threshold.
Live Long and Prosper
P.S.: That was actually the main R&D of the last month, that script I've released earlier came out as derivative.
P.S.: These 2 are the first R&Ds made completely in " art-space", St. Petersburg. Come and see me, say wassup🤘🏻
Cycles
SUPPLY AND DEMAND EB ADD TO CHART 1Key Changes:
Single Label: The script now creates a single label that shows the maximum energy value (either long or short) from the candle that produced the supply or demand line.
Storage of Max Energy: The maximum energy value is calculated and stored separately, ensuring only relevant data is displayed.
This ensures a cleaner output while still conveying the necessary information. Let me know if you need any further adjustments!
Velocity and AccelerationThe area of acceleration has been added.
In addition to velocity and acceleration, the area of acceleration provides another means to gauge divergence. In many cases, extreme volatilities may produce high readings of velocity and acceleration, thus making finding divergence difficult. The area of acceleration takes accumlated reading and is less susceptible to short term extremes.
Hodrick-Prescott Filter (YavuzAkbay)The Hodrick-Prescott (HP) Filter Trend indicator offers a condensed version of the traditional HP filter, which is frequently employed in time series analysis related to the economy and finance. To assist traders and analysts in determining the underlying long-term trend of an asset, this indicator smoothes the price series in order to extract a trend component.
How It Operates: A time series is divided into its trend and cycle using the HP filter. By eliminating short-term noise and emphasising the market's direction with a smoother line, this approach concentrates solely on the trend component. The trend's degree of adherence to price data can be adjusted by varying the smoothness parameter (lambda); a smoother line is produced by higher values.
Examples of Use:
Trend Identification: By separating the long-term trend and making it simpler to disregard short-term noise, the HP Filter Trend helps identify the dominant market direction.
Trading Signal Confirmation: To keep traders in line with the general trend, the HP trend line can be used to validate other trend-following signals.
Important Notes:
The choice of lambda is essential. Recommended lambda levels are 100, 1600 and 14,400.
This indicator will be much more useful if it is used together with another indicator of mine, HP Filter Cycle Component.
Trading is risky, and most traders lose money. The indicators Yavuz Akbay offers are for informational and educational purposes only. All content should be considered hypothetical, selected after the facts to demonstrate my product, and not constructed as financial advice. Decisions to buy, sell, hold, or trade in securities, commodities, and other investments involve risk and are best made based on the advice of qualified financial professionals. Past performance does not guarantee future results.
This indicator is experimental and will always remain experimental. The indicator will be updated by Yavuz Akbay according to market conditions.
Three SMAs with Dynamic EMA and MACD Filter StrategyThis Pine Script code is a trading strategy implemented in TradingView's strategy tester. It combines three simple moving averages (SMA), a dynamically adjustable period exponential moving average (EMA), and the moving average convergence divergence (MACD) to generate trading signals. Here’s a detailed breakdown of the code:
Strategy Settings:
The strategy() function defines the basic settings for the strategy, including the name, abbreviation, and whether it overlays on the price chart (overlay=true).
SMA Parameters:
len1, len2, and len3 are set to 5, 10, and 15, representing the periods of the three SMA lines.
sma1, sma2, and sma3 are calculated using the ta.sma() function, corresponding to the specified periods.
Dynamic EMA Setting:
ema_length is set using the input() function, allowing users to dynamically adjust the EMA period, with a default value of 200.
ema is the EMA calculated based on the user-defined period, using the ta.ema() function.
MACD Parameters:
fast_length, slow_length, and signal_length are set to 12, 26, and 9, which are standard parameters for calculating MACD.
fast_ma and slow_ma are the fast and slow EMAs, respectively.
macd represents the difference between the fast and slow EMAs.
signal is the signal line of the MACD, typically an EMA of the MACD line.
Plotting:
The plot() function is used to display the three SMA lines and the EMA line, each in a different color for easy differentiation.
Trade Conditions:
The buyCondition is triggered when sma1 > sma2 > sma3, the closing price is above the EMA, and the MACD line is above the signal line.
The sellCondition is triggered when sma3 > sma2 > sma1, the closing price is below the EMA, and the MACD line is below the signal line.
Executing Trades:
The strategy.entry() function is used to execute long or short trades based on the conditions.
This strategy combines trend-following elements (through the SMA and EMA) and momentum (through the MACD) to capture potential trading opportunities in given trend and momentum conditions. Its effectiveness depends on specific market conditions, so thorough backtesting and risk evaluation are essential before real-world application.
Estratégia Compre & Venda por média AjustadaEsse script vai fazer toda a leitura do mercado e posicionar a media de forma mais verdadeira onde apresente pra você somente a média real e com isso você ter mais certeza de onde buscar referencia da direção do preço .... Comprado ou vendido espere a confirmação de toque na linha e movimento contrário
Você pode usar um RSI e um MACD com Estocastico pra fazer a confirmação da leitura dele <3
Funciona muito e essa estrategia me deu 10K em pouco tempo!
Atenão com alavancagem e lembre-se que mercado financeiro é variavél.
Esse indicador não é bola de cristal e não pode prever o futuro!
ele apenas te auxilia a entrar nos melhores pontos
considere ainda usar stop e take profits ajustados
ESEA LE THANH HIEPĐây là chỉ báo kết hợp có tên là ESEA LE THANH HIEP, nó được lồng ghép bởi các chỉ báo RSI 14 + EMA 9 + WMA 45 giúp chúng ta có cái nhìn trực quan trong giao dịch.
S&P 100 Option Expiration Week StrategyThe Option Expiration Week Strategy aims to capitalize on increased volatility and trading volume that often occur during the week leading up to the expiration of options on stocks in the S&P 100 index. This period, known as the option expiration week, culminates on the third Friday of each month when stock options typically expire in the U.S. During this week, investors in this strategy take a long position in S&P 100 stocks or an equivalent ETF from the Monday preceding the third Friday, holding until Friday. The strategy capitalizes on potential upward price pressures caused by increased option-related trading activity, rebalancing, and hedging practices.
The phenomenon leveraged by this strategy is well-documented in finance literature. Studies demonstrate that options expiration dates have a significant impact on stock returns, trading volume, and volatility. This effect is driven by various market dynamics, including portfolio rebalancing, delta hedging by option market makers, and the unwinding of positions by institutional investors (Stoll & Whaley, 1987; Ni, Pearson, & Poteshman, 2005). These market activities intensify near option expiration, causing price adjustments that may create short-term profitable opportunities for those aware of these patterns (Roll, Schwartz, & Subrahmanyam, 2009).
The paper by Johnson and So (2013), Returns and Option Activity over the Option-Expiration Week for S&P 100 Stocks, provides empirical evidence supporting this strategy. The study analyzes the impact of option expiration on S&P 100 stocks, showing that these stocks tend to exhibit abnormal returns and increased volume during the expiration week. The authors attribute these patterns to intensified option trading activity, where demand for hedging and arbitrage around options expiration causes temporary price adjustments.
Scientific Explanation
Research has found that option expiration weeks are marked by predictable increases in stock returns and volatility, largely due to the role of options market makers and institutional investors. Option market makers often use delta hedging to manage exposure, which requires frequent buying or selling of the underlying stock to maintain a hedged position. As expiration approaches, their activity can amplify price fluctuations. Additionally, institutional investors often roll over or unwind positions during expiration weeks, creating further demand for underlying stocks (Stoll & Whaley, 1987). This increased demand around expiration week typically leads to temporary stock price increases, offering profitable opportunities for short-term strategies.
Key Research and Bibliography
Johnson, T. C., & So, E. C. (2013). Returns and Option Activity over the Option-Expiration Week for S&P 100 Stocks. Journal of Banking and Finance, 37(11), 4226-4240.
This study specifically examines the S&P 100 stocks and demonstrates that option expiration weeks are associated with abnormal returns and trading volume due to increased activity in the options market.
Stoll, H. R., & Whaley, R. E. (1987). Program Trading and Expiration-Day Effects. Financial Analysts Journal, 43(2), 16-28.
Stoll and Whaley analyze how program trading and portfolio insurance strategies around expiration days impact stock prices, leading to temporary volatility and increased trading volume.
Ni, S. X., Pearson, N. D., & Poteshman, A. M. (2005). Stock Price Clustering on Option Expiration Dates. Journal of Financial Economics, 78(1), 49-87.
This paper investigates how option expiration dates affect stock price clustering and volume, driven by delta hedging and other option-related trading activities.
Roll, R., Schwartz, E., & Subrahmanyam, A. (2009). Options Trading Activity and Firm Valuation. Journal of Financial Markets, 12(3), 519-534.
The authors explore how options trading activity influences firm valuation, finding that higher options volume around expiration dates can lead to temporary price movements in underlying stocks.
Cao, C., & Wei, J. (2010). Option Market Liquidity and Stock Return Volatility. Journal of Financial and Quantitative Analysis, 45(2), 481-507.
This study examines the relationship between options market liquidity and stock return volatility, finding that increased liquidity needs during expiration weeks can heighten volatility, impacting stock returns.
Summary
The Option Expiration Week Strategy utilizes well-researched financial market phenomena related to option expiration. By positioning long in S&P 100 stocks or ETFs during this period, traders can potentially capture abnormal returns driven by option market dynamics. The literature suggests that options-related activities—such as delta hedging, position rollovers, and portfolio adjustments—intensify demand for underlying assets, creating short-term profit opportunities around these key dates.
Payday Anomaly StrategyThe "Payday Effect" refers to a predictable anomaly in financial markets where stock returns exhibit significant fluctuations around specific pay periods. Typically, these are associated with the beginning, middle, or end of the month when many investors receive wages and salaries. This influx of funds, often directed automatically into retirement accounts or investment portfolios (such as 401(k) plans in the United States), temporarily increases the demand for equities. This phenomenon has been linked to a cycle where stock prices rise disproportionately on and around payday periods due to increased buy-side liquidity.
Academic research on the payday effect suggests that this pattern is tied to systematic cash flows into financial markets, primarily driven by employee retirement and savings plans. The regularity of these cash infusions creates a calendar-based pattern that can be exploited in trading strategies. Studies show that returns on days around typical payroll dates tend to be above average, and this pattern remains observable across various time periods and regions.
The rationale behind the payday effect is rooted in the behavioral tendencies of investors, specifically the automatic reinvestment mechanisms used in retirement funds, which align with monthly or semi-monthly salary payments. This regular injection of funds can cause market microstructure effects where stock prices temporarily increase, only to stabilize or reverse after the funds have been invested. Consequently, the payday effect provides traders with a potentially profitable opportunity by predicting these inflows.
Scientific Bibliography on the Payday Effect
Ma, A., & Pratt, W. R. (2017). Payday Anomaly: The Market Impact of Semi-Monthly Pay Periods. Social Science Research Network (SSRN).
This study provides a comprehensive analysis of the payday effect, exploring how returns tend to peak around payroll periods due to semi-monthly cash flows. The paper discusses how systematic inflows impact returns, leading to predictable stock performance patterns on specific days of the month.
Lakonishok, J., & Smidt, S. (1988). Are Seasonal Anomalies Real? A Ninety-Year Perspective. The Review of Financial Studies, 1(4), 403-425.
This foundational study explores calendar anomalies, including the payday effect. By examining data over nearly a century, the authors establish a framework for understanding seasonal and monthly patterns in stock returns, which provides historical support for the payday effect.
Owen, S., & Rabinovitch, R. (1983). On the Predictability of Common Stock Returns: A Step Beyond the Random Walk Hypothesis. Journal of Business Finance & Accounting, 10(3), 379-396.
This paper investigates predictability in stock returns beyond random fluctuations. It considers payday effects among various calendar anomalies, arguing that certain dates yield predictable returns due to regular cash inflows.
Loughran, T., & Schultz, P. (2005). Liquidity: Urban versus Rural Firms. Journal of Financial Economics, 78(2), 341-374.
While primarily focused on liquidity, this study provides insight into how cash flows, such as those from semi-monthly paychecks, influence liquidity levels and consequently impact stock prices around predictable pay dates.
Ariel, R. A. (1990). High Stock Returns Before Holidays: Existence and Evidence on Possible Causes. The Journal of Finance, 45(5), 1611-1626.
Ariel’s work highlights stock return patterns tied to certain dates, including paydays. Although the study focuses on pre-holiday returns, it suggests broader implications of predictable investment timing, reinforcing the calendar-based effects seen with payday anomalies.
Summary
Research on the payday effect highlights a repeating pattern in stock market returns driven by scheduled payroll investments. This cyclical increase in stock demand aligns with behavioral finance insights and market microstructure theories, offering a valuable basis for trading strategies focused on the beginning, middle, and end of each month.
Customizable BTC Seasonality StrategyThis strategy leverages intraday seasonality effects in Bitcoin, specifically targeting hours of statistically significant returns during periods when traditional financial markets are closed. Padysak and Vojtko (2022) demonstrate that Bitcoin exhibits higher-than-average returns from 21:00 UTC to 23:00 UTC, a period in which all major global exchanges, such as the New York Stock Exchange (NYSE), Tokyo Stock Exchange, and London Stock Exchange, are closed. The absence of competing trading activity from traditional markets during these hours appears to contribute to these statistically significant returns.
The strategy proceeds as follows:
Entry Time: A long position in Bitcoin is opened at a user-specified time, which defaults to 21:00 UTC, aligning with the beginning of the identified high-return window.
Holding Period: The position is held for two hours, capturing the positive returns typically observed during this period.
Exit Time: The position is closed at a user-defined time, defaulting to 23:00 UTC, allowing the strategy to exit as the favorable period concludes.
This simple seasonality strategy aims to achieve a 33% annualized return with a notably reduced volatility of 20.93% and maximum drawdown of -22.45%. The results suggest that investing only during these high-return hours is more stable and less risky than a passive holding strategy (Padysak & Vojtko, 2022).
References
Padysak, M., & Vojtko, R. (2022). Seasonality, Trend-following, and Mean reversion in Bitcoin.
Asian Session ShadingDescription
The "Asian Session Shading" indicator is designed to highlight the trading hours of the Asian market session on TradingView charts. This script shades the background of the chart in a pale blue color to visually distinguish the time period of the Asian trading session. By using this indicator, traders can easily identify when the Asian session is active, helping them to analyze and make informed trading decisions based on time-specific market behavior.
Features
Customizable Timing: The session start and end times can be adjusted to fit different Asian market hours.
Visual Clarity: The pale blue shading helps to visually separate the Asian session from other trading sessions.
Easy to Use: Simple implementation with clear visual cues on the chart.
Best Use Cases
Market Analysis: Traders can use this indicator to analyze market movements and trends specific to the Asian trading session.
Trading Strategies: This tool can assist in developing and implementing trading strategies that take into account the unique characteristics of the Asian market.
Time Management: Helps traders to manage their trading schedule by clearly marking the start and end of the Asian session.
How to Use
Apply to Chart: Save and apply the indicator to your chart to see the shaded Asian session.
This indicator is particularly useful for forex traders, stock traders, and anyone looking to incorporate the Asian market's influence into their trading strategy.
FS Scorpion TailKey Features & Components:
1. Custom Date & Chart-Based Controls
The software allows users to define whether they want signals to start on a specific date (useSpecificDate) or base calculations on the visible chart’s range (useRelativeScreenSumLeft and useRelativeScreenSumRight).
Users can input the number of stocks to buy/sell per signal and decide whether to sell only for profit.
2. Technical Indicators Used
EMA (Exponential Moving Average): Users can define the length of the EMA and specify if buy/sell signals should occur when the EMA is rising or falling.
MACD (Moving Average Convergence Divergence): MACD crossovers, slopes of the MACD line, signal line, and histogram are used for generating buy/sell signals.
ATR (Average True Range): Signals are generated based on rising or falling ATR.
Aroon Indicator: Buy and sell signals are based on the behavior of the Aroon upper and lower lines.
RSI (Relative Strength Index): Tracks whether the RSI and its moving average are rising or falling to generate signals.
Bollinger Bands: Buy/sell signals depend on the basis, upper, and lower band behavior (rising or falling).
3. Signal Detection
The software creates arrays for each indicator to store conditions for buy/sell signals.
The allTrue() function checks whether all conditions for buy/sell signals are true, ensuring that only valid signals are plotted.
Signals are differentiated between buy-only, sell-only, and both buy and sell (dual signal).
4. Visual Indicators
Vertical Lines: When buy, sell, or dual signals are detected, vertical lines are drawn at the corresponding bar with configurable colors (green for buy, red for sell, silver for dual).
Buy/Sell Labels: Visual labels are plotted directly on the chart to denote buy or sell signals, allowing for clear interpretation of the strategy.
5. Cash Flow & Metrics Display
The software maintains an internal ledger of how many stocks are bought/sold, their prices, and whether a profit is being made.
A table is displayed at the bottom right of the chart, showing:
Initial investment
Current stocks owned
Last buy price
Market stake
Net profit
The table background turns green for profit and red for loss.
6. Dynamic Decision Making
Buy Condition: If a valid buy signal is generated, the software decrements the cash balance and adds stocks to the inventory.
Sell Condition: If the sell signal is valid (and meets the profit requirement), stocks are sold, and cash is incremented.
A fallback check ensures the sell logic prevents selling more stocks than are available and adjusts stock holding appropriately (e.g., sell half).
Customization and Usage
Indicator Adjustments: The user can choose which indicators to activate (e.g., EMA, MACD, RSI) via input controls. Each indicator has specific customizable parameters such as lengths, slopes, and conditions.
Signal Flexibility: The user can adjust conditions for buying and selling based on various technical indicators, which adds flexibility in implementing trading strategies. For example, users may require the RSI to be higher than its moving average or trigger sales only when MACD crosses under the signal line.
Profit Sensitivity: The software allows the option to sell only when a profit is assured by checking if the current price is higher than the last buy price.
Summary of Usage:
Indicator Selection: Enable or disable technical indicators like EMA, MACD, RSI, Aroon, ATR, and Bollinger Bands to fit your trading strategy.
Custom Date/Chart Settings: Choose whether to calculate based on specific time ranges or visible portions of the chart.
Dynamic Signal Plotting: Once buy or sell conditions are met, the software will visually plot signals on your chart, giving clear entry and exit points.
Investment Tracking: Real-time tracking of stock quantities, investments, and profit ensures a clear view of your trading performance.
Backtesting: Use this software for backtesting your strategy by analyzing how buy and sell signals would have performed historically based on the chosen indicators.
Conclusion
The FS Scorpion Tail software is a robust and flexible trading tool, allowing traders to develop custom strategies based on multiple well-known technical indicators. Its visual aid, coupled with real-time investment tracking, makes it valuable for systematic traders looking to automate or refine their trading approach.
Breakout Strategy MTF 1hHello everyone,
I had the idea to optimize it on Gold.
It is profitable, with the following entry rules:
GOLD, contracts 1€, hourly timeframe
the breakout takes reference to the period from 20PM to 5AM (8 candles for me, because on my display I have no candle between 23PM and 12AM)
we take positions from 5AM to 18PM
stop loss : the other side of the breakout channel
take profit : 1.8 x stop loss
no cumulation of orders
if we are “long” and the next day we have a “short”, we close the “long” and go “short”
Others parameters are profitable, it should be easy to modify them and optimize this strategy :
starting and ending of breakout channel
starting and ending of positions
stop loss / take profit
accumulated positions
etc.
This can be automated, of course.
On the screenshot, the backtest was made WITHOUT spread, as I don’t know it.
Best Regards,
RSI Strategy & CandleStick StrategyRSI Indicator linked with some Candlestick Pattern to signal the time of selling and Buyinh
EMA Buy/Sell TIENTIENĐây là chỉ báo tín hiệu các đường EMA khi Cross nhau, nó dựa trên các đường EMA34, EMA89, EMA200, EMA400,...
ICT & SMC Strategy//@version=5
strategy("ICT & SMC Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
// إعدادات الهيكل السوقي
swingHigh = ta.highest(high, 5)
swingLow = ta.lowest(low, 5)
// تعريف كتل الأوامر - تعريف شمعة ذات زخم قوي
isBullishOrderBlock = (close > open) and (high - low > 1.5 * (close - open ))
isBearishOrderBlock = (close < open) and (high - low > 1.5 * (open - close ))
// مناطق السيولة (اعتمادًا على أعلى القمم وأدنى القيعان)
liquidityZoneHigh = ta.highest(high, 20)
liquidityZoneLow = ta.lowest(low, 20)
// إشارات الشراء والبيع بناءً على الهيكل السوقي وكتل الأوامر
longCondition = (ta.crossover(low, swingLow) or isBullishOrderBlock) and (close > liquidityZoneLow)
shortCondition = (ta.crossunder(high, swingHigh) or isBearishOrderBlock) and (close < liquidityZoneHigh)
// تنفيذ الأوامر
if (longCondition)
strategy.entry("Buy", strategy.long)
if (shortCondition)
strategy.entry("Sell", strategy.short)
// عرض مناطق السيولة وكتل الأوامر على الرسم البياني
plot(liquidityZoneHigh, color=color.red, linewidth=1, title="Liquidity Zone High")
plot(liquidityZoneLow, color=color.green, linewidth=1, title="Liquidity Zone Low")
bgcolor(isBullishOrderBlock ? color.new(color.green, 80) : na, title="Bullish Order Block")
bgcolor(isBearishOrderBlock ? color.new(color.red, 80) : na, title="Bearish Order Block")
MMRI Chart (Primary)The **Mannarino Market Risk Indicator (MMRI)** is a financial risk measurement tool created by financial strategist Gregory Mannarino. It’s designed to assess the risk level in the stock market and economy based on current bond market conditions and the strength of the U.S. dollar. The MMRI considers factors like the U.S. 10-Year Treasury Yield and the Dollar Index (DXY), which indicate investor confidence in government debt and the dollar's purchasing power, respectively.
The formula for MMRI uses the 10-Year Treasury Yield multiplied by the Dollar Index, divided by a constant (1.61) to normalize the risk measure. A higher MMRI score suggests increased market risk, while a lower score indicates more stability. Mannarino has set certain thresholds to interpret the MMRI score:
- **Below 100**: Low risk.
- **100–200**: Moderate risk.
- **200–300**: High risk.
- **Above 300**: Extreme risk, indicating market instability and potential downturns.
This tool aims to provide insight into economic conditions that may affect asset classes like stocks, bonds, and precious metals. Mannarino often updates MMRI scores and risk analyses in his public market updates.
Sash Trending SuiteIndicator Name: Sash's Suite
Purpose: To analyze market trends and identify potential price reversals.
Objective: To provide traders with a comprehensive tool for analyzing market trends and identifying potential price reversals, enabling informed trading decisions and improved market timing.
How (Process)
Trend Analysis: Utilizes moving averages (EMAs) and the Average Directional Index (ADX) to assess market strength and direction.
Reversal Detection: Employs the Relative Strength Index (RSI) alongside price movement to identify overbought and oversold conditions for potential reversals.
Micro Trend Signals: Incorporates shorter EMAs to capture rapid market movements and refine entry and exit points.
What (Components)
Macro Trend Parameters: Fast and slow EMA lengths, ADX length, and threshold settings.
Alpha Track Parameters: Adjustable track line intensity.
Reversal Signal Parameters: Minimum reversal percentage, RSI length, and overbought/oversold levels.
Micro Trend Parameters: Shorter EMAs for precise trend tracking.
Calculations:
Computes EMAs, ADX, and RSI values. Logic:
Detects bullish and bearish trends based on EMA relationships and ADX.
Identifies potential reversals using price crossovers and RSI conditions.
Plotting:
Visual indicators for trends, reversals, and local tops/bottoms with color-coded signals.
Alerts:
Notifies users of trend changes, reversals, and significant price points for proactive trading.
Order Block Detector with Touch Signal [LuxAlgo]// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) creativecommons.org
// © LuxAlgo
//@version=5
indicator("Order Block Detector with Touch Signal ", overlay = true, max_boxes_count = 500, max_labels_count = 500, max_lines_count = 500)
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------
length = input.int(5, 'Volume Pivot Length', minval = 1)
bull_ext_last = input.int(3, 'Bullish OB ', minval = 1, inline = 'bull')
bg_bull_css = input.color(color.new(#169400, 80), '', inline = 'bull')
bull_css = input.color(#169400, '', inline = 'bull')
bull_avg_css = input.color(color.new(#9598a1, 37), '', inline = 'bull')
bear_ext_last = input.int(3, 'Bearish OB', minval = 1, inline = 'bear')
bg_bear_css = input.color(color.new(#ff1100, 80), '', inline = 'bear')
bear_css = input.color(#ff1100, '', inline = 'bear')
bear_avg_css = input.color(color.new(#9598a1, 37), '', inline = 'bear')
line_style = input.string('⎯⎯⎯', 'Average Line Style', options = )
line_width = input.int(1, 'Average Line Width', minval = 1)
mitigation = input.string('Wick', 'Mitigation Methods', options = )
//-----------------------------------------------------------------------------
//Functions
//-----------------------------------------------------------------------------
get_line_style(style) =>
out = switch style
'⎯⎯⎯' => line.style_solid
'----' => line.style_dashed
'····' => line.style_dotted
get_coordinates(condition, top, btm, ob_val)=>
var ob_top = array.new_float(0)
var ob_btm = array.new_float(0)
var ob_avg = array.new_float(0)
var ob_left = array.new_int(0)
float ob = na
if condition
avg = math.avg(top, btm)
array.unshift(ob_top, top)
array.unshift(ob_btm, btm)
array.unshift(ob_avg, avg)
array.unshift(ob_left, time )
ob := ob_val
remove_mitigated(ob_top, ob_btm, ob_left, ob_avg, target, bull)=>
mitigated = false
target_array = bull ? ob_btm : ob_top
for element in target_array
idx = array.indexof(target_array, element)
if (bull ? target < element : target > element)
mitigated := true
array.remove(ob_top, idx)
array.remove(ob_btm, idx)
array.remove(ob_avg, idx)
array.remove(ob_left, idx)
mitigated
set_order_blocks(ob_top, ob_btm, ob_left, ob_avg, ext_last, bg_css, border_css, lvl_css)=>
var ob_box = array.new_box(0)
var ob_lvl = array.new_line(0)
if barstate.isfirst
for i = 0 to ext_last-1
array.unshift(ob_box, box.new(na,na,na,na, xloc = xloc.bar_time, extend= extend.right, bgcolor = bg_css, border_color = color.new(border_css, 70)))
array.unshift(ob_lvl, line.new(na,na,na,na, xloc = xloc.bar_time, extend = extend.right, color = lvl_css, style = get_line_style(line_style), width = line_width))
if barstate.islast
if array.size(ob_top) > 0
for i = 0 to math.min(ext_last-1, array.size(ob_top)-1)
get_box = array.get(ob_box, i)
get_lvl = array.get(ob_lvl, i)
box.set_lefttop(get_box, array.get(ob_left, i), array.get(ob_top, i))
box.set_rightbottom(get_box, array.get(ob_left, i), array.get(ob_btm, i))
line.set_xy1(get_lvl, array.get(ob_left, i), array.get(ob_avg, i))
line.set_xy2(get_lvl, array.get(ob_left, i)+1, array.get(ob_avg, i))
//-----------------------------------------------------------------------------
//Global elements
//-----------------------------------------------------------------------------
var os = 0
var target_bull = 0.
var target_bear = 0.
n = bar_index
upper = ta.highest(length)
lower = ta.lowest(length)
if mitigation == 'Close'
target_bull := ta.lowest(close, length)
target_bear := ta.highest(close, length)
else
target_bull := lower
target_bear := upper
os := high > upper ? 0 : low < lower ? 1 : os
phv = ta.pivothigh(volume, length, length)
//-----------------------------------------------------------------------------
//Get bullish/bearish order blocks coordinates
//-----------------------------------------------------------------------------
= get_coordinates(phv and os == 1, hl2 , low , low )
= get_coordinates(phv and os == 0, high , hl2 , high )
//-----------------------------------------------------------------------------
//Remove mitigated order blocks
//-----------------------------------------------------------------------------
mitigated_bull = remove_mitigated(bull_top, bull_btm, bull_left, bull_avg, target_bull, true)
mitigated_bear = remove_mitigated(bear_top, bear_btm, bear_left, bear_avg, target_bear, false)
//-----------------------------------------------------------------------------
//Display order blocks
//-----------------------------------------------------------------------------
set_order_blocks(bull_top, bull_btm, bull_left, bull_avg, bull_ext_last, bg_bull_css, bull_css, bull_avg_css)
set_order_blocks(bear_top, bear_btm, bear_left, bear_avg, bear_ext_last, bg_bear_css, bear_css, bear_avg_css)
plot(bull_ob, 'Bull OB', bull_css, 2, plot.style_linebr, offset = -length, display = display.none)
plot(bear_ob, 'Bear OB', bear_css, 2, plot.style_linebr, offset = -length, display = display.none)
//-----------------------------------------------------------------------------
// Alerts and Buy/Sell Signals
//-----------------------------------------------------------------------------
bull_touch_signal = array.size(bull_btm) > 0 and low <= array.get(bull_btm, 0) // Bullish OB touch
bear_touch_signal = array.size(bear_top) > 0 and high >= array.get(bear_top, 0) // Bearish OB touch
plotshape(series=bull_touch_signal, location=location.belowbar, color=color.green, style=shape.labelup, title="Buy Signal")
plotshape(series=bear_touch_signal, location=location.abovebar, color=color.red, style=shape.labeldown, title="Sell Signal")
alertcondition(bull_touch_signal, "Buy Signal", "Price touched Bullish Order Block - Buy Signal")
alertcondition(bear_touch_signal, "Sell Signal", "Price touched Bearish Order Block - Sell Signal")
//-----------------------------------------------------------------------------
Stock Booster// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © fluxchart
//@version=5
const bool DEBUG = false
const int maxDistanceToLastBar = 5000
const int labelCooldown = 8
const int KDELimit = 300
indicator("Stock Booster", overlay = true, max_labels_count = 500)
rsiLengthInput = input.int(14, minval = 1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
highPivotLen = input.int(21, "High Pivot Length", minval = 1, group = "Pivots", display = display.none)
lowPivotLen = input.int(21, "Low Pivot Length", minval = 1, group = "Pivots", display = display.none)
realPivotLabels = DEBUG ? input.bool(false, " Real Pivot Labels", group = "Pivots") : false
kdePivotLabels = DEBUG ? input.bool(false, " KDE Pivot Labels", group = "Pivots") : false
activationThresholdStr = input.string("Medium", "Activation Threshold", options = , group = "KDE", tooltip = "Determines the amount of arrows shown. Higher options will result in more arrows being rendered.")
string KDEKernel = input.string("Gaussian", "Kernel", options= , group = "KDE", tooltip = "The kernel function for KDE calculation. Gaussian is a commonly used kernel and is based on normal distribution.")
float KDEBandwidth = input.float(2.71828, "Bandwidth", group = "KDE", tooltip = "This setting sets the smoothness of the KDE function output.")
int KDEStep = input.int(100, "Nº Bins", minval = 1, group = "KDE", tooltip = "The number of elements the KDE Probability array will have. Higher settings will result in greater precision.")
activationThreshold = DEBUG ? input.float(0.25, " Activation Threshold", group = "KDE") : 0.25
if not DEBUG
activationThreshold := (activationThresholdStr == "High" ? 0.4 : activationThresholdStr == "Medium" ? 0.25 : 0.15)
probMode = DEBUG ? input.string("Sum", ' Probability Mode', options = , group = "KDE") : "Sum"
minPadding = DEBUG ? input.bool(false, ' KDE Min Padding', group = "KDE") : false
tableEnabled = input.bool(true, "Dashboard", group = "Dashboard", display = display.none)
tableLocation = input.string("Top Right", "Position", options = , group = "Dashboard", display = display.none)
screenerColor = input.color(#1B1F2B, 'Background', group = 'Dashboard', display = display.none)
frameColor = input.color(color.rgb(255, 255, 255), 'Frame', group = 'Dashboard', display = display.none)
borderColor = input.color(color.rgb(255, 255, 255), 'Border', group = 'Dashboard', display = display.none)
textColorDB = input.color(color.white, 'Text', group = 'Dashboard', display = display.none)
fillBackgrounds = input.bool(true, "Fill Backgrounds", group = "Dashboard", display = display.none)
bearishColor = input.color(#f23646, "High Pivots", group = "Style", inline = "col", display = display.none)
neutralColor = input.color(color.gray, "Neutral", group = "Style", inline = "col", display = display.none)
bullishColor = input.color(#089981, "Low Pivots", group = "Style", inline = "col", display = display.none)
textColor = input.color(color.white, 'Text', group = 'Style', inline = "col", display = display.none)
RSILabelsEnabled = input.bool(true, "RSI Labels", group = "Style")
KDELabelsEnabled = input.bool(true, "KDE Labels", group = "Style")
rsi = ta.rsi(rsiSourceInput, rsiLengthInput)
getPosition (positionText) =>
if positionText == "Top Right"
position.top_right
else if positionText == "Top Center"
position.top_center
else if positionText == "Right Center"
position.middle_right
else if positionText == "Left Center"
position.middle_left
else if positionText == "Bottom Center"
position.bottom_center
else if positionText == "Middle Center"
position.middle_center
//#region KDE
gaussian (float distance, float bandwidth = 1.0) => 1.0 / math.sqrt(2.0 * math.pi) * math.pow(math.e, -0.5 * math.pow(distance / bandwidth, 2.0))
uniform (float distance, float bandwidth = 1.0) => (math.abs(distance) > bandwidth) ? 0.0 : 0.5
sigmoid (float distance, float bandwidth = 1.0) => 2.0 / math.pi * (1.0 / (math.pow(math.e, (distance / bandwidth)) + math.pow(math.e, -(distance / bandwidth))))
kde (array arr, string kernel, float bandwidth, int steps) =>
arrSize = arr.size()
arrRange = arr.range()
arrMin = arr.min() - (minPadding ? (arrRange / 2.0) : 0)
stepCount = arrRange / steps
densityRange = array.new(steps * 2)
for i = 0 to (steps * 2) - 1
densityRange.set(i, arrMin + i * stepCount)
xArr = array.new()
yArr = array.new()
for i = 0 to densityRange.size() - 1
float temp = 0
for j = 0 to arr.size() - 1
switch KDEKernel
"Gaussian" => temp += gaussian(densityRange.get(i) - arr.get(j), 1.0 / bandwidth)
"Uniform" => temp += uniform(densityRange.get(i) - arr.get(j), 1.0 / bandwidth)
"Sigmoid" => temp += sigmoid(densityRange.get(i) - arr.get(j), 1.0 / bandwidth)
xArr.push(densityRange.get(i))
yArr.push(1.0 / arrSize * temp)
//#endregion
//#region Pivots
prefixSum (array arr, int l, int r) =>
arr.get(r) - (l == 0 ? 0 : arr.get(l - 1))
float MidKDEHigh = na
float MidKDELow = na
var array KDEHighX = na
var array KDEHighY = na
var array KDEHighYSum = array.new()
var array KDELowX = na
var array KDELowY = na
var array KDELowYSum = array.new()
highPivot = ta.pivothigh(highPivotLen, highPivotLen)
lowPivot = ta.pivotlow(lowPivotLen, lowPivotLen)
var highPivotRSIs = array.new()
var lowPivotRSIs = array.new()
if not na(highPivot)
if highPivotRSIs.size() > KDELimit
highPivotRSIs.remove(0)
highPivotRSIs.push(rsi )
= kde(highPivotRSIs, KDEKernel, KDEBandwidth, KDEStep)
KDEHighX := KDEHighX1
KDEHighY := KDEHighY1
KDEHighYSum.clear()
temp = 0.0
for i = 0 to KDEHighY.size() - 1
temp += KDEHighY.get(i)
KDEHighYSum.push(temp)
MidKDEHigh := array.get(KDEHighX, array.indexof(KDEHighY, array.max(KDEHighY)))
if not na(lowPivot)
if lowPivotRSIs.size() > KDELimit
lowPivotRSIs.remove(0)
lowPivotRSIs.push(rsi )
= kde(lowPivotRSIs, KDEKernel, KDEBandwidth, KDEStep)
KDELowX := KDELowX1
KDELowY := KDELowY1
KDELowYSum.clear()
temp = 0.0
for i = 0 to KDELowY.size() - 1
temp += KDELowY.get(i)
KDELowYSum.push(temp)
MidKDELow := array.get(KDELowX, array.indexof(KDELowY, array.max(KDELowY)))
//#endregion
//#region KDE Optimization
f_lin_interpolate(float x0, float x1, float y0, float y1, float x) =>
y0 + (x - x0) * (y1 - y0) / (x1 - x0)
float lowProb = na
float maxLowProb = na
float highProb = na
float maxHighProb = na
if last_bar_index - maxDistanceToLastBar < bar_index
if highPivotRSIs.size() > 0
highXIndexL = array.binary_search_leftmost(KDEHighX, rsi)
highXIndexR = math.min(array.binary_search_rightmost(KDEHighX, rsi), KDEHighX.size() - 1)
nearestIndex = (math.abs(rsi - KDEHighX.get(highXIndexL)) < math.abs(rsi - KDEHighX.get(highXIndexR))) ? highXIndexL : highXIndexR
if probMode == "Nearest"
highProb := KDEHighY.get(nearestIndex)
maxHighProb := array.max(KDEHighY)
else if probMode == "Sum"
highProb := prefixSum(KDEHighYSum, 0, nearestIndex)
if lowPivotRSIs.size() > 0
lowXIndexL = array.binary_search_leftmost(KDELowX, rsi)
lowXIndexR = math.min(array.binary_search_rightmost(KDELowX, rsi), KDELowX.size() - 1)
nearestIndex = (math.abs(rsi - KDELowX.get(lowXIndexL)) < math.abs(rsi - KDELowX.get(lowXIndexR))) ? lowXIndexL : lowXIndexR
if probMode == "Nearest"
lowProb := KDELowY.get(nearestIndex)
maxLowProb := array.max(KDELowY)
else if probMode == "Sum"
lowProb := prefixSum(KDELowYSum, nearestIndex, KDELowYSum.size() - 1)
if DEBUG and barstate.islastconfirmedhistory
for i = 0 to KDELowX.size() - 1
curX = KDELowX.get(i)
curY = KDELowY.get(i)
log.info(str.tostring(curX) + " = " + str.tostring(curY))
log.info("High Y Sum " + str.tostring(KDEHighY.sum()))
diffToHighKDE = math.abs(rsi - MidKDEHigh)
diffToLowKDE = math.abs(rsi - MidKDELow)
//#endregion
//#region Draw Pivots
color curColor = na
if (not na(KDELowY)) and (not na(KDEHighY))
if probMode == "Nearest"
if math.abs(lowProb - maxLowProb) < activationThreshold / 50.0
curColor := bullishColor
if math.abs(highProb - maxHighProb) < activationThreshold / 50.0
curColor := bearishColor
else if probMode == "Sum"
if lowProb > KDELowY.sum() * (1.0 - activationThreshold)
curColor := bullishColor
else if highProb > KDEHighY.sum() * (1.0 - activationThreshold)
curColor := bearishColor
//barcolor(curColor)
atr = ta.atr(50)
plotarrow(curColor == bullishColor and barstate.isconfirmed ? 1 : na, "Bullish Arrows", color.new(bullishColor, 70), color.new(bullishColor, 70), minheight = 20, maxheight = 20)
plotarrow(curColor == bearishColor and barstate.isconfirmed ? -1 : na, "Bearish Arrows", color.new(bearishColor, 70), color.new(bearishColor, 70), minheight = 20, maxheight = 20)
plotarrow((na(curColor) and curColor == bullishColor and barstate.isconfirmed) ? 1 : na, "Possible Bullish Pivot", bullishColor, bullishColor, minheight = 20, maxheight = 20)
plotarrow((na(curColor) and curColor == bearishColor and barstate.isconfirmed) ? -1 : na, "Possible Bearish Pivot", bearishColor, bearishColor, minheight = 20, maxheight = 20)
alertcondition(na(curColor) and curColor == bullishColor and barstate.isconfirmed, "Possible Bullish Pivot")
alertcondition(na(curColor) and curColor == bearishColor and barstate.isconfirmed, "Possible Bearish Pivot")
if KDELabelsEnabled or RSILabelsEnabled
var lastBullishLabel = 0
if (na(curColor) and curColor == bullishColor and barstate.isconfirmed) and (bar_index - lastBullishLabel) > labelCooldown
lastBullishLabel := bar_index
txt = ""
if RSILabelsEnabled and KDELabelsEnabled
txt := "RSI | " + str.tostring(rsi, "#") + " | " + str.tostring(lowProb * 100, "#.##") + "%"
else if RSILabelsEnabled
txt := "RSI | " + str.tostring(rsi, "#")
else
txt := str.tostring(rsi, "#") + "%"
label.new(bar_index, low, txt, yloc = yloc.belowbar, color = na, style = label.style_label_up, textcolor = textColor, force_overlay = true)
var lastBearishLabel = 0
if (na(curColor) and curColor == bearishColor and barstate.isconfirmed) and (bar_index - lastBearishLabel) > labelCooldown
lastBearishLabel := bar_index
txt = ""
if RSILabelsEnabled and KDELabelsEnabled
txt := "RSI | " + str.tostring(rsi, "#") + " | " + str.tostring(highProb * 100, "#.##") + "%"
else if RSILabelsEnabled
txt := "RSI | " + str.tostring(rsi, "#")
else
txt := str.tostring(rsi, "#") + "%"
label.new(bar_index, low, txt, yloc = yloc.abovebar, color = na, style = label.style_label_down, textcolor = textColor, force_overlay = true)
if kdePivotLabels
txt = str.tostring(rsi, "#.##") + " HP -> " + str.tostring(highProb, "#.##") + " LP -> " + str.tostring(lowProb, "#.##") + " MHP -> " + str.tostring(maxHighProb, "#.##") + " MLP -> " + str.tostring(maxLowProb, "#.##")
if math.abs(lowProb - maxLowProb) < activationThreshold
label.new(bar_index, high, txt, yloc = yloc.belowbar, color = textColor, style = label.style_label_up, textcolor = color.black, force_overlay = true)
if math.abs(highProb - maxHighProb) < activationThreshold
label.new(bar_index, high, txt, yloc = yloc.abovebar, color = textColor, style = label.style_label_down, textcolor = color.black, force_overlay = true)
if realPivotLabels
if not na(highPivot)
txt = str.tostring(rsi , "#.##") + " HP -> " + str.tostring(highProb , "#.##") + " LP -> " + str.tostring(lowProb , "#.##") + " MHP -> " + str.tostring(maxHighProb , "#.##") + " MLP -> " + str.tostring(maxLowProb , "#.##")
label.new(bar_index - highPivotLen, high, txt, yloc = yloc.abovebar, color = textColor, style = label.style_label_down, textcolor = color.black, force_overlay = true)
if not na(lowPivot)
txt = str.tostring(rsi , "#.##") + " HP -> " + str.tostring(highProb , "#.##") + " LP -> " + str.tostring(lowProb , "#.##") + " MHP -> " + str.tostring(maxHighProb , "#.##") + " MLP -> " + str.tostring(maxLowProb , "#.##")
label.new(bar_index - lowPivotLen, high, txt, yloc = yloc.belowbar, color = textColor, style = label.style_label_up, textcolor = color.black, force_overlay = true)
//#endregion
if tableEnabled
var table realtimeTable = table.new(getPosition(tableLocation), 2, 10, bgcolor = screenerColor, frame_width = 2, frame_color = frameColor, border_width = 1, border_color = borderColor)
// Header
table.merge_cells(realtimeTable, 0, 0, 1, 0)
table.cell(realtimeTable, 0, 0, "KDE Optimized RSI", text_color = textColorDB, bgcolor = screenerColor)
// RSI
table.cell(realtimeTable, 0, 1, "RSI", text_color = textColorDB, bgcolor = screenerColor)
table.cell(realtimeTable, 1, 1, str.tostring(rsi, "#"), text_color = textColorDB, bgcolor = screenerColor)
// KDE
table.cell(realtimeTable, 0, 2, (lowProb > highProb) ? "Bullish KDE" : "Bearish KDE", text_color = (lowProb > highProb) ? bullishColor : bearishColor, bgcolor = screenerColor)
table.cell(realtimeTable, 1, 2, str.tostring(nz(math.max(highProb, lowProb), 0) * 100, "#.##") + "%", text_color = textColorDB, bgcolor = screenerColor)