salman-mhmd-khan commited on
Commit
49aaa91
·
verified ·
1 Parent(s): 47a5e82

Upload 5 files

Browse files
Files changed (5) hide show
  1. Bitcoin.jpeg +0 -0
  2. Dockerfile +11 -0
  3. app.py +397 -0
  4. background.jpeg +0 -0
  5. black.jpeg +0 -0
Bitcoin.jpeg ADDED
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile
2
+ FROM python:3.10-slim
3
+
4
+ WORKDIR /app
5
+
6
+ COPY requirements.txt .
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ COPY app.py .
10
+
11
+ CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
app.py ADDED
@@ -0,0 +1,397 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import numpy as np
5
+ import feedparser
6
+ import base64
7
+
8
+ # Function to fetch cryptocurrency data
9
+ def get_crypto_data(symbol, period="30d", interval="1h"):
10
+ crypto = yf.Ticker(f"{symbol}-USD")
11
+ data = crypto.history(period=period, interval=interval)
12
+ return data
13
+
14
+ # Function to calculate RSI
15
+ def calculate_rsi(data, period=14):
16
+ delta = data['Close'].diff()
17
+ gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
18
+ loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
19
+ rs = gain / loss
20
+ rsi = 100 - (100 / (1 + rs))
21
+ return rsi
22
+
23
+ # Function to calculate Bollinger Bands
24
+ def calculate_bollinger_bands(data, period=20, std_dev=2):
25
+ sma = data['Close'].rolling(window=period).mean()
26
+ std = data['Close'].rolling(window=period).std()
27
+ upper_band = sma + (std * std_dev)
28
+ lower_band = sma - (std * std_dev)
29
+ return upper_band, lower_band
30
+
31
+ # Function to calculate MACD
32
+ def calculate_macd(data, short_window=12, long_window=26, signal_window=9):
33
+ short_ema = data['Close'].ewm(span=short_window, adjust=False).mean()
34
+ long_ema = data['Close'].ewm(span=long_window, adjust=False).mean()
35
+ macd = short_ema - long_ema
36
+ signal = macd.ewm(span=signal_window, adjust=False).mean()
37
+ return macd, signal
38
+
39
+ # Function to calculate EMA
40
+ def calculate_ema(data, period=20):
41
+ return data['Close'].ewm(span=period, adjust=False).mean()
42
+
43
+ # Function to calculate OBV
44
+ def calculate_obv(data):
45
+ obv = (np.sign(data['Close'].diff()) * data['Volume']).cumsum()
46
+ return obv
47
+
48
+ # Function to calculate probabilities for the next 12 hours
49
+ def calculate_probabilities(data):
50
+ # Calculate indicators on the entire dataset
51
+ data['RSI'] = calculate_rsi(data)
52
+ data['Upper_Band'], data['Lower_Band'] = calculate_bollinger_bands(data)
53
+ data['MACD'], data['MACD_Signal'] = calculate_macd(data)
54
+ data['EMA_50'] = calculate_ema(data, period=50)
55
+ data['EMA_200'] = calculate_ema(data, period=200)
56
+ data['OBV'] = calculate_obv(data)
57
+
58
+ # Use the most recent values for predictions
59
+ probabilities = {
60
+ "RSI": {"Value": data['RSI'].iloc[-1], "Pump": 0, "Dump": 0},
61
+ "Bollinger Bands": {"Value": data['Close'].iloc[-1], "Pump": 0, "Dump": 0},
62
+ "MACD": {"Value": data['MACD'].iloc[-1], "Pump": 0, "Dump": 0},
63
+ "EMA": {"Value": data['EMA_50'].iloc[-1], "Pump": 0, "Dump": 0},
64
+ "OBV": {"Value": data['OBV'].iloc[-1], "Pump": 0, "Dump": 0},
65
+ }
66
+
67
+ # RSI
68
+ rsi = data['RSI'].iloc[-1]
69
+ if rsi < 25:
70
+ probabilities["RSI"]["Pump"] = 90 # Strong Pump
71
+ elif 25 <= rsi < 30:
72
+ probabilities["RSI"]["Pump"] = 60 # Moderate Pump
73
+ elif 70 < rsi <= 75:
74
+ probabilities["RSI"]["Dump"] = 60 # Moderate Dump
75
+ elif rsi > 75:
76
+ probabilities["RSI"]["Dump"] = 90 # Strong Dump
77
+
78
+ # Bollinger Bands
79
+ close = data['Close'].iloc[-1]
80
+ upper_band = data['Upper_Band'].iloc[-1]
81
+ lower_band = data['Lower_Band'].iloc[-1]
82
+ if close <= lower_band:
83
+ probabilities["Bollinger Bands"]["Pump"] = 90 # Strong Pump
84
+ elif lower_band < close <= lower_band * 1.05:
85
+ probabilities["Bollinger Bands"]["Pump"] = 60 # Moderate Pump
86
+ elif upper_band * 0.95 <= close < upper_band:
87
+ probabilities["Bollinger Bands"]["Dump"] = 60 # Moderate Dump
88
+ elif close >= upper_band:
89
+ probabilities["Bollinger Bands"]["Dump"] = 90 # Strong Dump
90
+
91
+ # MACD
92
+ macd = data['MACD'].iloc[-1]
93
+ macd_signal = data['MACD_Signal'].iloc[-1]
94
+ if macd > macd_signal and macd > 0:
95
+ probabilities["MACD"]["Pump"] = 90 # Strong Pump
96
+ elif macd > macd_signal and macd <= 0:
97
+ probabilities["MACD"]["Pump"] = 60 # Moderate Pump
98
+ elif macd < macd_signal and macd >= 0:
99
+ probabilities["MACD"]["Dump"] = 60 # Moderate Dump
100
+ elif macd < macd_signal and macd < 0:
101
+ probabilities["MACD"]["Dump"] = 90 # Strong Dump
102
+
103
+ # EMA
104
+ ema_short = data['EMA_50'].iloc[-1]
105
+ ema_long = data['EMA_200'].iloc[-1]
106
+ if ema_short > ema_long and close > ema_short:
107
+ probabilities["EMA"]["Pump"] = 90 # Strong Pump
108
+ elif ema_short > ema_long and close <= ema_short:
109
+ probabilities["EMA"]["Pump"] = 60 # Moderate Pump
110
+ elif ema_short < ema_long and close >= ema_short:
111
+ probabilities["EMA"]["Dump"] = 60 # Moderate Dump
112
+ elif ema_short < ema_long and close < ema_short:
113
+ probabilities["EMA"]["Dump"] = 90 # Strong Dump
114
+
115
+ # OBV
116
+ obv = data['OBV'].iloc[-1]
117
+ if obv > 100000:
118
+ probabilities["OBV"]["Pump"] = 90 # Strong Pump
119
+ elif 50000 < obv <= 100000:
120
+ probabilities["OBV"]["Pump"] = 60 # Moderate Pump
121
+ elif -100000 <= obv < -50000:
122
+ probabilities["OBV"]["Dump"] = 60 # Moderate Dump
123
+ elif obv < -100000:
124
+ probabilities["OBV"]["Dump"] = 90 # Strong Dump
125
+
126
+ # Normalize Pump and Dump probabilities to sum to 100%
127
+ for indicator in probabilities:
128
+ pump_prob = probabilities[indicator]["Pump"]
129
+ dump_prob = probabilities[indicator]["Dump"]
130
+
131
+ # If pump probability is set, normalize dump
132
+ if pump_prob > 0:
133
+ probabilities[indicator]["Dump"] = 100 - pump_prob
134
+
135
+ # If dump probability is set, normalize pump
136
+ if dump_prob > 0:
137
+ probabilities[indicator]["Pump"] = 100 - dump_prob
138
+
139
+ return probabilities, data.iloc[-1]
140
+
141
+
142
+ # Function to calculate weighted probabilities
143
+ def calculate_weighted_probabilities(probabilities):
144
+ weightages = {
145
+ "RSI": 0.20,
146
+ "Bollinger Bands": 0.20,
147
+ "MACD": 0.25,
148
+ "EMA": 0.15,
149
+ "OBV": 0.20
150
+ }
151
+
152
+ # Initialize final probabilities
153
+ final_probabilities = {"Pump": 0, "Dump": 0}
154
+
155
+ # Calculate weighted probabilities
156
+ for indicator, values in probabilities.items():
157
+ pump_prob = values["Pump"] * weightages[indicator]
158
+ dump_prob = values["Dump"] * weightages[indicator]
159
+
160
+ final_probabilities["Pump"] += pump_prob
161
+ final_probabilities["Dump"] += dump_prob
162
+
163
+ # Normalize the final probabilities to ensure they sum to 100%
164
+ total = final_probabilities["Pump"] + final_probabilities["Dump"]
165
+
166
+ # Handle cases where the total sum of probabilities is zero
167
+ if total == 0:
168
+ final_probabilities["Pump"] = 50
169
+ final_probabilities["Dump"] = 50
170
+ else:
171
+ final_probabilities["Pump"] = (final_probabilities["Pump"] / total) * 100
172
+ final_probabilities["Dump"] = (final_probabilities["Dump"] / total) * 100
173
+
174
+ # Debugging the final probabilities to ensure they sum up to 100%
175
+ print(f"Final Pump Probability: {final_probabilities['Pump']}%")
176
+ print(f"Final Dump Probability: {final_probabilities['Dump']}%")
177
+
178
+ return final_probabilities
179
+
180
+
181
+ # Function to fetch news data from Google News RSS feeds
182
+ def fetch_news(coin_name):
183
+ try:
184
+ url = f"https://news.google.com/rss/search?q={coin_name}+cryptocurrency"
185
+ feed = feedparser.parse(url)
186
+ news_items = []
187
+ for entry in feed.entries[:5]: # Limit to 5 news items
188
+ news_items.append({
189
+ "title": entry.title,
190
+ "link": entry.link,
191
+ "published": entry.published,
192
+ })
193
+ return news_items
194
+ except Exception as e:
195
+ st.error(f"Error fetching news: {e}")
196
+ return []
197
+
198
+
199
+ # Streamlit App
200
+ st.set_page_config(page_title="Crypto Insights ", layout="wide")
201
+
202
+
203
+ # Add styled title with specific color
204
+ st.markdown(
205
+ """
206
+ <div style="text-align: center; margin-top: 5px; margin-left: 20px">
207
+ <h1 style="font-size: 2.5em; color: #FFD700;">Crypto Vision</h1>
208
+ </div>
209
+ """,
210
+ unsafe_allow_html=True
211
+ )
212
+
213
+ # Add styled subtitle with lines on both sides and reduced gap
214
+ st.markdown(
215
+ """
216
+ <div style="display: flex; align-items: center; justify-content: center; margin-top: 0px;">
217
+ <hr style="width: 20%; border: 1px solid #ccc; margin: 0 5px; height: 1px;">
218
+ <span style="font-size: 1.2em; color: gray; margin: 0;">MARKET ANALYZER</span>
219
+ <hr style="width: 20%; border: 1px solid #ccc; margin: 0 5px; height: 1px;">
220
+ </div>
221
+ """,
222
+ unsafe_allow_html=True
223
+ )
224
+
225
+
226
+ # Function to add a background image to the app
227
+ def add_background_to_main(image_file):
228
+ page_bg_img = f"""
229
+ <style>
230
+ /* Apply background image to the main container */
231
+ [data-testid="stAppViewContainer"] {{
232
+ background-image: url('data:image/jpeg;base64,{image_file}');
233
+ background-size: cover;
234
+ background-position: center;
235
+ background-repeat: no-repeat;
236
+ background-attachment: fixed;
237
+ min-height: 100vh;
238
+
239
+ }}
240
+ </style>
241
+ """
242
+ st.markdown(page_bg_img, unsafe_allow_html=True)
243
+
244
+ # Function to encode the image to Base64
245
+ def get_base64_of_image(image_path):
246
+ with open(image_path, "rb") as img_file:
247
+ return base64.b64encode(img_file.read()).decode()
248
+
249
+ # Add the background image (ensure the image file is in the correct path)
250
+ image_path = "black.jpeg" # Replace with your image file name
251
+ try:
252
+ encoded_image = get_base64_of_image(image_path)
253
+ add_background_to_main(encoded_image)
254
+ except FileNotFoundError:
255
+ st.warning(f"Background image '{image_path}' not found. Please check the file path.")
256
+
257
+ st.markdown("""
258
+ Welcome to the "Crypto Vision". This tool provides real-time predictions
259
+ and insights on cryptocurrency price movements using advanced technical indicators like RSI,
260
+ Bollinger Bands, MACD, and more. Simply enter the cryptocurrency symbol, and our tool will analyze the
261
+ market data, calculate indicators, and provide you with the probabilities of price movements (pump or dump).
262
+ Stay ahead in your crypto trading with this powerful tool!
263
+ """)
264
+
265
+ # Add CSS to make the sidebar fixed and apply hover effect on buttons
266
+ st.markdown(
267
+ """
268
+ <style>
269
+ /* Make the sidebar always visible and fixed */
270
+ [data-testid="stSidebar"] {
271
+ width: 300px;
272
+ min-width: 300px;
273
+ max-width: 300px;
274
+ position: fixed;
275
+ top: 0;
276
+ left: 0;
277
+ bottom: 0;
278
+ background-color: #2d2d2d;
279
+ padding-top: 20px;
280
+ z-index: 9999;
281
+ }
282
+ [data-testid="collapsedControl"] {
283
+ display: none;
284
+ }
285
+
286
+
287
+ /* Sidebar button hover effect */
288
+ .css-1emrehy.edgvbvh3 {
289
+ background-color: #3e3e3e;
290
+ color: #fff;
291
+ transition: all 0.3s ease;
292
+ }
293
+ .css-1emrehy.edgvbvh3:hover {
294
+ background-color: #FFD700;
295
+ color: black;
296
+ }
297
+ /* Optional: Add padding for better spacing */
298
+ .css-1emrehy.edgvbvh3 {
299
+ margin-bottom: 15px;
300
+ border-radius: 5px;
301
+ padding: 12px;
302
+ font-size: 16px;
303
+ font-weight: bold;
304
+ }
305
+ /* Customize the sidebar header */
306
+ .css-1r6slb0 {
307
+ color: #FFD700;
308
+ font-size: 20px;
309
+ font-weight: bold;
310
+ }
311
+ /* Customizing the text input inside the sidebar */
312
+ .stTextInput input {
313
+ background-color: #3e3e3e;
314
+ color: #fff;
315
+ border: 1px solid #FFD700;
316
+ border-radius: 5px;
317
+ padding: 10px;
318
+ }
319
+ /* Customize the buttons inside the sidebar */
320
+ .stButton button {
321
+ background-color: #3e3e3e;
322
+ color: #fff;
323
+ border-radius: 5px;
324
+ padding: 12px;
325
+ font-size: 16px;
326
+ font-weight: bold;
327
+ }
328
+ .stButton button:hover {
329
+ background-color: #C0C0C0;
330
+ color: black;
331
+ }
332
+ </style>
333
+ """,
334
+ unsafe_allow_html=True
335
+ )
336
+
337
+
338
+ # Sidebar for user input
339
+ st.sidebar.header("Cryptocurrency Symbol")
340
+ symbol = st.sidebar.text_input("Enter Cryptocurrency Symbol (e.g., BTC):", "BTC")
341
+
342
+ # Add buttons for navigation
343
+ show_news_button = st.sidebar.button("Show Latest News")
344
+ show_data_button = st.sidebar.button("Show Data and Prediction")
345
+
346
+
347
+ # Fetch data and news when the button is clicked
348
+ if show_data_button:
349
+ if symbol:
350
+ # Fetch data
351
+ data = get_crypto_data(symbol)
352
+ if data.empty:
353
+ st.error(f"No data found for {symbol}. Please check the symbol and try again.")
354
+ else:
355
+ # Display fetched data
356
+ st.write("**Fetched Data:**")
357
+ st.dataframe(data.tail())
358
+
359
+ # Ensure the DataFrame has enough rows
360
+ if len(data) < 20:
361
+ st.warning(f"Not enough data to calculate indicators. Only {len(data)} rows available. Please try a longer period.")
362
+ else:
363
+ # Calculate probabilities for the next 12 hours
364
+ probabilities, recent_data = calculate_probabilities(data)
365
+
366
+ # Create a DataFrame for the indicator values
367
+ indicator_values = {
368
+ "Indicator": ["RSI", "Bollinger Bands", "MACD", "EMA", "OBV"],
369
+ "Value": [probabilities["RSI"]["Value"], probabilities["Bollinger Bands"]["Value"], probabilities["MACD"]["Value"], probabilities["EMA"]["Value"], probabilities["OBV"]["Value"]],
370
+ }
371
+
372
+ # Convert dictionary to a DataFrame
373
+ df_indicators = pd.DataFrame(indicator_values)
374
+
375
+ # Display indicator values in table format
376
+ st.write("### **Indicators and Probabilities Table**:")
377
+ st.dataframe(df_indicators)
378
+
379
+ # Calculate weighted combined probabilities
380
+ weighted_probabilities = calculate_weighted_probabilities(probabilities)
381
+
382
+ # Display final combined probability predictions
383
+ st.write("### **Final Predicted Probabilities for the Next 12 Hours:**")
384
+ st.write(f"- **Pump Probability**: {weighted_probabilities['Pump']:.2f}%")
385
+ st.write(f"- **Dump Probability**: {weighted_probabilities['Dump']:.2f}%")
386
+
387
+ elif show_news_button:
388
+ if symbol:
389
+ # Fetch news
390
+ news_items = fetch_news(symbol)
391
+ if news_items:
392
+ st.write("### Latest News:")
393
+ for news_item in news_items:
394
+ st.markdown(f"**{news_item['title']}**: [Read More]({news_item['link']})")
395
+ st.write(f"Published on: {news_item['published']}")
396
+ else:
397
+ st.warning(f"No news found for {symbol}. Please try again later.")
background.jpeg ADDED
black.jpeg ADDED