Volume_Profile / volume_footprint_strealitm.py
Reddy7860
Create volume_footprint_strealitm.py
97653a8 unverified
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.")