hoffstadt / hoffstadt/DearPyGui

Precision Error When Calculating Minute Candle Series

Open
#2,067 1 comment 0 reactions 0 assignees View on GitHub
state: pending type: bug
Dominant language
C++
Stars
15.6k
Forks
783
PR merge metrics
No merged PRs in 30d

Description

## Version of Dear PyGui

Version: 1.8.0
Operating System: Fedora 37 Linux

## My Issue/Question

While using a candle series with the time unit set to `dpg.mvTimeUnit_Min` there seems to be a precision error when calculating the width and spaces between each candle stick.

## User: V-EIN found this:
```It's loss of precision when some numbers are converted to single-precision float during plot rendering. Here's what happens.

Your dates are too large to be precisely represented in float variables in C++ code. They require about 32 bits of precision, whereas float only has 24 bits. Luckily, in most cases double type is used, which is way more precise. However, when width of the candle is calculated, dates are temporarily converted to float. For developers: I'm talking about this line in mvPlotting.cpp:

float half_width = count > 1 ? ((float)xs[1] - (float)xs[0]) * width_percent : width_percent;
double x1 = 1678089480;
double x2 = 1678089540;
double d = x2 - x1; // d = 60.0
float fd = (float)x2 - (float)x1; // fd = 128.0

If you compute the distance between two neighbour dates in your data, you'll get 60 - but if you do the same using floats, you'll get 128 because floats lose some precision. That is, your candles will become more than twice wider than they are supposed to be!

As a workaround, I suggest you to try adding weight=0.1 or something like that on your add_candle_series call. It will make candles narrower. However, it does not remove the root issue of precision loss; your mileage will vary depending on what data you pass on X axis (but hey, since they're dates, they should mostly be within the same precision range for years to come).
[2:31 AM]
So as a TLDR: add weight=0.1 to add_candle_series and it should work for you in foreseeable future.
[2:32 AM]
And yes, open a ticket on GitHub. It's no good to lose precision on such data, given that it's always of the same order of magnitude.
```

## To Reproduce

Steps to reproduce the behavior:
Reconstruction: https://pastebin.com/zx8xFBUG
Data for candle series: https://pastebin.com/0ysXNLfw
Or go to my Discord support ticket: https://discord.com/channels/736279277242417272/1084477000850362400/1084477000850362400

## Expected behavior

The candles should be properly spaced as they are on higher timeframes.

## Screenshots/Video

![umD64Nqh](https://user-images.githubusercontent.com/23511285/227777597-3ed6f2e9-ecf5-4618-aa70-074f653093a9.jpg)

## Standalone, minimal, complete and verifiable example

```
import dearpygui.dearpygui as dpg

dpg.create_context()

with open("BTC_USD_1m.json", "r") as f:
candles = json.load(f)
# Please use this link for the data: https://pastebin.com/0ysXNLfw

with dpg.window(label=exchange_name.upper(), tag="Primary Window"):
with dpg.plot():
dpg.add_plot_legend()

xaxis_candles = dpg.add_plot_axis(dpg.mvXAxis, time=True)

with dpg.plot_axis(dpg.mvYAxis, label="USD"):

dpg.add_candle_series(
candles["dates"],
candles["opens"],
candles["closes"],
candles["lows"],
candles["highs"],
tag="candle_series",
time_unit=dpg.mvTimeUnit_Min,
)

dpg.fit_axis_data(dpg.top_container_stack())
dpg.fit_axis_data(xaxis_candles)

dpg.create_viewport(title='Custom Title', width=600, height=200, x_pos=500, y_pos=500)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("Primary Window", True)
dpg.start_dearpygui()
dpg.destroy_context()
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.