Spaces:
Sleeping
Sleeping
File size: 9,377 Bytes
79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 79e1719 ffe3438 |
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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
import pandas as pd
import pandas_ta as ta
import streamlit as st
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from modules.technical import TechnicalAnalysis
st.set_page_config(page_title="Technical Analysis", layout="wide")
# Load sample data (replace this with actual data)
data = pd.read_csv('data/brent_futures.csv')
data['Date'] = pd.to_datetime(data['Date'])
data.sort_values('Date', inplace=True)
# crudeData = TechnicalAnalysis('data/brent_futures.csv')
# Streamlit sidebar for user input
st.sidebar.title("Technical Analysis Settings")
# Allow user to choose which technical indicators to display using multiselect
indicators = st.sidebar.multiselect("Select Technical Indicators",
['Simple Moving Average', 'Bollinger Bands', 'RSI', 'MACD', 'Stochastic Oscillator', 'ADX'],
default=['Simple Moving Average'])
# Set lengths for technical indicators
with st.sidebar.expander("Simple Moving Average"):
sma_length = st.number_input('Simple Moving Average Length', min_value=5, max_value=300, value=5, step=1)
with st.sidebar.expander("Bollinger Bands"):
bb_length = st.number_input('Bollinger Bands Length', min_value=5, max_value=300, value=20, step=1)
with st.sidebar.expander("RSI"):
rsi_length = st.number_input('RSI Length', min_value=1, max_value=300, value=5, step=1)
with st.sidebar.expander("MACD"):
macd_fast_length = st.number_input("MACD Fast Length", min_value=5, max_value=300, value=12)
macd_slow_length = st.number_input("MACD Slow Length", min_value=10, max_value=300, value=26)
macd_signal_length = st.number_input("MACD Signal Length", min_value=5, max_value=300, value=9)
with st.sidebar.expander("Stochastic Oscillator"):
stocho_fast_length = st.number_input("Stochastic Oscillator Length", min_value=5, max_value=300, value=14)
stocho_slow_length = st.number_input("Stochastic Oscillator Length", min_value=5, max_value=300, value=28)
with st.sidebar.expander("ADX"):
adx_length = st.number_input("ADX Length", min_value=5, max_value=50, value=14)
# Initialize indicator choices
moving_avg_choice = 'Simple Moving Average' in indicators
bb_choice = 'Bollinger Bands' in indicators
rsi_choice = 'RSI' in indicators
macd_choice = 'MACD' in indicators
stocho_choice = 'Stochastic Oscillator' in indicators
adx_choice = 'ADX' in indicators
# Calculate indicators based on user input
if moving_avg_choice:
data['SMA'] = ta.sma(data['Close'], length=sma_length)
if bb_choice:
bbands = ta.bbands(data['Close'], length=bb_length)
data['BB_upper'], data['BB_middle'], data['BB_lower'] = bbands.iloc[:, 2], bbands.iloc[:, 1], bbands.iloc[:, 0]
if rsi_choice:
data['RSI'] = ta.rsi(data['Close'], length=rsi_length)
if macd_choice:
macd = ta.macd(data['Close'], fast=macd_fast_length, slow=macd_slow_length, signal=macd_signal_length)
data['MACD'], data['MACD_Signal'], data['MACD_Hist'] = macd.iloc[:, 0], macd.iloc[:, 1], macd.iloc[:, 2]
if stocho_choice:
stoch = ta.stoch(data['High'], data['Low'], data['Close'], k=stocho_fast_length, d=stocho_slow_length)
data['Stochastic_k'] = stoch.iloc[:, 0]
data['Stochastic_d'] = stoch.iloc[:, 1]
if adx_choice:
adx = ta.adx(data['High'], data['Low'], data['Close'], length=adx_length)
data['ADX'], data['ADX_DMP'], data['ADX_DMN'] = adx.iloc[:, 0], adx.iloc[:, 1], adx.iloc[:, 2]
# Dynamically calculate the number of rows based on selected options
rows = 1 # OHLC is mandatory
if rsi_choice:
rows += 1
if macd_choice:
rows += 1
if stocho_choice:
rows += 1
if adx_choice:
rows += 1
row_heights = [0.6] + [0.2] * (rows - 1)
# Create a subplot figure
subplot_titles = ['OHLC with Technical Indicators']
if rsi_choice:
subplot_titles.append('RSI')
if macd_choice:
subplot_titles.append('MACD')
if stocho_choice:
subplot_titles.append('Stochastic Oscillator')
if adx_choice:
subplot_titles.append('ADX')
subplot_titles.append('Volume')
fig = make_subplots(
rows=rows + 1, cols=1, # Extra row for Volume
shared_xaxes=True,
vertical_spacing=0.05,
row_heights=row_heights + [0.2],
subplot_titles=subplot_titles
)
# Plot OHLC candlestick
fig.add_trace(go.Candlestick(x=data['Date'], open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], name="OHLC"), row=1, col=1)
# Plot Moving Averages
if moving_avg_choice:
fig.add_trace(go.Scatter(x=data['Date'], y=data['SMA'], mode='lines', name=f'SMA {sma_length}', line=dict(color='blue')), row=1, col=1)
# Plot Bollinger Bands
if bb_choice:
fig.add_trace(go.Scatter(x=data['Date'], y=data['BB_upper'], mode='lines', name='BB Upper', line=dict(color='purple')), row=1, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['BB_middle'], mode='lines', name='BB Middle', line=dict(color='gray')), row=1, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['BB_lower'], mode='lines', name='BB Lower', line=dict(color='purple')), row=1, col=1)
# Plot RSI
if rsi_choice:
fig.add_trace(go.Scatter(x=data['Date'], y=data['RSI'], mode='lines', name=f'RSI {rsi_length}', line=dict(color='magenta')), row=2, col=1)
# Plot MACD
if macd_choice:
macd_row = 2 if not rsi_choice else 3
fig.add_trace(go.Scatter(x=data['Date'], y=data['MACD'], mode='lines', name='MACD', line=dict(color='blue')), row=macd_row, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['MACD_Signal'], mode='lines', name='MACD Signal', line=dict(color='red')), row=macd_row, col=1)
fig.add_trace(go.Bar(x=data['Date'], y=data['MACD_Hist'], name='MACD Hist', marker=dict(color='green')), row=macd_row, col=1)
# Plot Stochastic Oscillator
if stocho_choice:
stocho_row = 2 if not rsi_choice and not macd_choice else (3 if (not rsi_choice) or (not macd_choice) else 4)
fig.add_trace(go.Scatter(x=data['Date'], y=data['Stochastic_k'], mode='lines', name='Stochastic K', line=dict(color='blue')), row=stocho_row, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['Stochastic_d'], mode='lines', name='Stochastic D', line=dict(color='red')), row=stocho_row, col=1)
# Plot ADX
if adx_choice:
adx_row = 2 if not rsi_choice and not macd_choice and not stocho_choice else (
3 if (not macd_choice and not stocho_choice) or (not macd_choice and not rsi_choice) or (not stocho_choice and not rsi_choice) else (
4 if (not stocho_choice) or (not macd_choice) or (not rsi_choice) else 5))
fig.add_trace(go.Scatter(x=data['Date'], y=data['ADX'], mode='lines', name='ADX', line=dict(color='darkgreen')), row=adx_row, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['ADX_DMP'], mode='lines', name='ADX DMP', line=dict(color='lightgreen')), row=adx_row, col=1)
fig.add_trace(go.Scatter(x=data['Date'], y=data['ADX_DMN'], mode='lines', name='ADX DMN', line=dict(color='orange')), row=adx_row, col=1)
# Plot Volume
fig.add_trace(go.Bar(x=data['Date'], y=data['Volume'], name='Volume', marker=dict(color='darkgreen')), row=rows + 1, col=1)
# Customize layout
fig.update_layout(
title='Brent Crude Oil Futures',
height=700,
showlegend=True,
dragmode='pan',
xaxis_rangeslider_visible=False, # Hide default range slider
)
config = {'scrollZoom': True}
# Enable dynamic range for y-axes
fig.update_yaxes(autorange=True)
# Show the plot in Streamlit
st.plotly_chart(fig, config=config)
st.subheader('Technical Analysis Data')
st.dataframe(data)
st.markdown("""
## Notes for improvements
- Add interactive elements to allow users to customize the technical indicators
- Add features such as backtesting, alerts, and notifications, line annotations, etc.
""")
# ta = TechnicalAnalysis('data/brent_futures.csv')
# # Allow user to input settings
# length_ma = st.number_input("Moving Average Length", min_value=2, value=20)
# rsi_button = st.checkbox("Show RSI", value=False)
# bb_button = st.checkbox("Show Bollinger Bands", value=False)
# macd_button = st.checkbox("Show MACD", value=False)
# # Calculate moving average
# ta.moving_average(length=length_ma)
# # Conditionally calculate and show indicators
# if rsi_button:
# ta.rsi()
# if bb_button:
# ta.bollinger_bands()
# if macd_button:
# ta.macd()
# # Fetch the updated data
# data = ta.get_data()
# # Plot data using Plotly
# fig = go.Figure()
# # Add candlestick
# fig.add_trace(go.Candlestick(x=data.index, open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], name='Candlestick'))
# # Add moving average
# fig.add_trace(go.Scatter(x=data.index, y=data[f'MA_{length_ma}'], mode='lines', name=f'MA {length_ma}'))
# # Add indicators if toggled
# if rsi_button:
# fig.add_trace(go.Scatter(x=data.index, y=data[f'RSI_14'], mode='lines', name='RSI'))
# if bb_button:
# fig.add_trace(go.Scatter(x=data.index, y=data['BB_upper'], mode='lines', name='BB Upper'))
# fig.add_trace(go.Scatter(x=data.index, y=data['BB_middle'], mode='lines', name='BB Middle'))
# fig.add_trace(go.Scatter(x=data.index, y=data['BB_lower'], mode='lines', name='BB Lower'))
# if macd_button:
# fig.add_trace(go.Scatter(x=data.index, y=data['MACD'], mode='lines', name='MACD'))
# fig.add_trace(go.Scatter(x=data.index, y=data['MACD_Signal'], mode='lines', name='MACD Signal'))
# # Display the chart
# st.plotly_chart(fig) |