Nothing Special   »   [go: up one dir, main page]

Speedometer

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 5

// © nicholas nelo

//@version=4
study("RSI Speedometer ", overlay=false)
// ---------------------------------------------------------------
// ---------------- Required inputs and variables ----------------

offset = input(2, title="offset") //


How many bars to the left to set the right side of the speedometer
radius = input(50, title="radius in bars") //
Radius in bars of the semi circle
y_axis = input(0.00, title="y axis location") //
Where to place the y axis
y_scale = input(100, title="y axis scaling (multiplicative)", minval=1) //
Y axis scaling. 100 by default will size the semicircle to fit with for example RSI
or any other oscillator with a 0..100 range

var float pi = 2 * asin(1)


//
Required variables needed for calculations

x_axis = array.new_int(radius * 2, 0)
for i = offset to offset + 2 * radius - 1
array.set(x_axis, i - offset, time[i])

one_bar = int(change(time))
right_side = array.get(x_axis, 0)
left_side = array.get(x_axis, 2 * radius - 1)
x_center = array.get(x_axis, radius - 1)

// ---------------------------------------------------------------

// ---------------------------------------------------------------
// -------------------- Speedometer functions --------------------
// ---------------------------------------------------------------

// -------------------- Draw Sector Function ---------------------


//
_sector_num : Which sector of the semi circle we are drawing (out of
_total_sectors)
//
_total_sectors : the number of major divisions in the semicircle
//
_line_limit : Very important!!! Setting this too high so that the total number of
lines of your script exceeds ~50 will cause rendering errors.
//
I recommend getting the total number of lines as close to 50 as possible. You will
have to track this yourself manually.
//
The function will allow you to set a max number of lines to use and from there
determine how many segments to use for each sector.
//
The line limit is your limit for the entire semi circle.
//
e.g you use 10 other line plots (or other non label speedo functions). In this case
you could set the limit to 40.
//
_radius : radius in bars
//
_y_axis & _y_scale : from required inputs, needed to position the segments
//
_line_color : standard color format #xxxxxxxx or color.xxxxx
//
_line_width : integer, line width in pixels
f_draw_sector(_sector_num, _total_sectors, _line_limit, _radius, _y_axis, _y_scale,
_line_color, _line_width)=>
_segments_per_sector = floor(_line_limit / _total_sectors)
_total_segments = _segments_per_sector * _total_sectors
_radians_per_segment = pi / _total_segments
_radians_per_sector = pi / _total_sectors
_start_of_sector = _radians_per_sector * (_sector_num -1)
for _i = 0 to _segments_per_sector -1
_segment_line = line.new(x1 = array.get(x_axis,
int(round(cos(_start_of_sector + _radians_per_segment * _i) * (_radius - 1) +
radius - 1))),
y1 = _y_axis + sin(_start_of_sector +
_radians_per_segment * _i) * _y_scale,
x2 = array.get(x_axis,
int(round(cos(_start_of_sector + _radians_per_segment * (_i + 1)) * (_radius - 1) +
radius - 1))),
y2 = _y_axis + sin(_start_of_sector +
_radians_per_segment * (_i + 1)) * _y_scale,
xloc = xloc.bar_time,
color = _line_color,
width = _line_width)
line.delete(_segment_line[1])

// ---------------------------------------------------------------

// -------------------- Draw Base Line Function ------------------


//
_left & _right : should always be the left_side & right_side required variables
//
other input vars as above

f_draw_base_line(_left, _right, _y_axis, _color, _width)=>


_base_line = line.new(x1 = _left,
y1 = _y_axis,
x2 = _right,
y2 = _y_axis,
xloc = xloc.bar_time,
color = _color,
width = _width)
line.delete(_base_line[1])
// ---------------------------------------------------------------

// -------------------- Draw Needle Function ---------------------


//
_val : your metric in a range of 0 .. 100. You will have to perform your own
adjustments/normalization before inputting into the function
//
other input vars as above
f_draw_needle(_val, _x_center, _radius, _y_axis, _y_scale, _color, _width)=>
_needle = line.new(x1 = array.get(x_axis, int(round(cos(pi / 100 * _val) *
(_radius - 1) + radius - 1))),
y1 = _y_axis + sin(pi / 100 * _val) * _y_scale,
x2 = _x_center,
y2 = _y_axis,
xloc = xloc.bar_time,
color = _color,
width = _width)
line.delete(_needle[1])
// ---------------------------------------------------------------

// ----------------------- Draw Tick Function --------------------


//
Allows you to plot customizable interval ticks along the semicircle
//
_num : which tick interval to plot out of the number of _divisions
//
_divisions : number of ticks to determine spacing
//
_radius_perc : percentage [0..100] of radius to extend tick
//
_color & _width as above (line styling)

f_draw_tick(_num, _divisions, _radius_perc, _x_center, _radius, _y_axis, _y_scale,


_color, _width)=>
_pos = pi / _divisions * _num
_tick = line.new(x1 = array.get(x_axis, int(round(cos(_pos) * (_radius - 1) +
radius - 1))),
y1 = _y_axis + sin(_pos) * _y_scale,
x2 = array.get(x_axis, int(round(cos(_pos) * (_radius - 1) *
(1 - (_radius_perc / 100))+ _radius - 1))),
y2 = _y_axis + sin(_pos) * _y_scale * (1 - (_radius_perc /
100)),
xloc = xloc.bar_time,
color = _color,
width = _width)
line.delete(_tick[1])
// ---------------------------------------------------------------

// -------------------- Draw Sector Label ------------------------


// For placing labels in a simliar way to ticks
f_draw_sector_label(_num, _divisions, _radius, _y_axis, _y_scale, _color,
_txtcolor, _text)=>
_pos = pi / _divisions * _num
_x_coord = array.get(x_axis, int(round(cos(_pos) * (_radius - 1)) + _radius -
1))
_y_coord = _y_axis + sin(_pos) * _y_scale
_sector_label = label.new(x = _x_coord,
y = _y_coord,
xloc = xloc.bar_time,
color = _color,
textcolor = _txtcolor,
style = _pos <= pi / 6 ? label.style_label_right :
_pos < pi / 6 * 2 ? label.style_label_lower_right : _pos <= pi / 6 * 4 ?
label.style_label_down : _pos <= pi / 6 * 5 ? label.style_label_lower_left :
label.style_label_left,
text = _text)
label.delete(_sector_label[1])
// ---------------------------------------------------------------

// ----------------------- Draw Title Label ----------------------


// Labelling for below the speedometer
f_draw_title_label(_radius_perc, _x_center, _y_axis, _y_scale, _color, _txtcolor,
_text)=>
_title_label = label.new(x = _x_center,
y = _y_axis - (_radius_perc / 100) * _y_scale,
xloc = xloc.bar_time,
color = _color,
textcolor = _txtcolor,
style= label.style_label_center,
text = _text)
label.delete(_title_label[1])
// ---------------------------------------------------------------

// ---------------------------------------------------------------
// --------------- End of Speedometer Functions ------------------
// ---------------------------------------------------------------

// --------------------- Example Usage ---------------------------

// Draw the base line


f_draw_base_line(left_side, right_side, y_axis, color.white, 1)

// ---------------------------------------------------------------
// Plot each sector and it's "glow"
f_draw_sector(1, 5, 20, radius, y_axis, y_scale, color.red, 5)
f_draw_sector(1, 5, 20, radius, y_axis, y_scale, color.white, 1)

f_draw_sector(2, 5, 20, radius, y_axis, y_scale, color.red, 5)


f_draw_sector(2, 5, 20, radius, y_axis, y_scale, color.white, 1)

f_draw_sector(3, 5, 20, radius, y_axis, y_scale, color.gray, 5)


f_draw_sector(3, 5, 20, radius, y_axis, y_scale, color.white, 1)

f_draw_sector(4, 5, 20, radius, y_axis, y_scale, color.green, 5)


f_draw_sector(4, 5, 20, radius, y_axis, y_scale, color.white, 1)

f_draw_sector(5, 5, 20, radius, y_axis, y_scale, color.green, 5)


f_draw_sector(5, 5, 20, radius, y_axis, y_scale, color.white, 1)
// ---------------------------------------------------------------

// ----------------- Add some major and minor ticks --------------


// Major ticks
f_draw_tick(1, 5, 8, x_center, radius, y_axis, y_scale, color.white, 3)
f_draw_tick(2, 5, 8, x_center, radius, y_axis, y_scale, color.white, 3)
f_draw_tick(3, 5, 8, x_center, radius, y_axis, y_scale, color.white, 3)
f_draw_tick(4, 5, 8, x_center, radius, y_axis, y_scale, color.white, 3)

// Minor ticks
f_draw_tick(1, 10, 6, x_center, radius, y_axis, y_scale, color.white, 1)
f_draw_tick(3, 10, 6, x_center, radius, y_axis, y_scale, color.white, 1)
f_draw_tick(5, 10, 6, x_center, radius, y_axis, y_scale, color.white, 1)
f_draw_tick(7, 10, 6, x_center, radius, y_axis, y_scale, color.white, 1)
f_draw_tick(9, 10, 6, x_center, radius, y_axis, y_scale, color.white, 1)
// ---------------------------------------------------------------

// ---------------------- Label the Sectors ----------------------


f_draw_sector_label(1, 10, radius, y_axis, y_scale, color.red, color.white, "Strong
sell")
f_draw_sector_label(3, 10, radius, y_axis, y_scale, color.red, color.white, "sell")
f_draw_sector_label(5, 10, radius, y_axis, y_scale, color.gray, color.white,
"Neutral")
f_draw_sector_label(7, 10, radius, y_axis, y_scale, color.green, color.white,
"buy")
f_draw_sector_label(9, 10, radius, y_axis, y_scale, color.green, color.white,
"Strong buy")
// ---------------------------------------------------------------

// generate some metric RSI for illustration only


src = input(close, title="RSI source")
len = input(14, title="RSI length")

metric = rsi(src, len) // RSI is already 0..100 so no modification needed.

// Draw the needle and title using the metric


f_draw_needle(metric, x_center, radius, y_axis, y_scale, color.white, 1)
f_draw_title_label(25, x_center, y_axis, y_scale, color.white, color.black, "RSI ("
+ tostring(len) + "): " + tostring(round(metric * 100) / 100))
// ---------------------------------------------------------------

plot(metric)
hline(100), hline(0)

// Add some buffer around the RSI plot to give enough space for the labels to be
seeen
hline(y_scale * 1.2, color=#00000000)
hline(y_axis - y_scale * 0.2, color=#00000000)

You might also like