eshan6704 commited on
Commit
91633f0
·
verified ·
1 Parent(s): 11f39a0

Update chart_builder.py

Browse files
Files changed (1) hide show
  1. chart_builder.py +51 -58
chart_builder.py CHANGED
@@ -1,80 +1,73 @@
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)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # chart_builder.py
2
+ import plotly.graph_objs as go
3
  from plotly.subplots import make_subplots
4
  import pandas as pd
5
 
6
+ def build_chart(data, indicators):
7
  """
8
+ data: pd.DataFrame with OHLCV
9
+ indicators: dict of series (MACD, RSI, SMA20, etc.)
 
10
  """
 
11
  fig = make_subplots(
12
+ rows=3, cols=1,
13
+ row_heights=[0.5, 0.2, 0.3],
14
  shared_xaxes=True,
15
+ vertical_spacing=0.02,
16
+ specs=[[{"type":"candlestick"}],
17
+ [{"type":"bar"}],
18
+ [{"type":"scatter"}]] # indicator plot
19
  )
20
 
21
+ # --- Main candlestick ---
22
  fig.add_trace(go.Candlestick(
23
+ x=data.index,
24
+ open=data['Open'], high=data['High'],
25
+ low=data['Low'], close=data['Close'],
26
+ name='Candlestick'
27
  ), row=1, col=1)
28
 
29
+ # --- Add MA overlays on main chart ---
30
+ for ma_name in ['SMA20','SMA50','EMA20','EMA50']:
31
+ if ma_name in indicators:
32
  fig.add_trace(go.Scatter(
33
+ x=data.index, y=indicators[ma_name],
34
+ mode='lines', name=ma_name,
35
+ visible='legendonly' # initially hidden, toggle via legend or script
36
  ), row=1, col=1)
37
 
38
  # --- Volume subplot ---
39
  fig.add_trace(go.Bar(
40
+ x=data.index, y=data['Volume'],
41
+ name='Volume', marker_color='blue'
42
  ), row=2, col=1)
43
 
44
+ # --- Single indicator subplot (default empty, user selects via checkbox) ---
45
+ for ind_name in ['MACD', 'RSI', 'Stochastic']:
46
+ if ind_name in indicators:
47
+ fig.add_trace(go.Scatter(
48
+ x=data.index, y=indicators[ind_name],
49
+ mode='lines', name=ind_name,
50
+ visible=False # initially hidden, toggle via script
51
+ ), row=3, col=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ fig.update_layout(height=900, showlegend=True, margin=dict(l=20,r=20,t=40,b=20))
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ # --- Inject script for checkbox toggle ---
56
+ script = """
57
+ <script>
58
+ function applyIndicators() {
59
+ var checkboxes = document.querySelectorAll('input.indicator-toggle');
60
+ var update = {visible: []};
61
+ var traces = document.querySelectorAll('g.cartesianlayer .main-svg > g');
62
+ checkboxes.forEach(function(cb, i){
63
+ var idx = parseInt(cb.dataset.trace);
64
+ update.visible[idx] = cb.checked;
65
+ });
66
+ Plotly.restyle('chart', update);
67
+ }
68
+ </script>
69
+ """
70
+
71
+ # Return full HTML
72
+ chart_html = fig.to_html(full_html=False, include_plotlyjs=True, div_id="chart")
73
+ return chart_html + script