File size: 4,851 Bytes
0fc066d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
daa47a2
 
 
 
 
 
 
 
 
 
 
 
 
7fbad64
daa47a2
 
0fc066d
 
 
ba2f4fe
 
abe8703
ba2f4fe
 
0fc066d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ba2f4fe
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
import pandas as pd
import plotly.graph_objects as go
import pygwalker as pyg
import streamlit as st
import streamlit.components.v1 as components
import yfinance as yf
from plotly.subplots import make_subplots
from scipy.stats import norm

from utils.helper import *

# Streamlit app layout
st.set_page_config(layout="wide")
st.title("📊 Technical Trading Strategy Simulation 💹")


# Sidebar inputs
ticker = st.sidebar.text_input("Enter Stock Ticker", "AAPL").upper()
start_date = st.sidebar.date_input("Start Date", pd.to_datetime("2020-01-01"))
end_date = st.sidebar.date_input("End Date", pd.to_datetime("today"))

# Add sidebar slider for selecting two integers
st.sidebar.success("Please  select your own parameters.")

# Expander
with st.expander("Expand to fine tune the windows:"):
    short_window = st.sidebar.slider(
        "Select short window size", min_value=2, max_value=200, value=20
    )
    long_window = st.sidebar.slider(
        "Select long window size", min_value=2, max_value=250, value=95
    )
    signal_window = st.sidebar.slider(
        "Select signal window size", min_value=2, max_value=250, value=9
    )
    values = st.sidebar.slider(
        "Select a range of values", min_value=-100, max_value=100, value=(-10, 10), step=1
    )

option = st.sidebar.selectbox(
    "How would you like rescale data?", ("Original", "Normalization", "Percentile")
)
st.sidebar.markdown(
    f"""
    ## URL of the app: [here](https://huggingface.co/spaces/eagle0504/technical-trader).
    """
)

# Add submit button in the sidebar
submit_button = st.sidebar.button("Submit")

# Update to execute changes only when the submit button is clicked
if submit_button:
    with st.spinner("Wait for it..."):
        # Message
        if option == "Original":
            st.success(
                "We use the stock price (within the range selected) to create the MACD and Signal Line (which numerically vary based on price data)."
            )
        elif option == "Normalization":
            st.success(
                "We use the stock price (within the range selected) to create the MACD and Signal Line (which numerically vary based on price data). Next, we normalize the MACD/Signal Line so that fall in a consistent range, i.e. approximately from -2 to 2."
            )
        else:
            st.success(
                "We use the stock price (within the range selected) to create the MACD and Signal Line (which numerically vary based on price data). Next, we normalize the MACD/Signal Line so that fall in a consistent range, i.e. approximately from -2 to 2. Last, we use the normalized data to create probabilities from -100% to +100%. The probability means statistically what is believed to reverse the current direction."
            )

        # Download stock data
        data = yf.download(ticker, start=start_date, end=end_date)

        if not data.empty:
            if option == "Normalization":
                data = calculate_normalized_macd(
                    data, short_window, long_window, signal_window
                )
                some_warning_message = "normalized data"
            elif option == "Percentile":
                data = calculate_percentile_macd(
                    data, short_window, long_window, signal_window
                )
                some_warning_message = "percentile data (numbers in %)"
            else:
                data = calculate_macd(data, short_window, long_window, signal_window)
                some_warning_message = "original data"
            data = find_crossovers(data, values[0], values[1])

            # Plotting
            fig = create_fig(data, ticker)
            st.plotly_chart(fig, use_container_width=True)
            st.warning(f"In the above graph, we use {some_warning_message}.")
        else:
            st.write("No data available for the given ticker.")

        # New section to get and display fundamentals data under an expander
        with st.expander("View Fundamentals Data"):
            a, b, c = get_fundamentals(ticker)
            fundamentals_data = pd.concat([a, b, c], axis=0)
            fundamentals_data_t = fundamentals_data.transpose()
            fundamentals_data_t["date"] = fundamentals_data_t.index
            fundamentals_data_t.reset_index(drop=True, inplace=True)

            if not fundamentals_data.empty:
                # Generate a table (crude way)
                # st.table(fundamentals_data)

                # Generate the HTML using Pygwalker (user-friendly and flexible)
                pyg_html = pyg.walk(fundamentals_data_t, return_html=True)

                # Embed the HTML into the Streamlit app
                components.html(pyg_html, height=1000, scrolling=True)
            else:
                st.write("No fundamentals data available for the given ticker.")