File size: 17,844 Bytes
49aaa91
7bbcf8a
49aaa91
 
7bbcf8a
20564e7
49aaa91
af07741
 
 
7bbcf8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49aaa91
7bbcf8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0f42a49
c300f4c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b685424
 
0f42a49
 
 
 
538b9c2
c300f4c
b685424
538b9c2
c300f4c
 
 
538b9c2
c300f4c
 
 
538b9c2
c300f4c
b685424
538b9c2
c300f4c
 
 
 
 
7bbcf8a
 
 
 
 
 
 
49aaa91
 
 
7bbcf8a
 
 
 
 
 
 
49aaa91
 
 
 
 
7bbcf8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49aaa91
 
 
 
 
 
 
 
 
7bbcf8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49aaa91
7bbcf8a
49aaa91
 
 
7bbcf8a
538b9c2
 
49aaa91
7bbcf8a
 
49aaa91
7bbcf8a
 
 
 
49aaa91
 
7bbcf8a
 
 
db4d37d
7bbcf8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c300f4c
 
 
8db6775
bf5dd11
 
 
 
 
 
 
 
 
 
8db6775
 
 
c300f4c
b685424
 
 
 
bf5dd11
b685424
 
 
 
bf5dd11
 
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
import streamlit as st
import yfinance as yf
import pandas as pd
import numpy as np
import feedparser
import requests
import base64
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout

# Function to fetch cryptocurrency data
def get_crypto_data(symbol, period="30d", interval="1h"):
    crypto = yf.Ticker(f"{symbol}-USD")
    data = crypto.history(period=period, interval=interval)
    return data

# Function to calculate RSI
def calculate_rsi(data, period=14):
    delta = data['Close'].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# Function to calculate Bollinger Bands
def calculate_bollinger_bands(data, period=20, std_dev=2):
    sma = data['Close'].rolling(window=period).mean()
    std = data['Close'].rolling(window=period).std()
    upper_band = sma + (std * std_dev)
    lower_band = sma - (std * std_dev)
    return upper_band, lower_band

# Function to calculate MACD
def calculate_macd(data, short_window=12, long_window=26, signal_window=9):
    short_ema = data['Close'].ewm(span=short_window, adjust=False).mean()
    long_ema = data['Close'].ewm(span=long_window, adjust=False).mean()
    macd = short_ema - long_ema
    signal = macd.ewm(span=signal_window, adjust=False).mean()
    return macd, signal

# Function to calculate EMA
def calculate_ema(data, period=20):
    return data['Close'].ewm(span=period, adjust=False).mean()

# Function to calculate OBV
def calculate_obv(data):
    obv = (np.sign(data['Close'].diff()) * data['Volume']).cumsum()
    return obv

# Function to calculate probabilities for the next 12 hours
def calculate_probabilities(data):
    # Calculate indicators on the entire dataset
    data['RSI'] = calculate_rsi(data)
    data['Upper_Band'], data['Lower_Band'] = calculate_bollinger_bands(data)
    data['MACD'], data['MACD_Signal'] = calculate_macd(data)
    data['EMA_50'] = calculate_ema(data, period=50)
    data['EMA_200'] = calculate_ema(data, period=200)
    data['OBV'] = calculate_obv(data)
    
    # Use the most recent values for predictions
    probabilities = {
        "RSI": {"Value": data['RSI'].iloc[-1], "Pump": 0, "Dump": 0},
        "Bollinger Bands": {"Value": data['Close'].iloc[-1], "Pump": 0, "Dump": 0},
        "MACD": {"Value": data['MACD'].iloc[-1], "Pump": 0, "Dump": 0},
        "EMA": {"Value": data['EMA_50'].iloc[-1], "Pump": 0, "Dump": 0},
        "OBV": {"Value": data['OBV'].iloc[-1], "Pump": 0, "Dump": 0},
    }
    
    # RSI
    rsi = data['RSI'].iloc[-1]
    if rsi < 25:
        probabilities["RSI"]["Pump"] = 90  # Strong Pump
    elif 25 <= rsi < 30:
        probabilities["RSI"]["Pump"] = 60  # Moderate Pump
    elif 70 < rsi <= 75:
        probabilities["RSI"]["Dump"] = 60  # Moderate Dump
    elif rsi > 75:
        probabilities["RSI"]["Dump"] = 90  # Strong Dump
    
    # Bollinger Bands
    close = data['Close'].iloc[-1]
    upper_band = data['Upper_Band'].iloc[-1]
    lower_band = data['Lower_Band'].iloc[-1]
    if close <= lower_band:
        probabilities["Bollinger Bands"]["Pump"] = 90  # Strong Pump
    elif lower_band < close <= lower_band * 1.05:
        probabilities["Bollinger Bands"]["Pump"] = 60  # Moderate Pump
    elif upper_band * 0.95 <= close < upper_band:
        probabilities["Bollinger Bands"]["Dump"] = 60  # Moderate Dump
    elif close >= upper_band:
        probabilities["Bollinger Bands"]["Dump"] = 90  # Strong Dump
    
    # MACD
    macd = data['MACD'].iloc[-1]
    macd_signal = data['MACD_Signal'].iloc[-1]
    if macd > macd_signal and macd > 0:
        probabilities["MACD"]["Pump"] = 90  # Strong Pump
    elif macd > macd_signal and macd <= 0:
        probabilities["MACD"]["Pump"] = 60  # Moderate Pump
    elif macd < macd_signal and macd >= 0:
        probabilities["MACD"]["Dump"] = 60  # Moderate Dump
    elif macd < macd_signal and macd < 0:
        probabilities["MACD"]["Dump"] = 90  # Strong Dump
    
    # EMA
    ema_short = data['EMA_50'].iloc[-1]
    ema_long = data['EMA_200'].iloc[-1]
    if ema_short > ema_long and close > ema_short:
        probabilities["EMA"]["Pump"] = 90  # Strong Pump
    elif ema_short > ema_long and close <= ema_short:
        probabilities["EMA"]["Pump"] = 60  # Moderate Pump
    elif ema_short < ema_long and close >= ema_short:
        probabilities["EMA"]["Dump"] = 60  # Moderate Dump
    elif ema_short < ema_long and close < ema_short:
        probabilities["EMA"]["Dump"] = 90  # Strong Dump
    
    # OBV
    obv = data['OBV'].iloc[-1]
    if obv > 100000:
        probabilities["OBV"]["Pump"] = 90  # Strong Pump
    elif 50000 < obv <= 100000:
        probabilities["OBV"]["Pump"] = 60  # Moderate Pump
    elif -100000 <= obv < -50000:
        probabilities["OBV"]["Dump"] = 60  # Moderate Dump
    elif obv < -100000:
        probabilities["OBV"]["Dump"] = 90  # Strong Dump
    
    # Normalize Pump and Dump probabilities to sum to 100%
    for indicator in probabilities:
        pump_prob = probabilities[indicator]["Pump"]
        dump_prob = probabilities[indicator]["Dump"]
        
        # If pump probability is set, normalize dump
        if pump_prob > 0:
            probabilities[indicator]["Dump"] = 100 - pump_prob
        
        # If dump probability is set, normalize pump
        if dump_prob > 0:
            probabilities[indicator]["Pump"] = 100 - dump_prob
    
    return probabilities, data.iloc[-1]


# Function to calculate weighted probabilities
def calculate_weighted_probabilities(probabilities):
    weightages = {
        "RSI": 0.20,
        "Bollinger Bands": 0.20,
        "MACD": 0.25,
        "EMA": 0.15,
        "OBV": 0.20
    }

    # Initialize final probabilities
    final_probabilities = {"Pump": 0, "Dump": 0}

    # Calculate weighted probabilities
    for indicator, values in probabilities.items():
        pump_prob = values["Pump"] * weightages[indicator]
        dump_prob = values["Dump"] * weightages[indicator]
        
        final_probabilities["Pump"] += pump_prob
        final_probabilities["Dump"] += dump_prob
    
    # Normalize the final probabilities to ensure they sum to 100%
    total = final_probabilities["Pump"] + final_probabilities["Dump"]
    
    # Handle cases where the total sum of probabilities is zero
    if total == 0:
        final_probabilities["Pump"] = 50
        final_probabilities["Dump"] = 50
    else:
        final_probabilities["Pump"] = (final_probabilities["Pump"] / total) * 100
        final_probabilities["Dump"] = (final_probabilities["Dump"] / total) * 100

    # Debugging the final probabilities to ensure they sum up to 100%
    print(f"Final Pump Probability: {final_probabilities['Pump']}%")
    print(f"Final Dump Probability: {final_probabilities['Dump']}%")

    return final_probabilities


# Function to fetch news data from Google News RSS feeds
def fetch_news(coin_name):
    try:
        url = f"https://news.google.com/rss/search?q={coin_name}+cryptocurrency"
        feed = feedparser.parse(url)
        news_items = []
        for entry in feed.entries[:5]:  # Limit to 5 news items
            news_items.append({
                "title": entry.title,
                "link": entry.link,
                "published": entry.published,
            })
        return news_items
    except Exception as e:
        st.error(f"Error fetching news: {e}")
        return []

# Prepare data for LSTM Model
def prepare_lstm_data(df, seq_len=60):
    data = df['Price'].values.reshape(-1, 1)
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_data = scaler.fit_transform(data)

    sequences, labels = [], []
    for i in range(len(scaled_data) - seq_len):
        sequences.append(scaled_data[i:i + seq_len])
        labels.append(scaled_data[i + seq_len])

    return np.array(sequences), np.array(labels), scaler

# Build and train LSTM model
def build_lstm_model(input_shape):
    model = Sequential([
        LSTM(units=50, return_sequences=True, input_shape=input_shape),
        Dropout(0.2),
        LSTM(units=50, return_sequences=False),
        Dropout(0.2),
        Dense(units=25),
        Dense(units=1)
    ])
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model

# Calculate prediction based of LTSM model learning
def calculate_prediction_with_ltsm(symbol="BTC", period="5d", interval="5m"):
    st.write("**Fetched Data...")
    data = get_crypto_data(symbol, period, interval)
    prices = [(pd.to_datetime(index, unit='m'), price) for index, price in data['Close'].items()] 
    df = pd.DataFrame(prices, columns=['Date', 'Price'])

    st.write("**Preparing data for LTSM Model training......(processing)...")
    X, Y, scaler = prepare_lstm_data(df)

    st.write("**Build LTSM Model with X shape data.........(processing)...")
    model = build_lstm_model((X.shape[1], 1))

    # Train the model
    st.write("**Train LTSM Model with X,Y shape data with batch_size(32), epochs(10)............(processing)...")
    model.fit(X, Y, batch_size=32, epochs=10)
    
    # Predict the next price point
    st.write("**Sequence LTSM Model with X,Y shape data with batch_size(32), epochs(10)...............(processing)...")
    last_sequence = X[-1].reshape(1, X.shape[1], 1)

    st.write("**Predict realtime price with  LTSM Model trained with X,Y shape data with batch_size(32), epochs(10)..................(processing)...")
    scaled_prediction = model.predict(last_sequence)
    predicted_price = scaler.inverse_transform(scaled_prediction)

    return predicted_price

# Streamlit App
st.set_page_config(page_title="Crypto Insights ", layout="wide")


# Add styled title with specific color
st.markdown(
    """
    <div style="text-align: center; margin-top: 5px; margin-left: 20px">
        <h1 style="font-size: 2.5em; color: #FFD700;">Crypto Vision</h1>
    </div>
    """,
    unsafe_allow_html=True
)

# Add styled subtitle with lines on both sides and reduced gap
st.markdown(
    """
    <div style="display: flex; align-items: center; justify-content: center; margin-top: 0px;">
        <hr style="width: 20%; border: 1px solid #ccc; margin: 0 5px; height: 1px;">
        <span style="font-size: 1.2em; color: gray; margin: 0;">MARKET ANALYZER</span>
        <hr style="width: 20%; border: 1px solid #ccc; margin: 0 5px; height: 1px;">
    </div>
    """,
    unsafe_allow_html=True
)


# Function to add a background image to the app
def add_background_to_main(image_file):
    page_bg_img = f"""
    <style>
    /* Apply background image to the main container */
    [data-testid="stAppViewContainer"] {{
        background-image: url('data:image/jpeg;base64,{image_file}');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        background-attachment: fixed;
        min-height: 100vh;
        
    }}
    </style>
    """
    st.markdown(page_bg_img, unsafe_allow_html=True)

# Function to encode the image to Base64
def get_base64_of_image(image_path):
    with open(image_path, "rb") as img_file:
        return base64.b64encode(img_file.read()).decode()

# Add the background image (ensure the image file is in the correct path)
image_path = "black.jpeg"  # Replace with your image file name
try:
    encoded_image = get_base64_of_image(image_path)
    add_background_to_main(encoded_image)
except FileNotFoundError:
    st.warning(f"Background image '{image_path}' not found. Please check the file path.")

st.markdown("""
    Welcome to the "Crypto Vision". This tool provides real-time predictions 
    and insights on cryptocurrency price movements using advanced technical indicators like RSI, 
    Bollinger Bands, MACD, and more. Simply enter the cryptocurrency symbol, and our tool will analyze the 
    market data, calculate indicators, and provide you with the probabilities of price movements (pump or dump). 
    Stay ahead in your crypto trading with this powerful tool!
""")

# Add CSS to make the sidebar fixed and apply hover effect on buttons
st.markdown(
    """
   <style>
    /* Make the sidebar always visible and fixed */
    [data-testid="stSidebar"] {
        width: 300px;
        min-width: 300px;
        max-width: 300px;
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        background-color: #2d2d2d;
        padding-top: 20px;
        z-index: 9999;
    }
    [data-testid="collapsedControl"] {
    display: none;
    }
    
    /* Sidebar button hover effect */
    .css-1emrehy.edgvbvh3 {
        background-color: #3e3e3e;
        color: #fff;
        transition: all 0.3s ease;
    }
    .css-1emrehy.edgvbvh3:hover {
        background-color: #FFD700;
        color: black;
    }
    /* Optional: Add padding for better spacing */
    .css-1emrehy.edgvbvh3 {
        margin-bottom: 15px;
        border-radius: 5px;
        padding: 12px;
        font-size: 16px;
        font-weight: bold;
    }
    /* Customize the sidebar header */
    .css-1r6slb0 {
        color: #FFD700;
        font-size: 20px;
        font-weight: bold;
    }
    /* Customizing the text input inside the sidebar */
    .stTextInput input {
        background-color: #3e3e3e;
        color: #fff;
        border: 1px solid #FFD700;
        border-radius: 5px;
        padding: 10px;
    }
    /* Customize the buttons inside the sidebar */
    .stButton button {
        background-color: #3e3e3e;
        color: #fff;
        border-radius: 5px;
        padding: 12px;
        font-size: 16px;
        font-weight: bold;
    }
    .stButton button:hover {
        background-color: #C0C0C0;
        color: black;
    }
    </style>
    """,
    unsafe_allow_html=True
)


# Sidebar for user input
st.sidebar.header("Cryptocurrency Symbol")
symbol = st.sidebar.text_input("Enter Cryptocurrency Symbol (e.g., BTC):", "BTC")

# Add buttons for navigation
show_news_button = st.sidebar.button("Show Latest News")
show_data_button = st.sidebar.button("Show Data and Indicators")
predict_lstm_button = st.sidebar.button("Predict by training LSTM Model")


# Fetch data and news when the button is clicked
if show_data_button:
    if symbol:
        # Fetch data
        data = get_crypto_data(symbol)
        if data.empty:
            st.error(f"No data found for {symbol}. Please check the symbol and try again.")
        else:
            # Display fetched data
            st.write("**Fetched Data:**")
            st.dataframe(data.tail())
            
            # Ensure the DataFrame has enough rows
            if len(data) < 20:
                st.warning(f"Not enough data to calculate indicators. Only {len(data)} rows available. Please try a longer period.")
            else:
                # Calculate probabilities for the next 12 hours
                probabilities, recent_data = calculate_probabilities(data)
                
                # Create a DataFrame for the indicator values
                indicator_values = {
                    "Indicator": ["RSI", "Bollinger Bands", "MACD", "EMA", "OBV"],
                    "Value": [probabilities["RSI"]["Value"], probabilities["Bollinger Bands"]["Value"], probabilities["MACD"]["Value"], probabilities["EMA"]["Value"], probabilities["OBV"]["Value"]],
                }
                
                # Convert dictionary to a DataFrame
                df_indicators = pd.DataFrame(indicator_values)
                
                # Display indicator values in table format
                st.write("### **Indicators and Probabilities Table**:")
                st.dataframe(df_indicators)
                
                # Calculate weighted combined probabilities
                weighted_probabilities = calculate_weighted_probabilities(probabilities)
                
                # Display final combined probability predictions
                st.write("### **Final Predicted Probabilities for the Next 12 Hours:**")
                st.write(f"- **Pump Probability**: {weighted_probabilities['Pump']:.2f}%")
                st.write(f"- **Dump Probability**: {weighted_probabilities['Dump']:.2f}%")
    
elif show_news_button:
    if symbol:
        # Fetch news
        news_items = fetch_news(symbol)
        if news_items:
            st.write("### Latest News:")
            for news_item in news_items:
                st.markdown(f"**{news_item['title']}**: [Read More]({news_item['link']})")
                st.write(f"Published on: {news_item['published']}")
        else:
            st.warning(f"No news found for {symbol}. Please try again later.")

elif predict_lstm_button:
    if symbol:
        # Call the LSTM prediction function based on last 5 days with 5 interval of closing data
        st.markdown(
            """
            <h3 style="color: #FFD700;">Final Predicted Value Learned by training a LSTM Model</h3>
            <p style="font-size: 1.5em; color: #32CD32;">
                ***Based on the last 5 days with 5-minute intervals of closing data***
            </p>
            """, 
            unsafe_allow_html=True
        )
        
        period = "5d"
        interval = "5m"
        predicted_price = calculate_prediction_with_ltsm(symbol, period, interval)

        #st.write("### **Final Predicted value by learned LTSM model based on last 5 days with 5 interval of closing data** ###")
        #st.write(f"**Predicted next realtime price: ${predicted_price[0][0]:.10f}**")

        st.markdown(
            f"""
            <p style="font-size: 2em; font-weight: bold; color: #FF4500;">
                Predicted Next Realtime Price: ${predicted_price[0][0]:.10f}
            </p>
            """, 
            unsafe_allow_html=True
        )