Spaces:
Running
Running
File size: 4,329 Bytes
174e0f0 |
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 |
"""
Volume chart implementations.
"""
import plotly.graph_objects as go
import pandas as pd
import logging
from datetime import datetime
from typing import Dict, Any, Optional, Tuple
from ..config.constants import Y_AXIS_RANGES, FILE_PATHS
from .base_chart import BaseChart
logger = logging.getLogger(__name__)
class VolumeChart(BaseChart):
"""Chart for Volume visualizations."""
def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
"""Create Cumulative Volume bar chart."""
if df.empty:
return self._create_empty_chart("No volume data available")
# Calculate daily volume changes using the new method
daily_data = self.data_processor.calculate_daily_volume_changes(df)
if daily_data.empty:
return self._create_empty_chart("No daily volume data available")
# Create figure
fig = self._create_base_figure()
# Get time range
min_time = daily_data['date'].min()
max_time = daily_data['date'].max()
# Determine bar colors based on daily volume (all bars will be blue for cumulative volume)
bar_colors = ['blue'] * len(daily_data)
# Create custom hover text for bars
bar_hover_text = []
for _, row in daily_data.iterrows():
date_str = row['date'].strftime('%Y-%m-%d')
bar_hover_text.append(
f"Date: {date_str}<br>"
f"Daily Volume: {row['volume']:.2f}<br>"
f"Cumulative Volume: {row['cumulative_volume']:.2f}<br>"
f"Day-over-Day Change: {row['day_over_day_pct']:.1f}%<br>"
f"7-Day SMA: {row['sma_7d']:.1f}%"
)
# Add cumulative volume bar chart
fig.add_trace(
go.Bar(
x=daily_data['date'],
y=daily_data['cumulative_volume'],
marker=dict(
color=bar_colors,
line=dict(width=1, color='black'),
opacity=0.7
),
name='Daily Volume Change',
hovertext=bar_hover_text,
hoverinfo='text',
customdata=daily_data[['volume', 'day_over_day_pct']].values
)
)
# Add 7-Day SMA line
fig.add_trace(
go.Scatter(
x=daily_data['date'],
y=daily_data['sma_7d'],
mode='lines',
line=dict(color='red', width=3),
name='7-Day SMA',
hovertemplate='Date: %{x}<br>7-Day SMA: %{y:.1f}%<extra></extra>',
yaxis='y2'
)
)
# Update layout and axes
self._update_layout(
fig,
title="Daily Volume Change (%) with 7-Day SMA",
y_axis_title="Cumulative Volume"
)
# Update axes
self._update_axes(
fig,
x_range=[min_time, max_time],
y_auto=True
)
# Update primary y-axis to show volume format
fig.update_yaxes(tickformat=".2f")
# Add secondary y-axis for SMA
fig.update_layout(
yaxis2=dict(
title="Percentage Change (%)",
overlaying='y',
side='right',
tickformat=".1f"
)
)
# Save chart
self._save_chart(
fig,
FILE_PATHS['volume_graph_html'],
FILE_PATHS['volume_graph_png']
)
return fig
def generate_volume_visualizations(data_processor=None) -> Tuple[go.Figure, Optional[str]]:
"""Generate Volume visualizations."""
from ..data.data_processor import DataProcessor
if data_processor is None:
data_processor = DataProcessor()
# Fetch data
apr_df, _ = data_processor.fetch_apr_data_from_db()
# Filter for records with volume data
volume_df = apr_df[apr_df['volume'].notna()].copy()
# Create chart
volume_chart = VolumeChart(data_processor)
fig, csv_path = volume_chart.generate_visualization(
volume_df,
csv_filename=FILE_PATHS['volume_csv']
)
return fig, csv_path
|