Update app.py
Browse files
app.py
CHANGED
|
@@ -823,15 +823,11 @@ def update_advanced_technical_chart(indicator, selected_stock, period):
|
|
| 823 |
if indicator == 'RSI':
|
| 824 |
fig = go.Figure()
|
| 825 |
fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], mode='lines', name='RSI', line=dict(color='purple', width=2)))
|
| 826 |
-
# 根據台股慣例修改顏色
|
| 827 |
fig.add_hline(y=70, line_dash="dash", line_color="green", annotation_text="超買線(70)")
|
| 828 |
fig.add_hline(y=30, line_dash="dash", line_color="red", annotation_text="超賣線(30)")
|
| 829 |
fig.add_hline(y=50, line_dash="dot", line_color="gray", annotation_text="中線(50)")
|
| 830 |
-
|
| 831 |
-
# 根據台股慣例修改顏色
|
| 832 |
fig.add_hrect(y0=70, y1=100, fillcolor="green", opacity=0.1)
|
| 833 |
fig.add_hrect(y0=0, y1=30, fillcolor="red", opacity=0.1)
|
| 834 |
-
|
| 835 |
fig.update_layout(
|
| 836 |
title=f'{stock_name} - RSI 相對強弱指標',
|
| 837 |
xaxis_title='日期',
|
|
@@ -841,89 +837,47 @@ def update_advanced_technical_chart(indicator, selected_stock, period):
|
|
| 841 |
)
|
| 842 |
|
| 843 |
elif indicator == 'MACD':
|
| 844 |
-
# 建立兩個垂直排列的子圖,並共享X軸
|
| 845 |
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
|
| 846 |
-
vertical_spacing=0.1,
|
| 847 |
-
row_heights=[0.7, 0.3],
|
| 848 |
-
subplot_titles=('價格走勢', 'MACD 指標'))
|
| 849 |
-
|
| 850 |
-
# --- 上方子圖 (row=1):只繪製價格走勢 ---
|
| 851 |
fig.add_trace(go.Scatter(
|
| 852 |
-
x=data.index,
|
| 853 |
-
y=data['Close'],
|
| 854 |
-
mode='lines',
|
| 855 |
-
name='收盤價',
|
| 856 |
-
line=dict(color='black', width=1.5)
|
| 857 |
), row=1, col=1)
|
| 858 |
-
|
| 859 |
-
# --- 下方子圖 (row=2):繪製所有MACD相關指標 ---
|
| 860 |
-
# 1. MACD 快線 (DIF)
|
| 861 |
fig.add_trace(go.Scatter(
|
| 862 |
-
x=data.index,
|
| 863 |
-
y=data['MACD'],
|
| 864 |
-
mode='lines',
|
| 865 |
-
name='MACD (快線)',
|
| 866 |
-
line=dict(color='blue', width=2)
|
| 867 |
), row=2, col=1)
|
| 868 |
-
|
| 869 |
-
# 2. Signal 慢線 (MACD)
|
| 870 |
fig.add_trace(go.Scatter(
|
| 871 |
-
x=data.index,
|
| 872 |
-
y=data['MACD_Signal'],
|
| 873 |
-
mode='lines',
|
| 874 |
-
name='Signal (慢線)',
|
| 875 |
-
line=dict(color='red', width=2)
|
| 876 |
), row=2, col=1)
|
| 877 |
-
|
| 878 |
-
# 3. Histogram 柱狀圖
|
| 879 |
-
# 根據台股慣例修改顏色
|
| 880 |
colors = ['red' if x >= 0 else 'green' for x in data['MACD_Histogram']]
|
| 881 |
fig.add_trace(go.Bar(
|
| 882 |
-
x=data.index,
|
| 883 |
-
y=data['MACD_Histogram'],
|
| 884 |
-
name='MACD柱狀圖',
|
| 885 |
-
marker_color=colors
|
| 886 |
), row=2, col=1)
|
| 887 |
-
|
| 888 |
-
# 在MACD子圖中添加一條零軸水平線,方便觀察
|
| 889 |
fig.add_hline(y=0, line_dash="dash", line_color="gray", row=2, col=1)
|
| 890 |
-
|
| 891 |
-
# 更新整個圖表的佈局
|
| 892 |
fig.update_layout(
|
| 893 |
title_text=f'{stock_name} - MACD 指數平滑異同移動平均線',
|
| 894 |
-
height=550,
|
| 895 |
legend_title_text='圖例',
|
| 896 |
-
showlegend=True
|
| 897 |
)
|
| 898 |
-
# 隱藏柱狀圖的圖例,因為顏色已經表達了正負值
|
| 899 |
fig.update_traces(showlegend=False, selector=dict(type='bar'))
|
| 900 |
|
| 901 |
elif indicator == 'BB':
|
| 902 |
fig = go.Figure()
|
| 903 |
-
|
| 904 |
-
# 價格線
|
| 905 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 906 |
line=dict(color='black', width=2)))
|
| 907 |
-
|
| 908 |
-
# 布林通道上軌
|
| 909 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], mode='lines', name='上軌',
|
| 910 |
line=dict(color='red', width=1, dash='dash')))
|
| 911 |
-
|
| 912 |
-
# 布林通道中軌
|
| 913 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Middle'], mode='lines', name='中軌(MA20)',
|
| 914 |
line=dict(color='blue', width=1)))
|
| 915 |
-
|
| 916 |
-
# 布林通道下軌
|
| 917 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], mode='lines', name='下軌',
|
| 918 |
line=dict(color='green', width=1, dash='dash')))
|
| 919 |
-
|
| 920 |
-
# 填充通道區域
|
| 921 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], mode='lines',
|
| 922 |
line=dict(color='rgba(0,0,0,0)'), showlegend=False))
|
| 923 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], mode='lines',
|
| 924 |
fill='tonexty', fillcolor='rgba(173,216,230,0.2)',
|
| 925 |
line=dict(color='rgba(0,0,0,0)'), name='布林通道', showlegend=False))
|
| 926 |
-
|
| 927 |
fig.update_layout(
|
| 928 |
title=f'{stock_name} - 布林通道 (20日, 2σ)',
|
| 929 |
xaxis_title='日期',
|
|
@@ -936,28 +890,17 @@ def update_advanced_technical_chart(indicator, selected_stock, period):
|
|
| 936 |
vertical_spacing=0.1,
|
| 937 |
row_heights=[0.6, 0.4],
|
| 938 |
subplot_titles=('價格走勢', 'KD指標'))
|
| 939 |
-
|
| 940 |
-
# 上方:價格線
|
| 941 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 942 |
line=dict(color='black', width=1)), row=1, col=1)
|
| 943 |
-
|
| 944 |
-
# 下方:KD線
|
| 945 |
fig.add_trace(go.Scatter(x=data.index, y=data['K'], mode='lines', name='K線',
|
| 946 |
line=dict(color='blue', width=2)), row=2, col=1)
|
| 947 |
fig.add_trace(go.Scatter(x=data.index, y=data['D'], mode='lines', name='D線',
|
| 948 |
line=dict(color='red', width=2)), row=2, col=1)
|
| 949 |
-
|
| 950 |
-
# KD指標參考線
|
| 951 |
-
# 根據台股慣例修改顏色
|
| 952 |
fig.add_hline(y=80, line_dash="dash", line_color="green", annotation_text="超買線(80)", row=2, col=1)
|
| 953 |
fig.add_hline(y=20, line_dash="dash", line_color="red", annotation_text="超賣線(20)", row=2, col=1)
|
| 954 |
fig.add_hline(y=50, line_dash="dot", line_color="gray", annotation_text="中線(50)", row=2, col=1)
|
| 955 |
-
|
| 956 |
-
# 超買超賣區域
|
| 957 |
-
# 根據台股慣例修改顏色
|
| 958 |
fig.add_hrect(y0=80, y1=100, fillcolor="green", opacity=0.1, row=2, col=1)
|
| 959 |
fig.add_hrect(y0=0, y1=20, fillcolor="red", opacity=0.1, row=2, col=1)
|
| 960 |
-
|
| 961 |
fig.update_layout(
|
| 962 |
title=f'{stock_name} - KD 隨機指標 (9,3,3)',
|
| 963 |
height=500
|
|
@@ -969,26 +912,15 @@ def update_advanced_technical_chart(indicator, selected_stock, period):
|
|
| 969 |
vertical_spacing=0.1,
|
| 970 |
row_heights=[0.6, 0.4],
|
| 971 |
subplot_titles=('價格走勢', '威廉指標 %R'))
|
| 972 |
-
|
| 973 |
-
# 上方:價格線
|
| 974 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 975 |
line=dict(color='black', width=1)), row=1, col=1)
|
| 976 |
-
|
| 977 |
-
# 下方:威廉指標
|
| 978 |
fig.add_trace(go.Scatter(x=data.index, y=data['Williams_R'], mode='lines', name='威廉%R',
|
| 979 |
line=dict(color='purple', width=2)), row=2, col=1)
|
| 980 |
-
|
| 981 |
-
# 威廉指標參考線
|
| 982 |
-
# 根據台股慣例修改顏色
|
| 983 |
fig.add_hline(y=-20, line_dash="dash", line_color="green", annotation_text="超買線(-20)", row=2, col=1)
|
| 984 |
fig.add_hline(y=-80, line_dash="dash", line_color="red", annotation_text="超賣線(-80)", row=2, col=1)
|
| 985 |
fig.add_hline(y=-50, line_dash="dot", line_color="gray", annotation_text="中線(-50)", row=2, col=1)
|
| 986 |
-
|
| 987 |
-
# 超買超賣區域
|
| 988 |
-
# 根據台股慣例修改顏色
|
| 989 |
fig.add_hrect(y0=-20, y1=0, fillcolor="green", opacity=0.1, row=2, col=1)
|
| 990 |
fig.add_hrect(y0=-100, y1=-80, fillcolor="red", opacity=0.1, row=2, col=1)
|
| 991 |
-
|
| 992 |
fig.update_layout(
|
| 993 |
title=f'{stock_name} - 威廉指標 %R (14日)',
|
| 994 |
height=500
|
|
@@ -1000,19 +932,20 @@ def update_advanced_technical_chart(indicator, selected_stock, period):
|
|
| 1000 |
vertical_spacing=0.1,
|
| 1001 |
row_heights=[0.6, 0.4],
|
| 1002 |
subplot_titles=('價格走勢', 'DMI 指標'))
|
|
|
|
| 1003 |
# 過濾掉不穩定的初始數據(通常為14天)
|
| 1004 |
data_filtered = data.iloc[14:]
|
| 1005 |
|
| 1006 |
# 上方:價格線
|
| 1007 |
-
fig.add_trace(go.Scatter(x=
|
| 1008 |
line=dict(color='black', width=1)), row=1, col=1)
|
| 1009 |
|
| 1010 |
# 下方:DMI 線
|
| 1011 |
-
fig.add_trace(go.Scatter(x=
|
| 1012 |
line=dict(color='red', width=2)), row=2, col=1)
|
| 1013 |
-
fig.add_trace(go.Scatter(x=
|
| 1014 |
line=dict(color='green', width=2)), row=2, col=1)
|
| 1015 |
-
fig.add_trace(go.Scatter(x=
|
| 1016 |
line=dict(color='blue', width=2, dash='dot')), row=2, col=1)
|
| 1017 |
|
| 1018 |
# DMI 參考線
|
|
|
|
| 823 |
if indicator == 'RSI':
|
| 824 |
fig = go.Figure()
|
| 825 |
fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], mode='lines', name='RSI', line=dict(color='purple', width=2)))
|
|
|
|
| 826 |
fig.add_hline(y=70, line_dash="dash", line_color="green", annotation_text="超買線(70)")
|
| 827 |
fig.add_hline(y=30, line_dash="dash", line_color="red", annotation_text="超賣線(30)")
|
| 828 |
fig.add_hline(y=50, line_dash="dot", line_color="gray", annotation_text="中線(50)")
|
|
|
|
|
|
|
| 829 |
fig.add_hrect(y0=70, y1=100, fillcolor="green", opacity=0.1)
|
| 830 |
fig.add_hrect(y0=0, y1=30, fillcolor="red", opacity=0.1)
|
|
|
|
| 831 |
fig.update_layout(
|
| 832 |
title=f'{stock_name} - RSI 相對強弱指標',
|
| 833 |
xaxis_title='日期',
|
|
|
|
| 837 |
)
|
| 838 |
|
| 839 |
elif indicator == 'MACD':
|
|
|
|
| 840 |
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
|
| 841 |
+
vertical_spacing=0.1,
|
| 842 |
+
row_heights=[0.7, 0.3],
|
| 843 |
+
subplot_titles=('價格走勢', 'MACD 指標'))
|
|
|
|
|
|
|
| 844 |
fig.add_trace(go.Scatter(
|
| 845 |
+
x=data.index, y=data['Close'], mode='lines', name='收盤價', line=dict(color='black', width=1.5)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 846 |
), row=1, col=1)
|
|
|
|
|
|
|
|
|
|
| 847 |
fig.add_trace(go.Scatter(
|
| 848 |
+
x=data.index, y=data['MACD'], mode='lines', name='MACD (快線)', line=dict(color='blue', width=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 849 |
), row=2, col=1)
|
|
|
|
|
|
|
| 850 |
fig.add_trace(go.Scatter(
|
| 851 |
+
x=data.index, y=data['MACD_Signal'], mode='lines', name='Signal (慢線)', line=dict(color='red', width=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 852 |
), row=2, col=1)
|
|
|
|
|
|
|
|
|
|
| 853 |
colors = ['red' if x >= 0 else 'green' for x in data['MACD_Histogram']]
|
| 854 |
fig.add_trace(go.Bar(
|
| 855 |
+
x=data.index, y=data['MACD_Histogram'], name='MACD柱狀圖', marker_color=colors
|
|
|
|
|
|
|
|
|
|
| 856 |
), row=2, col=1)
|
|
|
|
|
|
|
| 857 |
fig.add_hline(y=0, line_dash="dash", line_color="gray", row=2, col=1)
|
|
|
|
|
|
|
| 858 |
fig.update_layout(
|
| 859 |
title_text=f'{stock_name} - MACD 指數平滑異同移動平均線',
|
| 860 |
+
height=550,
|
| 861 |
legend_title_text='圖例',
|
| 862 |
+
showlegend=True
|
| 863 |
)
|
|
|
|
| 864 |
fig.update_traces(showlegend=False, selector=dict(type='bar'))
|
| 865 |
|
| 866 |
elif indicator == 'BB':
|
| 867 |
fig = go.Figure()
|
|
|
|
|
|
|
| 868 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 869 |
line=dict(color='black', width=2)))
|
|
|
|
|
|
|
| 870 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], mode='lines', name='上軌',
|
| 871 |
line=dict(color='red', width=1, dash='dash')))
|
|
|
|
|
|
|
| 872 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Middle'], mode='lines', name='中軌(MA20)',
|
| 873 |
line=dict(color='blue', width=1)))
|
|
|
|
|
|
|
| 874 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], mode='lines', name='下軌',
|
| 875 |
line=dict(color='green', width=1, dash='dash')))
|
|
|
|
|
|
|
| 876 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], mode='lines',
|
| 877 |
line=dict(color='rgba(0,0,0,0)'), showlegend=False))
|
| 878 |
fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], mode='lines',
|
| 879 |
fill='tonexty', fillcolor='rgba(173,216,230,0.2)',
|
| 880 |
line=dict(color='rgba(0,0,0,0)'), name='布林通道', showlegend=False))
|
|
|
|
| 881 |
fig.update_layout(
|
| 882 |
title=f'{stock_name} - 布林通道 (20日, 2σ)',
|
| 883 |
xaxis_title='日期',
|
|
|
|
| 890 |
vertical_spacing=0.1,
|
| 891 |
row_heights=[0.6, 0.4],
|
| 892 |
subplot_titles=('價格走勢', 'KD指標'))
|
|
|
|
|
|
|
| 893 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 894 |
line=dict(color='black', width=1)), row=1, col=1)
|
|
|
|
|
|
|
| 895 |
fig.add_trace(go.Scatter(x=data.index, y=data['K'], mode='lines', name='K線',
|
| 896 |
line=dict(color='blue', width=2)), row=2, col=1)
|
| 897 |
fig.add_trace(go.Scatter(x=data.index, y=data['D'], mode='lines', name='D線',
|
| 898 |
line=dict(color='red', width=2)), row=2, col=1)
|
|
|
|
|
|
|
|
|
|
| 899 |
fig.add_hline(y=80, line_dash="dash", line_color="green", annotation_text="超買線(80)", row=2, col=1)
|
| 900 |
fig.add_hline(y=20, line_dash="dash", line_color="red", annotation_text="超賣線(20)", row=2, col=1)
|
| 901 |
fig.add_hline(y=50, line_dash="dot", line_color="gray", annotation_text="中線(50)", row=2, col=1)
|
|
|
|
|
|
|
|
|
|
| 902 |
fig.add_hrect(y0=80, y1=100, fillcolor="green", opacity=0.1, row=2, col=1)
|
| 903 |
fig.add_hrect(y0=0, y1=20, fillcolor="red", opacity=0.1, row=2, col=1)
|
|
|
|
| 904 |
fig.update_layout(
|
| 905 |
title=f'{stock_name} - KD 隨機指標 (9,3,3)',
|
| 906 |
height=500
|
|
|
|
| 912 |
vertical_spacing=0.1,
|
| 913 |
row_heights=[0.6, 0.4],
|
| 914 |
subplot_titles=('價格走勢', '威廉指標 %R'))
|
|
|
|
|
|
|
| 915 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='收盤價',
|
| 916 |
line=dict(color='black', width=1)), row=1, col=1)
|
|
|
|
|
|
|
| 917 |
fig.add_trace(go.Scatter(x=data.index, y=data['Williams_R'], mode='lines', name='威廉%R',
|
| 918 |
line=dict(color='purple', width=2)), row=2, col=1)
|
|
|
|
|
|
|
|
|
|
| 919 |
fig.add_hline(y=-20, line_dash="dash", line_color="green", annotation_text="超買線(-20)", row=2, col=1)
|
| 920 |
fig.add_hline(y=-80, line_dash="dash", line_color="red", annotation_text="超賣線(-80)", row=2, col=1)
|
| 921 |
fig.add_hline(y=-50, line_dash="dot", line_color="gray", annotation_text="中線(-50)", row=2, col=1)
|
|
|
|
|
|
|
|
|
|
| 922 |
fig.add_hrect(y0=-20, y1=0, fillcolor="green", opacity=0.1, row=2, col=1)
|
| 923 |
fig.add_hrect(y0=-100, y1=-80, fillcolor="red", opacity=0.1, row=2, col=1)
|
|
|
|
| 924 |
fig.update_layout(
|
| 925 |
title=f'{stock_name} - 威廉指標 %R (14日)',
|
| 926 |
height=500
|
|
|
|
| 932 |
vertical_spacing=0.1,
|
| 933 |
row_heights=[0.6, 0.4],
|
| 934 |
subplot_titles=('價格走勢', 'DMI 指標'))
|
| 935 |
+
|
| 936 |
# 過濾掉不穩定的初始數據(通常為14天)
|
| 937 |
data_filtered = data.iloc[14:]
|
| 938 |
|
| 939 |
# 上方:價格線
|
| 940 |
+
fig.add_trace(go.Scatter(x=data_filtered.index, y=data_filtered['Close'], mode='lines', name='收盤價',
|
| 941 |
line=dict(color='black', width=1)), row=1, col=1)
|
| 942 |
|
| 943 |
# 下方:DMI 線
|
| 944 |
+
fig.add_trace(go.Scatter(x=data_filtered.index, y=data_filtered['+DI'], mode='lines', name='+DI',
|
| 945 |
line=dict(color='red', width=2)), row=2, col=1)
|
| 946 |
+
fig.add_trace(go.Scatter(x=data_filtered.index, y=data_filtered['-DI'], mode='lines', name='-DI',
|
| 947 |
line=dict(color='green', width=2)), row=2, col=1)
|
| 948 |
+
fig.add_trace(go.Scatter(x=data_filtered.index, y=data_filtered['ADX'], mode='lines', name='ADX',
|
| 949 |
line=dict(color='blue', width=2, dash='dot')), row=2, col=1)
|
| 950 |
|
| 951 |
# DMI 參考線
|