-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLocalLimit.pine
137 lines (122 loc) · 4.44 KB
/
LocalLimit.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
// 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 Calculates the local upper or local lower limit for a given series. Applying multiple passes produces what appears like support or resistance levels.
library('LocalLimit', true)
export type Limit
float value
int trend
export type Level
Limit upper
Limit lower
///////////////////////////////////////////////////
// @function Produces the recent local upper limit for a given series.
// @param src The source series to derive from.
// @param padding Gives some extra room when lowering the level.
export upper(
series float src,
float padding = 0) =>
value = src[0]
valuePrev = src[1]
var limit = value
var int trend = 0
var int phase = 0
phase := if not na(value) and (value > limit or na(limit))
trend := +1
limit := value
0
else
switch phase
0 => 1
1 => value > valuePrev ? 2 : 1
2 =>
if value < valuePrev
trend := -1
limit := math.min(limit, valuePrev + nz(padding))
0
else
2
limit
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// @function Produces the recent local lower limit for a given series.
// @param src The source series to derive from.
// @param padding Gives some extra room when raising the level.
export lower(
series float src,
float padding = 0) =>
value = src[0]
valuePrev = src[1]
var limit = value
var int trend = 0
var int phase = 0
phase := if not na(value) and (value < limit or na(limit))
trend := -1
limit := value
0
else
switch phase
0 => 1
1 => value < valuePrev ? 2 : 1
2 =>
if value > valuePrev
trend := +1
limit := math.max(limit, valuePrev - nz(padding))
0
else
2
limit
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// @function Determines the local trend of a series that and persists the trend if the value is unchanged.
// @param src The source series to derive from.
// @return +1 when the trend is up; -1 when the trend is down; 0 if the trend is not yet established.
export trend(series float src) =>
var s = 0
if src > src[1]
s := +1
if src < src[1]
s := -1
s
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// @function Creates a Limit object that contains the value and the trend.
// @param src The source series to derive from.
export valueAndTrend(series float src) =>
Limit.new(src, trend(src))
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// @function Creates a Level object representing the local upper and lower limits.
// @param hiSrc The source to discover the upper limit from.
// @param loSrc The source to discover the lower limit from.
// @param padding Gives some extra room when raising the lower level and lowering the upper level.
export of(
series float hiSrc = high,
series float loSrc = low,
float padding = 0) =>
hi = valueAndTrend(upper(hiSrc, padding))
lo = valueAndTrend(lower(loSrc, padding))
Level.new(hi, lo)
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// @function Creates a Level object representing the local upper and lower limits.
// @param level The source levels to expand of.
// @param padding Gives some extra room when raising the lower level and lowering the upper level.
export of(
series Level level,
float padding = 0) =>
hi = valueAndTrend(upper(level.upper.value, padding))
lo = valueAndTrend(lower(level.lower.value, padding))
Level.new(hi, lo)
///////////////////////////////////////////////////
limit0 = of()
limit1 = of(limit0, 0.1)
limit2 = of(limit1, 0.5)
hColor = color.yellow
lColor = color.blue
plot(limit0.upper.value, "H0", hColor, 1)
plot(limit1.upper.value, "H1", hColor, 2)
plot(limit2.upper.value, "H2", hColor, 3)
plot(limit0.lower.value, "L0", lColor, 1)
plot(limit1.lower.value, "L1", lColor, 2)
plot(limit2.lower.value, "L3", lColor, 3)