-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrypto-price-app.py
169 lines (142 loc) · 6.48 KB
/
crypto-price-app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# This app is for educational purpose only. Insights gained is not financial advice. Use at your own risk!
import streamlit as st
from PIL import Image
import pandas as pd
import base64
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup
import requests
import json
import time
#---------------------------------#
# New feature (make sure to upgrade your streamlit library)
# pip install --upgrade streamlit
#---------------------------------#
# Page layout
## Page expands to full width
st.set_page_config(layout="wide")
#---------------------------------#
# Title
image = Image.open('logo.jpg')
st.image(image, width = 500)
st.title('Crypto Price App')
st.markdown("""
This app retrieves cryptocurrency prices for the top 100 cryptocurrency from the **CoinMarketCap**!
""")
#---------------------------------#
# About
expander_bar = st.beta_expander("About")
expander_bar.markdown("""
* **Python libraries:** base64, pandas, streamlit, numpy, matplotlib, seaborn, BeautifulSoup, requests, json, time
* **Data source:** [CoinMarketCap](http://coinmarketcap.com).
* **Credit:** Web scraper adapted from the Medium article *[Web Scraping Crypto Prices With Python](https://towardsdatascience.com/web-scraping-crypto-prices-with-python-41072ea5b5bf)* written by [Bryan Feng](https://medium.com/@bryanf).
""")
#---------------------------------#
# Page layout (continued)
## Divide page to 3 columns (col1 = sidebar, col2 and col3 = page contents)
col1 = st.sidebar
col2, col3 = st.beta_columns((2,1))
#---------------------------------#
# Sidebar + Main panel
col1.header('Input Options')
## Sidebar - Currency price unit
currency_price_unit = col1.selectbox('Select currency for price', ('USD', 'BTC', 'ETH'))
# Web scraping of CoinMarketCap data
@st.cache
def load_data():
cmc = requests.get('https://coinmarketcap.com')
soup = BeautifulSoup(cmc.content, 'html.parser')
data = soup.find('script', id='__NEXT_DATA__', type='application/json')
coins = {}
coin_data = json.loads(data.contents[0])
listings = coin_data['props']['initialState']['cryptocurrency']['listingLatest']['data']
for i in listings:
coins[str(i['id'])] = i['slug']
coin_name = []
coin_symbol = []
market_cap = []
percent_change_1h = []
percent_change_24h = []
percent_change_7d = []
price = []
volume_24h = []
for i in listings:
coin_name.append(i['slug'])
coin_symbol.append(i['symbol'])
price.append(i['quote'][currency_price_unit]['price'])
percent_change_1h.append(i['quote'][currency_price_unit]['percent_change_1h'])
percent_change_24h.append(i['quote'][currency_price_unit]['percent_change_24h'])
percent_change_7d.append(i['quote'][currency_price_unit]['percent_change_7d'])
market_cap.append(i['quote'][currency_price_unit]['market_cap'])
volume_24h.append(i['quote'][currency_price_unit]['volume_24h'])
df = pd.DataFrame(columns=['coin_name', 'coin_symbol', 'market_cap', 'percent_change_1h', 'percent_change_24h', 'percent_change_7d', 'price', 'volume_24h'])
df['coin_name'] = coin_name
df['coin_symbol'] = coin_symbol
df['price'] = price
df['percent_change_1h'] = percent_change_1h
df['percent_change_24h'] = percent_change_24h
df['percent_change_7d'] = percent_change_7d
df['market_cap'] = market_cap
df['volume_24h'] = volume_24h
return df
df = load_data()
## Sidebar - Cryptocurrency selections
sorted_coin = sorted( df['coin_symbol'] )
selected_coin = col1.multiselect('Cryptocurrency', sorted_coin, sorted_coin)
df_selected_coin = df[ (df['coin_symbol'].isin(selected_coin)) ] # Filtering data
## Sidebar - Number of coins to display
num_coin = col1.slider('Display Top N Coins', 1, 100, 100)
df_coins = df_selected_coin[:num_coin]
## Sidebar - Percent change timeframe
percent_timeframe = col1.selectbox('Percent change time frame',
['7d','24h', '1h'])
percent_dict = {"7d":'percent_change_7d',"24h":'percent_change_24h',"1h":'percent_change_1h'}
selected_percent_timeframe = percent_dict[percent_timeframe]
## Sidebar - Sorting values
sort_values = col1.selectbox('Sort values?', ['Yes', 'No'])
col2.subheader('Price Data of Selected Cryptocurrency')
col2.write('Data Dimension: ' + str(df_selected_coin.shape[0]) + ' rows and ' + str(df_selected_coin.shape[1]) + ' columns.')
col2.dataframe(df_coins)
# Download CSV data
# https://discuss.streamlit.io/t/how-to-download-file-in-streamlit/1806
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # strings <-> bytes conversions
href = f'<a href="data:file/csv;base64,{b64}" download="crypto.csv">Download CSV File</a>'
return href
col2.markdown(filedownload(df_selected_coin), unsafe_allow_html=True)
#---------------------------------#
# Preparing data for Bar plot of % Price change
col2.subheader('Table of % Price Change')
df_change = pd.concat([df_coins.coin_symbol, df_coins.percent_change_1h, df_coins.percent_change_24h, df_coins.percent_change_7d], axis=1)
df_change = df_change.set_index('coin_symbol')
df_change['positive_percent_change_1h'] = df_change['percent_change_1h'] > 0
df_change['positive_percent_change_24h'] = df_change['percent_change_24h'] > 0
df_change['positive_percent_change_7d'] = df_change['percent_change_7d'] > 0
col2.dataframe(df_change)
# Conditional creation of Bar plot (time frame)
col3.subheader('Bar plot of % Price Change')
if percent_timeframe == '7d':
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_7d'])
col3.write('*7 days period*')
plt.figure(figsize=(5,25))
plt.subplots_adjust(top = 1, bottom = 0)
df_change['percent_change_7d'].plot(kind='barh', color=df_change.positive_percent_change_7d.map({True: 'g', False: 'r'}))
col3.pyplot(plt)
elif percent_timeframe == '24h':
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_24h'])
col3.write('*24 hour period*')
plt.figure(figsize=(5,25))
plt.subplots_adjust(top = 1, bottom = 0)
df_change['percent_change_24h'].plot(kind='barh', color=df_change.positive_percent_change_24h.map({True: 'g', False: 'r'}))
col3.pyplot(plt)
else:
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_1h'])
col3.write('*1 hour period*')
plt.figure(figsize=(5,25))
plt.subplots_adjust(top = 1, bottom = 0)
df_change['percent_change_1h'].plot(kind='barh', color=df_change.positive_percent_change_1h.map({True: 'g', False: 'r'}))
col3.pyplot(plt)