@@ -89,7 +89,17 @@ <h4>Real-time data with <a href='https://helgasoft.github.io/echarty' target=_bl
89
89
</ p >
90
90
This page does data polling for Bitcoin price every 10 seconds using < i > jsonlite::fromJSON</ i > . < br >
91
91
Response is a timestamp and a value in $US. Additional data processing could be achieved in R - moving averages(MA), prediction, etc.< br >
92
- This chart displays Bollinger Bands - two standard deviations on simple moving average for a ~2 minutes rolling interval. < br >
92
+ The chart displays Bollinger Bands - two standard deviations on simple moving average of a rolling window. < br >
93
+ You can select < b > rolling window width</ b > here: < span >
94
+ < select id ='rwidth ' onchange ="updww() ">
95
+ < option value ='6 '> 6</ option >
96
+ < option value ='12 ' selected > 12</ option >
97
+ < option value ='18 '> 18</ option >
98
+ < option value ='24 '> 24</ option >
99
+ < option value ='36 '> 36</ option >
100
+ < option value ='48 '> 48</ option >
101
+ < option value ='60 '> 60</ option >
102
+ </ select > </ span > points (ex: 12 pts * ~10 secs = ~2 minutes window) < br >
93
103
Maximum number of points is limited to 500 (FIFO stack). < br >
94
104
Chrome browser timer throttling is bypassed through a background web worker. So data is collected even when the browser tab is not in focus.< br >
95
105
See also the < a href ='coder.html ' target ="_blank "> coder demo</ a > for interactive R-code chart editing.< br >
@@ -117,13 +127,14 @@ <h4>Real-time data with <a href='https://helgasoft.github.io/echarty' target=_bl
117
127
tbox <- list(right='20%', feature= ec.util(cmd='fullscreen'))
118
128
data <- list(list(as.character(Sys.time()), NA));
119
129
lobb <- hibb <- sma <- list()
130
+ prevPrice <- 0 # to compare prices
120
131
plot <- ec.init(elementId='ch1', backgroundColor='#110b29', darkMode=T,
121
132
title= list(text='Bitcoin Price Live', left='center', subtext=''),
122
133
xAxis= list(type='time', splitLine= list(show=FALSE), name='Local time', nameLocation='center', nameGap=24),
123
134
yAxis= list(name='₿ in USD', splitLine= list(lineStyle= list(opacity=0.5)), scale=T, max='dataMax', z=6),
124
135
tooltip= list(type='cross', trigger='axis', axisPointer= list(axis='x')), toolbox= tbox,
125
136
series= list(
126
- list(type= 'line', showSymbol=F, data= data, lineStyle= list(width=2, color='gold'), z=7,
137
+ list(type= 'line', name='price', showSymbol=F, data= data, lineStyle= list(width=2, color='gold'), z=7,
127
138
endLabel= list(show=T, color='yellow', offset=c(9,0),
128
139
formatter= ec.clmn('(p) => { return p.data[1].toLocaleString(undefined, {maximumFractionDigits:2});}')) ),
129
140
list(type= 'line', name='+BB', showSymbol=F, data= hibb, areaStyle= list(color='navy',opacity=0.7), smooth=T, lineStyle=list(width=1,color='lightblue')),
@@ -140,6 +151,8 @@ <h4>Real-time data with <a href='https://helgasoft.github.io/echarty' target=_bl
140
151
# remote data refreshed every 10 secs
141
152
142
153
price <- round(json$RAW$PRICE, 2)
154
+ if (prevPrice == price) return(list()); # dont add identical price
155
+ prevPrice <- price;
143
156
newData <- list(as.character(as.POSIXct(json$RAW$LASTUPDATE)), price )
144
157
data <- append(data, list(newData)); # gather same data in R too
145
158
# calc st.deviation of price, 12* 10sec= 2min rolling stdev
@@ -148,12 +161,20 @@ <h4>Real-time data with <a href='https://helgasoft.github.io/echarty' target=_bl
148
161
dd <- tail(sapply(data, '[[', 2), ww)
149
162
stdev <- rollapply(dd, width=ww, FUN=sd, fill=0, align='r')[ww]
150
163
sma <- rollmean(dd, k=ww, fill=NA, align='right')[ww]
151
- newData <- c(newData, round(stdev,2), round(sma,2))
164
+ hibb = round(sma + stdev * 2, 2);
165
+ lobb = round(sma - stdev * 2, 2);
166
+ newData <- c(newData, round(sma,2), hibb, lobb)
152
167
}
153
168
if (length(data) > 500)
154
169
data <- data[2:length(data)]
155
170
newData
156
171
`
172
+ curww = '12' ;
173
+ function updww ( ) { // update rolling window width
174
+ newrw = document . getElementById ( "rwidth" ) . value ;
175
+ dataCode = dataCode . replace ( 'ww <- ' + curww , 'ww <- ' + newrw ) ;
176
+ curww = newrw ;
177
+ } ;
157
178
158
179
async function doChart ( ) {
159
180
document . getElementById ( 'app' ) . innerHTML = 'Wait...' ;
@@ -220,41 +241,33 @@ <h4>Real-time data with <a href='https://helgasoft.github.io/echarty' target=_bl
220
241
}
221
242
worker . postMessage ( 10000 ) ; // msec for refresh
222
243
223
- prevPrice = 0 ;
224
244
async function updChart ( ) {
225
245
const rlist = await webR . evalR ( dataCode )
226
246
const tmp = await rlist . toJs ( ) ;
227
247
darr = recurs2 ( tmp ) ;
228
-
229
- if ( prevPrice == darr [ 1 ] ) return ; // dont add identical price
230
- prevPrice = darr [ 1 ] ;
231
-
232
- // Bollinger Bands
233
- hibb = null ;
248
+ if ( darr . length == 0 ) return ; // dont add identical price
249
+ price = [ darr [ 0 ] , darr [ 1 ] ] ; // [time,price,sma,+BB,-BB]
250
+ hibb = null ;
234
251
if ( darr . length > 2 && darr [ 2 ] > 0 ) {
235
- hibb = [ darr [ 0 ] , ( darr [ 3 ] + darr [ 2 ] * 2 ) . toFixed ( 2 ) ] ;
236
- lobb = [ darr [ 0 ] , ( darr [ 3 ] - darr [ 2 ] * 2 ) . toFixed ( 2 ) ] ;
237
- sma = [ darr [ 0 ] , darr [ 3 ] ] ;
238
- darr . pop ( ) ; darr . pop ( ) ;
252
+ sma = [ darr [ 0 ] , darr [ 2 ] ] ;
253
+ hibb = [ darr [ 0 ] , darr [ 3 ] ] ;
254
+ lobb = [ darr [ 0 ] , darr [ 4 ] ] ;
239
255
}
240
-
241
256
chart = get_e_charts ( 'ch1' ) ;
242
257
opt1 = chart . getOption ( ) ;
243
258
pts = opt1 . series [ 0 ] . data . length ;
244
259
if ( pts > 500 ) {
245
- opt1 . series [ 0 ] . data . shift ( ) ;
246
- opt1 . series [ 1 ] . data . shift ( ) ;
247
- opt1 . series [ 2 ] . data . shift ( ) ;
260
+ for ( i = 0 ; i < 4 ; i ++ ) opt1 . series [ i ] . data . shift ( ) ;
248
261
}
249
262
pts = opt1 . series [ 0 ] . data . length ;
250
263
opt1 . title [ 0 ] . subtext = pts + ' points' ;
251
- opt1 . series [ 0 ] . data . push ( darr ) ;
264
+ opt1 . series [ 0 ] . data . push ( price ) ;
252
265
if ( hibb ) {
253
266
opt1 . series [ 1 ] . data . push ( hibb ) ;
254
267
opt1 . series [ 2 ] . data . push ( lobb ) ;
255
268
opt1 . series [ 3 ] . data . push ( sma ) ;
256
269
}
257
- opt1 . series [ 4 ] . data = [ darr ] ; // effectscatter
270
+ opt1 . series [ 4 ] . data = [ price ] ; // effectscatter
258
271
chart . setOption ( opt1 ) ;
259
272
} ;
260
273
0 commit comments