Point and Figure (PnF) MACDThis is live and non-repainting Point and Figure Chart MACD tool. The script has it’s own P&F engine and not using integrated function of Trading View.
Point and Figure method is over 150 years old. It consist of columns that represent filtered price movements. Time is not a factor on P&F chart but as you can see with this script P&F chart created on time chart.
P&F chart provide several advantages, some of them are filtering insignificant price movements and noise, focusing on important price movements and making support/resistance levels much easier to identify.
P&F MACD is calculated and shown by using its own P&F engine.
If you are new to Point & Figure Chart then you better get some information about it before using this tool. There are very good web sites and books. Please PM me if you need help about resources.
Options in the Script
Box size is one of the most important part of Point and Figure Charting. Chart price movement sensitivity is determined by the Point and Figure scale. Large box sizes see little movement across a specific price region, small box sizes see greater price movement on P&F chart. There are four different box scaling with this tool: Traditional, Percentage, Dynamic (ATR), or User-Defined
4 different methods for Box size can be used in this tool.
User Defined: The box size is set by user. A larger box size will result in more filtered price movements and fewer reversals. A smaller box size will result in less filtered price movements and more reversals.
ATR: Box size is dynamically calculated by using ATR, default period is 20.
Percentage: uses box sizes that are a fixed percentage of the stock's price. If percentage is 1 and stock’s price is $100 then box size will be $1
Traditional: uses a predefined table of price ranges to determine what the box size should be.
Price Range Box Size
Under 0.25 0.0625
0.25 to 1.00 0.125
1.00 to 5.00 0.25
5.00 to 20.00 0.50
20.00 to 100 1.0
100 to 200 2.0
200 to 500 4.0
500 to 1000 5.0
1000 to 25000 50.0
25000 and up 500.0
Default value is “ATR”, you may use one of these scaling method that suits your trading strategy.
If ATR or Percentage is chosen then there is rounding algorithm according to mintick value of the security. For example if mintick value is 0.001 and box size (ATR/Percentage) is 0.00124 then box size becomes 0.001.
And also while using dynamic box size (ATR or Percentage), box size changes only when closing price changed.
Reversal : It is the number of boxes required to change from a column of Xs to a column of Os or from a column of Os to a column of Xs. Default value is 3 (most used). For example if you choose reversal = 2 then you get the chart similar to Renko chart.
Source: Closing price or High-Low prices can be chosen as data source for P&F charting.
P&F MACD Part
Fast Length: Fast Length for P&F MACD , default value is 12
Slow Length: Fast Length for P&F MACD , default value is 26
Signal Smoothing: Signal Length, default value is 9
Source: Moving averages on P&F charts are based on the average price of each column. Bar chart moving averages are based on each close price. Average price means “(ClosePrice + OpenPrice) / 2”. You can choose Close Price or Average Price as source. Default is Average Price.
There are 2 Alerts:
If PNF MACD line crossover the signal line
If PNF MACD line crossunder the signal line
While adding alert “Once Per Bar Close” option should be chosen.
Cari skrip untuk "美股道琼斯工业平均指数、纳斯达克指数、标普500指数的成交量数据"
Point and Figure (PnF) CCIThis is live and non-repainting Point and Figure Chart Commodity Channel Index - CCI tool. The script has it’s own P&F engine and not using integrated function of Trading View.
Point and Figure method is over 150 years old. It consist of columns that represent filtered price movements. Time is not a factor on P&F chart but as you can see with this script P&F chart created on time chart.
P&F chart provide several advantages, some of them are filtering insignificant price movements and noise, focusing on important price movements and making support/resistance levels much easier to identify.
Commodity Channel Index – CCI was developed by Donalt Lambert. CCI can be used to identify overbought or oversold, a new trend or warn of extreme conditions. CCI measures the difference between a security's price change and its average price change. High positive readings indicate that prices are well above their average, which is a show of strength. Low negative readings indicate that prices are well below their average, which is a show of weakness.
The Formula for the Commodity Channel Index ( CCI ) Is:
CCI = (Typical Price – L-period SMA of TP) / (0.015 * Mean Deviation)
Mean Deviation = (SumOf 1->L ( |TP – MA| )) / L
L = Length
TP = Typical Price
If you are new to Point & Figure Chart then you better get some information about it before using this tool. There are very good web sites and books. Please PM me if you need help about resources.
Options in the Script
Box size is one of the most important part of Point and Figure Charting. Chart price movement sensitivity is determined by the Point and Figure scale. Large box sizes see little movement across a specific price region, small box sizes see greater price movement on P&F chart. There are four different box scaling with this tool: Traditional, Percentage, Dynamic (ATR), or User-Defined
4 different methods for Box size can be used in this tool.
User Defined: The box size is set by user. A larger box size will result in more filtered price movements and fewer reversals. A smaller box size will result in less filtered price movements and more reversals.
ATR: Box size is dynamically calculated by using ATR, default period is 20.
Percentage: uses box sizes that are a fixed percentage of the stock's price. If percentage is 1 and stock’s price is $100 then box size will be $1
Traditional: uses a predefined table of price ranges to determine what the box size should be.
Price Range Box Size
Under 0.25 0.0625
0.25 to 1.00 0.125
1.00 to 5.00 0.25
5.00 to 20.00 0.50
20.00 to 100 1.0
100 to 200 2.0
200 to 500 4.0
500 to 1000 5.0
1000 to 25000 50.0
25000 and up 500.0
Default value is “ATR”, you may use one of these scaling method that suits your trading strategy.
If ATR or Percentage is chosen then there is rounding algorithm according to mintick value of the security. For example if mintick value is 0.001 and box size (ATR/Percentage) is 0.00124 then box size becomes 0.001.
And also while using dynamic box size (ATR or Percentage), box size changes only when closing price changed.
Reversal : It is the number of boxes required to change from a column of Xs to a column of Os or from a column of Os to a column of Xs. Default value is 3 (most used). For example if you choose reversal = 2 then you get the chart similar to Renko chart.
Source: Closing price or High-Low prices can be chosen as data source for P&F charting.
Upper Band : as default, Upper band is 100
Lower Band : as default, Lower band is -100
There are alerts when P&F CCI moves above Upper Band or moves below Lower Band.
Point and Figure (PnF) Bollinger BandsThis is live and non-repainting Point and Figure Chart Bollinger Bands tool. The script has it’s own P&F engine and not using integrated function of Trading View.
Point and Figure method is over 150 years old. It consist of columns that represent filtered price movements. Time is not a factor on P&F chart but as you can see with this script P&F chart created on time chart.
P&F chart provide several advantages, some of them are filtering insignificant price movements and noise, focusing on important price movements and making support/resistance levels much easier to identify.
P&F Bollinger Bands is calculated and shown by using its own P&F engine. Because of Point and Figure Chart Moving averages are already smoothed, better to use smaller moving average periods, 5 or 10 etc. This period can be chosen by prives movements and characteristics. You can see the consolidation areas and with P&F Breakout signals it’s possible to see the direction. Narrowing bands indicate a consolidation and narrowing does not provide a direction clue. You must look for the next P&F signal to establish direction. But beware of the ‘head fake’. This occurs when prices break a band, then suddenly reverse and move the other way (Trap).
An example for Head Fake:
If you are new to Point & Figure Chart then you better get some information about it before using this tool. There are very good web sites and books. Please PM me if you need help about resources.
Options in the Script
Box size is one of the most important part of Point and Figure Charting. Chart price movement sensitivity is determined by the Point and Figure scale. Large box sizes see little movement across a specific price region, small box sizes see greater price movement on P&F chart. There are four different box scaling with this tool: Traditional, Percentage, Dynamic (ATR), or User-Defined
4 different methods for Box size can be used in this tool.
User Defined: The box size is set by user. A larger box size will result in more filtered price movements and fewer reversals. A smaller box size will result in less filtered price movements and more reversals.
ATR: Box size is dynamically calculated by using ATR, default period is 20.
Percentage: uses box sizes that are a fixed percentage of the stock's price. If percentage is 1 and stock’s price is $100 then box size will be $1
Traditional: uses a predefined table of price ranges to determine what the box size should be.
Price Range Box Size
Under 0.25 0.0625
0.25 to 1.00 0.125
1.00 to 5.00 0.25
5.00 to 20.00 0.50
20.00 to 100 1.0
100 to 200 2.0
200 to 500 4.0
500 to 1000 5.0
1000 to 25000 50.0
25000 and up 500.0
Default value is “ATR”, you may use one of these scaling method that suits your trading strategy.
If ATR or Percentage is chosen then there is rounding algorithm according to mintick value of the security. For example if mintick value is 0.001 and box size (ATR/Percentage) is 0.00124 then box size becomes 0.001.
And also while using dynamic box size (ATR or Percentage), box size changes only when closing price changed.
Reversal : It is the number of boxes required to change from a column of Xs to a column of Os or from a column of Os to a column of Xs. Default value is 3 (most used). For example if you choose reversal = 2 then you get the chart similar to Renko chart.
Source: Closing price or High-Low prices can be chosen as data source for P&F charting.
Options P&F Bollimger Bands:
Length: Base Moving Average Length, default value is 5
StdDev: Standart Deviation, default value ise 2. (Standart deviation is calculated by the engine)
MA Source: Moving averages on P&F charts are based on the average price of each column. Bar chart moving averages are based on each close price. Average price means “(ClosePrice + OpenPrice) / 2”. You can choose Close Price or Average Price as source. Default is Average Price.
Point and Figure (PnF) RSIThis is live and non-repainting Point and Figure Chart RSI tool. The script has it’s own P&F engine and not using integrated function of Trading View.
Point and Figure method is over 150 years old. It consist of columns that represent filtered price movements. Time is not a factor on P&F chart but as you can see with this script P&F chart created on time chart.
P&F chart provide several advantages, some of them are filtering insignificant price movements and noise, focusing on important price movements and making support/resistance levels much easier to identify.
P&F RSI is calculated and shown by using its own P&F engine.
If you are new to Point & Figure Chart then you better get some information about it before using this tool. There are very good web sites and books. Please PM me if you need help about resources.
Options in the Script
Box size is one of the most important part of Point and Figure Charting. Chart price movement sensitivity is determined by the Point and Figure scale. Large box sizes see little movement across a specific price region, small box sizes see greater price movement on P&F chart. There are four different box scaling with this tool: Traditional, Percentage, Dynamic (ATR), or User-Defined
4 different methods for Box size can be used in this tool.
User Defined: The box size is set by user. A larger box size will result in more filtered price movements and fewer reversals. A smaller box size will result in less filtered price movements and more reversals.
ATR: Box size is dynamically calculated by using ATR, default period is 20.
Percentage: uses box sizes that are a fixed percentage of the stock's price. If percentage is 1 and stock’s price is $100 then box size will be $1
Traditional: uses a predefined table of price ranges to determine what the box size should be.
Price Range Box Size
Under 0.25 0.0625
0.25 to 1.00 0.125
1.00 to 5.00 0.25
5.00 to 20.00 0.50
20.00 to 100 1.0
100 to 200 2.0
200 to 500 4.0
500 to 1000 5.0
1000 to 25000 50.0
25000 and up 500.0
Default value is “ATR”, you may use one of these scaling method that suits your trading strategy.
If ATR or Percentage is chosen then there is rounding algorithm according to mintick value of the security. For example if mintick value is 0.001 and box size (ATR/Percentage) is 0.00124 then box size becomes 0.001.
And also while using dynamic box size (ATR or Percentage), box size changes only when closing price changed.
Reversal : It is the number of boxes required to change from a column of Xs to a column of Os or from a column of Os to a column of Xs. Default value is 3 (most used). For example if you choose reversal = 2 then you get the chart similar to Renko chart.
Source: Closing price or High-Low prices can be chosen as data source for P&F charting.
you can use PNF type RSI or RENKO type RSI.
What is the difference between them?
While calculating PNF type RSI, the script checks last X/O column's closing price but when using RENKO type RSI the scipt calculates RSI on every price changes according to number of boxes. and also with RENKO type RSI, calculation is made for each boxes on price changes.
Important note if you use this PNF script with reversal = 2 then you get RENKO chart. So, with this RENKO chart better to use RENKO type RSI ;)
Point and Figure (PnF) ChartThis is live and non-repainting Point and Figure Charting tool. The tool has it’s own P&F engine and not using integrated function of Trading View.
Point and Figure method is over 150 years old. It consist of columns that represent filtered price movements. Time is not a factor on P&F chart but as you can see with this script P&F chart created on time chart.
P&F chart provide several advantages, some of them are filtering insignificant price movements and noise, focusing on important price movements and making support/resistance levels much easier to identify.
If you are new to Point & Figure Chart then you better get some information about it before using this tool. There are very good web sites and books. Please PM me if you need help about resources.
Options in the Script
Box size is one of the most important part of Point and Figure Charting. Chart price movement sensitivity is determined by the Point and Figure scale. Large box sizes see little movement across a specific price region, small box sizes see greater price movement on P&F chart. There are four different box scaling with this tool: Traditional, Percentage, Dynamic (ATR), or User-Defined
4 different methods for Box size can be used in this tool.
User Defined: The box size is set by user. A larger box size will result in more filtered price movements and fewer reversals. A smaller box size will result in less filtered price movements and more reversals.
ATR: Box size is dynamically calculated by using ATR, default period is 20.
Percentage: uses box sizes that are a fixed percentage of the stock's price. If percentage is 1 and stock’s price is $100 then box size will be $1
Traditional: uses a predefined table of price ranges to determine what the box size should be.
Price Range Box Size
Under 0.25 0.0625
0.25 to 1.00 0.125
1.00 to 5.00 0.25
5.00 to 20.00 0.50
20.00 to 100 1.0
100 to 200 2.0
200 to 500 4.0
500 to 1000 5.0
1000 to 25000 50.0
25000 and up 500.0
Default value is “ATR”, you may use one of these scaling method that suits your trading strategy.
If ATR or Percentage is chosen then there is rounding algorithm according to mintick value of the security. For example if mintick value is 0.001 and box size (ATR/Percentage) is 0.00124 then box size becomes 0.001.
And also while using dynamic box size (ATR or Percentage), box size changes only when closing price changed.
Reversal : It is the number of boxes required to change from a column of Xs to a column of Os or from a column of Os to a column of Xs. Default value is 3 (most used). For example if you choose reversal = 2 then you get the chart similar to Renko chart.
Source: Closing price or High-Low prices can be chosen as data source for P&F charting.
Chart Style: There are 3 options for chart style: “Candle”, “Area” or “Don’t show”.
As Area:
As Candle:
X/O Column Style: it can show all columns from opening price or only last Xs/Os.
Color Theme: different themes exist => Green/Red, Yellow/Blue, White/Yellow, Orange/Blue, Lime/Red, Blue/Red
Show Breakouts is the option to show Breakouts
This tool detects & shows following Breakouts:
Triple Top/Bottom,
Triple Top Ascending,
Triple Bottom Descending,
Simple Buy/Sell (Double Top/Bottom),
Simple Buy With Rising Bottom,
Simple Sell With Declining Top
Catapult bullish/bearish
Show Horizontal Count Targets: Finds the congestion or consolidation pattern and if there is breakout then it calculates the Target by using Horizontal Count method (based on the width of congestion pattern). It shows how many column exist on congestion area. There is no guarantee that prices will reach the target.
Show Vertical Count Targets: When Triple Top/Bottom Breakouts occured the script calculates the target by using Vertical Count Method (based on the length of the column). There is no guarantee that prices will reach the target.
For both methods there is auto target cancellation if price goes below congestion bottom or above congestion top.
trend is calculated by EMA of closing price of the P&F
Whipsaw protection:
Last options are “Show info panel” and Labeling Offset. Script shows current box size, reversal, and recommanded minimum and maximum box size. And also it shows the price level to reverse the column (Xs <-> Os) and the price level to add at least 1 more box to column. This is the option to put these labels 10, 20, 30, 50 or 100 bars away from the last bar. Labeling content and color change according to X/O column.
do not hesitate to comment.
Candlesticks ANN for Stock Markets TF : 1WHello, this script consists of training candlesticks with Artificial Neural Networks (ANN).
In addition to the first series, candlesticks' bodies and wicks were also introduced as training inputs.
The inputs are individually trained to find the relationship between the subsequent historical value of all candlestick values 1.(High,Low,Close,Open)
The outputs are adapted to the current values with a simple forecast code.
Once the OHLC value is found, the exponential moving averages of 5 and 20 periods are used.
Reminder : OHLC = (Open + High + Close + Low ) / 4
First version :
Script is designed for S&P 500 Indices,Funds,ETFs, especially S&P 500 Stocks,and for all liquid Stocks all around the World.
NOTE: This script is only suitable for 1W time-frame for Stocks.
The average training error rates are less than 5 per thousand for each candlestick variable. (Average Error < 0.005 )
I've just finished it and haven't tested it in detail.
So let's use it carefully as a supporter.
Best regards !
TNZ - Index above MA Use this indicator to filter stock selection based on the relevant index value being above the selected simple moving average.
For example, only buying the S+P 500 stock if the S+P 500 index value is above the 10 period moving average.
The time frame used is that displayed
Macroeconomic Artificial Neural Networks
This script was created by training 20 selected macroeconomic data to construct artificial neural networks on the S&P 500 index.
No technical analysis data were used.
The average error rate is 0.01.
In this respect, there is a strong relationship between the index and macroeconomic data.
Although it affects the whole world,I personally recommend using it under the following conditions: S&P 500 and related ETFs in 1W time-frame (TF = 1W SPX500USD, SP1!, SPY, SPX etc. )
Macroeconomic Parameters
Effective Federal Funds Rate (FEDFUNDS)
Initial Claims (ICSA)
Civilian Unemployment Rate (UNRATE)
10 Year Treasury Constant Maturity Rate (DGS10)
Gross Domestic Product , 1 Decimal (GDP)
Trade Weighted US Dollar Index : Major Currencies (DTWEXM)
Consumer Price Index For All Urban Consumers (CPIAUCSL)
M1 Money Stock (M1)
M2 Money Stock (M2)
2 - Year Treasury Constant Maturity Rate (DGS2)
30 Year Treasury Constant Maturity Rate (DGS30)
Industrial Production Index (INDPRO)
5-Year Treasury Constant Maturity Rate (FRED : DGS5)
Light Weight Vehicle Sales: Autos and Light Trucks (ALTSALES)
Civilian Employment Population Ratio (EMRATIO)
Capacity Utilization (TOTAL INDUSTRY) (TCU)
Average (Mean) Duration Of Unemployment (UEMPMEAN)
Manufacturing Employment Index (MAN_EMPL)
Manufacturers' New Orders (NEWORDER)
ISM Manufacturing Index (MAN : PMI)
Artificial Neural Network (ANN) Training Details :
Learning cycles: 16231
AutoSave cycles: 100
Grid
Input columns: 19
Output columns: 1
Excluded columns: 0
Training example rows: 998
Validating example rows: 0
Querying example rows: 0
Excluded example rows: 0
Duplicated example rows: 0
Network
Input nodes connected: 19
Hidden layer 1 nodes: 2
Hidden layer 2 nodes: 0
Hidden layer 3 nodes: 0
Output nodes: 1
Controls
Learning rate: 0.1000
Momentum: 0.8000 (Optimized)
Target error: 0.0100
Training error: 0.010000
NOTE : Alerts added . The red histogram represents the bear market and the green histogram represents the bull market.
Bars subject to region changes are shown as background colors. (Teal = Bull , Maroon = Bear Market )
I hope it will be useful in your studies and analysis, regards.
Damped Sine Wave Weighted FilterIntroduction
Remember that we can make filters by using convolution, that is summing the product between the input and the filter coefficients, the set of filter coefficients is sometime denoted "kernel", those coefficients can be a same value (simple moving average), a linear function (linearly weighted moving average), a gaussian function (gaussian filter), a polynomial function (lsma of degree p with p = order of the polynomial), you can make many types of kernels, note however that it is easy to fall into the redundancy trap.
Today a low-lag filter who weight the price with a damped sine wave is proposed, the filter characteristics are discussed below.
A Damped Sine Wave
A damped sine wave is a like a sine wave with the difference that the sine wave peak amplitude decay over time.
A damped sine wave
Used Kernel
We use a damped sine wave of period length as kernel.
The coefficients underweight older values which allow the filter to reduce lag.
Step Response
Because the filter has overshoot in the step response we can conclude that there are frequencies amplified in the passband, we could have reached to this conclusion by simply seeing the negative values in the kernel or the "zero-lag" effect on the closing price.
Enough ! We Want To See The Filter !
I should indeed stop bothering you with transient responses but its always good to see how the filter act on simpler signals before seeing it on the closing price. The filter has low-lag and can be used as input for other indicators
Filter with length = 100 as input for the rsi.
The bands trailing stop utility using rolling squared mean average error with length 500 using the filter of length 500 as input.
Approximating A Least Squares Moving Average
A least squares moving average has a linear kernel with certain values under 0, a lsma of length k can be approximated using the proposed filter using period p where p = k + k/4 .
Proposed filter (red) with length = 250 and lsma (blue) with length = 200.
Conclusions
The use of damping in filter design can provide extremely useful filters, in fact the ideal kernel, the sinc function, is also a damped sine wave.
VIX reversion-Buschi
English:
A significant intraday reversion (commonly used: 3 points) on a high (over 20 points) S&P 500 Volatility Index (VIX) can be a sign of a market bottom, because there is the assumption that some of the "big guys" liquidated their options / insurances because the worst is over.
This indicator shows these reversions (3 points as default) when the VIX was over 20 points. The character "R" is then shown directly over the daily column, the VIX need not to be loaded explicitly.
Deutsch:
Eine deutliche Intraday-Umkehr (3 Punkte im Normalfall) bei einem hohen (über 20 Punkte) S&P 500 Volatility Index (VIX) kann ein Zeichen für eine Bodenbildung im Markt sein, weil möglicherweise einige "große Jungs" ihre Optionen / Versicherungen auflösen, weil das schlimmste vorbei ist.
Dieser Indikator zeigt diese Umkehr (Standardwert: 3 Punkte), wenn der VIX vorher über 20 Punkte lag. Der Buchstabe "R" wird dabei direkt über dem Tagesbalken angezeigt, wobei der VIX nicht explizit geladen werden muss.
Relative Price StrengthThe strength of a stock relative to the S&P 500 is key part of most traders decision making process. Hence the default reference security is SPY, the most commonly trades S&P 500 ETF.
Most profitable traders buy stocks that are showing persistence intermediate strength verses the S&P as this has been shown to work. Hence the default period is 63 days or 3 months.
TICK Extremes IndicatorSimple TICK indicator, plots candles and HL2 line
Conditional green/red coloring for highs above 500, 900 and lows above 0, and for lows below -500, -900, and highs above 0
Probably best used for 1 - 5 min timeframes
Always open to suggestions if criteria needs tweaking or if something else would make it more useful or user-friendly!
Market direction and pullback based on S&P 500.A simple indicator based on www.swing-trade-stocks.com The link is also the guide for how to use it.
0 - nothing. If the indicator is showing 0 for a prolonged amount of time, it is likely the market is in "momentum mode" (referred to in the link above).
1 - indicates an uptrend based on SMA and EMA and also a place where a reversal to the upside is likely to occur. You should look only for long trades in the stock market when you see a spike upwards and S&P 500 is showing an obvious uptrend.
-1 - indicates a downtrend based on SMA and EMA and also a place where a reversal to the downside is likely to occur. You should look only for short trades in the stock market when you see a spike upwards and S&P 500 is showing an obvious uptrend.
Net XRP Margin PositionTotal XRP Longs minus XRP Shorts in order to give you the total outstanding XRP margin debt.
ie: If 500,000 XRP has been longed, and 400,000 XRP has been shorted, then 500,000 has been bought, and 400,000 sold, leaving us with 100,000 XRP (net) remaining to be sold to give us an overall neutral margin position.
That isn't to say that the net margin position must move towards zero, but it is a sensible reference point, and historical net values may provide useful insights into the current circumstances.
Net DASH Margin PositionTotal DASH Longs minus DASH Shorts in order to give you the total outstanding DASH margin debt.
ie: If 500,000 DASH has been longed, and 400,000 DASH has been shorted, then 500,000 has been bought, and 400,000 sold, leaving us with 100,000 DASH (net) remaining to be sold to give us an overall neutral margin position.
That isn't to say that the net margin position must move towards zero, but it is a sensible reference point, and historical net values may provide useful insights into the current circumstances.
(Anyone know what category this script should be in?)
Net NEO Margin PositionTotal NEO Longs minus NEO Shorts in order to give you the total outstanding NEO margin debt.
ie: If 500,000 NEO has been longed, and 400,000 NEO has been shorted, then 500,000 has been bought, and 400,000 sold, leaving us with 100,000 NEO (net) remaining to be sold to give us an overall neutral margin position.
That isn't to say that the net margin position must move towards zero, but it is a sensible reference point, and historical net values may provide useful insights into the current circumstances.
(Anyone know what category this script should be in?)
Everyday 0002 _ MAC 1st Trading Hour WalkoverThis is the second strategy for my Everyday project.
Like I wrote the last time - my goal is to create a new strategy everyday
for the rest of 2016 and post it here on TradingView.
I'm a complete beginner so this is my way of learning about coding strategies.
I'll give myself between 15 minutes and 2 hours to complete each creation.
This is basically a repetition of the first strategy I wrote - a Moving Average Crossover,
but I added a tiny thing.
I read that "Statistics have proven that the daily high or low is established within the first hour of trading on more than 70% of the time."
(source: )
My first Moving Average Crossover strategy, tested on VOLVB daily, got stoped out by the volatility
and because of this missed one nice bull run and a very nice bear run.
So I added this single line: if time("60", "1000-1600") regarding when to take exits:
if time("60", "1000-1600")
strategy.exit("Close Long", "Long", profit=2000, loss=500)
strategy.exit("Close Short", "Short", profit=2000, loss=500)
Sweden is UTC+2 so I guess UTC 1000 equals 12.00 in Stockholm. Not sure if this is correct, actually.
Anyway, I hope this means the strategy will only take exits based on price action which occur in the afternoon, when there is a higher probability of a lower volatility.
When I ran the new modified strategy on the same VOLVB daily it didn't get stoped out so easily.
On the other hand I'll have to test this on various stocks .
Reading and learning about how to properly test strategies is on my todo list - all tips on youtube videos or blogs
to read on this topic is very welcome!
Like I said the last time, I'm posting these strategies hoping to learn from the community - so any feedback, advice, or corrections is very much welcome and appreciated!
/pbergden
Grouped Peaks Screener (5/5) V4//@version=6
indicator("Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — screener ready", overlay=true, max_lines_count=500, max_labels_count=0, max_boxes_count=0, format=format.volume)
// ---------- user spec constants
LEFT = 5
RIGHT = 5
MS_PER_DAY = 24 * 60 * 60 * 1000
// ---------- typed arrays (Pine v6 best practice)
var int grp_ticks = array.new_int()
var int grp_counts = array.new_int()
var int grp_types = array.new_int() // 1 = high(res), -1 = low(sup)
var int grp_start = array.new_int() // bar_index of earliest peak in group
var line grp_lines = array.new_line()
var bool grp_active = array.new_bool()
// ---------- table (top-right)
max_table_rows = 20
var table infoTbl = table.new(position.top_right, 2, max_table_rows + 1, border_width = 1)
// ---------- helper: safely clear groups and delete drawings
f_clear_groups() =>
int nLines = array.size(grp_lines)
if nLines > 0
for i = 0 to nLines - 1
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.clear(grp_ticks)
array.clear(grp_counts)
array.clear(grp_types)
array.clear(grp_start)
array.clear(grp_lines)
array.clear(grp_active)
// ---------- trading day detection (premarket start 04:00 ET)
int y = year(time, "America/New_York")
int mo = month(time, "America/New_York")
int d = dayofmonth(time, "America/New_York")
int preStart = timestamp("America/New_York", y, mo, d, 4, 0)
int trading_day_start = time >= preStart ? preStart : preStart - MS_PER_DAY
var int prev_trading_day_start = na
if na(prev_trading_day_start)
prev_trading_day_start := trading_day_start
// reset at new premarket
if trading_day_start != prev_trading_day_start
f_clear_groups()
prev_trading_day_start := trading_day_start
bool allow_detection = time >= trading_day_start
// ---------- pivot detection (5 left / 5 right)
float ph = ta.pivothigh(high, LEFT, RIGHT)
float pl = ta.pivotlow(low, LEFT, RIGHT)
// ---------- process peak (add new or merge into existing same-price group)
f_process_peak(float price, int startBar, int kind) =>
int tick = int(math.round(price / syminfo.mintick))
int found = -1
int sz = array.size(grp_ticks)
if sz > 0
for i = 0 to sz - 1
if array.get(grp_active, i) and array.get(grp_types, i) == kind and array.get(grp_ticks, i) == tick
found := i
break
if found != -1
// merge into existing group
array.set(grp_counts, found, array.get(grp_counts, found) + 1)
if startBar < array.get(grp_start, found)
array.set(grp_start, found, startBar)
line ln = array.get(grp_lines, found)
if not na(ln)
line.set_xy1(ln, startBar, float(array.get(grp_ticks, found)) * syminfo.mintick)
line.set_xy2(ln, startBar + 1, float(array.get(grp_ticks, found)) * syminfo.mintick)
line ln2 = array.get(grp_lines, found)
if not na(ln2)
line.set_color(ln2, color.yellow)
else
color col = kind == 1 ? color.red : color.green
line lnNew = line.new(startBar, price, startBar + 1, price, xloc = xloc.bar_index, extend = extend.right, color = col, width = 2)
array.push(grp_ticks, tick)
array.push(grp_counts, 1)
array.push(grp_types, kind)
array.push(grp_start, startBar)
array.push(grp_lines, lnNew)
array.push(grp_active, true)
// apply pivots (pivot bar is bar_index - RIGHT, pivot confirmed at current bar)
if not na(ph)
int pivotBarIdxH = bar_index - RIGHT
int pivotTimeH = time
if allow_detection and pivotTimeH >= trading_day_start
f_process_peak(ph, pivotBarIdxH, 1)
if not na(pl)
int pivotBarIdxL = bar_index - RIGHT
int pivotTimeL = time
if allow_detection and pivotTimeL >= trading_day_start
f_process_peak(pl, pivotBarIdxL, -1)
// ---------- deletion rule: if price crosses level by >=1 tick -> delete group immediately
int nGroups = array.size(grp_ticks)
if nGroups > 0
for i = 0 to nGroups - 1
if array.get(grp_active, i)
int tick = array.get(grp_ticks, i)
int kind = array.get(grp_types, i)
int startB = array.get(grp_start, i)
if bar_index >= startB
if kind == 1
int highTick = int(math.round(high / syminfo.mintick))
if highTick > tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
else
int lowTick = int(math.round(low / syminfo.mintick))
if lowTick < tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
// ---------- Update top-right table "Equal H/L" and "Equal H/L price"
// header
table.cell(infoTbl, 0, 0, "Equal H/L", text_color = color.white, bgcolor = color.new(color.gray, 40))
table.cell(infoTbl, 1, 0, "Equal H/L price", text_color = color.white, bgcolor = color.new(color.gray, 40))
// clear rest of rows to avoid stale values
for r = 1 to max_table_rows
table.cell(infoTbl, 0, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
table.cell(infoTbl, 1, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
// populate grouped entries (count >= 2) that are active today
int row = 1
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
int kind = array.get(grp_types, i)
string typS = kind == 1 ? "H" : "L"
string leftText = str.tostring(array.get(grp_counts, i)) + "x " + typS
float p = float(array.get(grp_ticks, i)) * syminfo.mintick
string ptxt = str.tostring(p, format.mintick)
table.cell(infoTbl, 0, row, leftText, text_color = color.white, bgcolor = color.new(color.black, 60))
table.cell(infoTbl, 1, row, ptxt, text_color = color.white, bgcolor = color.new(color.black, 60))
row += 1
if row > max_table_rows
break
// ---------- Screener-ready plot (use this plot as the Screener column/filter)
// Screener reads plots. Plot = 1 when there is at least one active grouped Equal H/L (count >= 2)
bool hasEqualHL = false
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
hasEqualHL := true
break
// Additional check: ensure we have enough data for the pivot detection
bool hasEnoughData = bar_index >= LEFT + RIGHT + 10 // Add some buffer
// Only consider EqualHL valid if we have enough data and it's within the current trading day
bool isValidEqualHL = hasEqualHL and hasEnoughData and allow_detection
float equalHLPlot = isValidEqualHL ? 1.0 : 0.0
// Hidden on chart but visible to Screener. If you prefer a visible mark remove `display=display.none`.
plot(equalHLPlot, title="EqualHL", style=plot.style_columns, color=color.new(color.yellow, 0), linewidth=2, display=display.none)
// invisible plot to keep indicator active
plot(na)
Grouped Peaks Screener (5/5) V3- Z//@version=6
indicator("Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — screener ready", overlay=true, max_lines_count=500, max_labels_count=0, max_boxes_count=0, format=format.volume)
// ---------- user spec constants
LEFT = 5
RIGHT = 5
MS_PER_DAY = 24 * 60 * 60 * 1000
// ---------- typed arrays (Pine v6 best practice)
var int grp_ticks = array.new_int()
var int grp_counts = array.new_int()
var int grp_types = array.new_int() // 1 = high(res), -1 = low(sup)
var int grp_start = array.new_int() // bar_index of earliest peak in group
var line grp_lines = array.new_line()
var bool grp_active = array.new_bool()
// ---------- table (top-right)
max_table_rows = 20
var table infoTbl = table.new(position.top_right, 2, max_table_rows + 1, border_width = 1)
// ---------- helper: safely clear groups and delete drawings
f_clear_groups() =>
int nLines = array.size(grp_lines)
if nLines > 0
for i = 0 to nLines - 1
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.clear(grp_ticks)
array.clear(grp_counts)
array.clear(grp_types)
array.clear(grp_start)
array.clear(grp_lines)
array.clear(grp_active)
// ---------- trading day detection (premarket start 04:00 ET)
int y = year(time, "America/New_York")
int mo = month(time, "America/New_York")
int d = dayofmonth(time, "America/New_York")
int preStart = timestamp("America/New_York", y, mo, d, 4, 0)
int trading_day_start = time >= preStart ? preStart : preStart - MS_PER_DAY
var int prev_trading_day_start = na
if na(prev_trading_day_start)
prev_trading_day_start := trading_day_start
// reset at new premarket
if trading_day_start != prev_trading_day_start
f_clear_groups()
prev_trading_day_start := trading_day_start
bool allow_detection = time >= trading_day_start
// ---------- pivot detection (5 left / 5 right)
float ph = ta.pivothigh(high, LEFT, RIGHT)
float pl = ta.pivotlow(low, LEFT, RIGHT)
// ---------- process peak (add new or merge into existing same-price group)
f_process_peak(float price, int startBar, int kind) =>
int tick = int(math.round(price / syminfo.mintick))
int found = -1
int sz = array.size(grp_ticks)
if sz > 0
for i = 0 to sz - 1
if array.get(grp_active, i) and array.get(grp_types, i) == kind and array.get(grp_ticks, i) == tick
found := i
break
if found != -1
// merge into existing group
array.set(grp_counts, found, array.get(grp_counts, found) + 1)
if startBar < array.get(grp_start, found)
array.set(grp_start, found, startBar)
line ln = array.get(grp_lines, found)
if not na(ln)
line.set_xy1(ln, startBar, float(array.get(grp_ticks, found)) * syminfo.mintick)
line.set_xy2(ln, startBar + 1, float(array.get(grp_ticks, found)) * syminfo.mintick)
line ln2 = array.get(grp_lines, found)
if not na(ln2)
line.set_color(ln2, color.yellow)
else
color col = kind == 1 ? color.red : color.green
line lnNew = line.new(startBar, price, startBar + 1, price, xloc = xloc.bar_index, extend = extend.right, color = col, width = 2)
array.push(grp_ticks, tick)
array.push(grp_counts, 1)
array.push(grp_types, kind)
array.push(grp_start, startBar)
array.push(grp_lines, lnNew)
array.push(grp_active, true)
// apply pivots (pivot bar is bar_index - RIGHT, pivot confirmed at current bar)
if not na(ph)
int pivotBarIdxH = bar_index - RIGHT
int pivotTimeH = time
if allow_detection and pivotTimeH >= trading_day_start
f_process_peak(ph, pivotBarIdxH, 1)
if not na(pl)
int pivotBarIdxL = bar_index - RIGHT
int pivotTimeL = time
if allow_detection and pivotTimeL >= trading_day_start
f_process_peak(pl, pivotBarIdxL, -1)
// ---------- deletion rule: if price crosses level by >=1 tick -> delete group immediately
int nGroups = array.size(grp_ticks)
if nGroups > 0
for i = 0 to nGroups - 1
if array.get(grp_active, i)
int tick = array.get(grp_ticks, i)
int kind = array.get(grp_types, i)
int startB = array.get(grp_start, i)
if bar_index >= startB
if kind == 1
int highTick = int(math.round(high / syminfo.mintick))
if highTick > tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
else
int lowTick = int(math.round(low / syminfo.mintick))
if lowTick < tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
// ---------- Update top-right table "Equal H/L" and "Equal H/L price"
// header
table.cell(infoTbl, 0, 0, "Equal H/L", text_color = color.white, bgcolor = color.new(color.gray, 40))
table.cell(infoTbl, 1, 0, "Equal H/L price", text_color = color.white, bgcolor = color.new(color.gray, 40))
// clear rest of rows to avoid stale values
for r = 1 to max_table_rows
table.cell(infoTbl, 0, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
table.cell(infoTbl, 1, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
// populate grouped entries (count >= 2) that are active today
int row = 1
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
int kind = array.get(grp_types, i)
string typS = kind == 1 ? "H" : "L"
string leftText = str.tostring(array.get(grp_counts, i)) + "x " + typS
float p = float(array.get(grp_ticks, i)) * syminfo.mintick
string ptxt = str.tostring(p, format.mintick)
table.cell(infoTbl, 0, row, leftText, text_color = color.white, bgcolor = color.new(color.black, 60))
table.cell(infoTbl, 1, row, ptxt, text_color = color.white, bgcolor = color.new(color.black, 60))
row += 1
if row > max_table_rows
break
// ---------- Screener-ready plot (use this plot as the Screener column/filter)
// Screener reads plots. Plot = 1 when there is at least one active grouped Equal H/L (count >= 2)
bool hasEqualHL = false
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
hasEqualHL := true
break
float equalHLPlot = hasEqualHL ? 1.0 : 0.0
// Hidden on chart but visible to Screener. If you prefer a visible mark remove `display=display.none`.
plot(equalHLPlot, title="EqualHL", style=plot.style_columns, color=color.new(color.yellow, 0), linewidth=2, display=display.none)
// invisible plot to keep indicator active
plot(na)
Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — V2//@version=6
indicator("Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — screener ready", overlay=true, max_lines_count=500, max_labels_count=0, max_boxes_count=0)
// ---------- user spec constants
LEFT = 5
RIGHT = 5
MS_PER_DAY = 24 * 60 * 60 * 1000
// ---------- typed arrays (Pine v6 best practice)
var int grp_ticks = array.new_int()
var int grp_counts = array.new_int()
var int grp_types = array.new_int() // 1 = high(res), -1 = low(sup)
var int grp_start = array.new_int() // bar_index of earliest peak in group
var line grp_lines = array.new_line()
var bool grp_active = array.new_bool()
// ---------- table (top-right)
max_table_rows = 20
var table infoTbl = table.new(position.top_right, 2, max_table_rows + 1, border_width = 1)
// ---------- helper: safely clear groups and delete drawings
f_clear_groups() =>
int nLines = array.size(grp_lines)
if nLines > 0
for i = 0 to nLines - 1
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.clear(grp_ticks)
array.clear(grp_counts)
array.clear(grp_types)
array.clear(grp_start)
array.clear(grp_lines)
array.clear(grp_active)
// ---------- trading day detection (premarket start 04:00 ET)
int y = year(time, "America/New_York")
int mo = month(time, "America/New_York")
int d = dayofmonth(time, "America/New_York")
int preStart = timestamp("America/New_York", y, mo, d, 4, 0)
int trading_day_start = time >= preStart ? preStart : preStart - MS_PER_DAY
var int prev_trading_day_start = na
if na(prev_trading_day_start)
prev_trading_day_start := trading_day_start
// reset at new premarket
if trading_day_start != prev_trading_day_start
f_clear_groups()
prev_trading_day_start := trading_day_start
bool allow_detection = time >= trading_day_start
// ---------- pivot detection (5 left / 5 right)
float ph = ta.pivothigh(high, LEFT, RIGHT)
float pl = ta.pivotlow(low, LEFT, RIGHT)
// ---------- process peak (add new or merge into existing same-price group)
f_process_peak(float price, int startBar, int kind) =>
int tick = int(math.round(price / syminfo.mintick))
int found = -1
int sz = array.size(grp_ticks)
if sz > 0
for i = 0 to sz - 1
if array.get(grp_active, i) and array.get(grp_types, i) == kind and array.get(grp_ticks, i) == tick
found := i
break
if found != -1
// merge into existing group
array.set(grp_counts, found, array.get(grp_counts, found) + 1)
if startBar < array.get(grp_start, found)
array.set(grp_start, found, startBar)
line ln = array.get(grp_lines, found)
if not na(ln)
line.set_xy1(ln, startBar, float(array.get(grp_ticks, found)) * syminfo.mintick)
line.set_xy2(ln, startBar + 1, float(array.get(grp_ticks, found)) * syminfo.mintick)
line ln2 = array.get(grp_lines, found)
if not na(ln2)
line.set_color(ln2, color.yellow)
else
color col = kind == 1 ? color.red : color.green
line lnNew = line.new(startBar, price, startBar + 1, price, xloc = xloc.bar_index, extend = extend.right, color = col, width = 2)
array.push(grp_ticks, tick)
array.push(grp_counts, 1)
array.push(grp_types, kind)
array.push(grp_start, startBar)
array.push(grp_lines, lnNew)
array.push(grp_active, true)
// apply pivots (pivot bar is bar_index - RIGHT, pivot confirmed at current bar)
if not na(ph)
int pivotBarIdxH = bar_index - RIGHT
int pivotTimeH = time
if allow_detection and pivotTimeH >= trading_day_start
f_process_peak(ph, pivotBarIdxH, 1)
if not na(pl)
int pivotBarIdxL = bar_index - RIGHT
int pivotTimeL = time
if allow_detection and pivotTimeL >= trading_day_start
f_process_peak(pl, pivotBarIdxL, -1)
// ---------- deletion rule: if price crosses level by >=1 tick -> delete group immediately
int nGroups = array.size(grp_ticks)
if nGroups > 0
for i = 0 to nGroups - 1
if array.get(grp_active, i)
int tick = array.get(grp_ticks, i)
int kind = array.get(grp_types, i)
int startB = array.get(grp_start, i)
if bar_index >= startB
if kind == 1
int highTick = int(math.round(high / syminfo.mintick))
if highTick > tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
else
int lowTick = int(math.round(low / syminfo.mintick))
if lowTick < tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
// ---------- Update top-right table "Equal H/L" and "Equal H/L price"
// header
table.cell(infoTbl, 0, 0, "Equal H/L", text_color = color.white, bgcolor = color.new(color.gray, 40))
table.cell(infoTbl, 1, 0, "Equal H/L price", text_color = color.white, bgcolor = color.new(color.gray, 40))
// clear rest of rows to avoid stale values
for r = 1 to max_table_rows
table.cell(infoTbl, 0, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
table.cell(infoTbl, 1, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
// populate grouped entries (count >= 2) that are active today
int row = 1
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
int kind = array.get(grp_types, i)
string typS = kind == 1 ? "H" : "L"
string leftText = str.tostring(array.get(grp_counts, i)) + "x " + typS
float p = float(array.get(grp_ticks, i)) * syminfo.mintick
string ptxt = str.tostring(p, format.mintick)
table.cell(infoTbl, 0, row, leftText, text_color = color.white, bgcolor = color.new(color.black, 60))
table.cell(infoTbl, 1, row, ptxt, text_color = color.white, bgcolor = color.new(color.black, 60))
row += 1
if row > max_table_rows
break
// ---------- Screener-ready plot (use this plot as the Screener column/filter)
// Screener reads plots. Plot = 1 when there is at least one active grouped Equal H/L (count >= 2)
bool hasEqualHL = false
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
hasEqualHL := true
break
float equalHLPlot = hasEqualHL ? 1.0 : 0.0
// Hidden on chart but visible to Screener. If you prefer a visible mark remove `display=display.none`.
plot(equalHLPlot, title="EqualHL", style=plot.style_columns, color=color.new(color.yellow, 0), linewidth=2, display=display.none)
// invisible plot to keep indicator active
plot(na)
Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — V1//@version=6
indicator("Grouped Peaks Screener (5/5) — Intraday (04:00 ET reset) — v2", overlay=true, max_lines_count=500, max_labels_count=0, max_boxes_count=0)
// ---------- user spec constants
LEFT = 5
RIGHT = 5
MS_PER_DAY = 24 * 60 * 60 * 1000
// ---------- typed arrays (Pine v6 best practice)
var int grp_ticks = array.new_int()
var int grp_counts = array.new_int()
var int grp_types = array.new_int() // 1 = high(res), -1 = low(sup)
var int grp_start = array.new_int() // bar_index of earliest peak in group
var line grp_lines = array.new_line()
var bool grp_active = array.new_bool()
// ---------- table (top-right)
max_table_rows = 20
var table infoTbl = table.new(position.top_right, 2, max_table_rows + 1, border_width = 1)
// ---------- helper: safely clear groups and delete drawings
f_clear_groups() =>
int nLines = array.size(grp_lines)
if nLines > 0
for i = 0 to nLines - 1
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.clear(grp_ticks)
array.clear(grp_counts)
array.clear(grp_types)
array.clear(grp_start)
array.clear(grp_lines)
array.clear(grp_active)
// ---------- trading day detection (premarket start 04:00 ET)
int y = year(time, "America/New_York")
int mo = month(time, "America/New_York")
int d = dayofmonth(time, "America/New_York")
int preStart = timestamp("America/New_York", y, mo, d, 4, 0)
int trading_day_start = time >= preStart ? preStart : preStart - MS_PER_DAY
var int prev_trading_day_start = na
if na(prev_trading_day_start)
prev_trading_day_start := trading_day_start
// reset at new premarket
if trading_day_start != prev_trading_day_start
f_clear_groups()
prev_trading_day_start := trading_day_start
bool allow_detection = time >= trading_day_start
// ---------- pivot detection (5 left / 5 right)
float ph = ta.pivothigh(high, LEFT, RIGHT)
float pl = ta.pivotlow(low, LEFT, RIGHT)
// ---------- process peak (add new or merge into existing same-price group)
f_process_peak(float price, int startBar, int kind) =>
int tick = int(math.round(price / syminfo.mintick))
int found = -1
int sz = array.size(grp_ticks)
if sz > 0
for i = 0 to sz - 1
if array.get(grp_active, i) and array.get(grp_types, i) == kind and array.get(grp_ticks, i) == tick
found := i
break
if found != -1
// merge into existing group
array.set(grp_counts, found, array.get(grp_counts, found) + 1)
if startBar < array.get(grp_start, found)
array.set(grp_start, found, startBar)
line ln = array.get(grp_lines, found)
if not na(ln)
line.set_xy1(ln, startBar, float(array.get(grp_ticks, found)) * syminfo.mintick)
line.set_xy2(ln, startBar + 1, float(array.get(grp_ticks, found)) * syminfo.mintick)
line ln2 = array.get(grp_lines, found)
if not na(ln2)
line.set_color(ln2, color.yellow)
else
color col = kind == 1 ? color.red : color.green
line lnNew = line.new(startBar, price, startBar + 1, price, xloc = xloc.bar_index, extend = extend.right, color = col, width = 2)
array.push(grp_ticks, tick)
array.push(grp_counts, 1)
array.push(grp_types, kind)
array.push(grp_start, startBar)
array.push(grp_lines, lnNew)
array.push(grp_active, true)
// apply pivots (pivot bar is bar_index - RIGHT, pivot confirmed at current bar)
if not na(ph)
int pivotBarIdxH = bar_index - RIGHT
int pivotTimeH = time
if allow_detection and pivotTimeH >= trading_day_start
f_process_peak(ph, pivotBarIdxH, 1)
if not na(pl)
int pivotBarIdxL = bar_index - RIGHT
int pivotTimeL = time
if allow_detection and pivotTimeL >= trading_day_start
f_process_peak(pl, pivotBarIdxL, -1)
// ---------- deletion rule: if price crosses level by >=1 tick -> delete group immediately
int nGroups = array.size(grp_ticks)
if nGroups > 0
for i = 0 to nGroups - 1
if array.get(grp_active, i)
int tick = array.get(grp_ticks, i)
int kind = array.get(grp_types, i)
int startB = array.get(grp_start, i)
if bar_index >= startB
if kind == 1
int highTick = int(math.round(high / syminfo.mintick))
if highTick > tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
else
int lowTick = int(math.round(low / syminfo.mintick))
if lowTick < tick
line ln = array.get(grp_lines, i)
if not na(ln)
line.delete(ln)
array.set(grp_active, i, false)
// ---------- Update top-right table "Equal H/L" and "Equal H/L price"
// header
table.cell(infoTbl, 0, 0, "Equal H/L", text_color = color.white, bgcolor = color.new(color.gray, 40))
table.cell(infoTbl, 1, 0, "Equal H/L price", text_color = color.white, bgcolor = color.new(color.gray, 40))
// clear rest of rows to avoid stale values
for r = 1 to max_table_rows
table.cell(infoTbl, 0, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
table.cell(infoTbl, 1, r, "", text_color = color.white, bgcolor = color.new(color.black, 100))
// populate grouped entries (count >= 2) that are active today
int row = 1
if array.size(grp_ticks) > 0
for i = 0 to array.size(grp_ticks) - 1
if array.get(grp_active, i) and array.get(grp_counts, i) >= 2
int kind = array.get(grp_types, i)
string typS = kind == 1 ? "H" : "L"
string leftText = str.tostring(array.get(grp_counts, i)) + "x " + typS
float p = float(array.get(grp_ticks, i)) * syminfo.mintick
string ptxt = str.tostring(p, format.mintick)
table.cell(infoTbl, 0, row, leftText, text_color = color.white, bgcolor = color.new(color.black, 60))
table.cell(infoTbl, 1, row, ptxt, text_color = color.white, bgcolor = color.new(color.black, 60))
row += 1
if row > max_table_rows
break
// invisible plot to keep indicator active
plot(na)
Previous candle - D-T.R.A.D.I.N.G//@version=6
indicator("Previous candle - byDen (Body % line & Wick size) ", overlay=true, max_boxes_count=200, max_lines_count=200, max_labels_count=200)
// ---------------- Inputs ----------------
showHighLow = input.bool(true, "Show High/Low lines")
showHLBox = input.bool(true, "Show High-Low Box (full range)")
showMidLine = input.bool(true, "Show Middle Line")
showCloseLine = input.bool(true, "Show Close Line")
showBodyPct = input.bool(true, "Show Body % Line")
enableWickBox = input.bool(true, "Show Wick-Body Box (previous candle)")
keepLastWick = input.bool(false, "Keep last Wick-Box when disabled")
bodyPct = input.float(25.0, "Body % Level", step=0.1, minval=0.0, maxval=100.0)
// colors / styles
cHighLow = input.color(color.white, "H/L Line Color")
hlStyleStr = input.string("solid", "H/L Style", options= )
hlWidth = input.int(1, "H/L Width", minval=1, maxval=5)
cMid = input.color(color.yellow, "Mid Line Color")
midStyleStr = input.string("dashed", "Mid Style", options= )
midWidth = input.int(1, "Mid Width", minval=1, maxval=5)
cClose = input.color(color.yellow, "Close Line Color")
closeStyleStr = input.string("dotted", "Close Style", options= )
closeWidth = input.int(1, "Close Width", minval=1, maxval=5)
cBoxBorder = input.color(color.red, "HL Box Border")
cBoxFill = color.new(input.color(color.gray, "HL Box Fill"), 85)
cBullBox = color.new(input.color(color.green, "Bull WickBox"), 80)
cBearBox = color.new(input.color(color.red, "Bear WickBox"), 80)
cWboxBorder = input.color(color.white, "WickBox Border")
cBodyPct = input.color(color.blue, "Body % Line Color")
bodyPctStyle = input.string("dashed", "Body % Line Style", options= )
bodyPctWidth = input.int(1, "Body % Line Width", minval=1, maxval=5)
// table colors / pip size
cPipBox = input.color(color.new(color.blue, 80), "Table Background Color")
cPipText = input.color(color.white, "Table Text Color")
pipSize = input.float(0.1, "Pip size (XAUUSD=0.1)", step=0.01)
wickLabelText = input.string("Wick", "Opis za wick")
bodyLabelText = input.string("H/L-Body%", "Opis za H/L-Body%")
descFontSizeStr = input.string("small", "Table Description Font Size", options= )
valFontSizeStr = input.string("normal", "Table Value Font Size", options= )
// custom texts for line labels
txtHigh = input.string("High", "Label Text - High")
txtLow = input.string("Low", "Label Text - Low")
txtMid = input.string("Mid", "Label Text - Mid")
txtClose = input.string("Close", "Label Text - Close")
txtBody = input.string("Body%", "Label Text - Body %")
lineFontSizeStr = input.string("small", "Line Label Font Size", options= )
lineLabelPos = input.string("above", "Line Label Position", options= )
lineLabelAlign = input.string("center", "Line Label Align", options= )
// ---------------- Candle Display Options ----------------
highDisplay = input.string("Both", "High Line Display", options= )
lowDisplay = input.string("Both", "Low Line Display", options= )
midDisplay = input.string("Both", "Mid Line Display", options= )
closeDisplay = input.string("Both", "Close Line Display", options= )
bodyDisplay = input.string("Both", "Body % Line Display", options= )
hlBoxDisplay = input.string("Both", "HL Box Display", options= )
wickBoxDisplay = input.string("Both", "Wick Box Display", options= )
// timeframe filter
enabledTFs = input.string("1,5,15,30,60,240,D", "Enable on timeframes")
// ---------------- Helpers ----------------
is_tf_enabled(tfStr) =>
str.contains("," + enabledTFs + ",", "," + tfStr + ",")
line_style_from_str(s) =>
s == "dotted" ? line.style_dotted : s == "dashed" ? line.style_dashed : line.style_solid
get_font_size(fs) =>
fs == "tiny" ? size.tiny : fs == "small" ? size.small : fs == "large" ? size.large : fs == "huge" ? size.huge : size.normal
get_label_style(a) =>
a == "left" ? label.style_label_left : a == "right" ? label.style_label_right : label.style_label_center
get_y_pos(basePrice, pos) =>
pos == "above" ? basePrice + (syminfo.mintick * 10) : basePrice - (syminfo.mintick * 10)
// ---------------- Data ----------------
tf = timeframe.period
= request.security(syminfo.tickerid, tf, , lookahead=barmerge.lookahead_off)
midLevel = (prevH + prevL) / 2
isBull = prevC > prevO
// ---------------- Persistent ----------------
var line lHigh = na
var line lLow = na
var line lMid = na
var line lClose = na
var line lBodyPct = na
var box bHL = na
var box wickBox = na
var table wickTable = na
var label labHigh = na
var label labLow = na
var label labMid = na
var label labClose = na
var label labBodyPct = na
offsetBars = input.int(20, "Bars right", minval=1, maxval=500)
leftX_base = bar_index
rightX_base = bar_index + offsetBars
if na(wickTable)
wickTable := table.new(position.bottom_right, 2, 2, border_width=1, frame_color=color.white)
// ---------------- DRAW ----------------
if barstate.isconfirmed and is_tf_enabled(tf)
// delete previous labels
if not na(labHigh)
label.delete(labHigh)
labHigh := na
if not na(labLow)
label.delete(labLow)
labLow := na
if not na(labMid)
label.delete(labMid)
labMid := na
if not na(labClose)
label.delete(labClose)
labClose := na
if not na(labBodyPct)
label.delete(labBodyPct)
labBodyPct := na
// --- DRAW HIGH ---
drawHigh = (highDisplay=="Both") or (highDisplay=="Bullish" and isBull) or (highDisplay=="Bearish" and not isBull)
if showHighLow and drawHigh
if not na(lHigh)
line.delete(lHigh)
lHigh := line.new(leftX_base, prevH, rightX_base, prevH, xloc=xloc.bar_index, color=cHighLow, width=hlWidth, style=line_style_from_str(hlStyleStr))
labHigh := label.new(rightX_base, get_y_pos(prevH,lineLabelPos), txtHigh, xloc=xloc.bar_index, yloc=yloc.price, style=get_label_style(lineLabelAlign), textcolor=cHighLow, size=get_font_size(lineFontSizeStr))
// --- DRAW LOW ---
drawLow = (lowDisplay=="Both") or (lowDisplay=="Bullish" and isBull) or (lowDisplay=="Bearish" and not isBull)
if showHighLow and drawLow
if not na(lLow)
line.delete(lLow)
lLow := line.new(leftX_base, prevL, rightX_base, prevL, xloc=xloc.bar_index, color=cHighLow, width=hlWidth, style=line_style_from_str(hlStyleStr))
labLow := label.new(rightX_base, get_y_pos(prevL,lineLabelPos), txtLow, xloc=xloc.bar_index, yloc=yloc.price, style=get_label_style(lineLabelAlign), textcolor=cHighLow, size=get_font_size(lineFontSizeStr))
// --- DRAW MID ---
drawMid = (midDisplay=="Both") or (midDisplay=="Bullish" and isBull) or (midDisplay=="Bearish" and not isBull)
if showMidLine and drawMid
if not na(lMid)
line.delete(lMid)
lMid := line.new(leftX_base, midLevel, rightX_base, midLevel, xloc=xloc.bar_index, color=cMid, width=midWidth, style=line_style_from_str(midStyleStr))
labMid := label.new(rightX_base, get_y_pos(midLevel,lineLabelPos), txtMid, xloc=xloc.bar_index, yloc=yloc.price, style=get_label_style(lineLabelAlign), textcolor=cMid, size=get_font_size(lineFontSizeStr))
// --- DRAW CLOSE ---
drawClose = (closeDisplay=="Both") or (closeDisplay=="Bullish" and isBull) or (closeDisplay=="Bearish" and not isBull)
if showCloseLine and drawClose
if not na(lClose)
line.delete(lClose)
lClose := line.new(leftX_base, prevC, rightX_base, prevC, xloc=xloc.bar_index, color=cClose, width=closeWidth, style=line_style_from_str(closeStyleStr))
labClose := label.new(rightX_base, get_y_pos(prevC,lineLabelPos), txtClose, xloc=xloc.bar_index, yloc=yloc.price, style=get_label_style(lineLabelAlign), textcolor=cClose, size=get_font_size(lineFontSizeStr))
// --- DRAW BODY% ---
float bodySize = math.abs(prevC-prevO)
float levelPct = na
drawBody = (bodyDisplay=="Both") or (bodyDisplay=="Bullish" and isBull) or (bodyDisplay=="Bearish" and not isBull)
if showBodyPct and bodySize>0 and drawBody
if not na(lBodyPct)
line.delete(lBodyPct)
levelPct := isBull ? (prevC - (bodyPct/100)*bodySize) : (prevC + (bodyPct/100)*bodySize)
lBodyPct := line.new(leftX_base, levelPct, rightX_base, levelPct, xloc=xloc.bar_index, color=cBodyPct, width=bodyPctWidth, style=line_style_from_str(bodyPctStyle))
labBodyPct := label.new(rightX_base, get_y_pos(levelPct,lineLabelPos), txtBody, xloc=xloc.bar_index, yloc=yloc.price, style=get_label_style(lineLabelAlign), textcolor=cBodyPct, size=get_font_size(lineFontSizeStr))
// --- BOXES ---
drawHLBox = (hlBoxDisplay=="Both") or (hlBoxDisplay=="Bullish" and isBull) or (hlBoxDisplay=="Bearish" and not isBull)
if showHLBox and drawHLBox
if not na(bHL)
box.delete(bHL)
bHL := box.new(leftX_base, prevH, rightX_base, prevL, xloc=xloc.bar_index, border_color=cBoxBorder, bgcolor=cBoxFill)
drawWickBox = (wickBoxDisplay=="Both") or (wickBoxDisplay=="Bullish" and isBull) or (wickBoxDisplay=="Bearish" and not isBull)
if enableWickBox and drawWickBox
float topP = isBull ? prevH : prevC
float botP = isBull ? prevC : prevL
if not na(topP) and not na(botP)
if not na(wickBox)
box.delete(wickBox)
wickBox := box.new(leftX_base, topP, rightX_base, botP, xloc=xloc.bar_index, border_color=cWboxBorder, bgcolor=(isBull?cBullBox:cBearBox))
else if not enableWickBox and not keepLastWick and not na(wickBox)
box.delete(wickBox)
wickBox := na
// --- TABLE (vedno na obeh) ---
float wickPips = isBull ? prevH-prevC : prevC-prevL
float bodyPips = na
if not na(levelPct)
bodyPips := isBull ? math.round((prevH-levelPct)/pipSize) : math.round((levelPct-prevL)/pipSize)
table.cell(wickTable, 0, 0, wickLabelText, text_color=cPipText, bgcolor=cPipBox, text_size=get_font_size(descFontSizeStr))
table.cell(wickTable, 1, 0, str.tostring(wickPips/pipSize), text_color=cPipText, bgcolor=cPipBox, text_size=get_font_size(valFontSizeStr))
if not na(bodyPips)
table.cell(wickTable, 0, 1, bodyLabelText, text_color=cPipText, bgcolor=cPipBox, text_size=get_font_size(descFontSizeStr))
table.cell(wickTable, 1, 1, str.tostring(bodyPips), text_color=cPipText, bgcolor=cPipBox, text_size=get_font_size(valFontSizeStr))
Previous candle - byDen (Body % line & Wick size)
//@version=6
indicator("Previous candle - byDen (Body % line & Wick size) ", overlay=true, max_boxes_count=200, max_lines_count=200, max_labels_count=200)
// ---------------- Inputs ----------------
showHighLow = input.bool(true, "Show High/Low lines")
showHLBox = input.bool(true, "Show High-Low Box (full range)")
showMidLine = input.bool(true, "Show Middle Line")
showCloseLine = input.bool(true, "Show Close Line")
showBodyPct = input.bool(true, "Show Body % Line")
enableWickBox = input.bool(true, "Show Wick-Body Box (previous candle)")
keepLastWick = input.bool(false, "Keep last Wick-Box when disabled")
bodyPct = input.float(25.0, "Body % Level", step=0.1, minval=0.0, maxval=100.0)
// colors / styles
cHighLow = input.color(color.white, "H/L Line Color")
hlStyleStr = input.string("solid", "H/L Style", options= )
hlWidth = input.int(1, "H/L Width", minval=1, maxval=5)
cMid = input.color(color.yellow, "Mid Line Color")
midStyleStr = input.string("dashed", "Mid Style", options= )
midWidth = input.int(1, "Mid Width", minval=1, maxval=5)
cClose = input.color(color.yellow, "Close Line Color")
closeStyleStr = input.string("dotted", "Close Style", options= )
closeWidth = input.int(1, "Close Width", minval=1, maxval=5)
cBoxBorder = input.color(color.red, "HL Box Border")
cBoxFill = color.new(input.color(color.gray, "HL Box Fill"), 85)
cBullBox = color.new(input.color(color.green, "Bull WickBox"), 80)
cBearBox = color.new(input.color(color.red, "Bear WickBox"), 80)
cWboxBorder = input.color(color.white, "WickBox Border")
cBodyPct = input.color(color.blue, "Body % Line Color")
bodyPctStyle = input.string("dashed", "Body % Line Style", options= )
bodyPctWidth = input.int(1, "Body % Line Width", minval=1, maxval=5)
// wick label
cPipBox = input.color(color.new(color.blue, 80), "Wick Box Color")
cPipText = input.color(color.white, "Wick Text Color")
pipSize = input.float(0.1, "Pip size (XAUUSD=0.1)", step=0.01)
// Label settings
showLabels = input.bool(true, "Show Line Labels")
labelAbove = input.bool(true, "Labels Above Line?")
fontSizeStr = input.string("normal", "Label Font Size", options= )
labelAlignX = input.string("center", "Label Alignment", options= )
// custom texts for labels
txtHigh = input.string("High", "Label Text - High")
txtLow = input.string("Low", "Label Text - Low")
txtMid = input.string("Mid", "Label Text - Mid")
txtClose = input.string("Close", "Label Text - Close")
txtBody = input.string("Body %", "Label Text - Body %")
// Wick pips font size (same options)
wickFontSizeStr = input.string("normal", "Wick Pips Font Size", options= )
// timeframe filter
enabledTFs = input.string("1,5,15,30,60,240,D", "Enable on timeframes")
// ---------------- Helpers ----------------
is_tf_enabled(tfStr) =>
str.contains("," + enabledTFs + ",", "," + tfStr + ",")
line_style_from_str(s) =>
s == "dotted" ? line.style_dotted : s == "dashed" ? line.style_dashed : line.style_solid
get_label_style(_align) =>
_align == "left" ? label.style_label_left : _align == "right" ? label.style_label_right : label.style_label_center
get_font_size(fs) =>
if fs == "tiny"
size.tiny
else if fs == "small"
size.small
else if fs == "large"
size.large
else if fs == "huge"
size.huge
else
size.normal
// ---------------- Data ----------------
tf = timeframe.period
= request.security(syminfo.tickerid, tf, , lookahead=barmerge.lookahead_off)
midLevel = (prevH + prevL) / 2
isBull = prevC > prevO
// ---------------- Persistent ----------------
var line lHigh = na
var line lLow = na
var line lMid = na
var line lClose = na
var line lBodyPct = na
var box bHL = na
var box wickBox = na
var table wickTable = na
// labels
var label labHigh = na
var label labLow = na
var label labMid = na
var label labClose = na
var label labBody = na
offsetBars = input.int(20, "Bars right", minval=1, maxval=500)
leftX_base = bar_index
rightX_base = bar_index + offsetBars
if na(wickTable)
wickTable := table.new(position.bottom_right, 1, 1, border_width=1, frame_color=color.white)
// ---------------- DRAW ----------------
if barstate.isconfirmed and is_tf_enabled(tf)
// clean old labels
if not na(labHigh)
label.delete(labHigh)
if not na(labLow)
label.delete(labLow)
if not na(labMid)
label.delete(labMid)
if not na(labClose)
label.delete(labClose)
if not na(labBody)
label.delete(labBody)
// style for labels
labStyle = get_label_style(labelAlignX)
labSize = get_font_size(fontSizeStr)
wickSize = get_font_size(wickFontSizeStr)
yOffset = labelAbove ? 1 : -1
if showHighLow
if not na(lHigh)
line.delete(lHigh)
if not na(lLow)
line.delete(lLow)
lHigh := line.new(leftX_base, prevH, rightX_base, prevH, xloc=xloc.bar_index, color=cHighLow, width=hlWidth, style=line_style_from_str(hlStyleStr))
lLow := line.new(leftX_base, prevL, rightX_base, prevL, xloc=xloc.bar_index, color=cHighLow, width=hlWidth, style=line_style_from_str(hlStyleStr))
if showLabels
labHigh := label.new(rightX_base, prevH + yOffset*syminfo.mintick, txtHigh, xloc=xloc.bar_index, yloc=yloc.price, style=labStyle, textcolor=cHighLow, size=labSize)
labLow := label.new(rightX_base, prevL + yOffset*syminfo.mintick, txtLow, xloc=xloc.bar_index, yloc=yloc.price, style=labStyle, textcolor=cHighLow, size=labSize)
if showMidLine
if not na(lMid)
line.delete(lMid)
lMid := line.new(leftX_base, midLevel, rightX_base, midLevel, xloc=xloc.bar_index, color=cMid, width=midWidth, style=line_style_from_str(midStyleStr))
if showLabels
labMid := label.new(rightX_base, midLevel + yOffset*syminfo.mintick, txtMid, xloc=xloc.bar_index, yloc=yloc.price, style=labStyle, textcolor=cMid, size=labSize)
if showCloseLine
if not na(lClose)
line.delete(lClose)
lClose := line.new(leftX_base, prevC, rightX_base, prevC, xloc=xloc.bar_index, color=cClose, width=closeWidth, style=line_style_from_str(closeStyleStr))
if showLabels
labClose := label.new(rightX_base, prevC + yOffset*syminfo.mintick, txtClose, xloc=xloc.bar_index, yloc=yloc.price, style=labStyle, textcolor=cClose, size=labSize)
if showBodyPct
if not na(lBodyPct)
line.delete(lBodyPct)
float bodySize = math.abs(prevC - prevO)
if bodySize > 0
float levelPct = isBull ? (prevC - (bodyPct/100.0) * bodySize) : (prevC + (bodyPct/100.0) * bodySize)
lBodyPct := line.new(leftX_base, levelPct, rightX_base, levelPct, xloc=xloc.bar_index, color=cBodyPct, width=bodyPctWidth, style=line_style_from_str(bodyPctStyle))
if showLabels
labBody := label.new(rightX_base, levelPct + yOffset*syminfo.mintick, txtBody + " " + str.tostring(bodyPct), xloc=xloc.bar_index, yloc=yloc.price, style=labStyle, textcolor=cBodyPct, size=labSize)
if showHLBox
if not na(bHL)
box.delete(bHL)
bHL := box.new(leftX_base, prevH, rightX_base, prevL, xloc=xloc.bar_index, border_color=cBoxBorder, bgcolor=cBoxFill)
if not enableWickBox
if not na(wickBox) and not keepLastWick
box.delete(wickBox)
wickBox := na
else
float topP = isBull ? prevH : prevC
float botP = isBull ? prevC : prevL
if not na(topP) and not na(botP)
if not na(wickBox)
box.delete(wickBox)
wickBox := box.new(leftX_base, topP, rightX_base, botP, xloc=xloc.bar_index, border_color=cWboxBorder, bgcolor=(isBull ? cBullBox : cBearBox))
// wick izračun (v pipih)
float wickPips = isBull ? prevH - prevC : prevC - prevL
float wickInPips = math.round(wickPips / pipSize)
// prikaži samo številko v desnem spodnjem kotu (z nastavljivo velikostjo)
table.cell(wickTable, 0, 0, str.tostring(wickInPips), text_color=cPipText, bgcolor=cPipBox, text_size=wickSize)