Adding signals on the candle chart - python

I would like to plot signals on my chart is there is a way to do it on candle stick?
I did the following and got stuck :(
!pip install yfinance
!pip install mplfinance
import yfinance as yf
import mplfinance as mpf
import numpy as np
import pandas as pd
df=yf.download('BTC-USD',start='2008-01-04',end='2021-06-3',interval='1d')
buy=np.where((df['Close'] > df['Open']) & (df['Close'].shift(1) < df['Open'].shift(1),1,0)
fig = plt.figure(figsize = (20,10))
mpf.plot(df,figsize=(20,12),type ='candle',volume=True);
# any idea how to add the signal?

import yfinance as yf
import mplfinance as mpf
import numpy as np
df = yf.download('BTC-USD', start='2008-01-04', end='2021-06-3', interval='1d').tail(50)
buy = np.where((df['Close'] > df['Open']) & (df['Close'].shift(1) < df['Open'].shift(1)), 1, np.nan) * 0.95 * df['Low']
apd = [mpf.make_addplot(buy, scatter=True, markersize=100, marker=r'$\Uparrow$', color='green')]
mpf.plot(df, type='candle', volume=True, addplot=apd)
I just added .tail() for better visualization.
Output:

You place signals on the plot using the "make additional plot" api: mpf.make_addplot(data,**kwargs). The data that you pass in to make_addplot must be the same length as your original candlestick dataframe (so that mplfinance can line it up appropriately with the candlesticks). If you do not want to plot a signal at every location you simply fill the data with nan values except where you do want to plot a signal.
The return value from ap = mpf.make_addplot() is then passed into mpf.plot(df,addplot=ap) using the addplot kwarg.
You can see many examples in this tutorial on adding your own technical studies to plots.
Take the time (maybe 10 minutes or so) to go carefully through the entire tutorial. It will be time well spent.

Related

How can i make this time series graph interactive?

I am new to Python and Pandas so any help is much appreciated.
I am trying to make the graph below interactive, it would also be good to be able to choose which attributes show rather than them all.
Here is what I have so far
df.set_index('Current Year').plot(rot=45)
plt.xlabel("Year",size=16)
plt.ylabel("",size=16)
plt.title("Current year time series plot", size=18)
I know that i need to import the following import plotly.graph_objects as go but no idea how to implement this with the above time series graph. Thanks
EDIT
I am getting this error when trying to enter my plotted data.
All you need is:
df.plot()
As long as you import the correct libraries and set plotly as the plotting backend for pandas like this:
import pandas as pd
pd.options.plotting.backend = "plotly"
df = pd.DataFrame({'year':['2020','2021','2022'], 'value':[1,3,2]}).set_index('year')
fig = df.plot(title = "Current year time series plot")
fig.show()
Plot:
Complete code:
import pandas as pd
pd.options.plotting.backend = "plotly"
df = pd.DataFrame({'year':['2020','2021','2022'], 'value':[1,3,2]}).set_index('year')
fig = df.plot(title = "Current year time series plot")
fig.show()

Creating a visualization with 2 Y-Axis scales

I am currently trying to plot the price of the 1080 graphics card against the price of bitcoin over time, but the scales of the Y axis are just way off. This is my code so far:
import pandas as pd
from datetime import date
import matplotlib.pyplot as plt
from matplotlib.pyplot import *
import numpy as np
GPUDATA = pd.read_csv("1080Prices.csv")
BCDATA = pd.read_csv("BitcoinPrice.csv")
date = pd.to_datetime(GPUDATA["Date"])
price = GPUDATA["Price_USD"]
date1 = pd.to_datetime(BCDATA["Date"])
price1 = BCDATA["Close"]
plot(date, price)
plot(date1, price1)
And that produces this:
The GPU prices, of course, are in blue and the price of bitcoin is in orange. I am fairly new to visualizations and I'm having a rough time finding anything online that could help me fix this issue. Some of the suggestions I found on here seem to deal with plotting data from a single datasource, but my data comes from 2 datasources.
One has entries of the GPU price in a given day, the other has the open, close, high, and low price of bitcoin in a given day. I am struggling to find a solution, any advice would be more than welcome! Thank you!
What you want to do is twin the X-axis, such that both plots will share the X-axis, but have separate Y-axes. That can be done in this way:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
GPUDATA = pd.read_csv("1080Prices.csv")
BCDATA = pd.read_csv("BitcoinPrice.csv")
gpu_dates = pd.to_datetime(GPUDATA["Date"])
gpu_prices = GPUDATA["Price_USD"]
btc_dates = pd.to_datetime(BCDATA["Date"])
btc_prices = BCDATA["Close"]
fig, ax1 = plt.subplots()
ax2 = ax1.twinx() # Create a new Axes object sharing ax1's x-axis
ax1.plot(gpu_dates, gpu_prices, color='blue')
ax2.plot(btc_dates, btc_prices, color='red')
As you have not provided sample data, I am unable to show a relevant demonstration, but this should work.

Matplotlib plots turn out blank even having values

I am new to analytics,python and machine learning and I am working on Time forecasting. Using the following code I am getting the value for train and test data but the graph is plotted blank.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.tsa.api as ExponentialSmoothing
#Importing data
df = pd.read_csv('international-airline-passengers - Copy.csv')
#Printing head
print(df.head())
#Printing tail
print(df.tail())
df = pd.read_csv('international-airline-passengers - Copy.csv', nrows = 11856)
#Creating train and test set
#Index 10392 marks the end of October 2013
train=df[0:20]
test=df[20:]
#Aggregating the dataset at daily level
df.Timestamp = pd.to_datetime(df.Month,format='%m/%d/%Y %H:%M')
df.index = df.Timestamp
df = df.resample('D').mean()
train.Timestamp = pd.to_datetime(train.Month,format='%m/%d/%Y %H:%M')
print('1')
print(train.Timestamp)
train.index = train.Timestamp
train = train.resample('D').mean()
test.Timestamp = pd.to_datetime(test.Month,format='%m/%d/%Y %H:%M')
test.index = test.Timestamp
test = test.resample('D').mean()
train.Count.plot(figsize=(15,8), title= 'Result', fontsize=14)
test.Count.plot(figsize=(15,8), title= 'Result', fontsize=14)
plt.show()
Not able to understand the reason for getting the graph blank even when train and test data is having value.
Thanks in advance.
I think I found the issue here. The thing is you are using train.Count.plot here, while the value of "plt" is still empty.If you go through the documentation of matplotlib(link down below), you will find that you need to store some value in plt first and here since plt is empty, it is giving back empty plot.
Basically you are not plotting anything and just showing up the blank plot.
Eg: plt.subplots(values) or plt.scatter(values), or any of its function depending on requirements.Hope this helps.
https://matplotlib.org/
import holoviews as hv
import pandas as pd
import numpy as np
data=pd.read_csv("C:/Users/Nisarg.Bhatt/Documents/data.csv", engine="python")
train=data.groupby(["versionCreated"])["Polarity Score"].mean()
table=hv.Table(train)
print(table)
bar=hv.Bars(table).opts(plot=dict(width=1500))
renderer = hv.renderer('bokeh')
app = renderer.app(bar)
print(app)
from bokeh.server.server import Server
server = Server({'/': app}, port=0)
server.start()
server.show("/")
This is done by using Holoviews, it is used for visualisation purpose.If you are using for a professional application, you should definitely try this. Here the versionCreated is date and Polarity is similar to count. Try this
OR, if you want to stick to matplotlib try this:
fig, ax = plt.subplots(figsize=(16,9))
ax.plot(msft.index, msft, label='MSFT')
ax.plot(short_rolling_msft.index, short_rolling_msft, label='20 days rolling')
ax.plot(long_rolling_msft.index, long_rolling_msft, label='100 days rolling')
ax.set_xlabel('Date')
ax.set_ylabel('Adjusted closing price ($)')
ax.legend()
Also this can be used, if you want to stick with matplotlib

Plotting from a pandas dataframe with a timedelta index

I'm trying to plot some data from a pandas dataframe with a timedelta index and I want to customize the time ticks and labels in my x-axis. This should be simple but it's proving to be a tough job.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as dates
## I have a df similar to this
timestamps = pd.date_range(start="2017-05-08", freq="10T", periods=6*6)
timedeltas = timestamps - pd.to_datetime("2017-05-08")
yy = np.random.random((len(timedeltas),10))
df = pd.DataFrame(data=yy, index=timedeltas) # Ok, this is what I have
## Now I want to plot this but I want detailed control of the plot so I use matplotlib instead of df.plot
fig,axes=plt.subplots()
axes.plot(df.index.values, df.values)
#axes.plot_date(df.index, df.values, '-')
axes.xaxis.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
axes.xaxis.set_minor_locator(dates.MinuteLocator(byminute=range(0,24*60,10)))
axes.xaxis.set_major_formatter(dates.DateFormatter('%H:%M'))
plt.show()
As you can see, the ticks are not even showing up. How can I add major ticks and labels every two hours and minor ticks every 10 minutes, for example?
Although I don't know exactly what the root issue is, it seems that it is related to the used package versions. When I run your example with an older python distribution (matplotlib 1.5.1, numpy 1.11.1, pandas 0.18.1 and python 2.7.12), then I get a plot without ticks just as you described.
However I can get a plot with the correct ticks
by running the code below with a recent python distribution (matplot 2.0.1, numpy 1.12.1, pandas 0.19.1 and python 3.6.1).
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as dates
timestamps = pd.date_range(start="2017-05-08", freq="10T", periods=6*6)
timedeltas = timestamps - pd.to_datetime("2017-05-08")
yy = np.random.random((len(timedeltas),10))
df = pd.DataFrame(data=yy, index=timedeltas)
fig,axes=plt.subplots()
axes.plot_date(df.index, df.values, '-')
axes.xaxis.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
axes.xaxis.set_minor_locator(dates.MinuteLocator(byminute=range(0,24*60,10)))
axes.xaxis.set_major_formatter(dates.DateFormatter('%H:%M'))
plt.show()

faceting and x axis selection in seaborn

I am working with this dataframe containing bit coin data from yahoo finance. I set a list of cryptocurrencies and I would like:
a. to limit the x axis to the last 2 months
b. try to put all the graphs together, like faceting one close to the other in a graph table, as it s possible to do in ggplot in R.
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
%matplotlib inline
# For reading stock data from yahoo
from pandas.io.data import DataReader
# For time stamps
from datetime import datetime
# For division
from __future__ import division
tech_list = ['BTC','TTC','DGC','DEE','PPC']
end = datetime.now()
start = datetime(end.year - 1,end.month,end.day)
for stock in tech_list:
# Set DataFrame as the Stock Ticker
globals()[stock] = DataReader(stock,'yahoo',start,end)
DEE['Volume'].plot(legend=True,figsize=(10,4))
Should I change something in the time definition or in seaborn itself?
thanks
Your question has nothing to do with seaborn, it is basic
matplotlib stuff. seaborn only changes the style of figures in
your case, so I exclude it from the code I provide below, but you can
import it if you want to change the style.
To get the data for the last 2 months you should make your start for two months before today. It is easy to do with relativedelta:
from dateutil.relativedelta import relativedelta
start = dt.datetime(end.year,end.month,end.day) - relativedelta(months=2)
Changing limits of x axis would be more painful if you plot with padnas.DataFrame.plot(). But if you want to import all data and then select only data for the last 2 months, you can use the same relativedelta trick, but with indexing, like this:
DEE.loc[DEE.index >= end - relativedelta(months=2),'Volume'].plot()
As for putting the graphs together, your question is not phrased clearly, so I can only guess that you meant putting all stocks one under another as subplots, like this:
I rewrote your code to do this:
import pandas as pd
# For reading stock data from yahoo
from pandas.io.data import DataReader
import matplotlib.pyplot as plt
%matplotlib inline
# For time stamps
import datetime as dt
from dateutil.relativedelta import relativedelta
end = dt.datetime.now()
start = dt.datetime(end.year-1,end.month,end.day)
tech_list = dict({'BTC':None,'TTC':None,'DGC':None,'DEE':None,'PPC':None})
for stock in tech_list.keys():
tech_list[stock] = DataReader(stock,'yahoo',start,end)
months_to_plot = relativedelta(months=2)
fig = plt.figure(figsize=(8,10))
for (n,stock) in enumerate(tech_list.keys()):
ax = fig.add_subplot(len(tech_list),1,n)
tech_list[stock].loc[tech_list[stock].index >= end - months_to_plot,'Volume'].plot()
ax.set_title(stock)
plt.tight_layout()
P.S. Please be more clear in the future with your questions if you want a concise answer. The code you provided contains extra lines, not necessary for your question, which makes it more difficult to understand what exactly you want to do. Your question, on the other hand, is not nearly as detailed as it could be.

Categories