volumes to ticks
This commit is contained in:
parent
158f9ebf71
commit
2beb1d8cef
218
realtime.py
218
realtime.py
@ -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 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 price line
|
||||
fig.add_trace(go.Scatter(
|
||||
x=timestamps,
|
||||
y=prices,
|
||||
mode='lines',
|
||||
name='Price',
|
||||
line=dict(color='#4CAF50', width=1.5)
|
||||
))
|
||||
# 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
|
||||
fig.add_trace(go.Bar(
|
||||
x=timestamps,
|
||||
y=scaled_volumes,
|
||||
name='Volume',
|
||||
marker=dict(color='rgba(128, 128, 255, 0.3)'),
|
||||
opacity=0.5,
|
||||
yaxis='y2'
|
||||
))
|
||||
# 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=volumes,
|
||||
name='Volume',
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user