matplotlib / mplfinance

Financial Markets Data Visualization using Matplotlib
https://pypi.org/project/mplfinance/
Other
3.5k stars 612 forks source link

Is there a way to plot OHLC figure in mplfinance with live data that isn't in a dataframe format #91

Open LrdKgb opened 4 years ago

LrdKgb commented 4 years ago

Hi,

I am querying an API to get High, low, close, open prices and volume in order to make a chart that is faster/lighter than the one on trading view. I was wondering if I could input raw live data in mplfinance and get it to plot a candlestick chart? Perhaps there is a way to do something that resembles this:

` open= api_response['open'] high = api_response['max_price'] low = api_response['min_price'] close= api_response['close'] volume = api_response['volume'] xdate = time.strftime("%X", time.gmtime())

daily(xdate,open,high,low,close,volume,width=0.6) # use data that isn't in the dataframe format like in matplotlib `

I can't seem to get OHLC data in the proper format from the API of the exchange I am using. So I was thinking of getting the live data then plotting it as new information is sent thru the exchanges API within a loop then animating it. I've read issues #17 #25 but they don't seem to cover the format type. Thank you very much for your help and the work you have put in for this project.

DanielGoldfarb commented 4 years ago

@LrdKgb The original plan was to allow for multiple formats of input data, however:

For live data, I don't know that a DataFrame format will work so well. I have only a little experience working with live data, but I can imagine that the DataFrame format might not be the best. I intend educate myself more about plotting live data before embarking on #25 which, given my current schedule, probably won't be for at least another 3 months.

Since, as you know, live-data is not yet supported in mplfinance, if you want any help or suggestions on how to most easily re-format your data, just let me know and I will be glad to help.

All the best. --Daniel

DanielGoldfarb commented 4 years ago

Regarding your code for acquiring data:

open= api_response['open']
high = api_response['max_price']
low = api_response['min_price']
close= api_response['close']
volume = api_response['volume']
xdate = time.strftime("%X", time.gmtime())

Note also: if you are familiar with, and more comfortable with, the old API, then you can still use it as noted here.

LrdKgb commented 4 years ago

Hi Daniel, I should be able to format the data using the proper format, I have been quite busy lately and should be able to do it once I take the time to sit in front of my pc and code. As regards to your question, each response corresponds to a single point in time. I do add each point in a list but only for setting certain conditions in my code. Thank you very much for your response and for this module you have created and have a pleasant week, good luck for the future. Regards, Gareth Le mardi 14 avril 2020 à 00:27:17 UTC+1, Daniel Goldfarb notifications@github.com a écrit :

Regarding your code for acquiring data: open= api_response['open'] high = api_response['max_price'] low = api_response['min_price'] close= api_response['close'] volume = api_response['volume'] xdate = time.strftime("%X", time.gmtime())

Note also: if you are familiar with, and more comfortable with, the old API, then you can still use it as noted here.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

DanielGoldfarb commented 2 years ago

@LrdKgb Do you still have an interest in using mplfinace to plot live data coming from an api?

Since we last communicated, I've gained a lot more experience with this and mplfinance now supports live updating of candlestick plots.

Please let me know if this is something you are still interested in; otherwise I will soon close this issue. Thank you.

manuelwithbmw commented 2 years ago

@DanielGoldfarb Hope he will reply he still is :) I am going to read through your links above as I am interested ' Thank you

DanielGoldfarb commented 2 years ago

@manuelwithbmw Great. Let me know if you have any questions. Regarding my comments above from a long time ago, that is:

for static data, it is trivial for the caller to put the data into a DataFrame, thus freeing up mplfinance to focus on visualization and not have to maintain a bunch of generalized code for data reformating ... For live data, I don't know that a DataFrame format will work so well ...

I am now of the opinion that the DataFrame is also fine for live data, as it is relatively simple to append new data to an existing dataframe.

manuelwithbmw commented 2 years ago

@DanielGoldfarb - This is exactly what I am doing, pulling offline data from a provider (not an API to be fair, am using yfinance instead) into a dataframe and enriching it (append) with additional columns (for technical analysis or signal generation purposes) to then elaborate signals and plot them if needs be. I believe DataFrame could be used for live data as well.
Do you intend to work this feature strictly around data coming from an api or also with a repository of live data (yfinance)?

DanielGoldfarb commented 2 years ago

@manuelwithbmw

Do you intend to work this feature strictly around data coming from an api or also with a repository of live data (yfinance)?

Manuel, it's not completely clear to me what you are asking. As a general rule it is my intention that mplfinance will always accept a pandas dataframe as data input for the ohlc(v) data. Other data (via addplot) can be a series, array or list that has the same length as the ohlc(v) data.

It is my intention to avoid adding any more dependencies to mplfinance. Presently mplfinance depends only on matplotlib (and its dependencies) and pandas (and its dependencies). I don't want to put users in a position to have to install any other packages.

That said, it is not necessarily beyond the scope of mplfinance to possibly provide utilities that make it easier to use data from various sources. Perhaps utilities that provide conversions of a sort, but without creating a dependency on a package that is not already with the existing matplotlib and pandas dependency chain.

Live updating of plots in mplfinance works fine as it is, taking data from a dataframe, and mplfinance can be complelely agnostic as to the source of that data (since it sees only the dataframe). The only issue that I see is that live updating of plots with mplfinance is somewhat slow, because it completely repaints the plot with every update. In my own testing this limits the update period to somewhere between 100 milliseconds and 500 milliseconds. The code could, in theory, be modified to support what matplotlib calls "blitting," which involves only repainting those portions of the plot that have changed. This would require a significant restructuring of the mplfinance code, however it would only benefit certain types of live updating. (For example, those types of live updating that change the range of the x-axis or y-axis will require re-painting most of the plot at anyway, so there is little benefit to blitting).

In addition to this, I am of the opinion that there is little to no benefit to updating a plot more than twice per second (although 4 to 5 times per second can be achieved with mplfinance depending upon the quantity of data). I can't imagine any trade decisions, based on a human looking at a live plot, that would be a different decision if the plot updated 10 times per second versus 2 times per second. (The human eye and mind is just not that fast.)

Such rapid trade decisions are better made by algoirthms that look strictly at the numbers and that do not take the time to plot a visualization. In another issue on this repository (can't recall which one right now) a user was attempting to do just that -- that is, to make alrgorithmic trade decisions and visualize the result in a plot at the same time. My recommendation was to split those tasks into two separate programs. Algorithmic trading must be very low latency and this can only be achieved by minimizing what the code needs to do. The trading program can always use a low latency method to write its results to a location (memory or otherwise) that can be independently (asyncronously) picked up by a separate visualization thread or program, and the user will then see the visualization of the trade typically within 500 milliseconds after it happens. (Which seems to me more than adequate).

manuelwithbmw commented 2 years ago

@DanielGoldfarb Hi Daniel, sorry I have not been clear enough, I do agree on all your above points.

What I currently do is manually and occasionally running my python code, so that it can pull live and updated data, to check how trading signals are developing - then, I would manually take action. What I would like to achieve is having my code to update my chart+signals on the background without closing the chart.

DanielGoldfarb commented 2 years ago

@manuelwithbmw

What I would like to achieve is having my code to update my chart+signals on the background without closing the chart.

Hopefully you have already figured out how to do this. If not, this is a good example. Notice that the fetching of new data is inside the animate() function. The iterval in the call to FuncAnimation() can be made larger. interval=250 is 4 times per second. No reason you can't set the interval to 300000 for once every 5 minutes.