Spaces:
Configuration error
Configuration error
| import streamlit as st | |
| import pandas as pd | |
| import json | |
| from datetime import datetime, timedelta | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| from scipy.signal import find_peaks | |
| # Title of the app | |
| st.title("File Upload and Timeframe Selection") | |
| # File uploader | |
| uploaded_file = st.file_uploader("Upload a text file") | |
| # Dropdown for timeframe selection | |
| timeframe_options = ["5 seconds", "5 minutes", "1 day"] | |
| timeframe = st.selectbox("Select Timeframe", timeframe_options, index=1) # Default to "5 minutes" | |
| # Date and time picker for base timestamp | |
| base_date = st.date_input("Select Base Date", datetime(2024, 6, 14).date()) | |
| base_time = st.time_input("Select Base Time", datetime.strptime("15:55:00", "%H:%M:%S").time()) | |
| # Combine date and time into a single datetime object | |
| base_timestamp = datetime.combine(base_date, base_time) | |
| # Date picker for subsetting the data | |
| subset_date = st.date_input("Select Subset Date", datetime(2024, 6, 1).date()) | |
| # Define the trading holidays | |
| trading_holidays = [ | |
| datetime(2024, 1, 1), # Monday, January 1 | |
| datetime(2024, 1, 15), # Monday, January 15 | |
| datetime(2024, 2, 19), # Monday, February 19 | |
| datetime(2024, 3, 29), # Friday, March 29 | |
| datetime(2024, 5, 27), # Monday, May 27 | |
| datetime(2024, 6, 19), # Wednesday, June 19 | |
| datetime(2024, 7, 4) # Thursday, July 4 | |
| ] | |
| # Submit button | |
| if st.button("Submit"): | |
| if uploaded_file is not None: | |
| # Read and process the uploaded file | |
| file_content = uploaded_file.read().decode("utf-8") | |
| # Strip everything after the ~m~98~m~ marker | |
| marker = '~m~98~m~' | |
| file_content = file_content.split(marker)[0] | |
| try: | |
| # Load the JSON data from the file content | |
| main_data = json.loads(file_content) | |
| data_section = main_data['p'][1]['st1']['ns']['d'] | |
| # data_section = main_data['p'][1]['st2']['ns']['d'] | |
| nested_data = json.loads(data_section) | |
| footprint_levels = nested_data['graphicsCmds']['create']['footprintLevels'] | |
| df = pd.DataFrame(footprint_levels[0]['data']) | |
| footprints = nested_data['graphicsCmds']['create']['footprints'] | |
| df1 = pd.DataFrame(footprints[0]['data']) | |
| # Display the resulting DataFrame | |
| st.write("Footprint Levels DataFrame:") | |
| st.dataframe(df) | |
| st.write("Footprints DataFrame:") | |
| st.dataframe(df1) | |
| # Initialize the current timestamp with the selected base timestamp | |
| current_timestamp = base_timestamp | |
| # Initialize a dictionary to store timestamps for each index | |
| index_to_timestamp = {max(df1['index']): current_timestamp} | |
| # Market hours | |
| market_open = timedelta(hours=9, minutes=30) | |
| market_close = timedelta(hours=15, minutes=55) | |
| day_increment = timedelta(days=1) | |
| weekend_days = [5, 6] # Saturday and Sunday | |
| # Calculate the timestamps backward in 5-minute intervals, excluding weekends and outside market hours | |
| for index in range(max(df1['index']) - 1, -1, -1): | |
| # Subtract 5 minutes | |
| current_timestamp -= timedelta(minutes=5) | |
| # Check if current timestamp is before market open | |
| while (current_timestamp.time() < (datetime.min + market_open).time() or | |
| current_timestamp.time() > (datetime.min + market_close).time() or | |
| current_timestamp.weekday() in weekend_days or | |
| current_timestamp.date() in [holiday.date() for holiday in trading_holidays]): | |
| # Move to previous trading day if before market open | |
| if current_timestamp.time() < (datetime.min + market_open).time(): | |
| current_timestamp = datetime.combine(current_timestamp.date() - day_increment, (datetime.min + market_close).time()) | |
| else: | |
| # Otherwise, just subtract 5 minutes | |
| current_timestamp -= timedelta(minutes=5) | |
| # Skip weekends and trading holidays | |
| while current_timestamp.weekday() in weekend_days or current_timestamp.date() in [holiday.date() for holiday in trading_holidays]: | |
| current_timestamp -= day_increment | |
| current_timestamp = datetime.combine(current_timestamp.date(), (datetime.min + market_close).time()) | |
| # Assign the calculated timestamp to the index | |
| index_to_timestamp[index] = current_timestamp | |
| # Create a list to hold the time series data | |
| time_series_data = [] | |
| # Iterate over df1 and extract levels data | |
| for i, row in df1.iterrows(): | |
| timestamp = index_to_timestamp.get(row['index']) | |
| if timestamp: | |
| levels = row['levels'] | |
| for level in levels: | |
| time_series_data.append({ | |
| 'timestamp': timestamp, | |
| 'price': level['price'], | |
| 'buyVolume': level['buyVolume'], | |
| 'sellVolume': level['sellVolume'], | |
| 'imbalance': level['imbalance'], | |
| 'index': row['index'] | |
| }) | |
| # Create the dataframe from the time series data | |
| series_df = pd.DataFrame(time_series_data) | |
| series_df['timestamp'] = pd.to_datetime(series_df['timestamp']) | |
| series_df['date'] = series_df['timestamp'].dt.date | |
| # Subset the data based on the selected subset date | |
| subset_df = series_df[series_df['date'] == subset_date] | |
| st.write("Time Series DataFrame (last 20 entries):") | |
| st.dataframe(series_df.tail(20)) | |
| st.write(f"Subset DataFrame (entries on {subset_date}):") | |
| st.dataframe(subset_df) | |
| # Group by timestamp and sum the buyVolume and sellVolume | |
| grouped_df = subset_df.groupby('timestamp').agg({ | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum', | |
| 'price': ['min', 'max'] | |
| }).reset_index() | |
| # Rename columns for clarity | |
| grouped_df.columns = ['timestamp', 'total_buy_volume', 'total_sell_volume', 'min_price', 'max_price'] | |
| # Sort values by timestamp | |
| grouped_df = grouped_df.sort_values(by='timestamp', ascending=True) | |
| # Calculate VWAP | |
| def calculate_vwap(df): | |
| df['cum_volume'] = df['total_buy_volume'] + df['total_sell_volume'] | |
| df['cum_vwap'] = (df['min_price'] * df['total_buy_volume'] + df['max_price'] * df['total_sell_volume']).cumsum() / df['cum_volume'].cumsum() | |
| return df['cum_vwap'] | |
| # Calculate Support and Resistance Levels | |
| def calc_support_resistance(df, window_size=5): | |
| support_levels = [] | |
| resistance_levels = [] | |
| for i in range(len(df)): | |
| if i < window_size: | |
| support_levels.append(np.nan) | |
| resistance_levels.append(np.nan) | |
| continue | |
| window = df.iloc[i-window_size:i] | |
| # Identify support and resistance based on volume peaks and price reversals | |
| buy_peak = window.loc[window['total_buy_volume'].idxmax()] | |
| sell_peak = window.loc[window['total_sell_volume'].idxmax()] | |
| support = buy_peak['min_price'] if buy_peak['min_price'] < df['min_price'].iloc[i] else np.nan | |
| resistance = sell_peak['max_price'] if sell_peak['max_price'] > df['max_price'].iloc[i] else np.nan | |
| support_levels.append(support) | |
| resistance_levels.append(resistance) | |
| return support_levels, resistance_levels | |
| # Calculate VWAP | |
| grouped_df['VWAP'] = calculate_vwap(grouped_df) | |
| # Calculate support and resistance levels | |
| grouped_df['Support'], grouped_df['Resistance'] = calc_support_resistance(grouped_df) | |
| # Plotting with Plotly | |
| fig = go.Figure() | |
| # Add price line | |
| fig.add_trace(go.Scatter(x=grouped_df['timestamp'], y=(grouped_df['min_price'] + grouped_df['max_price'])/2, mode='lines', name='Price')) | |
| # Add VWAP line | |
| fig.add_trace(go.Scatter(x=grouped_df['timestamp'], y=grouped_df['VWAP'], mode='lines', name='VWAP', line=dict(dash='dash'))) | |
| # Add support levels | |
| fig.add_trace(go.Scatter(x=grouped_df['timestamp'], y=grouped_df['Support'], mode='markers', name='Support', | |
| marker=dict(color='green', size=5, symbol='triangle-up'))) | |
| # Add resistance levels | |
| fig.add_trace(go.Scatter(x=grouped_df['timestamp'], y=grouped_df['Resistance'], mode='markers', name='Resistance', | |
| marker=dict(color='red', size=5, symbol='triangle-down'))) | |
| # Add buy imbalance markers | |
| buy_imbalance = subset_df[subset_df['imbalance'] == 'buy'] | |
| fig.add_trace(go.Scatter(x=buy_imbalance['timestamp'], y=buy_imbalance['price'], mode='markers', name='Buy Imbalance', | |
| marker=dict(color='blue', size=5, symbol='circle'))) | |
| # Add sell imbalance markers | |
| sell_imbalance = subset_df[subset_df['imbalance'] == 'sell'] | |
| fig.add_trace(go.Scatter(x=sell_imbalance['timestamp'], y=sell_imbalance['price'], mode='markers', name='Sell Imbalance', | |
| marker=dict(color='orange', size=5, symbol='circle'))) | |
| # Update layout | |
| fig.update_layout( | |
| title='Price with Support and Resistance Levels based on Volume and Imbalance', | |
| xaxis_title='Time', | |
| yaxis_title='Price', | |
| xaxis=dict( | |
| tickformat='%H:%M\n%b %d', | |
| tickmode='linear', | |
| dtick=300000 # 5 minutes in milliseconds | |
| ), | |
| template='plotly_dark' | |
| ) | |
| # Show the plot | |
| st.plotly_chart(fig) | |
| # Additional chart for buy and sell volumes at each price point | |
| # Sum up the buy and sell volumes at each price point | |
| volume_df = subset_df.groupby(['timestamp', 'price']).agg({ | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum' | |
| }).reset_index() | |
| # Calculate the sum of buy and sell volumes at each timestamp | |
| volume_sum_df = subset_df.groupby('timestamp').agg({ | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum' | |
| }).reset_index() | |
| # Create the figure | |
| fig2 = go.Figure() | |
| # Add the price line | |
| fig2.add_trace(go.Scatter(x=volume_df['timestamp'], y=volume_df['price'], mode='lines', name='Price', line=dict(color='blue'))) | |
| # Add buy volumes as green markers | |
| fig2.add_trace(go.Scatter(x=volume_df['timestamp'], y=volume_df['price'], mode='markers', name='Buy Volume', | |
| marker=dict(color='green', size=volume_df['buyVolume'] / 1000, symbol='circle'), opacity=0.6)) | |
| # Add sell volumes as red markers | |
| fig2.add_trace(go.Scatter(x=volume_df['timestamp'], y=volume_df['price'], mode='markers', name='Sell Volume', | |
| marker=dict(color='red', size=volume_df['sellVolume'] / 1000, symbol='circle'), opacity=0.6)) | |
| # Add secondary y-axis for volume sums | |
| fig2.add_trace(go.Bar(x=volume_sum_df['timestamp'], y=volume_sum_df['buyVolume'], name='Total Buy Volume', | |
| marker=dict(color='green'), yaxis='y2')) | |
| fig2.add_trace(go.Bar(x=volume_sum_df['timestamp'], y=volume_sum_df['sellVolume'], name='Total Sell Volume', | |
| marker=dict(color='red'), yaxis='y2')) | |
| # Update layout for secondary y-axis | |
| fig2.update_layout( | |
| title='Buy and Sell Volumes at Each Price Point', | |
| xaxis_title='Time', | |
| yaxis_title='Price', | |
| yaxis2=dict(title='Volume', overlaying='y', side='right'), | |
| template='plotly_dark', | |
| barmode='stack', | |
| bargap=0.2 | |
| ) | |
| # Show the plot | |
| st.plotly_chart(fig2) | |
| # Third chart: Candlestick with highlighted candles | |
| # Sum up the buy and sell volumes at each price point | |
| volume_df = subset_df.groupby(['timestamp', 'price']).agg({ | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum' | |
| }).reset_index() | |
| # Calculate the sum of buy and sell volumes at each timestamp | |
| volume_sum_df = subset_df.groupby('timestamp').agg({ | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum' | |
| }).reset_index() | |
| temp_volume_df = volume_df | |
| temp_volume_df['timestamp'] = pd.to_datetime(temp_volume_df['timestamp']) | |
| # Group by timestamp and calculate the min and max price for each timestamp | |
| grouped_prices = temp_volume_df.groupby('timestamp').agg( | |
| maxprice=('price', 'max'), | |
| minprice=('price', 'min') | |
| ).reset_index() | |
| # Merge the grouped prices back into the original dataframe | |
| temp_volume_df = temp_volume_df.merge(grouped_prices, on='timestamp', how='left') | |
| # Function to calculate volumes at min and max prices for each timestamp | |
| def calculate_volumes(group): | |
| min_price = group['minprice'].iloc[0] | |
| max_price = group['maxprice'].iloc[0] | |
| min_price_data = group[group['price'] == min_price] | |
| max_price_data = group[group['price'] == max_price] | |
| min_buy_volume = min_price_data['buyVolume'].sum() | |
| min_sell_volume = min_price_data['sellVolume'].sum() | |
| max_buy_volume = max_price_data['buyVolume'].sum() | |
| max_sell_volume = max_price_data['sellVolume'].sum() | |
| group['minPricebuyVolume'] = min_buy_volume | |
| group['minPricesellVolume'] = min_sell_volume | |
| group['maxPricebuyVolume'] = max_buy_volume | |
| group['maxPricesellVolume'] = max_sell_volume | |
| return group | |
| # Apply the function to calculate volumes for each group | |
| temp_volume_df = temp_volume_df.groupby('timestamp').apply(calculate_volumes).reset_index(drop=True) | |
| # Calculate the min and max price for each timestamp and the total buy/sell volume | |
| candlestick_data = temp_volume_df.groupby('timestamp').agg({ | |
| 'price': ['min', 'max'], | |
| 'buyVolume': 'sum', | |
| 'sellVolume': 'sum', | |
| 'minPricebuyVolume': 'first', | |
| 'minPricesellVolume': 'first', | |
| 'maxPricebuyVolume': 'first', | |
| 'maxPricesellVolume': 'first' | |
| }) | |
| candlestick_data.columns = [ | |
| 'low', 'high', 'totalBuyVolume', 'totalSellVolume', | |
| 'MinPricebuyVolume', 'MinPricesellVolume', | |
| 'MaxPricebuyVolume', 'MaxPricesellVolume' | |
| ] | |
| candlestick_data.reset_index(inplace=True) | |
| # Create the candlestick chart | |
| fig3 = go.Figure() | |
| for i, row in candlestick_data.iterrows(): | |
| color = 'red' if (row['MinPricebuyVolume'] != 0) else 'blue' | |
| color = 'green' if (row['MaxPricesellVolume'] != 0) else 'blue' | |
| fig3.add_trace(go.Candlestick( | |
| x=[row['timestamp']], | |
| open=[row['low']], | |
| high=[row['high']], | |
| low=[row['low']], | |
| close=[row['high']], | |
| increasing_line_color=color, | |
| decreasing_line_color=color, | |
| showlegend=False | |
| )) | |
| fig3.update_layout( | |
| title='Candlestick Chart with Highlighted Candles', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price' | |
| ) | |
| st.plotly_chart(fig3) | |
| # Fourth chart: Volume Clusters | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| # Group by price to calculate total buy and sell volumes at each price level | |
| volume_by_price = volume_df.groupby('price').agg( | |
| totalBuyVolume=('buyVolume', 'sum'), | |
| totalSellVolume=('sellVolume', 'sum') | |
| ).reset_index() | |
| # Calculate the min and max price for each timestamp for the candlestick chart | |
| candlestick_data = volume_df.groupby('timestamp').agg( | |
| open=('price', 'first'), | |
| high=('price', 'max'), | |
| low=('price', 'min'), | |
| close=('price', 'last') | |
| ).reset_index() | |
| # Plot the candlestick chart | |
| fig4 = go.Figure(data=[go.Candlestick( | |
| x=candlestick_data['timestamp'], | |
| open=candlestick_data['open'], | |
| high=candlestick_data['high'], | |
| low=candlestick_data['low'], | |
| close=candlestick_data['close'] | |
| )]) | |
| # Add buy volume clusters | |
| fig4.add_trace(go.Bar( | |
| x=volume_by_price['totalBuyVolume'], | |
| y=volume_by_price['price'], | |
| orientation='h', | |
| marker=dict(color='green', opacity=0.5), | |
| name='Buy Volume', | |
| xaxis='x2' | |
| )) | |
| # Add sell volume clusters | |
| fig4.add_trace(go.Bar( | |
| x=volume_by_price['totalSellVolume'], | |
| y=volume_by_price['price'], | |
| orientation='h', | |
| marker=dict(color='red', opacity=0.5), | |
| name='Sell Volume', | |
| xaxis='x2' | |
| )) | |
| # Update layout to include secondary x-axis and adjust the size | |
| fig4.update_layout( | |
| title='Candlestick Chart with Volume Clusters', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| xaxis2=dict(title='Volume', overlaying='x', side='top'), | |
| barmode='overlay', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig4) | |
| # Fifth chart: Candlestick with HVNs and LVNs | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| # Group by price to calculate total buy and sell volumes at each price level | |
| volume_by_price = volume_df.groupby('price').agg( | |
| totalBuyVolume=('buyVolume', 'sum'), | |
| totalSellVolume=('sellVolume', 'sum') | |
| ).reset_index() | |
| # Identify High Volume Nodes (HVNs) and Low Volume Nodes (LVNs) | |
| threshold_high = volume_by_price['totalBuyVolume'].quantile(0.75) | |
| threshold_low = volume_by_price['totalBuyVolume'].quantile(0.25) | |
| hvns = volume_by_price[volume_by_price['totalBuyVolume'] >= threshold_high] | |
| lvns = volume_by_price[volume_by_price['totalBuyVolume'] <= threshold_low] | |
| # Calculate the min and max price for each timestamp for the candlestick chart | |
| candlestick_data = volume_df.groupby('timestamp').agg( | |
| open=('price', 'first'), | |
| high=('price', 'max'), | |
| low=('price', 'min'), | |
| close=('price', 'last') | |
| ).reset_index() | |
| # Plot the candlestick chart | |
| fig5 = go.Figure(data=[go.Candlestick( | |
| x=candlestick_data['timestamp'], | |
| open=candlestick_data['open'], | |
| high=candlestick_data['high'], | |
| low=candlestick_data['low'], | |
| close=candlestick_data['close'] | |
| )]) | |
| # Add HVNs | |
| fig5.add_trace(go.Scatter( | |
| x=hvns['totalBuyVolume'], | |
| y=hvns['price'], | |
| mode='markers', | |
| marker=dict(color='blue', size=10), | |
| name='High Volume Nodes (HVNs)', | |
| xaxis='x2' | |
| )) | |
| # Add LVNs | |
| fig5.add_trace(go.Scatter( | |
| x=lvns['totalBuyVolume'], | |
| y=lvns['price'], | |
| mode='markers', | |
| marker=dict(color='yellow', size=10), | |
| name='Low Volume Nodes (LVNs)', | |
| xaxis='x2' | |
| )) | |
| # Add support and resistance lines based on HVNs | |
| for price in hvns['price']: | |
| fig5.add_hline(y=price, line=dict(color='green', dash='dash'), name=f'Resistance {price}') | |
| # Add potential breakout/breakdown zones based on LVNs | |
| for price in lvns['price']: | |
| fig5.add_hline(y=price, line=dict(color='red', dash='dash'), name=f'Breakout/Breakdown {price}') | |
| # Update layout to include secondary x-axis and adjust the size | |
| fig5.update_layout( | |
| title='Candlestick Chart with HVNs, LVNs, Support and Resistance', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| xaxis2=dict(title='Volume', overlaying='x', side='top'), | |
| barmode='overlay', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig5) | |
| # Sixth chart: Delta (Buy Volume - Sell Volume) by Price and Timestamp | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| # Calculate delta (buy volume - sell volume) for each price level | |
| volume_df['delta'] = volume_df['buyVolume'] - volume_df['sellVolume'] | |
| # Group by timestamp and price to calculate total delta at each price level | |
| delta_by_price = volume_df.groupby(['timestamp', 'price']).agg( | |
| totalDelta=('delta', 'sum') | |
| ).reset_index() | |
| # Plot delta with x axis as timestamp, y axis as price and delta at those prices | |
| fig6 = go.Figure(data=go.Heatmap( | |
| x=delta_by_price['timestamp'], | |
| y=delta_by_price['price'], | |
| z=delta_by_price['totalDelta'], | |
| colorscale='RdYlGn', | |
| colorbar=dict(title='Delta') | |
| )) | |
| # Update layout to adjust the size | |
| fig6.update_layout( | |
| title='Delta (Buy Volume - Sell Volume) by Price and Timestamp', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig6) | |
| # Seventh chart: Candlestick Chart with Top 5 Market Absorptions | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| # Calculate the min and max price for each timestamp | |
| candlestick_data = volume_df.groupby('timestamp').agg({'price': ['min', 'max']}) | |
| candlestick_data.columns = ['low', 'high'] | |
| candlestick_data.reset_index(inplace=True) | |
| # Calculate total volume (buyVolume + sellVolume) for each price level | |
| volume_df['totalVolume'] = volume_df['buyVolume'] + volume_df['sellVolume'] | |
| # Identify the top 5 prices with the highest market absorption (totalVolume) for the entire day | |
| top_absorptions = volume_df.nlargest(5, 'totalVolume') | |
| # Create the candlestick chart | |
| fig7 = go.Figure(data=[go.Candlestick( | |
| x=candlestick_data['timestamp'], | |
| low=candlestick_data['low'], | |
| high=candlestick_data['high'], | |
| open=candlestick_data['low'], | |
| close=candlestick_data['high'] | |
| )]) | |
| # Plot top 5 market absorptions as lines | |
| for _, row in top_absorptions.iterrows(): | |
| fig7.add_shape( | |
| type="line", | |
| x0=row['timestamp'], | |
| y0=row['price'], | |
| x1=row['timestamp'] + pd.Timedelta(minutes=30), # Adjust the end point as needed | |
| y1=row['price'], | |
| line=dict(color="Purple", width=2), | |
| name='Top Market Absorption' | |
| ) | |
| fig7.update_layout( | |
| title='Candlestick Chart with Top 5 Market Absorptions', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig7) | |
| # Eighth chart: Aggressive Orders + Delta Setup | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| volume_df['delta'] = volume_df['buyVolume'] - volume_df['sellVolume'] | |
| # Step 1: Identify strong Support/Resistance zones (for simplicity, we'll set static S/R zones) | |
| support_zone = 250.59 | |
| resistance_zone = 253.40 | |
| # Step 2: Analyze Order Flow data to identify aggressive orders near S/R zones | |
| aggressive_orders = volume_df[ | |
| ((volume_df['price'] <= support_zone) & (volume_df['buyVolume'] > volume_df['sellVolume'])) | | |
| ((volume_df['price'] >= resistance_zone) & (volume_df['sellVolume'] > volume_df['buyVolume'])) | |
| ] | |
| # Step 3: Confirm trades with Delta values | |
| trades = [] | |
| for _, row in aggressive_orders.iterrows(): | |
| if row['price'] <= support_zone and row['delta'] > 0: | |
| trades.append((row['timestamp'], row['price'], 'Long')) | |
| elif row['price'] >= resistance_zone and row['delta'] < 0: | |
| trades.append((row['timestamp'], row['price'], 'Short')) | |
| trades_df = pd.DataFrame(trades, columns=['timestamp', 'price', 'direction']) | |
| # Create the candlestick chart | |
| candlestick_data = volume_df.groupby('timestamp').agg({'price': ['min', 'max']}) | |
| candlestick_data.columns = ['low', 'high'] | |
| candlestick_data.reset_index(inplace=True) | |
| fig8 = go.Figure(data=[go.Candlestick( | |
| x=candlestick_data['timestamp'], | |
| low=candlestick_data['low'], | |
| high=candlestick_data['high'], | |
| open=candlestick_data['low'], | |
| close=candlestick_data['high'] | |
| )]) | |
| # Add Support/Resistance zones | |
| fig8.add_shape( | |
| type="rect", | |
| x0=volume_df['timestamp'].min(), | |
| y0=support_zone - 0.05, | |
| x1=volume_df['timestamp'].max(), | |
| y1=support_zone + 0.05, | |
| fillcolor="Green", | |
| opacity=0.2, | |
| line_width=0, | |
| name='Support Zone' | |
| ) | |
| fig8.add_shape( | |
| type="rect", | |
| x0=volume_df['timestamp'].min(), | |
| y0=resistance_zone - 0.05, | |
| x1=volume_df['timestamp'].max(), | |
| y1=resistance_zone + 0.05, | |
| fillcolor="Red", | |
| opacity=0.2, | |
| line_width=0, | |
| name='Resistance Zone' | |
| ) | |
| # Add trades to the chart | |
| for _, trade in trades_df.iterrows(): | |
| color = 'green' if trade['direction'] == 'Long' else 'red' | |
| fig8.add_trace(go.Scatter( | |
| x=[trade['timestamp']], | |
| y=[trade['price']], | |
| mode='markers+text', | |
| marker=dict(color=color, size=10), | |
| text=trade['direction'], | |
| textposition='top center', | |
| name=trade['direction'] | |
| )) | |
| fig8.update_layout( | |
| title='Aggressive Orders + Delta Setup', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig8) | |
| # Ninth chart: Cumulative Delta Confirmation Setup | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| volume_df['delta'] = volume_df['buyVolume'] - volume_df['sellVolume'] | |
| volume_df['cumDelta'] = volume_df['delta'].cumsum() | |
| # Step 1: Identify strong Support/Resistance zones (for simplicity, we'll set static S/R zones) | |
| support_zone = 253.10 | |
| resistance_zone = 253.50 | |
| # Step 2: Create a Cumulative Delta line chart | |
| cum_delta_trace = go.Scatter( | |
| x=volume_df['timestamp'], | |
| y=volume_df['cumDelta'], | |
| mode='lines', | |
| name='Cumulative Delta', | |
| line=dict(color='blue') | |
| ) | |
| # Step 3: Identify divergences between Price and Cum. Delta | |
| divergences = [] | |
| for i in range(1, len(volume_df)): | |
| if volume_df['price'].iloc[i] > volume_df['price'].iloc[i-1] and volume_df['cumDelta'].iloc[i] < volume_df['cumDelta'].iloc[i-1]: | |
| divergences.append((volume_df['timestamp'].iloc[i], volume_df['price'].iloc[i], 'Short')) | |
| elif volume_df['price'].iloc[i] < volume_df['price'].iloc[i-1] and volume_df['cumDelta'].iloc[i] > volume_df['cumDelta'].iloc[i-1]: | |
| divergences.append((volume_df['timestamp'].iloc[i], volume_df['price'].iloc[i], 'Long')) | |
| divergences_df = pd.DataFrame(divergences, columns=['timestamp', 'price', 'direction']) | |
| # Create the candlestick chart | |
| candlestick_data = volume_df.groupby('timestamp').agg({'price': ['min', 'max']}) | |
| candlestick_data.columns = ['low', 'high'] | |
| candlestick_data.reset_index(inplace=True) | |
| fig9 = go.Figure(data=[go.Candlestick( | |
| x=candlestick_data['timestamp'], | |
| low=candlestick_data['low'], | |
| high=candlestick_data['high'], | |
| open=candlestick_data['low'], | |
| close=candlestick_data['high'], | |
| name='Price' | |
| )]) | |
| # Add Cumulative Delta line chart | |
| fig9.add_trace(cum_delta_trace) | |
| # Add Support/Resistance zones | |
| fig9.add_shape( | |
| type="rect", | |
| x0=volume_df['timestamp'].min(), | |
| y0=support_zone - 0.05, | |
| x1=volume_df['timestamp'].max(), | |
| y1=support_zone + 0.05, | |
| fillcolor="Green", | |
| opacity=0.2, | |
| line_width=0, | |
| name='Support Zone' | |
| ) | |
| fig9.add_shape( | |
| type="rect", | |
| x0=volume_df['timestamp'].min(), | |
| y0=resistance_zone - 0.05, | |
| x1=volume_df['timestamp'].max(), | |
| y1=resistance_zone + 0.05, | |
| fillcolor="Red", | |
| opacity=0.2, | |
| line_width=0, | |
| name='Resistance Zone' | |
| ) | |
| # Add divergences to the chart | |
| for _, divergence in divergences_df.iterrows(): | |
| color = 'green' if divergence['direction'] == 'Long' else 'red' | |
| fig9.add_trace(go.Scatter( | |
| x=[divergence['timestamp']], | |
| y=[divergence['price']], | |
| mode='markers+text', | |
| marker=dict(color=color, size=10), | |
| text=divergence['direction'], | |
| textposition='top center', | |
| name=divergence['direction'] | |
| )) | |
| fig9.update_layout( | |
| title='Cumulative Delta Confirmation Setup', | |
| xaxis_title='Timestamp', | |
| yaxis_title='Price', | |
| width=1200, | |
| height=800 | |
| ) | |
| st.plotly_chart(fig9) | |
| # Tenth chart: Volume Profile Shape Identification | |
| volume_df['timestamp'] = pd.to_datetime(volume_df['timestamp']) | |
| volume_df['totalVolume'] = volume_df['buyVolume'] + volume_df['sellVolume'] | |
| # Group by price to get the total volume for each price level | |
| volume_profile = volume_df.groupby('price').agg(totalVolume=('totalVolume', 'sum')).reset_index() | |
| # Identify peaks in the volume profile | |
| volumes = volume_profile['totalVolume'].values | |
| prices = volume_profile['price'].values | |
| peaks, _ = find_peaks(volumes, distance=1) | |
| # Determine the shape | |
| shape = "" | |
| if len(peaks) == 1: | |
| shape = "I-shape" | |
| elif len(peaks) == 2: | |
| shape = "B-shape" | |
| else: | |
| if peaks[0] < len(volumes) / 3: | |
| shape = "P-shape" | |
| elif peaks[-1] > 2 * len(volumes) / 3: | |
| shape = "B-shape" | |
| else: | |
| shape = "D-shape" | |
| # Create the volume profile bar chart | |
| fig10 = go.Figure() | |
| fig10.add_trace(go.Bar( | |
| x=volume_profile['totalVolume'], | |
| y=volume_profile['price'], | |
| orientation='h', | |
| marker=dict(color='blue'), | |
| name='Volume Profile' | |
| )) | |
| # Add peaks to the chart | |
| fig10.add_trace(go.Scatter( | |
| x=volumes[peaks], | |
| y=prices[peaks], | |
| mode='markers', | |
| marker=dict(color='red', size=10), | |
| name='Peaks' | |
| )) | |
| fig10.update_layout( | |
| title=f'Volume Profile Shape: {shape}', | |
| xaxis_title='Volume', | |
| yaxis_title='Price', | |
| width=800, | |
| height=600 | |
| ) | |
| st.plotly_chart(fig10) | |
| except json.JSONDecodeError: | |
| st.write("Error: The uploaded file does not contain valid JSON data.") | |
| except KeyError as e: | |
| st.write(f"Error: Key {e} not found in the JSON data.") | |
| else: | |
| st.write("Please upload a file before submitting.") | |