Skip to content

Commit c802623

Browse files
committed
update to v2.1.0
- Collect more then one candle per product and timeframe. - On events you get all candles for this collection. - Products and timeframes can now be removed from the collection. - Added function to get the average time difference between messages and local time.
1 parent be3f68b commit c802623

File tree

8 files changed

+131
-152
lines changed

8 files changed

+131
-152
lines changed

CHANGELOG.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Changelog
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [2.1.0] - 2019-07-23
8+
### Added
9+
- Collect more then one candle per product and timeframe.
10+
- On events you get all candles for this collection.
11+
- Products and timeframes can now be removed from the collection.
12+
- Added function to get the average time difference between messages and local time.
13+
14+
### Fixed
15+
- Clock don't need to be a Singleton.
16+
17+
## [2.0.0] - 2018-11-08
18+
### Added
19+
- Added support for multiple products and timeframes
20+
- Only one clock for all products.
21+
- Added adjustable clock.
22+
23+
## [1.0.0] - 2018-10-31
24+
### Added
25+
- Forked from gdax-candles

README.md

+44-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Candles
22

3-
Candles gives you the ability to create candlesticks from your tick data. The candlesticks will be created from live tick data and not historical tick data. For example, via websocket clients.
3+
Candles gives you the ability to create candlesticks from your tick data. The candlesticks will be created from live tick data and not historical tick data. For example, via websocket clients.
44

55
### About
66

7-
This project started as an fork of [gdax-candles](https://github.com/swimclan/gdax-candles).
7+
This project started as an fork of [gdax-candles](https://github.com/swimclan/gdax-candles).
88
During use, it turned out that there was a need to use it on other exchanges. So it changed to candles.
99

1010
## Installation
@@ -72,6 +72,7 @@ Candlestick {
7272
ratio: '1.00000000' },
7373
closed: true,
7474
market: 'bullish' }
75+
*/
7576
```
7677
### Constructor
7778

@@ -92,8 +93,8 @@ const Candlecollection = new candles(options);
9293
```
9394

9495
* `enabled` Enabling the correction of timelag.
95-
* `fixed` for a fixed lag between your provider and you local system set fixed to true. Otherwise the lagtime will be calculated be the given message timestamp, you have to pass.
96-
* `value` only when fixed lag selected, the lag in ms has to be specified.
96+
* `fixed` For a fixed lag between your provider and you local system set fixed to true. Otherwise the lagtime will be calculated by the given message timestamp, you have to pass.
97+
* `value` Only when fixed lag selected, the lag in ms has to be specified.
9798
* `samples` For the calculated lagtime an average of x samples will be calculated.
9899

99100
### Functions
@@ -105,16 +106,37 @@ After creating an instance of candles, you have to add products and timeframes.
105106
```js
106107
const product = ['ETH-USD', 'BTC-USD'];
107108
const timeframe = ['30s', '1m', '2m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '24h'];
108-
Candlecollection.addProduct(product, timeframe);
109+
Candlecollection.addProduct(product, timeframe, serieslength);
109110
```
110111

111112
* `product` You can set a name for your own, but it make sense to put the name of the currencypair in here. You have to tell candle this name, every time you update the current candle.
112-
* `timeframe` Setup the timeframe of your choice. The timeframes have to be writen in any number of s=seconds, m=minutes, h=hours and d=days. Feel free to use 13m or 7s as well as 21h.
113+
* `timeframe` Setup the timeframe of your choice. The timeframes have to be writen in any number of s=seconds, m=minutes, h=hours and d=days. Feel free to use 13m or 7s as well as 21h.
113114
Product and Timeframe can both be arrays. Then for every product the given timeframe will be created. You can also seperate it.
115+
* `serieslength` [optional] If you like to collect a amount of last x candles, set the amount here. If not passed, only the last candle will be hold in memmory.
114116

115117
```js
116118
Candlecollection.addProduct('ETH-USD', '30s');
117-
Candlecollection.addProduct('BTC-USD', '1m');
119+
Candlecollection.addProduct('BTC-USD', '1m', 60);
120+
```
121+
122+
#### removeProduct()
123+
124+
Removing products is as easy as adding, just provide the product(s) and timeframe(s).
125+
126+
```js
127+
// removing these timeframes in these products
128+
const product = ['ETH-USD', 'BTC-USD'];
129+
const timeframe = ['30s', '1m', '2m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '24h'];
130+
Candlecollection.removeProduct(product, timeframe);
131+
```
132+
133+
* `product` You have to set the same name(s), you use for adding your product(s).
134+
* `timeframe` same as above.
135+
136+
```js
137+
// removing one timeframe in a product
138+
Candlecollection.removeProduct('ETH-USD', '30s');
139+
Candlecollection.removeProduct('BTC-USD', '1m');
118140
```
119141

120142
#### SetSeriesPrice()
@@ -128,23 +150,31 @@ const size = 0.39818029;
128150
Candlecollection.SetSeriesPrice(product, price, size)
129151
```
130152

131-
* `product` The name you set in addProduct() before.
153+
* `product` The name you set in addProduct() before.
132154
* `price` The actual price you got from provider.
133155
* `size` This is an optional parameter. If your provider don't give you any volume information, just leave it. Then your candlesticks volume will be 0.
134156

135157
#### adjustClock()
136158

137-
If you setup timelag correction, by enabling and setting samples count, you can pass your message timestamps to candles. Candles will build an average of these and your system clock, so the timestamp of the created candle will more accorate.
159+
If you setup timelag correction, by enabling and setting samples count, you can pass your message timestamps to candles. Candles will build an average of these and your system clock, so the timestamp of the created candle will be more accorate.
138160

139161
```js
140162
Candlecollection.adjustClock(timestamp);
141163
```
142164

143165
* `timestamp` Will be the timestamp from your providers message.
144166

167+
#### getTimeDrift()
168+
169+
Gives you the average difference between exchange and local time. Depends on the timediff options you set. The value is in ms.
170+
171+
```js
172+
Candlecollection.getTimeDrift();
173+
```
174+
145175
### Events
146176

147-
Events emitted from candles. For all events the current candle will be passed.
177+
Events emitted from candles. For all events the current candle and the candle collection will be passed.
148178

149179
* `open` when a new candle created
150180
* `close` when a candle is closed
@@ -156,21 +186,21 @@ These events can be more specific by adding the timeframe and/or the productname
156186
* `open BTC-USD 1m` when a new candle of product 'BTC-USD' with timeframe '1m' created
157187
* `open 1m` when a new candle with timeframe '1m' created
158188

159-
This works for close and current events to.
189+
This works also for close and current events to.
160190

161191
like:
162192

163193
```js
164-
Candlecollection.on('close BTC-USD 30s', candle => {
165-
console.log(candle);
194+
Candlecollection.on('close BTC-USD 30s', currentCandle, candles => {
195+
console.log(currentCandle);
166196
});
167197
```
168198

169199
### Properties
170200

171201
The candles instance provides you following properties.
172202

173-
Candles collects all candlesticks for you in a series. You can get it by using the product and timeframe as propertienames.
203+
Candles collects all candlesticks for you in a series. You can get it by using the product and timeframe as property name.
174204

175205
```js
176206
Candlecollection.series['BTC-USD'].timeframe['30s'].candles

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "candles",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"description": "Generate candlesticks from your tick data in realtime.",
55
"main": "index.js",
66
"scripts": {
@@ -10,8 +10,12 @@
1010
"keywords": [
1111
"trading",
1212
"candlestick",
13+
"realtime",
1314
"ohlcv",
14-
"technical-analysis"
15+
"ohlc",
16+
"time series",
17+
"trading",
18+
"stock"
1519
],
1620
"author": "Flippo24",
1721
"contributors": [

src/Candles.js

+44-22
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ class candles extends EventEmitter {
1414
samples: options.timediff.samples || 100,
1515
}
1616
};
17-
this.clock = new Clock.getInstance();
17+
this.clock = new Clock;
1818
this.clock.setOptions(this.options.timediff)
1919
}
2020

21-
addProduct(product, timeframe) {
21+
addProduct(product, timeframe, serieslength=0) {
2222
if (!product) {
2323
throw 'product is missing'
2424
}
@@ -27,31 +27,32 @@ class candles extends EventEmitter {
2727
}
2828
if (Array.isArray(product)) {
2929
product.forEach(product => {
30-
this.addTimeframe(product, timeframe);
30+
this.addTimeframe(product, timeframe, serieslength);
3131
})
3232
} else {
33-
this.addTimeframe(product, timeframe);
33+
this.addTimeframe(product, timeframe, serieslength);
3434
}
3535
};
3636

37-
addTimeframe(product, timeframe) {
37+
addTimeframe(product, timeframe, serieslength) {
3838
if (Array.isArray(timeframe)) {
3939
timeframe.forEach(timeframe => {
40-
this.addSeries(product, timeframe);
40+
this.addSeries(product, timeframe, serieslength);
4141
})
4242
} else {
43-
this.addSeries(product, timeframe);
43+
this.addSeries(product, timeframe, serieslength);
4444
}
4545
}
4646

47-
addSeries(product, timeframe) {
48-
if (!this.clock || !this.clock.resolutions[timeframe]) {
49-
this.clock = new Clock.getInstance(timeframe).start();
47+
addSeries(product, timeframe, serieslength) {
48+
if (!this.clock.resolutions[timeframe]) {
49+
this.clock.addResolution(timeframe);
50+
this.clock.start();
5051
}
51-
var series = new Series(product, timeframe);
52+
var series = new Series(product, timeframe, serieslength);
5253
this.clock.on('tick '+ timeframe, series.onSeriesClockTick.bind(series));
5354
series.on('open',this.seriesOpen.bind(this));
54-
series.on('close',this.seriesClose.bind(this));
55+
series.on('close',this.seriesClose.bind(this));
5556
if (!this.series[product]) {
5657
this.series[product] = {};
5758
}
@@ -61,27 +62,48 @@ class candles extends EventEmitter {
6162
this.series[product].timeframe[timeframe] = series;
6263
}
6364

65+
getTimeDrift() {
66+
return this.clock.timediff.drift
67+
}
68+
69+
removeProduct(product, timeframe) {
70+
if (this.series[product].timeframe[timeframe]) {
71+
this.clock.off('tick '+ timeframe, this.series[product].timeframe[timeframe].onSeriesClockTick.bind(this.series[product].timeframe[timeframe]));
72+
this.series[product].timeframe[timeframe].off('open',this.seriesOpen.bind(this));
73+
this.series[product].timeframe[timeframe].off('close',this.seriesOpen.bind(this));
74+
delete this.series[product].timeframe[timeframe];
75+
}
76+
if (this.series[product].timeframe.lenght == 0) {
77+
delete this.series[product];
78+
}
79+
}
80+
6481
SetSeriesPrice(product, price, size=0) {
6582
Object.keys(this.series[product].timeframe).forEach(timeframe => {
83+
if (!this.series[product].timeframe[timeframe]) {
84+
return;
85+
}
6686
this.series[product].timeframe[timeframe].price = Number.parseFloat(price);
6787
this.series[product].timeframe[timeframe].currentCandle.updatePrice(Number.parseFloat(price), Number.parseFloat(size).toFixed(8));
88+
this.emit('current ' + this.series[product].product + ' ' + this.series[product].timeframe[timeframe].timeframe, this.series[product].timeframe[timeframe].currentCandle);
89+
this.emit('current ' + this.series[product].product, this.series[product].timeframe[timeframe].currentCandle);
6890
this.emit('current ' + this.series[product].timeframe[timeframe].timeframe, this.series[product].timeframe[timeframe].currentCandle);
6991
this.emit('current', this.series[product].timeframe[timeframe].currentCandle);
7092
});
7193
}
7294

73-
seriesClose(currentCandle) {
74-
this.emit('close ' + currentCandle.product, currentCandle);
75-
this.emit('close ' + currentCandle.product + ' ' + currentCandle.timeframe, currentCandle);
76-
this.emit('close ' + currentCandle.timeframe, currentCandle);
77-
this.emit('close', currentCandle);
95+
seriesClose(currentCandle, candles) {
96+
this.emit('close ' + currentCandle.product, currentCandle, candles);
97+
this.emit('close ' + currentCandle.product + ' ' + currentCandle.timeframe, currentCandle, candles);
98+
this.emit('close ' + currentCandle.timeframe, currentCandle, candles);
99+
this.emit('close', currentCandle, candles);
78100
}
79101

80-
seriesOpen(currentCandle) {
81-
this.emit('open ' + currentCandle.product, currentCandle);
82-
this.emit('open ' + currentCandle.product + ' ' + currentCandle.timeframe, currentCandle);
83-
this.emit('open ' + currentCandle.timeframe, currentCandle);
84-
this.emit('open', currentCandle);
102+
seriesOpen(currentCandle, candles) {
103+
this.emit('open ' + currentCandle.product, currentCandle, candles);
104+
this.emit('open ' + currentCandle.product + ' ' + currentCandle.timeframe, currentCandle, candles);
105+
this.emit('open ' + currentCandle.timeframe, currentCandle, candles);
106+
this.emit('open', currentCandle, candles);
85107
}
86108

87109
adjustClock(time) {

src/Candlestick.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Candlestick {
4646
this.wick.bottom = (Number.parseFloat(this.close) - Number.parseFloat(this.low)).toFixed(8);
4747
}
4848
this.wick.size = Math.abs(Number.parseFloat(this.wick.top) - Number.parseFloat(this.wick.bottom)).toFixed(8);
49-
if (Number.parseFloat(this.size) > 0) {
49+
if (Number.parseFloat(this.size)> 0) {
5050
this.wick.ratio = (Number.parseFloat(this.wick.size) / Number.parseFloat(this.size)).toFixed(8);
5151
} else {
5252
this.wick.ratio = Number.parseFloat(0).toFixed(8);

0 commit comments

Comments
 (0)