Skip to content

Commit ba42d9f

Browse files
committed
Updates
- set wap default value to `nan` - manage first bar to avoit operations with `nan` - align functionality within `Timebars`, `TickBars` and `VolumeBars`. They all emit on new ticks `self.bars.updateEvent.emit(self.bars, False)` with parameter `hasNewBar` set `False`. Aligned with `reqHistoricalData` and `reqRealTimeBars`
1 parent 2930c07 commit ba42d9f

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

ib_async/ticker.py

+28-23
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
from ib_async.contract import Contract
1010
from ib_async.objects import (
11-
DOMLevel,
1211
Dividends,
12+
DOMLevel,
1313
FundamentalRatios,
1414
MktDepthData,
1515
OptionComputation,
@@ -267,7 +267,7 @@ class Bar:
267267
low: float = nan
268268
close: float = nan
269269
volume: int = 0
270-
wap: float = 0
270+
wap: float = nan
271271
count: int = 0
272272

273273

@@ -305,10 +305,10 @@ def on_source(self, time, price, size):
305305
bar.low = min(bar.low, price)
306306
bar.close = price
307307
# wap
308-
if (bar.volume + size) == 0:
309-
bar.wap = bar.wap
310-
else:
311-
bar.wap = ((bar.wap * bar.volume) + (price * size)) / (bar.volume + size)
308+
if (bar.volume + size) != 0: # Prevent division by zero on empty bar
309+
bar.wap = (
310+
((bar.wap if not isNan(bar.wap) else 0) * bar.volume) + (price * size)
311+
) / (bar.volume + size)
312312
bar.volume += size
313313
bar.count += 1
314314
self.bars.updateEvent.emit(self.bars, False)
@@ -350,19 +350,22 @@ def on_source(self, time, price, size):
350350
bar.low = min(bar.low, price)
351351
bar.close = price
352352
# wap
353-
if (bar.volume + size) == 0:
354-
bar.wap = bar.wap
355-
else:
356-
bar.wap = ((bar.wap * bar.volume) + (price * size)) / (
357-
bar.volume + size
358-
)
353+
if (bar.volume + size) != 0: # Prevent division by zero on empty bar
354+
bar.wap = (
355+
((bar.wap if not isNan(bar.wap) else 0) * bar.volume)
356+
+ (price * size)
357+
) / (bar.volume + size)
359358
bar.volume += size
360359
bar.count += 1
361-
if bar.count == self._count:
362-
if bar.wap == 0:
360+
if bar.count == self._count: # full bar
361+
if isNan(bar.wap):
363362
bar.wap = bar.close
364363
self.bars.updateEvent.emit(self.bars, True)
365364
self.emit(self.bars)
365+
else: # partial bar
366+
if isNan(bar.wap):
367+
bar.wap = bar.close
368+
self.bars.updateEvent.emit(self.bars, False)
366369

367370

368371
class VolumeBars(Op):
@@ -385,17 +388,19 @@ def on_source(self, time, price, size):
385388
bar.high = max(bar.high, price)
386389
bar.low = min(bar.low, price)
387390
# wap
388-
bar.close = price
389-
if (bar.volume + size) == 0:
390-
bar.wap = bar.wap
391-
else:
392-
bar.wap = ((bar.wap * bar.volume) + (price * size)) / (
393-
bar.volume + size
394-
)
391+
if (bar.volume + size) != 0: # Prevent division by zero on empty bar
392+
bar.wap = (
393+
((bar.wap if not isNan(bar.wap) else 0) * bar.volume)
394+
+ (price * size)
395+
) / (bar.volume + size)
395396
bar.volume += size
396397
bar.count += 1
397-
if bar.volume >= self._volume:
398-
if bar.wap == 0:
398+
if bar.volume >= self._volume: # full bar
399+
if isNan(bar.wap):
399400
bar.wap = bar.close
400401
self.bars.updateEvent.emit(self.bars, True)
401402
self.emit(self.bars)
403+
else: # partial bar
404+
if isNan(bar.wap):
405+
bar.wap = bar.close
406+
self.bars.updateEvent.emit(self.bars, False)

0 commit comments

Comments
 (0)