8
8
9
9
from ib_async .contract import Contract
10
10
from ib_async .objects import (
11
- DOMLevel ,
12
11
Dividends ,
12
+ DOMLevel ,
13
13
FundamentalRatios ,
14
14
MktDepthData ,
15
15
OptionComputation ,
@@ -267,7 +267,7 @@ class Bar:
267
267
low : float = nan
268
268
close : float = nan
269
269
volume : int = 0
270
- wap : float = 0
270
+ wap : float = nan
271
271
count : int = 0
272
272
273
273
@@ -305,10 +305,10 @@ def on_source(self, time, price, size):
305
305
bar .low = min (bar .low , price )
306
306
bar .close = price
307
307
# 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 )
312
312
bar .volume += size
313
313
bar .count += 1
314
314
self .bars .updateEvent .emit (self .bars , False )
@@ -350,19 +350,22 @@ def on_source(self, time, price, size):
350
350
bar .low = min (bar .low , price )
351
351
bar .close = price
352
352
# 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 )
359
358
bar .volume += size
360
359
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 ) :
363
362
bar .wap = bar .close
364
363
self .bars .updateEvent .emit (self .bars , True )
365
364
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 )
366
369
367
370
368
371
class VolumeBars (Op ):
@@ -385,17 +388,19 @@ def on_source(self, time, price, size):
385
388
bar .high = max (bar .high , price )
386
389
bar .low = min (bar .low , price )
387
390
# 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 )
395
396
bar .volume += size
396
397
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 ) :
399
400
bar .wap = bar .close
400
401
self .bars .updateEvent .emit (self .bars , True )
401
402
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