forked from Electrified-Trading/Libraries
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVolatility.pine
182 lines (165 loc) · 8 KB
/
Volatility.pine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Electrified (electrifiedtrading)
// @version=5
// @description Functions for determining if volatility (true range) is within or exceeds normal.
library('Volatility')
import Electrified/MovingAverages/10 as MA
import Electrified/SessionInfo/9 as Session
import Electrified/GapDetection/5 as Gap
// The "true range" (ta.tr) is used for measuring volatility.
// Values are normalized by the volume adjusted weighted moving average (VAWMA) to be more like percent moves than price.
//////////////////////////////////////////////////
// @function Calculates the true range for a given span of bars.
// @param span Number of bars measure the true range.
// @param quantized When true, the true range is calculated once for every span. When false (default), the true range is calulated for the span on every bar.
export trueRange(
simple int span,
simple bool quantized = false) =>
if span < 1
runtime.error("The 'span' value must be at least 1.")
if span <= 1
ta.tr
else if quantized
var bar = 0
bar += 1
var float tr = na
if bar % span == 0
Cp = close[span]
H = ta.highest(high, span)
L = na.lowest(low, span)
tr := math.max(H - L, H - Cp, Cp - L)
tr
else
Cp = close[span]
H = ta.highest(high, span)
L = na.lowest(low, span)
math.max(H - L, H - Cp, Cp - L)
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// @function Calculates the max range for a given span of bars.
// @param span Number of bars measure the max range.
// @param period When true, the true range is calculated once for every span. When false (default), the true range is calulated for the span on every bar.
export maxRange(
simple int span,
simple int period) =>
if span < 1
runtime.error("The 'span' value must be at least 1.")
if span <= 1
ta.tr
else if quantized
var bar = 0
bar += 1
var float tr = na
if bar % span == 0
Cp = close[span]
H = ta.highest(high, span)
L = na.lowest(low, span)
tr := math.max(H - L, H - Cp, Cp - L)
tr
else
Cp = close[span]
H = ta.highest(high, span)
L = na.lowest(low, span)
math.max(H - L, H - Cp, Cp - L)
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// @function Returns the normal upper range of volatility and the normal gap value.
// @param len Number of bars to measure volatility.
// @param maxDeviation The limit of volatility before considered an outlier.
// @param level The amount of standard deviation after cleaning outliers to be considered within normal.
// @param gapDays The number of days in the past to measure overnight gap volaility.
// @param spec session.regular (default), session.extended or other time spec.
// @param res The resolution (default = '1440').
// @param volatility The value to use as a volatility measure. Default is (ta.tr) the "True Range".
// @returns [atr + stdev * level, Gap.normal(gapDays, spec, res)]
export normalWithGap(
simple int len,
simple float maxDeviation = 3,
simple float level = 1,
simple int gapDays = 50,
simple string spec = session.regular,
simple string res = '1440',
series float volatility = ta.tr) =>
var values = array.new_float()
vawma = MA.vawma(len)
tr = volatility / vawma // VAWMA is used to normalize the values to a price paid per share. Closer to % than price.
stdRaw = ta.stdev(tr, len)
avgRaw = ta.sma(tr, len)
if tr < avgRaw + maxDeviation * stdRaw
array.push(values, tr)
if array.size(values)>len
array.shift(values)
atr = array.avg(values)
stdev = array.stdev(values)
latest = atr + stdev * level
[latest * vawma, Gap.normal(gapDays, 2, spec, res) * level]
///////////////////////////////////////////////////
//////////////////////////////////////////////////
// @function Returns the normal upper range of volatility. Compensates for overnight gaps within a regular session.
// @param len Number of bars to measure volatility.
// @param maxDeviation The limit of volatility before considered an outlier.
// @param level The amount of standard deviation after cleaning outliers to be considered within normal.
// @param gapDays The number of days in the past to measure overnight gap volaility.
// @param spec session.regular (default), session.extended or other time spec.
// @param res The resolution (default = '1440').
// @param volatility The value to use as a volatility measure. Default is (ta.tr) the "True Range".
export normal(
simple int len,
simple float maxDeviation = 3,
simple float level = 1,
simple int gapDays = 50,
simple string spec = session.regular,
simple string res = '1440',
series float volatility = ta.tr) =>
[n, g] = normalWithGap(len, maxDeviation, level, gapDays, spec, res, volatility)
syminfo.session == session.regular and Session.isFirstBar() ? g : n
///////////////////////////////////////////////////
//////////////////////////////////////////////////
// @function Returns true if the volatility (true range) is within normal levels. Compensates for overnight gaps within a regular session.
// @param len Number of bars to measure volatility.
// @param maxDeviation The limit of volatility before considered an outlier.
// @param level The amount of standard deviation after cleaning outliers to be considered within normal.
// @param gapDays The number of days in the past to measure overnight gap volaility.
// @param spec session.regular (default), session.extended or other time spec.
// @param res The resolution (default = '1440').
// @param volatility The value to use as a volatility measure. Default is (ta.tr) the "True Range".
export isNormal(
simple int len,
simple float maxDeviation = 3,
simple float level = 1,
simple int gapDays = 50,
simple string spec = session.regular,
simple string res = '1440',
series float volatility = ta.tr) =>
volatility < normal(len, maxDeviation, level, gapDays, spec, res)
///////////////////////////////////////////////////
//////////////////////////////////////////////////
// @function Returns ratio of the current value to the normal value. Compensates for overnight gaps within a regular session.
// @param len Number of bars to measure volatility.
// @param maxDeviation The limit of volatility before considered an outlier.
// @param level The amount of standard deviation after cleaning outliers to be considered within normal.
// @param gapDays The number of days in the past to measure overnight gap volaility.
// @param spec session.regular (default), session.extended or other time spec.
// @param res The resolution (default = '1440').
// @param volatility The value to use as a volatility measure. Default is (ta.tr) the "True Range".
export severity(
simple int len,
simple float maxDeviation = 3,
simple float level = 1,
simple int gapDays = 50,
simple string spec = session.regular,
simple string res = '1440',
series float volatility = ta.tr) =>
volatility / normal(len, maxDeviation, level, gapDays, spec, res)
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Example ////////////////////////////////////////
///////////////////////////////////////////////////
days = input.int(50, 'Days to Measure', tooltip='The number of days to use in measuring volatility.')
maxDev = input.float(2, 'Max Deviation', minval=1, tooltip='The limit of volatility before considered an outlier.')
level = input.float(2, 'Standard Deviation Level', minval=1, tooltip='The amount of standard deviation after cleaning outliers to be considered within normal.')
int len = days * 390 / timeframe.multiplier
volatility = ta.tr
normalVol = normal(len, maxDev, level, days)
plot(volatility, 'Volatility', color.red)
plot(normalVol, 'Volatility Normal', color.green)