eshan6704 commited on
Commit
b706a05
·
verified ·
1 Parent(s): a86b9f2

Update chart_builder.py

Browse files
Files changed (1) hide show
  1. chart_builder.py +59 -39
chart_builder.py CHANGED
@@ -1,60 +1,80 @@
1
  # chart_builder.py
2
- import pandas as pd
3
- import plotly.graph_objs as go
4
  from plotly.subplots import make_subplots
 
5
 
6
- def build_chart(df, indicators=None):
7
  """
8
- df: OHLCV dataframe
9
- indicators: dict of indicator_name -> DataFrame
10
- Returns HTML string of chart
11
  """
 
12
  fig = make_subplots(
13
- rows=2,
14
  cols=1,
15
  shared_xaxes=True,
16
- row_heights=[0.7, 0.3],
17
  vertical_spacing=0.03,
18
- subplot_titles=("Price & Indicators", "Volume / Subplots")
19
  )
20
 
21
- # Main OHLC
22
  fig.add_trace(go.Candlestick(
23
- x=df.index, open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'], name="Price"
 
24
  ), row=1, col=1)
25
 
26
- # Default volume subplot
 
 
 
 
 
 
 
 
27
  fig.add_trace(go.Bar(
28
- x=df.index, y=df['Volume'], name="Volume", marker_color='lightblue'
29
  ), row=2, col=1)
30
 
31
- # Overlay indicators
32
- if indicators:
33
- for name, ind_df in indicators.items():
34
- if ind_df is None:
35
- continue
36
- if name.lower() in ['sma20','sma50','ema20','ema50','bb_upper','bb_middle','bb_lower','supertrend']:
37
- # Overlay on main chart
38
- for col in ind_df.columns:
39
- fig.add_trace(go.Scatter(
40
- x=ind_df.index, y=ind_df[col], mode='lines', name=col,
41
- visible='legendonly' # hidden by default
42
- ), row=1, col=1)
43
- else:
44
- # Other indicators like MACD/RSI as subplots
45
- for col in ind_df.columns:
46
- fig.add_trace(go.Scatter(
47
- x=ind_df.index, y=ind_df[col], mode='lines', name=col,
48
- visible='legendonly'
49
- ), row=2, col=1)
 
 
 
 
 
 
 
50
 
51
  fig.update_layout(
52
- xaxis_rangeslider_visible=False,
53
- height=800,
54
- template='plotly_dark',
55
- legend=dict(orientation='h', y=1.02)
 
 
 
 
 
 
56
  )
57
 
58
- # Inject JS for toggling indicators (all by legend click)
59
- html_chart = fig.to_html(full_html=False, include_plotlyjs='cdn')
60
- return html_chart
 
1
  # chart_builder.py
2
+ import plotly.graph_objects as go
 
3
  from plotly.subplots import make_subplots
4
+ import pandas as pd
5
 
6
+ def build_chart(df, indicators):
7
  """
8
+ df: OHLCV DataFrame with ['Open','High','Low','Close','Volume']
9
+ indicators: dict from indicater.py
10
+ Returns: HTML string of Plotly chart with JS toggles
11
  """
12
+ # --- Create subplots ---
13
  fig = make_subplots(
14
+ rows=2 + sum(1 for k in indicators if k not in ['SMA_5','SMA_10','SMA_20','SMA_50','EMA_5','EMA_10','EMA_20','EMA_50','Volume']),
15
  cols=1,
16
  shared_xaxes=True,
 
17
  vertical_spacing=0.03,
18
+ row_heights=[0.5, 0.2] + [0.2]*sum(1 for k in indicators if k not in ['SMA_5','SMA_10','SMA_20','SMA_50','EMA_5','EMA_10','EMA_20','EMA_50','Volume'])
19
  )
20
 
21
+ # --- Main Candle Chart ---
22
  fig.add_trace(go.Candlestick(
23
+ x=df.index, open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'],
24
+ name='Price'
25
  ), row=1, col=1)
26
 
27
+ # --- Add MA/EMA overlays on main chart ---
28
+ for key in ['SMA_5','SMA_10','SMA_20','SMA_50','EMA_5','EMA_10','EMA_20','EMA_50']:
29
+ if key in indicators:
30
+ fig.add_trace(go.Scatter(
31
+ x=df.index, y=indicators[key],
32
+ mode='lines', name=key, visible=False # initially hidden
33
+ ), row=1, col=1)
34
+
35
+ # --- Volume subplot ---
36
  fig.add_trace(go.Bar(
37
+ x=df.index, y=df['Volume'], name='Volume'
38
  ), row=2, col=1)
39
 
40
+ # --- Other indicators in separate subplots ---
41
+ row_counter = 3
42
+ for key, series in indicators.items():
43
+ if key in ['SMA_5','SMA_10','SMA_20','SMA_50','EMA_5','EMA_10','EMA_20','EMA_50','Volume']:
44
+ continue
45
+ fig.add_trace(go.Scatter(
46
+ x=df.index, y=series,
47
+ mode='lines', name=key, visible=False
48
+ ), row=row_counter, col=1)
49
+ row_counter += 1
50
+
51
+ fig.update_layout(
52
+ height=600 + 200*(row_counter-3),
53
+ showlegend=True,
54
+ margin=dict(l=40, r=40, t=40, b=40),
55
+ xaxis_rangeslider_visible=False
56
+ )
57
+
58
+ # --- Inject JS buttons to toggle visibility ---
59
+ buttons = []
60
+ for i, trace in enumerate(fig.data):
61
+ buttons.append(dict(
62
+ label=trace.name,
63
+ method='restyle',
64
+ args=['visible', [j==i for j in range(len(fig.data))]],
65
+ ))
66
 
67
  fig.update_layout(
68
+ updatemenus=[dict(
69
+ type="dropdown",
70
+ direction="down",
71
+ buttons=buttons,
72
+ showactive=True,
73
+ x=1.02,
74
+ xanchor="left",
75
+ y=1.15,
76
+ yanchor="top"
77
+ )]
78
  )
79
 
80
+ return fig.to_html(full_html=False)