1
+ import * as utils from "@ekliptor/apputils" ;
2
+ const logger = utils . logger
3
+ , nconf = utils . nconf ;
4
+ import { AbstractIndicator , MomentumIndicatorParams , PivotPointsParams } from "./AbstractIndicator" ;
5
+ import { TaLib , TaLibParams , TaLibResult } from "./TaLib" ;
6
+ import { Currency , Trade , Candle } from "@ekliptor/bit-models" ;
7
+
8
+ /**
9
+ * An indicator calculating Standard Pivot Points.
10
+ * // TODO Fibonacci Pivot Points and Demark Pivot Points
11
+ * https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:pivot_points
12
+ */
13
+ export default class PivotPoints extends AbstractIndicator {
14
+ protected params : PivotPointsParams ;
15
+ protected candleHistory : Candle . Candle [ ] = [ ] ;
16
+ protected pivotPoint : number = - 1 ;
17
+ protected resistance1 : number = - 1 ;
18
+ protected resistance2 : number = - 1 ;
19
+ protected resistance3 : number = - 1 ;
20
+ protected support1 : number = - 1 ;
21
+ protected support2 : number = - 1 ;
22
+ protected support3 : number = - 1 ;
23
+ protected high : number = - 1 ;
24
+ protected low : number = - 1 ;
25
+ protected close : number = - 1 ;
26
+ protected open : number = - 1 ;
27
+
28
+ constructor ( params : PivotPointsParams ) {
29
+ super ( params )
30
+ this . params = Object . assign ( new PivotPointsParams ( ) , this . params ) ;
31
+ }
32
+
33
+ public addCandle ( candle : Candle . Candle ) {
34
+ return new Promise < void > ( ( resolve , reject ) => {
35
+ this . addCandleHistory ( candle ) ;
36
+ resolve ( ) ;
37
+ } )
38
+ }
39
+
40
+ public getValue ( ) {
41
+ return this . pivotPoint ;
42
+ }
43
+
44
+ public getPivotPoint ( ) {
45
+ return this . pivotPoint ;
46
+ }
47
+
48
+ public getResistance1 ( ) {
49
+ return this . resistance1 ;
50
+ }
51
+
52
+ public getResistance2 ( ) {
53
+ return this . resistance2 ;
54
+ }
55
+
56
+ public getResistance3 ( ) {
57
+ return this . resistance3 ;
58
+ }
59
+
60
+ public getSupport1 ( ) {
61
+ return this . support1 ;
62
+ }
63
+
64
+ public getSupport2 ( ) {
65
+ return this . support2 ;
66
+ }
67
+
68
+ public getSupport3 ( ) {
69
+ return this . support3 ;
70
+ }
71
+
72
+ public isReady ( ) {
73
+ return this . pivotPoint !== - 1 && this . candleHistory . length >= this . params . interval ;
74
+ }
75
+
76
+ public getAllValues ( ) {
77
+ return {
78
+ pivotPoint : this . pivotPoint ,
79
+ resistance1 : this . resistance1 ,
80
+ resistance2 : this . resistance2 ,
81
+ resistance3 : this . resistance3 ,
82
+ support1 : this . support1 ,
83
+ support2 : this . support2 ,
84
+ support3 : this . support3
85
+ }
86
+ }
87
+
88
+ public serialize ( ) {
89
+ let state = super . serialize ( ) ;
90
+ state . candleHistory = this . candleHistory ;
91
+ state . pivotPoint = this . pivotPoint ;
92
+ state . resistance1 = this . resistance1 ;
93
+ state . resistance2 = this . resistance2 ;
94
+ state . resistance3 = this . resistance3 ;
95
+ state . support1 = this . support1 ;
96
+ state . support2 = this . support2 ;
97
+ state . support3 = this . support3 ;
98
+ state . high = this . high ;
99
+ state . low = this . low ;
100
+ state . close = this . close ;
101
+ state . open = this . open ;
102
+ return state ;
103
+ }
104
+
105
+ public unserialize ( state : any ) {
106
+ super . unserialize ( state ) ;
107
+ this . candleHistory = Candle . Candle . copy ( state . candleHistory ) ;
108
+ this . pivotPoint = state . pivotPoint ;
109
+ this . resistance1 = state . resistance1 ;
110
+ this . resistance2 = state . resistance2 ;
111
+ this . resistance3 = state . resistance3 ;
112
+ this . support1 = state . support1 ;
113
+ this . support2 = state . support2 ;
114
+ this . support3 = state . support3 ;
115
+ this . high = state . high ;
116
+ this . low = state . low ;
117
+ this . close = state . close ;
118
+ this . open = state . open ;
119
+ }
120
+
121
+ // ################################################################
122
+ // ###################### PRIVATE FUNCTIONS #######################
123
+
124
+ protected addCandleHistory ( candle : Candle . Candle ) {
125
+ this . candleHistory . push ( candle ) ;
126
+ if ( this . candleHistory . length >= this . params . interval * 2 ) {
127
+ this . updatePivotPoints ( ) ; // calc from oldest candles (previous period)
128
+ while ( this . candleHistory . length > this . params . interval ) // remove the 1st time period completely
129
+ this . candleHistory . shift ( ) ;
130
+ console . log ( "cleaned" , this . candleHistory . length )
131
+ }
132
+ else if ( this . pivotPoint === - 1 && this . candleHistory . length === this . params . interval )
133
+ this . updatePivotPoints ( ) ; // initial update
134
+ }
135
+
136
+ protected updatePivotPoints ( ) {
137
+ console . log ( "PIVOT update" , this . candleHistory . length , this . candleHistory [ this . candleHistory . length - 1 ] . start )
138
+ this . calcHighLowClose ( ) ;
139
+ switch ( this . params . type )
140
+ {
141
+ case "standard" :
142
+ this . pivotPoint = ( this . high + this . low + this . close ) / 3 ;
143
+ this . support1 = this . pivotPoint * 2 - this . high ;
144
+ this . support2 = this . pivotPoint - ( this . high - this . low ) ;
145
+ this . resistance1 = this . pivotPoint * 2 - this . low ;
146
+ this . resistance2 = this . pivotPoint + ( this . high - this . low ) ;
147
+ break ;
148
+ case "fibonacci" :
149
+ this . pivotPoint = ( this . high + this . low + this . close ) / 3 ;
150
+ this . support1 = this . pivotPoint - ( 0.382 * ( this . high - this . low ) ) ;
151
+ this . support2 = this . pivotPoint - ( 0.618 * ( this . high - this . low ) ) ;
152
+ this . support3 = this . pivotPoint - ( 1.0 * ( this . high - this . low ) ) ;
153
+ this . resistance1 = this . pivotPoint + ( 0.382 * ( this . high - this . low ) ) ;
154
+ this . resistance2 = this . pivotPoint + ( 0.618 * ( this . high - this . low ) ) ;
155
+ this . resistance3 = this . pivotPoint + ( 1.0 * ( this . high - this . low ) ) ;
156
+ break ;
157
+ case "demark" :
158
+ let x : number ;
159
+ if ( this . close < this . open )
160
+ x = this . high + 2 * this . low + this . close ;
161
+ else if ( this . close > this . open )
162
+ x = 2 * this . high + this . low + this . close ;
163
+ else // close == open
164
+ x = this . high + this . low + 2 * this . close ;
165
+ this . pivotPoint = x / 4 ;
166
+ this . support1 = x / 2 - this . high ;
167
+ this . resistance1 = x / 2 - this . low ;
168
+ break ;
169
+ default :
170
+ utils . test . assertUnreachableCode ( this . params . type ) ;
171
+ }
172
+ console . log ( this . getAllValues ( ) )
173
+ }
174
+
175
+ protected calcHighLowClose ( ) {
176
+ let high = 0 , close = 0 , open = - 1 , low = Number . MAX_VALUE ;
177
+ for ( let i = 0 ; i < this . params . interval && i < this . candleHistory . length ; i ++ )
178
+ {
179
+ // go through the first half of our candle history to get the HLC for this period
180
+ const candle = this . candleHistory [ i ] ;
181
+ if ( open === - 1 )
182
+ open = candle . open ;
183
+ if ( candle . high > high )
184
+ high = candle . high ;
185
+ if ( candle . low < low )
186
+ low = candle . low ;
187
+ close = candle . close ;
188
+ }
189
+ this . high = high ;
190
+ this . low = low ;
191
+ this . close = close ;
192
+ this . open = open ;
193
+ }
194
+ }
195
+
196
+ export { PivotPoints }
0 commit comments