Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
- // Β© doth4581 (DotH)
- // Version 1.0 - 2nd January 2023
- // This is an implementation for displaying a tick based chart in Trading View.
- //
- // Tick based charts are charts with candles that are rendered in the same way as traditional candles.
- // However, instead of rendering a new candle at a specific time period,tick based candles are rendered after
- // a set number of ticks have occured.
- // There are benefits to using ticks based candles, as each candle represents the same number of "price moves"
- // For more info see this page (not affiliated with me):
- // https://www.centralcharts.com/en/gm/1-learn/7-technical-analysis/29-chart/569-understanding-tick-charts
- //
- // Limitations/known issues:
- // - Currently the indicator has been restricted to 100 candles. This is for limiting the line and box usage to a max of 300 objects.
- // - On timeframes above 1 minute, the seconds values will always be 0. In order to be able to see seconds values in the chart scale
- // you need to be on a second level chart, which requires a premium TradingView subscription.
- // - Changing the parameters in the settings will cause the chart to empty and start redrawing from its first candle again. This is
- // because the tick chart is being drawn from realtime data, unlike the standard TradingView charts.
- //
- // TODOs & Bugs:
- // - Add some moving average indicators (SMA, EMA as a minmum)
- // - Add a corresponding tick based volume chart
- // - Create RSI, MACD, BB variations of this indicator
- // if you have any ideas/suggestions or bug reports, please feel free to let me know, however keep in mind
- // that I do not have too much spare time to add things, so updates are going to be sporadic.
- //
- // CODE REUSE:
- // If you plan to use this code to make a derivative indicator or strategy, it would be nice to know,
- // so let me know if you like!
- //
- //@version=5
- indicator(shorttitle = "TBC", title="Tick based chart [DotH]", overlay=false,max_boxes_count = 100,max_lines_count = 200,max_bars_back = 2)
- //Input parameters
- int ticks_per_candle=input.int(20,"Ticks per candle",1,1000,1)
- int max_candles_in_chart=input.int(50,"Max number of candles to render",5,100,1)
- int scale_labels_pos_ticksize=input.int(1,"Time scale labels position below ticksize multiplier",0,100,1)
- //Initialize our globals
- varip openp=open
- varip highp=high
- varip lowp=low
- varip closep=close
- varip timep=time
- varip tick_count = ticks_per_candle
- varip open_prices = array.new_float()
- varip high_prices = array.new_float()
- varip low_prices = array.new_float()
- varip close_prices = array.new_float()
- varip close_times = array.new_int()
- varip tick_counter = array.new_int(1,ticks_per_candle+1)
- varip new_candle = array.new_bool(1,true)
- varip openID=0
- varip highID=1
- varip lowID=2
- varip closeID=3
- varip timeID=4
- varip prices = array.new_float(5,close)
- //Reset a candle for first use
- reset_candle_prices() =>
- array.set(prices,openID,close)
- array.set(prices,highID,close)
- array.set(prices,lowID,close)
- array.set(prices,closeID,close)
- array.set(prices,timeID,time)
- //Calculate OHLC of candle
- update_candle_prices(tick_price) =>
- array.set(prices,timeID,time)
- if array.get(new_candle,0)
- array.set(prices,openID,tick_price)
- array.set(prices,highID,tick_price)
- array.set(prices,lowID,tick_price)
- array.set(prices,closeID,tick_price)
- array.set(new_candle,0,false)
- else
- array.set(prices,highID,math.max(array.get(prices,highID), tick_price))
- array.set(prices,lowID,math.min(array.get(prices,lowID), tick_price))
- array.set(prices,closeID,tick_price)
- //Update and close the last candle and add a new candle
- save_candle() =>
- array.unshift(open_prices,array.get(prices,openID))
- array.unshift(high_prices,array.get(prices,highID))
- array.unshift(low_prices,array.get(prices,lowID))
- array.unshift(close_prices,array.get(prices,closeID))
- array.unshift(close_times,int(array.get(prices,timeID)))
- reset_candle_prices()
- if (array.size(open_prices)>max_candles_in_chart)
- array.pop(open_prices)
- array.pop(high_prices)
- array.pop(low_prices)
- array.pop(close_prices)
- array.pop(close_times)
- //Update values of last candle
- update_last_candle() =>
- array.set(high_prices,0,array.get(prices,highID))
- array.set(low_prices,0,array.get(prices,lowID))
- array.set(close_prices,0,array.get(prices,closeID))
- array.set(close_times,0,int(array.get(prices,timeID)))
- //Calculate candles
- updatecandles(tick_price) =>
- update_candle_prices(tick_price)
- tick_counter_newval = array.get(tick_counter,0)+1
- array.set(tick_counter,0,tick_counter_newval)
- if array.get(tick_counter,0) >= tick_count
- save_candle()
- array.set(tick_counter,0,0)
- array.set(new_candle,0,false)
- //If this is the last bar, calculate our tick based candles
- if last_bar_index==bar_index
- updatecandles(close)
- //Clear all previous boxes
- a_allBoxes = box.all
- if array.size(a_allBoxes) > 0
- for i = 0 to array.size(a_allBoxes) - 1
- box.delete(array.get(a_allBoxes, i))
- //Clear all previous labels
- a_allLabels = label.all
- if array.size(a_allLabels) > 0
- for i = 0 to array.size(a_allLabels) - 1
- label.delete(array.get(a_allLabels, i))
- //Clear all previous lines
- a_allLines = line.all
- if array.size(a_allLines) > 0
- for i = 0 to array.size(a_allLines) - 1
- line.delete(array.get(a_allLines, i))
- // Calculate scale and time labeling minimum and maximum positions
- lowPosT=math.min(array.min(low_prices),array.get(prices,lowID))-syminfo.mintick*scale_labels_pos_ticksize
- highPosT=math.max(array.max(high_prices),array.get(prices,highID))+syminfo.mintick*scale_labels_pos_ticksize
- //Render past candles
- if array.size(open_prices)>0
- for i = 0 to array.size(open_prices)-1 by 1
- pos=i*3
- openp:=array.get(open_prices,i)
- highp:=array.get(high_prices,i)
- lowp:=array.get(low_prices,i)
- closep:=array.get(close_prices,i)
- timep:=array.get(close_times,i)
- past_candles_color=openp>closep?color.red:color.rgb(37, 190, 150)
- box.new(bar_index-pos,math.max(openp,closep),bar_index-pos+2,math.min(openp,closep),past_candles_color,1,line.style_solid,extend.none,xloc.bar_index,past_candles_color)
- line.new(bar_index-pos+1,math.max(openp,closep),bar_index-pos+1,highp,color = past_candles_color,width = 2)
- line.new(bar_index-pos+1,math.min(openp,closep),bar_index-pos+1,lowp,color = past_candles_color,width = 2)
- if pos%30==0 and pos>15
- label.new(bar_index-pos+1,lowPosT,str.format_time(timep,'MM/DD-HH:mm:ss'),size = size.tiny,textcolor = color.white,style = label.style_none,yloc = yloc.price,textalign = text.align_center,text_font_family=font.family_monospace)
- line.new(bar_index-pos+1,lowPosT,bar_index-pos+1,highPosT,color = color.gray,width = 1,style = line.style_dotted)
- //Render current candle
- lpos=-3
- current_candle_color=array.get(prices,openID)>array.get(prices,closeID)?color.red:color.rgb(37, 190, 150)
- box.new(bar_index-lpos,math.max(array.get(prices,openID),array.get(prices,closeID)),bar_index-lpos+2,math.min(array.get(prices,openID),array.get(prices,closeID)),current_candle_color,1,line.style_solid,extend.none,xloc.bar_index,current_candle_color)
- line.new(bar_index-lpos+1,math.max(array.get(prices,openID),array.get(prices,closeID)),bar_index-lpos+1,array.get(prices,highID),color = current_candle_color,width = 2)
- line.new(bar_index-lpos+1,math.min(array.get(prices,openID),array.get(prices,closeID)),bar_index-lpos+1,array.get(prices,lowID),color = current_candle_color,width = 2)
- label.new(bar_index-lpos+1,lowPosT,str.format_time(int(array.get(prices,timeID)),'MM/DD-HH:mm:ss'),size = size.tiny,textcolor = color.white,style = label.style_none,yloc = yloc.price,textalign = text.align_center,text_font_family=font.family_monospace)
- line.new(bar_index-lpos+1,lowPosT,bar_index-lpos+1,highPosT,color = color.gray,width = 1,style = line.style_dotted)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement