volumes to ticks

This commit is contained in:
Dobromir Popov 2025-03-19 00:06:48 +02:00
parent 158f9ebf71
commit 2beb1d8cef

View File

@ -1321,6 +1321,16 @@ class RealTimeChart:
total_volume = sum(volumes)
avg_volume = total_volume / len(volumes) if volumes else 0
# Calculate additional volume stats
max_volume = max(volumes) if volumes else 0
min_volume = min(volumes) if volumes else 0
median_volume = sorted(volumes)[len(volumes)//2] if volumes else 0
# Calculate trade value in USDT
trade_values = [p * v for p, v in zip(prices, volumes)]
total_value = sum(trade_values)
avg_trade_value = total_value / len(trade_values) if trade_values else 0
first_timestamp = filtered_ticks[0]['timestamp']
last_timestamp = filtered_ticks[-1]['timestamp']
time_span_ms = last_timestamp - first_timestamp
@ -1383,6 +1393,18 @@ class RealTimeChart:
html.Div("Total Volume", style=label_style),
html.Div(f"{total_volume:.8f}", style=value_style),
html.Div(f"Avg: {avg_volume:.8f}", style=label_style)
], style=card_style),
html.Div([
html.Div("Max Volume", style=label_style),
html.Div(f"{max_volume:.8f}", style=value_style),
html.Div("Median: {:.8f}".format(median_volume), style=label_style)
], style=card_style),
html.Div([
html.Div("Total Value", style=label_style),
html.Div(f"{total_value:.2f}", style=value_style),
html.Div(f"Avg: {avg_trade_value:.2f}", style=label_style)
], style=card_style)
]
@ -1499,8 +1521,14 @@ class RealTimeChart:
# Get filtered ticks
filtered_ticks = self.tick_storage.get_ticks_from_time(start_time_ms=start_time)
# Create figure
fig = go.Figure()
# Create figure with 2 subplots - price and volume
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.03,
row_heights=[0.7, 0.3],
subplot_titles=(f"Price Movement (Last {window_seconds // 60} minutes)", "Volume")
)
if not filtered_ticks:
fig.add_annotation(
@ -1516,31 +1544,101 @@ class RealTimeChart:
prices = [tick['price'] for tick in filtered_ticks]
volumes = [tick.get('volume', 0) for tick in filtered_ticks]
# Scale volumes for better visibility
max_volume = max(volumes) if volumes else 1
scaled_volumes = [vol * (max(prices) - min(prices)) / max_volume * 0.2 + min(prices) for vol in volumes]
# Add price line
fig.add_trace(go.Scatter(
# Add price scatter plot
fig.add_trace(
go.Scatter(
x=timestamps,
y=prices,
mode='lines',
name='Price',
line=dict(color='#4CAF50', width=1.5)
))
),
row=1, col=1
)
# Add volume bars
fig.add_trace(go.Bar(
# Create a volume profile on the right side of the price chart
if len(prices) > 5: # Only create profile if we have enough data
# Group prices into bins
price_min = min(prices)
price_max = max(prices)
# Create approximately 20 bins based on price range
bin_size = max(0.01, (price_max - price_min) / 20)
# Create a dictionary to hold volume by price level
volume_by_price = {}
# Group volumes by price bins
for p, v in zip(prices, volumes):
bin_key = round(p / bin_size) * bin_size
if bin_key in volume_by_price:
volume_by_price[bin_key] += v
else:
volume_by_price[bin_key] = v
# Sort by price level
sorted_bins = sorted(volume_by_price.items())
profile_prices = [p for p, _ in sorted_bins]
profile_volumes = [v for _, v in sorted_bins]
# Add separate volume profile trace
fig.add_trace(
go.Bar(
y=profile_prices,
x=profile_volumes,
orientation='h',
name='Volume Profile',
marker=dict(
color=['#33CC33' if p <= latest_price else '#FF4136' for p in profile_prices],
opacity=0.5
),
showlegend=True,
hovertemplate='Price: %{y:.2f}<br>Volume: %{x:.8f}<extra></extra>'
),
row=1, col=1
)
# Add a line marking the latest price
fig.add_shape(
type="line",
y0=latest_price, y1=latest_price,
x0=0, x1=max(profile_volumes) * 1.1,
line=dict(color="yellow", width=1, dash="dash"),
row=1, col=1
)
# Add volume bars in separate subplot
# Color volume bars green for price increases, red for decreases
if len(timestamps) > 1:
# Compare each price with the previous to determine color
colors = []
for i in range(len(prices)):
if i == 0:
colors.append('#33CC33') # Default to green for first tick
else:
if prices[i] >= prices[i-1]:
colors.append('#33CC33') # Green for price increase/same
else:
colors.append('#FF4136') # Red for price decrease
else:
colors = ['#33CC33'] # Default green if only one tick
fig.add_trace(
go.Bar(
x=timestamps,
y=scaled_volumes,
y=volumes,
name='Volume',
marker=dict(color='rgba(128, 128, 255, 0.3)'),
opacity=0.5,
yaxis='y2'
))
marker=dict(color=colors)
),
row=2, col=1
)
# Compute stats for annotations
latest_price = prices[-1] if prices else 0
total_volume = sum(volumes)
max_volume = max(volumes) if volumes else 0
avg_volume = total_volume / len(volumes) if volumes else 0
# Add annotations for latest price
latest_price = prices[-1] if prices else 0
fig.add_annotation(
x=timestamps[-1] if timestamps else 0,
y=latest_price,
@ -1551,41 +1649,63 @@ class RealTimeChart:
arrowwidth=2,
arrowcolor="#4CAF50",
font=dict(size=12, color="#4CAF50"),
xshift=50
xshift=50,
row=1, col=1
)
# Add annotations for volume stats
fig.add_annotation(
x=timestamps[-1] if timestamps else 0,
y=max_volume,
text=f"Max: {max_volume:.8f}",
showarrow=False,
font=dict(size=10, color="rgba(128, 128, 255, 1)"),
xshift=50,
row=2, col=1
)
# Update layout
fig.update_layout(
title=f"{self.symbol} Price Movement (Last {window_seconds // 60} minutes)",
title_text=f"{self.symbol} Tick Data",
title_x=0.5,
xaxis=dict(
title="Time",
showgrid=True,
gridcolor='rgba(128,128,128,0.2)'
),
yaxis=dict(
title="Price (USDT)",
showgrid=True,
gridcolor='rgba(128,128,128,0.2)'
),
yaxis2=dict(
title="Volume",
overlaying='y',
side='right',
showgrid=False,
showticklabels=False
),
template='plotly_dark',
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(25,25,50,1)',
height=500,
margin=dict(l=40, r=40, t=50, b=40),
height=600, # Increased height for better visualization
margin=dict(l=40, r=40, t=80, b=40),
legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=0.01
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
),
hovermode="x unified" # Show all data points at the same x-coordinate
)
# Update x-axis to be shared
fig.update_xaxes(
showgrid=True,
gridwidth=1,
gridcolor='rgba(128,128,128,0.2)',
rangeslider_visible=False
)
# Update y-axes
fig.update_yaxes(
title_text="Price (USDT)",
showgrid=True,
gridwidth=1,
gridcolor='rgba(128,128,128,0.2)',
row=1, col=1
)
fig.update_yaxes(
title_text="Volume",
showgrid=True,
gridwidth=1,
gridcolor='rgba(128,128,128,0.2)',
row=2, col=1
)
return fig