Spaces:
Sleeping
Sleeping
Add application
Browse files- .gitignore +5 -0
- Dockerfile +59 -0
- README.md +1 -0
- finance-app-tutorial/README.md +3 -0
- finance-app-tutorial/charts.py +117 -0
- finance-app-tutorial/daily_APPLE.csv +101 -0
- finance-app-tutorial/daily_IBM.csv +101 -0
- finance-app-tutorial/earnings-data.json +0 -0
- finance-app-tutorial/main.py +183 -0
- finance-app-tutorial/prompts.py +134 -0
- finance-app-tutorial/static/README.md +8 -0
- finance-app-tutorial/static/custom.css +12 -0
- finance-app-tutorial/static/favicon.png +0 -0
- finance-app-tutorial/stock_data.py +91 -0
- finance-app-tutorial/ui.json +749 -0
- pyproject.toml +15 -0
.gitignore
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
venv
|
2 |
+
__pycache__
|
3 |
+
.env
|
4 |
+
tmp*.pdf
|
5 |
+
.DS_Store
|
Dockerfile
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Build stage
|
2 |
+
FROM python:3.11-slim-buster AS Build
|
3 |
+
|
4 |
+
# Set environment variables for Python and Poetry
|
5 |
+
ENV PYTHONUNBUFFERED=1 \
|
6 |
+
PIP_NO_CACHE_DIR=1 \
|
7 |
+
POETRY_NO_INTERACTION=1 \
|
8 |
+
POETRY_VIRTUALENVS_CREATE=false \
|
9 |
+
POETRY_VERSION=1.7.1
|
10 |
+
|
11 |
+
# Set the working directory in the container
|
12 |
+
WORKDIR /app
|
13 |
+
|
14 |
+
# Copy the dependencies file to the working directory
|
15 |
+
COPY ./pyproject.toml /app/
|
16 |
+
|
17 |
+
# Update, install dependencies, and prepare the Python environment
|
18 |
+
RUN apt-get update && \
|
19 |
+
apt-get install -y gcc g++ unixodbc-dev && \
|
20 |
+
pip install "poetry==$POETRY_VERSION" && \
|
21 |
+
poetry export --without-hashes --format requirements.txt --output requirements.txt && \
|
22 |
+
python3 -m pip wheel --no-cache-dir --no-deps -w /app/wheels -r requirements.txt
|
23 |
+
|
24 |
+
# Runtime stage
|
25 |
+
FROM python:3.11-slim-buster AS Run
|
26 |
+
|
27 |
+
# Set environment variables for Python and Poetry
|
28 |
+
ENV HOME=/home/user \
|
29 |
+
PATH=/home/user/.local/bin:$PATH
|
30 |
+
|
31 |
+
# Create a non-root user
|
32 |
+
RUN useradd -m -u 1000 user
|
33 |
+
|
34 |
+
# Switch to the non-root user
|
35 |
+
USER user
|
36 |
+
|
37 |
+
# Copy wheel files from the build stage
|
38 |
+
COPY --from=build /app/wheels $HOME/app/wheels
|
39 |
+
|
40 |
+
# Set the working directory to where the wheels are
|
41 |
+
WORKDIR $HOME/app/wheels
|
42 |
+
|
43 |
+
# Install the wheel files
|
44 |
+
RUN pip3 --no-cache-dir install *.whl
|
45 |
+
|
46 |
+
# Copy the application files to the working directory (change to your app name)
|
47 |
+
COPY --chown=user ./finance-app-tutorial $HOME/app
|
48 |
+
|
49 |
+
# Set the working directory to the application files
|
50 |
+
WORKDIR $HOME/app
|
51 |
+
|
52 |
+
# Specify the command to run the application
|
53 |
+
ENTRYPOINT [ "writer", "run" ]
|
54 |
+
|
55 |
+
# Expose the port the app runs on
|
56 |
+
EXPOSE 8080
|
57 |
+
|
58 |
+
# Set the default command to run the app
|
59 |
+
CMD [ ".", "--port", "8080", "--host", "0.0.0.0" ]
|
README.md
CHANGED
@@ -5,6 +5,7 @@ colorFrom: green
|
|
5 |
colorTo: red
|
6 |
sdk: docker
|
7 |
pinned: false
|
|
|
8 |
---
|
9 |
|
10 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
5 |
colorTo: red
|
6 |
sdk: docker
|
7 |
pinned: false
|
8 |
+
app_port: 8080
|
9 |
---
|
10 |
|
11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
finance-app-tutorial/README.md
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
This app was created using Writer Framework.
|
2 |
+
|
3 |
+
To learn more about it, visit https://dev.writer.com/framework
|
finance-app-tutorial/charts.py
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import plotly.express as px
|
3 |
+
import plotly.graph_objects as go
|
4 |
+
from plotly.subplots import make_subplots
|
5 |
+
|
6 |
+
def handle_click(state, context: dict, ui):
|
7 |
+
# Resetting the classes for active button
|
8 |
+
if state["active_button"]:
|
9 |
+
active_button = ui.find(state["active_button"])
|
10 |
+
active_button.content["cssClasses"] = ""
|
11 |
+
|
12 |
+
event_target = context["target"]
|
13 |
+
button = ui.find(event_target)
|
14 |
+
|
15 |
+
# Storing the clicked button ID in state
|
16 |
+
state["active_button"] = event_target
|
17 |
+
|
18 |
+
button_text = button.content["text"]
|
19 |
+
_handle_time_period(state, button_text)
|
20 |
+
button.content["cssClasses"] = "button-click"
|
21 |
+
|
22 |
+
button_max = ui.find("e13teponreio9yyz")
|
23 |
+
button_max.content["cssClasses"] = ""
|
24 |
+
|
25 |
+
ui.component_tree.updated = True
|
26 |
+
|
27 |
+
def _handle_time_period(state, period):
|
28 |
+
state["main_df_subset"] = state["main_df"]
|
29 |
+
if period == "5D":
|
30 |
+
state["main_df_subset"] = state["main_df_subset"][:5]
|
31 |
+
elif period == "1M":
|
32 |
+
state["main_df_subset"] = state["main_df_subset"][:30]
|
33 |
+
elif period == "3M":
|
34 |
+
state["main_df_subset"] = state["main_df_subset"][:90]
|
35 |
+
elif period == "1Y":
|
36 |
+
state["main_df_subset"] = state["main_df_subset"][:360]
|
37 |
+
elif period == "5Y":
|
38 |
+
state["main_df_subset"] = state["main_df_subset"][:1800]
|
39 |
+
elif period == "Max":
|
40 |
+
# No need to slice, already has the full data
|
41 |
+
pass
|
42 |
+
update_scatter_chart(state)
|
43 |
+
|
44 |
+
def update_scatter_chart(state):
|
45 |
+
fig = px.line(state["main_df_subset"], x="Date", y="Open", height=400)
|
46 |
+
|
47 |
+
df1 = state["main_df_subset"]
|
48 |
+
df2 = state["another_df"]
|
49 |
+
df2 = df2.head(len(df1))
|
50 |
+
|
51 |
+
# Add a new column to each dataframe to identify the source
|
52 |
+
df1["Source"] = "Main_DF"
|
53 |
+
df2["Source"] = "Another_DF"
|
54 |
+
|
55 |
+
# Concatenate the dataframes
|
56 |
+
combined_df = pd.concat([df1, df2])
|
57 |
+
state["main_df_subset"] = combined_df
|
58 |
+
|
59 |
+
# Plot the lines
|
60 |
+
fig = make_subplots(specs=[[{"secondary_y": True}]])
|
61 |
+
|
62 |
+
# Add traces for the primary y-axis (Main_DF)
|
63 |
+
fig.add_trace(
|
64 |
+
go.Scatter(x=df1["Date"], y=df1["Open"], name=state["symbol"], mode='lines'),
|
65 |
+
secondary_y=False,
|
66 |
+
)
|
67 |
+
|
68 |
+
# Add traces for the secondary y-axis (Another_DF)
|
69 |
+
fig.add_trace(
|
70 |
+
go.Scatter(x=df2["Date"], y=df2["Open"], name="S&P 500", mode='lines'),
|
71 |
+
secondary_y=True,
|
72 |
+
)
|
73 |
+
|
74 |
+
# Set axis titles
|
75 |
+
fig.update_yaxes(title_text=f"{state["symbol"]} Stock Price", secondary_y=False)
|
76 |
+
fig.update_yaxes(title_text="S&P 500", secondary_y=True)
|
77 |
+
|
78 |
+
# Update layout
|
79 |
+
fig.update_layout(height=550, title_text=f"{state["symbol"]} Stock vs the S&P 500", title_x = 0.5, title_y = 0.9, legend=dict(
|
80 |
+
orientation='h',
|
81 |
+
yanchor='top',
|
82 |
+
y=-0.2, # Adjust this value as needed
|
83 |
+
xanchor='center',
|
84 |
+
x=0.5
|
85 |
+
))
|
86 |
+
|
87 |
+
state["scatter_chart"] = fig
|
88 |
+
|
89 |
+
def update_bar_graph(state):
|
90 |
+
fig = px.line(state["main_df_subset"], x="Date", y="Open", height=400)
|
91 |
+
|
92 |
+
df = state["income_statement_df"]
|
93 |
+
selected_metrics = ["Total Revenue", "Net Income", "Operating Income"]
|
94 |
+
df_filtered = df.loc[selected_metrics]
|
95 |
+
|
96 |
+
# Transpose the DataFrame for easier plotting
|
97 |
+
df_transposed = df_filtered.transpose().reset_index()
|
98 |
+
df_transposed = df_transposed.melt(
|
99 |
+
id_vars=["index"], var_name="Metric", value_name="Value"
|
100 |
+
)
|
101 |
+
|
102 |
+
# Create the bar graph using Plotly Express
|
103 |
+
fig = px.bar(
|
104 |
+
df_transposed,
|
105 |
+
x="index",
|
106 |
+
y="Value",
|
107 |
+
color="Metric",
|
108 |
+
barmode="group",
|
109 |
+
labels={"index": "", "Value": ""},
|
110 |
+
title="Summary of Quarterly Income Statement",
|
111 |
+
)
|
112 |
+
|
113 |
+
fig.update_layout(
|
114 |
+
legend=dict(orientation="h", yanchor="top", y=-0.2, xanchor="center", x=0.5)
|
115 |
+
)
|
116 |
+
|
117 |
+
state["bar_graph"] = fig
|
finance-app-tutorial/daily_APPLE.csv
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
timestamp,open,high,low,close,volume
|
2 |
+
2024-06-17,213.3700,218.9500,212.7200,216.6700,93728300
|
3 |
+
2024-06-14,213.8500,215.1700,211.3000,212.4900,70122748
|
4 |
+
2024-06-13,214.7400,216.7500,211.6000,214.2400,97862729
|
5 |
+
2024-06-12,207.3700,220.2000,206.9000,213.0700,198134293
|
6 |
+
2024-06-11,193.6500,207.1600,193.6300,207.1500,172373296
|
7 |
+
2024-06-10,196.9000,197.3000,192.1500,193.1200,97262077
|
8 |
+
2024-06-07,194.6500,196.9400,194.1400,196.8900,53103912
|
9 |
+
2024-06-06,195.6850,196.5000,194.1700,194.4800,41181753
|
10 |
+
2024-06-05,195.4000,196.9000,194.8700,195.8700,54156785
|
11 |
+
2024-06-04,194.6350,195.3200,193.0342,194.3500,47471445
|
12 |
+
2024-06-03,192.9000,194.9900,192.5200,194.0300,50080539
|
13 |
+
2024-05-31,191.4400,192.5700,189.9100,192.2500,75158277
|
14 |
+
2024-05-30,190.7600,192.1800,190.6300,191.2900,49947941
|
15 |
+
2024-05-29,189.6100,192.2470,189.5100,190.2900,53068016
|
16 |
+
2024-05-28,191.5100,193.0000,189.1000,189.9900,52280051
|
17 |
+
2024-05-24,188.8200,190.5800,188.0404,189.9800,36326975
|
18 |
+
2024-05-23,190.9800,191.0000,186.6250,186.8800,51005924
|
19 |
+
2024-05-22,192.2650,192.8231,190.2700,190.9000,34648547
|
20 |
+
2024-05-21,191.0900,192.7300,190.9201,192.3500,42309401
|
21 |
+
2024-05-20,189.3250,191.9199,189.0100,191.0400,44361275
|
22 |
+
2024-05-17,189.5100,190.8100,189.1800,189.8700,41282925
|
23 |
+
2024-05-16,190.4700,191.0950,189.6601,189.8400,52845230
|
24 |
+
2024-05-15,187.9100,190.6500,187.3700,189.7200,70399988
|
25 |
+
2024-05-14,187.5100,188.3000,186.2900,187.4300,52393619
|
26 |
+
2024-05-13,185.4350,187.1000,184.6200,186.2800,72044809
|
27 |
+
2024-05-10,184.9000,185.0900,182.1300,183.0500,50759496
|
28 |
+
2024-05-09,182.5600,184.6600,182.1100,184.5700,48982972
|
29 |
+
2024-05-08,182.8500,183.0700,181.4500,182.7400,45057087
|
30 |
+
2024-05-07,183.4500,184.9000,181.3200,182.4000,77305771
|
31 |
+
2024-05-06,182.3540,184.2000,180.4200,181.7100,78569667
|
32 |
+
2024-05-03,186.6450,187.0000,182.6600,183.3800,163224109
|
33 |
+
2024-05-02,172.5100,173.4150,170.8900,173.0300,94214915
|
34 |
+
2024-05-01,169.5800,172.7050,169.1100,169.3000,50383147
|
35 |
+
2024-04-30,173.3300,174.9900,170.0000,170.3300,65934776
|
36 |
+
2024-04-29,173.3700,176.0300,173.1000,173.5000,68169419
|
37 |
+
2024-04-26,169.8800,171.3400,169.1800,169.3000,44838354
|
38 |
+
2024-04-25,169.5250,170.6100,168.1511,169.8900,50558329
|
39 |
+
2024-04-24,166.5400,169.3000,166.2100,169.0200,48251835
|
40 |
+
2024-04-23,165.3500,167.0500,164.9200,166.9000,49537761
|
41 |
+
2024-04-22,165.5150,167.2600,164.7700,165.8400,48116443
|
42 |
+
2024-04-19,166.2100,166.4000,164.0750,165.0000,68149377
|
43 |
+
2024-04-18,168.0300,168.6400,166.5500,167.0400,43122903
|
44 |
+
2024-04-17,169.6100,170.6500,168.0000,168.0000,50901210
|
45 |
+
2024-04-16,171.7500,173.7600,168.2700,169.3800,73711235
|
46 |
+
2024-04-15,175.3600,176.6300,172.5000,172.6900,73531773
|
47 |
+
2024-04-12,174.2600,178.3600,174.2100,176.5500,101670886
|
48 |
+
2024-04-11,168.3400,175.4600,168.1600,175.0400,91070275
|
49 |
+
2024-04-10,168.8000,169.0900,167.1100,167.7800,49709336
|
50 |
+
2024-04-09,168.7000,170.0800,168.3500,169.6700,42231444
|
51 |
+
2024-04-08,169.0300,169.2000,168.2400,168.4500,37216858
|
52 |
+
2024-04-05,169.5900,170.3900,168.9500,169.5800,41975776
|
53 |
+
2024-04-04,170.2900,171.9200,168.8200,168.8200,53355055
|
54 |
+
2024-04-03,168.7900,170.6800,168.5800,169.6500,45571129
|
55 |
+
2024-04-02,169.0800,169.3400,168.2302,168.8400,49013991
|
56 |
+
2024-04-01,171.1900,171.2500,169.4750,170.0300,43772506
|
57 |
+
2024-03-28,171.7500,172.2300,170.5100,171.4800,65672690
|
58 |
+
2024-03-27,170.4100,173.6000,170.1100,173.3100,60273265
|
59 |
+
2024-03-26,170.0000,171.4200,169.5800,169.7100,57388449
|
60 |
+
2024-03-25,170.5650,171.9400,169.4500,170.8500,54288328
|
61 |
+
2024-03-22,171.7600,173.0500,170.0600,172.2800,71160138
|
62 |
+
2024-03-21,177.0500,177.4900,170.8400,171.3700,106181270
|
63 |
+
2024-03-20,175.7200,178.6700,175.0900,178.6700,53423102
|
64 |
+
2024-03-19,174.3400,176.6050,173.0300,176.0800,55215244
|
65 |
+
2024-03-18,175.5700,177.7100,173.5200,173.7200,75604184
|
66 |
+
2024-03-15,171.1700,172.6200,170.2850,172.6200,121752699
|
67 |
+
2024-03-14,172.9100,174.3078,172.0500,173.0000,72571635
|
68 |
+
2024-03-13,172.7700,173.1850,170.7600,171.1300,51948951
|
69 |
+
2024-03-12,173.1500,174.0300,171.0100,173.2300,59544927
|
70 |
+
2024-03-11,172.9400,174.3800,172.0500,172.7500,58929918
|
71 |
+
2024-03-08,169.0000,173.7000,168.9400,170.7300,76267041
|
72 |
+
2024-03-07,169.1500,170.7300,168.4900,169.0000,71765061
|
73 |
+
2024-03-06,171.0600,171.2400,168.6800,169.1200,68587707
|
74 |
+
2024-03-05,170.7600,172.0400,169.6200,170.1200,95132355
|
75 |
+
2024-03-04,176.1500,176.9000,173.7900,175.1000,81510101
|
76 |
+
2024-03-01,179.5500,180.5300,177.3800,179.6600,73563082
|
77 |
+
2024-02-29,181.2700,182.5700,179.5300,180.7500,136682597
|
78 |
+
2024-02-28,182.5100,183.1200,180.1300,181.4200,48953939
|
79 |
+
2024-02-27,181.1000,183.9225,179.5600,182.6300,54318851
|
80 |
+
2024-02-26,182.2400,182.7600,180.6500,181.1600,40867421
|
81 |
+
2024-02-23,185.0100,185.0400,182.2300,182.5200,45119677
|
82 |
+
2024-02-22,183.4800,184.9550,182.4600,184.3700,52292208
|
83 |
+
2024-02-21,181.9400,182.8888,180.6600,182.3200,41529674
|
84 |
+
2024-02-20,181.7900,182.4300,180.0000,181.5600,53665553
|
85 |
+
2024-02-16,183.4200,184.8500,181.6650,182.3100,49752465
|
86 |
+
2024-02-15,183.5500,184.4900,181.3500,183.8600,65434496
|
87 |
+
2024-02-14,185.3200,185.5300,182.4400,184.1500,54630517
|
88 |
+
2024-02-13,185.7700,186.2100,183.5128,185.0400,56529529
|
89 |
+
2024-02-12,188.4150,188.6700,186.7900,187.1500,41781934
|
90 |
+
2024-02-09,188.6500,189.9900,188.0000,188.8500,45155216
|
91 |
+
2024-02-08,189.3850,189.5350,187.3500,188.3200,40962046
|
92 |
+
2024-02-07,190.6400,191.0500,188.6100,189.4100,53438955
|
93 |
+
2024-02-06,186.8600,189.3100,186.7695,189.3000,43490759
|
94 |
+
2024-02-05,188.1500,189.2500,185.8400,187.6800,69668820
|
95 |
+
2024-02-02,179.8600,187.3300,179.2500,185.8500,102551680
|
96 |
+
2024-02-01,183.9850,186.9500,183.8200,186.8600,64885408
|
97 |
+
2024-01-31,187.0400,187.0950,184.3500,184.4000,55467803
|
98 |
+
2024-01-30,190.9400,191.8000,187.4700,188.0400,55859370
|
99 |
+
2024-01-29,192.0100,192.2000,189.5800,191.7300,47145622
|
100 |
+
2024-01-26,194.2700,194.7600,191.9400,192.4200,44594011
|
101 |
+
2024-01-25,195.2200,196.2675,193.1125,194.1700,54822126
|
finance-app-tutorial/daily_IBM.csv
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
timestamp,open,high,low,close,volume
|
2 |
+
2024-06-17,168.7600,169.7200,167.5000,169.5000,3239815
|
3 |
+
2024-06-14,168.2900,169.4700,167.2300,169.2100,2777717
|
4 |
+
2024-06-13,169.0100,169.5900,168.3350,169.1200,3525717
|
5 |
+
2024-06-12,171.3500,172.4700,168.1010,169.0000,3522698
|
6 |
+
2024-06-11,169.9800,170.0000,166.8100,169.3200,2951251
|
7 |
+
2024-06-10,169.5500,170.7600,168.8800,170.3800,3444684
|
8 |
+
2024-06-07,168.1800,171.3050,168.0600,170.0100,3475495
|
9 |
+
2024-06-06,167.3800,168.4400,166.8000,168.2000,2207263
|
10 |
+
2024-06-05,166.4100,167.7900,165.7800,167.3800,3049377
|
11 |
+
2024-06-04,164.6000,166.4000,163.8800,165.8100,2594203
|
12 |
+
2024-06-03,166.5400,166.7800,163.5300,165.2800,2776058
|
13 |
+
2024-05-31,165.7000,166.9700,163.8400,166.8500,4905002
|
14 |
+
2024-05-30,165.5600,166.7300,164.2300,165.6300,3852963
|
15 |
+
2024-05-29,168.0000,168.6300,166.2100,167.0500,4206576
|
16 |
+
2024-05-28,170.4400,171.0850,168.6500,169.6600,2629645
|
17 |
+
2024-05-24,171.4800,172.0100,170.2100,170.8900,2587829
|
18 |
+
2024-05-23,175.3900,175.4600,170.4350,170.6700,3341335
|
19 |
+
2024-05-22,173.3900,174.9900,172.7600,173.6900,3294900
|
20 |
+
2024-05-21,169.9400,174.9700,169.9400,173.4700,6459800
|
21 |
+
2024-05-20,169.0000,170.1600,168.3800,169.9200,2726261
|
22 |
+
2024-05-17,168.9700,169.1100,167.3300,169.0300,2956387
|
23 |
+
2024-05-16,168.2600,169.6300,167.7900,168.9700,3492267
|
24 |
+
2024-05-15,167.9400,168.3500,167.3400,168.2600,4468823
|
25 |
+
2024-05-14,167.8600,168.1300,166.4800,167.3600,2600967
|
26 |
+
2024-05-13,167.5000,168.0600,166.7600,167.5600,2414859
|
27 |
+
2024-05-10,167.1300,168.0700,166.3200,167.1500,2255370
|
28 |
+
2024-05-09,167.5000,167.5500,165.8800,166.2700,4266616
|
29 |
+
2024-05-08,168.0100,170.2600,167.9000,169.9000,3522011
|
30 |
+
2024-05-07,169.0000,169.2900,167.9400,168.3800,3155260
|
31 |
+
2024-05-06,166.5000,168.6700,166.3800,168.6100,4222266
|
32 |
+
2024-05-03,165.0000,166.6100,164.9200,165.7100,3400405
|
33 |
+
2024-05-02,164.3500,164.8800,162.6200,164.6900,3829853
|
34 |
+
2024-05-01,165.6900,166.2700,164.3000,164.4300,4030960
|
35 |
+
2024-04-30,166.4900,166.7600,165.2605,166.2000,6011634
|
36 |
+
2024-04-29,167.4000,168.2200,166.2250,167.4300,5263342
|
37 |
+
2024-04-26,167.5000,167.8700,165.7300,167.1300,8983796
|
38 |
+
2024-04-25,168.2000,172.4500,165.6600,168.9100,16702150
|
39 |
+
2024-04-24,183.1700,184.2900,181.4000,184.1000,7616643
|
40 |
+
2024-04-23,182.7300,184.6800,179.0000,182.1900,5950229
|
41 |
+
2024-04-22,182.4500,183.3150,180.4500,181.9000,3076451
|
42 |
+
2024-04-19,182.4300,182.8000,180.5700,181.5800,3037990
|
43 |
+
2024-04-18,182.3500,183.4600,180.1700,181.4700,2886733
|
44 |
+
2024-04-17,184.1600,184.6700,181.7800,183.1000,3003033
|
45 |
+
2024-04-16,185.5900,185.7100,182.8600,183.7500,4473654
|
46 |
+
2024-04-15,185.5700,187.4800,180.8800,181.2500,3528140
|
47 |
+
2024-04-12,184.0000,185.1699,181.6850,182.2700,3547378
|
48 |
+
2024-04-11,186.0400,186.7950,184.5800,185.9000,2861736
|
49 |
+
2024-04-10,187.4200,187.9150,185.5200,186.0400,3081915
|
50 |
+
2024-04-09,190.5400,191.2500,186.6600,189.3100,2790673
|
51 |
+
2024-04-08,189.2400,190.2400,188.9118,189.8200,2673611
|
52 |
+
2024-04-05,188.5900,190.3200,188.0200,189.1400,2012428
|
53 |
+
2024-04-04,192.0000,193.2800,187.3400,187.9400,2924438
|
54 |
+
2024-04-03,188.6000,191.3500,188.4850,190.9000,2818910
|
55 |
+
2024-04-02,189.1400,189.8000,187.6000,188.8800,2689711
|
56 |
+
2024-04-01,190.0000,190.4600,188.5200,189.8300,2362586
|
57 |
+
2024-03-28,190.9400,191.9299,190.3400,190.9600,3742169
|
58 |
+
2024-03-27,189.6000,190.9600,188.6000,190.8000,3693305
|
59 |
+
2024-03-26,189.0200,190.0000,188.5000,188.5000,4229535
|
60 |
+
2024-03-25,190.2600,190.8200,188.7500,188.7900,3718289
|
61 |
+
2024-03-22,192.0000,192.9850,190.5100,190.8400,3988398
|
62 |
+
2024-03-21,193.0000,193.3700,190.0100,191.9000,6013561
|
63 |
+
2024-03-20,192.8700,193.9800,191.3100,193.9600,3238643
|
64 |
+
2024-03-19,191.4900,193.5800,190.2800,193.3400,5317341
|
65 |
+
2024-03-18,191.7000,193.2300,190.3200,191.6900,5410562
|
66 |
+
2024-03-15,191.9900,193.0573,190.7000,191.0700,8828184
|
67 |
+
2024-03-14,196.9500,197.7480,192.1200,193.4300,4102202
|
68 |
+
2024-03-13,197.5500,198.1000,195.3200,196.7000,3960737
|
69 |
+
2024-03-12,192.4600,199.1800,192.1500,197.7800,5862512
|
70 |
+
2024-03-11,195.0900,195.3800,190.8800,191.7300,4712688
|
71 |
+
2024-03-08,196.0600,197.7700,194.3800,195.9500,3943113
|
72 |
+
2024-03-07,197.5800,198.7300,196.1400,196.5400,4604458
|
73 |
+
2024-03-06,193.5000,198.1300,192.9600,196.1600,6945818
|
74 |
+
2024-03-05,192.0000,193.9400,190.5700,191.9500,5653641
|
75 |
+
2024-03-04,187.7600,193.8980,187.6000,193.0600,7938266
|
76 |
+
2024-03-01,185.4900,188.3800,185.1800,188.2000,4018354
|
77 |
+
2024-02-29,186.1500,186.8495,184.6900,185.0300,6458487
|
78 |
+
2024-02-28,184.6300,185.3700,183.5500,185.3000,3216345
|
79 |
+
2024-02-27,184.1600,185.1300,182.6200,184.8700,3641378
|
80 |
+
2024-02-26,185.6000,186.1250,184.0600,184.1300,4620815
|
81 |
+
2024-02-23,184.9000,186.4550,184.5700,185.7200,3433800
|
82 |
+
2024-02-22,182.4500,184.5500,181.9300,184.2100,5078398
|
83 |
+
2024-02-21,182.5600,183.0300,178.7500,179.7000,4728473
|
84 |
+
2024-02-20,187.6400,188.7700,183.0600,183.4400,4247181
|
85 |
+
2024-02-16,186.6300,188.9500,185.9452,187.6400,4842840
|
86 |
+
2024-02-15,183.6200,186.9800,183.6200,186.8700,4714301
|
87 |
+
2024-02-14,185.0000,185.0000,182.2600,183.5700,3173391
|
88 |
+
2024-02-13,184.2800,184.7700,182.3600,183.7000,4290453
|
89 |
+
2024-02-12,185.9000,186.4800,184.0300,186.1600,4724021
|
90 |
+
2024-02-09,184.4400,187.1800,183.8500,186.3400,5064641
|
91 |
+
2024-02-08,182.6300,184.5500,181.4900,184.3600,5161185
|
92 |
+
2024-02-07,183.3400,184.0200,182.6250,183.7400,4841188
|
93 |
+
2024-02-06,183.5500,184.6800,183.0400,183.4100,3338196
|
94 |
+
2024-02-05,185.5100,185.7800,183.2550,183.4200,4379602
|
95 |
+
2024-02-02,187.1000,187.3900,185.6150,185.7900,4055411
|
96 |
+
2024-02-01,183.6300,187.5100,182.7100,186.9000,4669444
|
97 |
+
2024-01-31,187.0500,187.6500,183.1400,183.6600,8876055
|
98 |
+
2024-01-30,187.7100,188.6500,186.7700,187.8700,4575058
|
99 |
+
2024-01-29,187.4600,189.4600,186.0500,187.1400,6107908
|
100 |
+
2024-01-26,191.3100,192.3896,186.1600,187.4200,9895941
|
101 |
+
2024-01-25,184.9600,196.9000,184.8300,190.4300,29596239
|
finance-app-tutorial/earnings-data.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
finance-app-tutorial/main.py
ADDED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import writer as wf
|
2 |
+
import writer.ai
|
3 |
+
import pandas as pd
|
4 |
+
from prompts import stock_prompts, income_prompts, earnings_prompt
|
5 |
+
from stock_data import download_data, download_sp500, stock_news, _one_day_data, income_statement, earnings_calls
|
6 |
+
from charts import update_scatter_chart
|
7 |
+
from dotenv import load_dotenv
|
8 |
+
import os
|
9 |
+
|
10 |
+
load_dotenv()
|
11 |
+
|
12 |
+
writer.ai.init(os.getenv("WRITER_API_KEY"))
|
13 |
+
|
14 |
+
# Update all data
|
15 |
+
def updates(state):
|
16 |
+
state["message"] = "% Refreshing stock data..."
|
17 |
+
earnings_calls(state)
|
18 |
+
download_sp500(state)
|
19 |
+
stock_news(state)
|
20 |
+
download_data(state)
|
21 |
+
income_statement(state)
|
22 |
+
update_scatter_chart(state)
|
23 |
+
_one_day_data(state)
|
24 |
+
_refresh_window(state)
|
25 |
+
|
26 |
+
# Refresh the window
|
27 |
+
def _refresh_window(state):
|
28 |
+
state["show_income_metrics"]["visible"] = False
|
29 |
+
state["show_bar_graph"]["visible"] = False
|
30 |
+
state["show_analysis_text"]["visible"] = False
|
31 |
+
state["show_analysis_text"]["language"] = False
|
32 |
+
state["message"] = "Writer AI insights will be generated here"
|
33 |
+
|
34 |
+
# Summarize earnings call using Palmyra-Fin model
|
35 |
+
def summarize_earnings(state):
|
36 |
+
_refresh_window(state)
|
37 |
+
state["message"] = f"% {state["symbol"]} earnings call will be summarized here"
|
38 |
+
|
39 |
+
earnings_transcript = state["earnings_transcript"]
|
40 |
+
prompt = earnings_prompt.format(earnings_transcript=earnings_transcript)
|
41 |
+
submission = writer.ai.complete(prompt, config={"model": "palmyra-fin-32k", "temperature": 0.7, "max_tokens": 8192})
|
42 |
+
state["message"] = f"+ {state["symbol"]} earnings call summary"
|
43 |
+
state["analysis"] = submission.strip()
|
44 |
+
state["show_analysis_text"]["visible"] = True
|
45 |
+
|
46 |
+
def prompt_parameters_words(state,payload):
|
47 |
+
state["prompt_parameters_words"] = payload
|
48 |
+
_refresh_window(state)
|
49 |
+
|
50 |
+
def prompt_parameters_lang(state,payload):
|
51 |
+
state["prompt_parameters_lang"] = payload
|
52 |
+
generate_stock_analysis(state)
|
53 |
+
|
54 |
+
def generate_stock_analysis(state):
|
55 |
+
_refresh_window(state)
|
56 |
+
if(state["prompt_parameters_lang"] == ""):
|
57 |
+
state["prompt_parameters_lang"] == "English"
|
58 |
+
|
59 |
+
state["message"] = f"% {state["symbol"]} trends will be analyzed here in {state['prompt_parameters_lang']}"
|
60 |
+
stock_name = state["symbol"]
|
61 |
+
stock_data = state["main_df"][:365]
|
62 |
+
|
63 |
+
rounded_value = round(state["prompt_parameters_words"], 0)
|
64 |
+
language = state["prompt_parameters_lang"]
|
65 |
+
# Convert the rounded value to an integer
|
66 |
+
integer_value = int(rounded_value)
|
67 |
+
|
68 |
+
prompt = stock_prompts.format(language=language, stock_name=stock_name,words=integer_value,stock_data=stock_data)
|
69 |
+
submission = writer.ai.complete(prompt, config={"model": "palmyra-fin-32k", "temperature": 0.7, "max_tokens": 8192})
|
70 |
+
state["analysis"] = submission.strip()
|
71 |
+
state["message"] = f"+ {state["symbol"]} trends analyzed"
|
72 |
+
state["show_analysis_text"]["visible"] = True
|
73 |
+
state["show_analysis_text"]["language"] = True
|
74 |
+
|
75 |
+
return submission
|
76 |
+
|
77 |
+
|
78 |
+
def generate_income_analysis(state):
|
79 |
+
_refresh_window(state)
|
80 |
+
state["message"] = f"% {state["symbol"]} income statement will be visualized here"
|
81 |
+
stock_name = state["symbol"]
|
82 |
+
stock_data = state["main_df"][:365]
|
83 |
+
income_statement_data = state["income_statement_df"][:365]
|
84 |
+
prompt = income_prompts.format(
|
85 |
+
income_statement_data=income_statement_data,
|
86 |
+
stock_data=stock_data,
|
87 |
+
stock_name=stock_name,
|
88 |
+
)
|
89 |
+
submission = writer.ai.complete(prompt, config={"model": "palmyra-fin-32k", "temperature": 0.7, "max_tokens": 8192})
|
90 |
+
state["analysis"] = submission.strip()
|
91 |
+
state["message"] = f"+ {state["symbol"]} income statement visualized"
|
92 |
+
state["show_income_metrics"]["visible"] = True
|
93 |
+
state["show_analysis_text"]["visible"] = True
|
94 |
+
state["show_bar_graph"]["visible"] = True
|
95 |
+
return submission
|
96 |
+
|
97 |
+
def stock_tags(state, payload):
|
98 |
+
state["symbol"] = payload
|
99 |
+
updates(state)
|
100 |
+
|
101 |
+
def _get_main_df(filename):
|
102 |
+
main_df = pd.read_csv(filename)
|
103 |
+
return main_df
|
104 |
+
|
105 |
+
initial_state = wf.init_state(
|
106 |
+
{
|
107 |
+
"last_24_hours_open": "168.76",
|
108 |
+
"last_24_hours_high": "169.72",
|
109 |
+
"last_24_hours_low": "167.50",
|
110 |
+
"message": None,
|
111 |
+
"main_df": _get_main_df("daily_IBM.csv"),
|
112 |
+
"main_df_subset": _get_main_df("daily_IBM.csv"),
|
113 |
+
"symbol": "AAPL",
|
114 |
+
"articles": {
|
115 |
+
"EU seeks views on Microsoft, OpenAI, Google and Samsung deals, EU's Vestager says": {
|
116 |
+
"source": "Reuters",
|
117 |
+
"published_at": "June 28, 2024 at 15:40",
|
118 |
+
"url": "https://finance.yahoo.com/news/eu-seeks-views-microsoft-openai-144044802.html",
|
119 |
+
},
|
120 |
+
"Forget the S&P 500 -- Buy This Magnificent ETF Instead": {
|
121 |
+
"source": "Motley Fool",
|
122 |
+
"published_at": "June 28, 2024 at 15:00",
|
123 |
+
"url": "https://finance.yahoo.com/m/662fcc10-7b6c-3bd1-8b7f-6cc25e8a1e61/forget-the-s%26p-500-buy.html",
|
124 |
+
},
|
125 |
+
"Microsoft Corporation (MSFT) is Attracting Investor Attention: Here is What You Should Know": {
|
126 |
+
"source": "Zacks",
|
127 |
+
"published_at": "June 28, 2024 at 14:00",
|
128 |
+
"url": "https://finance.yahoo.com/news/microsoft-corporation-msft-attracting-investor-130015018.html",
|
129 |
+
},
|
130 |
+
},
|
131 |
+
"show_analysis_text": {
|
132 |
+
"visible": False,
|
133 |
+
"language": False
|
134 |
+
},
|
135 |
+
"show_income_metrics": {
|
136 |
+
"visible": False,
|
137 |
+
},
|
138 |
+
"tab_message": "- **Performance** tab highlights stock trends using an interactive graph where time filters can be selected.<br><li>**Stock data** tab shows the stock data from Yahoo Finance. <br><li>**Income data** tab shows the income statement from Yahoo Finance. <br><li>**View 10-K** tab shows the selected stock 10-K in a PDF viewer shown via an _API integration_.",
|
139 |
+
"prompt_parameters_lang": "English",
|
140 |
+
"prompt_parameters_words": 100,
|
141 |
+
"message": "Writer AI insights will be generated here",
|
142 |
+
"show_bar_graph": {"visible": False},
|
143 |
+
"output_language": {
|
144 |
+
"English": "English",
|
145 |
+
"Arabic": "Arabic",
|
146 |
+
"Bengali": "Bengali",
|
147 |
+
"Bulgarian": "Bulgarian",
|
148 |
+
"Chinese simplified": "Chinese simplified",
|
149 |
+
"Chinese traditional": "Chinese traditional",
|
150 |
+
"Croatian": "Croatian",
|
151 |
+
"Czech": "Czech",
|
152 |
+
"Danish": "Danish",
|
153 |
+
"Dutch": "Dutch",
|
154 |
+
"Finnish": "Finnish",
|
155 |
+
"French": "French",
|
156 |
+
"German": "German",
|
157 |
+
"Greek": "Greek",
|
158 |
+
"Hebrew": "Hebrew",
|
159 |
+
"Hindi": "Hindi",
|
160 |
+
"Hungarian": "Hungarian",
|
161 |
+
"Indonesian": "Indonesian",
|
162 |
+
"Italian": "Italian",
|
163 |
+
"Japanese": "Japanese",
|
164 |
+
"Korean": "Korean",
|
165 |
+
"Lithuanian": "Lithuanian",
|
166 |
+
"Polish": "Polish",
|
167 |
+
"Portuguese": "Portuguese",
|
168 |
+
"Romanian": "Romanian",
|
169 |
+
"Russian": "Russian",
|
170 |
+
"Spanish": "Spanish",
|
171 |
+
"Swahili": "Swahili",
|
172 |
+
"Swedish": "Swedish",
|
173 |
+
"Thai": "Thai",
|
174 |
+
"Turkish": "Turkish",
|
175 |
+
"Ukrainian": "Ukrainian",
|
176 |
+
"Vietnamese": "Vietnamese",
|
177 |
+
},
|
178 |
+
}
|
179 |
+
)
|
180 |
+
|
181 |
+
updates(initial_state)
|
182 |
+
|
183 |
+
initial_state.import_stylesheet("theme", "/static/custom.css?18")
|
finance-app-tutorial/prompts.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# BASE PROMPTS (TAILORED TO EACH COMPANY)
|
2 |
+
|
3 |
+
# base_prompts = {}
|
4 |
+
|
5 |
+
stock_prompts = """
|
6 |
+
|
7 |
+
Variables:
|
8 |
+
|
9 |
+
{language}, {stock_name}, {words}, {stock_data}
|
10 |
+
|
11 |
+
************************
|
12 |
+
|
13 |
+
Prompt:
|
14 |
+
You will be acting as a stock market analyst. When I provide the stock data in the specified format between the <stock_data> tags, your task is to carefully review the data and provide insights, trends, and financial analysis for the stock specified in the {stock_name} variable.
|
15 |
+
|
16 |
+
<stock_data>
|
17 |
+
{stock_data}
|
18 |
+
</stock_data>
|
19 |
+
|
20 |
+
Please analyze the stock data concisely in {words} words using paragraphs, considering the following steps:
|
21 |
+
|
22 |
+
1. Identify any notable trends in the stock's price, volume, or other key metrics over the given time period. Discuss potential reasons behind these trends.
|
23 |
+
|
24 |
+
2. Compare the stock's performance and financial metrics to industry averages and key competitors. Discuss how the stock stacks up against its peers.
|
25 |
+
|
26 |
+
3. Based on your analysis, provide an overall assessment of the stock's current position and future prospects. Consider factors such as growth potential, risk level, and market sentiment.
|
27 |
+
|
28 |
+
Before giving your final recommendation, please provide detailed reasoning and analysis to support your conclusions inside <reasoning> tags.
|
29 |
+
|
30 |
+
Finally, offer a clear recommendation inside <recommendation> tags on whether to buy, hold, or sell {stock_name}, taking into account both the stock's current valuation and its long-term potential.
|
31 |
+
|
32 |
+
Remember to base your analysis and recommendation solely on the provided stock data for
|
33 |
+
{stock_name}. If there is insufficient information to draw a conclusion, state this limitation in your response.
|
34 |
+
|
35 |
+
Output the analysis in {language}.
|
36 |
+
|
37 |
+
"""
|
38 |
+
|
39 |
+
income_prompts = """
|
40 |
+
|
41 |
+
Variables:
|
42 |
+
|
43 |
+
{income_statement_data}, {stock_name}
|
44 |
+
|
45 |
+
************************
|
46 |
+
|
47 |
+
Prompt:
|
48 |
+
You are a financial analyst tasked with analyzing the income statement of a
|
49 |
+
company. To assist in your analysis, you have been provided with the following data:
|
50 |
+
|
51 |
+
<stock_name>
|
52 |
+
{stock_name}
|
53 |
+
</stock_name>
|
54 |
+
|
55 |
+
<income_statement_data>
|
56 |
+
{income_statement_data}
|
57 |
+
</income_statement_data>
|
58 |
+
|
59 |
+
Using the provided data, please conduct an executive summary analysis in 100 words, using paragraphs, of the company's financial health and
|
60 |
+
future prospects. Your analysis should include:
|
61 |
+
|
62 |
+
<scratchpad>
|
63 |
+
- Analyze key financial metrics from the income statement, such as revenue growth, profit margins,
|
64 |
+
and expenses
|
65 |
+
- Assess the company's profitability and efficiency based on the income statement data
|
66 |
+
- Identify any potential risks or opportunities for the company based on the financial data
|
67 |
+
- Consider industry trends and market conditions that may impact the company's performance
|
68 |
+
</scratchpad>
|
69 |
+
|
70 |
+
After conducting your analysis, please provide your findings and conclusions in the following
|
71 |
+
format:
|
72 |
+
|
73 |
+
<analysis>
|
74 |
+
Income Statement Analysis:
|
75 |
+
- [Discuss the company's revenue growth and profitability based on the income statement data]
|
76 |
+
- [Identify any significant changes or trends in expenses or profit margins]
|
77 |
+
- [Assess the company's overall financial health and efficiency based on the income statement
|
78 |
+
metrics]
|
79 |
+
|
80 |
+
Risks and Opportunities:
|
81 |
+
- [Identify any potential risks or challenges the company may face based on the financial data]
|
82 |
+
- [Discuss any opportunities for growth or improvement based on the analysis]
|
83 |
+
|
84 |
+
Conclusion:
|
85 |
+
- [Provide a summary of your overall assessment of the company's financial performance and future
|
86 |
+
prospects]
|
87 |
+
- [Include any recommendations or insights for investors or stakeholders]
|
88 |
+
</analysis>
|
89 |
+
|
90 |
+
Please ensure that your analysis is clear, concise, and well-supported by the provided financial
|
91 |
+
data. Use specific examples and figures from the stock data and income statement to support your
|
92 |
+
conclusions.
|
93 |
+
|
94 |
+
"""
|
95 |
+
|
96 |
+
earnings_prompt = """
|
97 |
+
|
98 |
+
Variables:
|
99 |
+
|
100 |
+
{earnings_transcript}
|
101 |
+
|
102 |
+
************************
|
103 |
+
|
104 |
+
Prompt:
|
105 |
+
You are an expert at analyzing quarterly earnings reports. Please carefully review the following earnings call transcript:
|
106 |
+
|
107 |
+
<transcript>
|
108 |
+
{earnings_transcript}
|
109 |
+
</transcript>
|
110 |
+
|
111 |
+
After reading through the transcript, take some time to think through the key insights and takeaways
|
112 |
+
in a <scratchpad>. Consider the following aspects:
|
113 |
+
- Financial performance: How did the company perform financially this quarter? Were revenue,
|
114 |
+
profits, margins, etc. up or down compared to prior periods? Did they meet, exceed or fall short of
|
115 |
+
expectations?
|
116 |
+
- Future outlook: What is the company's outlook for upcoming quarters? Are they optimistic or
|
117 |
+
cautious? What are their projections for key metrics?
|
118 |
+
- Strategic initiatives: Did the company discuss any major strategic initiatives, partnerships, new
|
119 |
+
products, expansion plans or other projects? What is the rationale and potential impact?
|
120 |
+
- Significant changes: Were there any notable leadership changes, restructurings, pivots in strategy
|
121 |
+
or other significant developments disclosed?
|
122 |
+
</scratchpad>
|
123 |
+
|
124 |
+
Once you've thought through the main points, please provide a summary of the key insights from the
|
125 |
+
earnings call. The summary should concisely hit on the major takeaways around
|
126 |
+
financial performance, outlook, strategy and changes while including specific details that support
|
127 |
+
the main points. Aim for around 4-6 paragraphs.
|
128 |
+
|
129 |
+
Remember, your goal is to extract and communicate the most important information from the earnings
|
130 |
+
call in a clear, insightful executive summary. Focus on the high-level story and don't get too in
|
131 |
+
the weeds with minor details. Put yourself in the shoes of an analyst or investor and highlight what
|
132 |
+
you think they would care about most.
|
133 |
+
|
134 |
+
"""
|
finance-app-tutorial/static/README.md
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Serving static files
|
2 |
+
|
3 |
+
You can use this folder to store files which will be served statically in the "/static" route.
|
4 |
+
|
5 |
+
This is useful to store images and other files which will be served directly to the user of your application.
|
6 |
+
|
7 |
+
For example, if you store an image named "myimage.jpg" in this folder, it'll be accessible as "static/myimage.jpg".
|
8 |
+
You can use this relative route as the source in an Image component.
|
finance-app-tutorial/static/custom.css
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.link {
|
2 |
+
text-align: right !important;
|
3 |
+
}
|
4 |
+
|
5 |
+
.button-click {
|
6 |
+
background-color: #5551ff !important;
|
7 |
+
color: white !important;
|
8 |
+
}
|
9 |
+
|
10 |
+
.custom-iframe {
|
11 |
+
height: 700px !important;
|
12 |
+
}
|
finance-app-tutorial/static/favicon.png
ADDED
finance-app-tutorial/stock_data.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
from datetime import datetime
|
3 |
+
import yfinance as yf
|
4 |
+
from charts import update_bar_graph
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
import json
|
7 |
+
|
8 |
+
load_dotenv()
|
9 |
+
|
10 |
+
# Download stock data and format into a DataFrame
|
11 |
+
def download_data(state):
|
12 |
+
df = yf.download(state["symbol"], period="max", interval="1d")
|
13 |
+
df = df.reset_index()
|
14 |
+
df = df.sort_values(by="Date", ascending=False)
|
15 |
+
df = df.round({"Open": 2, "High": 2, "Low": 2, "Close": 2, "Adj Close": 2})
|
16 |
+
df["Date"] = pd.to_datetime(df["Date"])
|
17 |
+
state["main_df_subset"] = df
|
18 |
+
state["main_df"] = state["main_df_subset"]
|
19 |
+
|
20 |
+
# Download S&P 500 data and format into a DataFrame
|
21 |
+
def download_sp500(state):
|
22 |
+
df = yf.download(tickers="^GSPC", period="max", interval="1d")
|
23 |
+
df = df.reset_index()
|
24 |
+
df = df.sort_values(by="Date", ascending=False)
|
25 |
+
df = df.round({"Open": 2, "High": 2, "Low": 2, "Close": 2, "Adj Close": 2})
|
26 |
+
df["Date"] = pd.to_datetime(df["Date"])
|
27 |
+
state["another_df"] = df
|
28 |
+
|
29 |
+
# Retrieve latest stock news
|
30 |
+
def stock_news(state):
|
31 |
+
msft = yf.Ticker(state["symbol"])
|
32 |
+
articles = {}
|
33 |
+
data = msft.news
|
34 |
+
latest_articles = sorted(
|
35 |
+
data, key=lambda x: x["providerPublishTime"], reverse=True
|
36 |
+
)[:4]
|
37 |
+
|
38 |
+
for item in latest_articles:
|
39 |
+
provider_publish_time = item.get("providerPublishTime", "")
|
40 |
+
if provider_publish_time:
|
41 |
+
# Convert the timestamp to a readable date
|
42 |
+
formatted_date = datetime.fromtimestamp(provider_publish_time)
|
43 |
+
readable_date = formatted_date.strftime("%B %d, %Y at %H:%M")
|
44 |
+
else:
|
45 |
+
readable_date = "Date not available"
|
46 |
+
|
47 |
+
title = item.get("title", "No Title")
|
48 |
+
articles[title] = {
|
49 |
+
"source": item.get("publisher", ""),
|
50 |
+
"published_at": readable_date,
|
51 |
+
"url": item.get("link", ""),
|
52 |
+
}
|
53 |
+
state["articles"] = articles
|
54 |
+
|
55 |
+
# Retrieve income statement data
|
56 |
+
def income_statement(state):
|
57 |
+
quarterly_income_stmt = yf.Ticker(state["symbol"]).quarterly_income_stmt
|
58 |
+
df = pd.DataFrame(quarterly_income_stmt)
|
59 |
+
df.columns = pd.to_datetime(df.columns).strftime("%Y-%m-%d")
|
60 |
+
state["income_statement_df"] = df
|
61 |
+
update_bar_graph(state)
|
62 |
+
show_fin_metrics(state)
|
63 |
+
|
64 |
+
# Show financial metrics
|
65 |
+
def show_fin_metrics(state):
|
66 |
+
stock = yf.Ticker(state["symbol"])
|
67 |
+
operating_margins = stock.info['operatingMargins']
|
68 |
+
gross_margin = stock.info['grossMargins']
|
69 |
+
ebitda_margin = stock.info['ebitdaMargins']
|
70 |
+
|
71 |
+
state["operating_margin"] = f"{operating_margins * 100:.2f}%"
|
72 |
+
state["gross_margin"] = f"{gross_margin * 100:.2f}%"
|
73 |
+
state["ebitda_margin"] = f"{ebitda_margin * 100:.2f}%"
|
74 |
+
|
75 |
+
def _one_day_data(state):
|
76 |
+
state["last_24_hours_open"] = round(state["main_df"]["Open"].iloc[0], 2)
|
77 |
+
state["last_24_hours_high"] = round(state["main_df"]["High"].iloc[0], 2)
|
78 |
+
state["last_24_hours_low"] = round(state["main_df"]["Low"].iloc[0], 2)
|
79 |
+
|
80 |
+
# Retrieve earnings call transcript from JSON file
|
81 |
+
# You could replace this with a call to an API like Financial Modeling Prep
|
82 |
+
def earnings_calls(state):
|
83 |
+
ticker = state["symbol"]
|
84 |
+
with open('earnings-data.json', 'r') as file:
|
85 |
+
earnings_transcript = json.load(file)
|
86 |
+
if earnings_transcript:
|
87 |
+
for item in earnings_transcript:
|
88 |
+
if item['symbol'] == ticker:
|
89 |
+
state["earnings_transcript"] = item["content"]
|
90 |
+
else:
|
91 |
+
print("No earnings transcript found.")
|
finance-app-tutorial/ui.json
ADDED
@@ -0,0 +1,749 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"metadata": {
|
3 |
+
"writer_version": "0.7.0rc2"
|
4 |
+
},
|
5 |
+
"components": {
|
6 |
+
"root": {
|
7 |
+
"id": "root",
|
8 |
+
"type": "root",
|
9 |
+
"content": {
|
10 |
+
"appName": "Finance Dashboard"
|
11 |
+
},
|
12 |
+
"isCodeManaged": false,
|
13 |
+
"position": 0,
|
14 |
+
"handlers": {},
|
15 |
+
"visible": true
|
16 |
+
},
|
17 |
+
"c0f99a9e-5004-4e75-a6c6-36f17490b134": {
|
18 |
+
"id": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
19 |
+
"type": "page",
|
20 |
+
"content": {
|
21 |
+
"pageMode": ""
|
22 |
+
},
|
23 |
+
"isCodeManaged": false,
|
24 |
+
"position": 0,
|
25 |
+
"parentId": "root",
|
26 |
+
"handlers": {},
|
27 |
+
"visible": true
|
28 |
+
},
|
29 |
+
"bebc5fe9-63a7-46a7-b0fa-62303555cfaf": {
|
30 |
+
"id": "bebc5fe9-63a7-46a7-b0fa-62303555cfaf",
|
31 |
+
"type": "header",
|
32 |
+
"content": {
|
33 |
+
"text": "Finance Research Dashboard"
|
34 |
+
},
|
35 |
+
"isCodeManaged": false,
|
36 |
+
"position": 0,
|
37 |
+
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
38 |
+
"handlers": {},
|
39 |
+
"visible": true
|
40 |
+
},
|
41 |
+
"ahwykl4cny005thy": {
|
42 |
+
"id": "ahwykl4cny005thy",
|
43 |
+
"type": "dataframe",
|
44 |
+
"content": {
|
45 |
+
"dataframe": "@{main_df_subset}",
|
46 |
+
"showIndex": "no",
|
47 |
+
"enableSearch": "no"
|
48 |
+
},
|
49 |
+
"isCodeManaged": false,
|
50 |
+
"position": 0,
|
51 |
+
"parentId": "vyij4ox2ad95xyr9",
|
52 |
+
"handlers": {},
|
53 |
+
"visible": true
|
54 |
+
},
|
55 |
+
"opn16nq04zq9xha8": {
|
56 |
+
"id": "opn16nq04zq9xha8",
|
57 |
+
"type": "plotlygraph",
|
58 |
+
"content": {
|
59 |
+
"spec": "@{scatter_chart}"
|
60 |
+
},
|
61 |
+
"isCodeManaged": false,
|
62 |
+
"position": 2,
|
63 |
+
"parentId": "1db76a00z7imlyz1",
|
64 |
+
"handlers": {
|
65 |
+
"plotly-click": "charts.update_scatter_chart"
|
66 |
+
}
|
67 |
+
},
|
68 |
+
"e13teponreio9yyz": {
|
69 |
+
"id": "e13teponreio9yyz",
|
70 |
+
"type": "button",
|
71 |
+
"content": {
|
72 |
+
"text": "Max",
|
73 |
+
"buttonColor": "#BFCBFF",
|
74 |
+
"cssClasses": "",
|
75 |
+
"buttonTextColor": "#000000"
|
76 |
+
},
|
77 |
+
"isCodeManaged": false,
|
78 |
+
"position": 0,
|
79 |
+
"parentId": "g5mgb80xt38atz4f",
|
80 |
+
"handlers": {
|
81 |
+
"wf-click": "charts.handle_click"
|
82 |
+
},
|
83 |
+
"visible": true
|
84 |
+
},
|
85 |
+
"g5mgb80xt38atz4f": {
|
86 |
+
"id": "g5mgb80xt38atz4f",
|
87 |
+
"type": "horizontalstack",
|
88 |
+
"content": {},
|
89 |
+
"isCodeManaged": false,
|
90 |
+
"position": 1,
|
91 |
+
"parentId": "1db76a00z7imlyz1",
|
92 |
+
"handlers": {},
|
93 |
+
"visible": true
|
94 |
+
},
|
95 |
+
"juip2rw7hywumv35": {
|
96 |
+
"id": "juip2rw7hywumv35",
|
97 |
+
"type": "button",
|
98 |
+
"content": {
|
99 |
+
"text": "5D",
|
100 |
+
"buttonColor": "#BFCBFF",
|
101 |
+
"cssClasses": "",
|
102 |
+
"buttonTextColor": "#000000"
|
103 |
+
},
|
104 |
+
"isCodeManaged": false,
|
105 |
+
"position": 1,
|
106 |
+
"parentId": "g5mgb80xt38atz4f",
|
107 |
+
"handlers": {
|
108 |
+
"wf-click": "charts.handle_click"
|
109 |
+
},
|
110 |
+
"visible": true
|
111 |
+
},
|
112 |
+
"afamuurw1lpjkkze": {
|
113 |
+
"id": "afamuurw1lpjkkze",
|
114 |
+
"type": "button",
|
115 |
+
"content": {
|
116 |
+
"text": "1M",
|
117 |
+
"buttonColor": "#BFCBFF",
|
118 |
+
"cssClasses": "",
|
119 |
+
"buttonTextColor": "#000000"
|
120 |
+
},
|
121 |
+
"isCodeManaged": false,
|
122 |
+
"position": 2,
|
123 |
+
"parentId": "g5mgb80xt38atz4f",
|
124 |
+
"handlers": {
|
125 |
+
"wf-click": "charts.handle_click"
|
126 |
+
},
|
127 |
+
"visible": true
|
128 |
+
},
|
129 |
+
"77u7x4pf0ximsf0j": {
|
130 |
+
"id": "77u7x4pf0ximsf0j",
|
131 |
+
"type": "button",
|
132 |
+
"content": {
|
133 |
+
"text": "3M",
|
134 |
+
"buttonColor": "#BFCBFF",
|
135 |
+
"cssClasses": "",
|
136 |
+
"buttonTextColor": "#000000"
|
137 |
+
},
|
138 |
+
"isCodeManaged": false,
|
139 |
+
"position": 3,
|
140 |
+
"parentId": "g5mgb80xt38atz4f",
|
141 |
+
"handlers": {
|
142 |
+
"wf-click": "charts.handle_click"
|
143 |
+
},
|
144 |
+
"visible": true
|
145 |
+
},
|
146 |
+
"oh2g51ixvuu8gdwa": {
|
147 |
+
"id": "oh2g51ixvuu8gdwa",
|
148 |
+
"type": "metric",
|
149 |
+
"content": {
|
150 |
+
"name": "Open",
|
151 |
+
"note": "L24",
|
152 |
+
"description": "",
|
153 |
+
"metricValue": "@{last_24_hours_open}"
|
154 |
+
},
|
155 |
+
"isCodeManaged": false,
|
156 |
+
"position": 0,
|
157 |
+
"parentId": "rgv1dgdrvgiosh42",
|
158 |
+
"handlers": {},
|
159 |
+
"visible": true
|
160 |
+
},
|
161 |
+
"rgv1dgdrvgiosh42": {
|
162 |
+
"id": "rgv1dgdrvgiosh42",
|
163 |
+
"type": "horizontalstack",
|
164 |
+
"content": {},
|
165 |
+
"isCodeManaged": false,
|
166 |
+
"position": 0,
|
167 |
+
"parentId": "1db76a00z7imlyz1",
|
168 |
+
"handlers": {},
|
169 |
+
"visible": true
|
170 |
+
},
|
171 |
+
"6646510g33an9r0g": {
|
172 |
+
"id": "6646510g33an9r0g",
|
173 |
+
"type": "metric",
|
174 |
+
"content": {
|
175 |
+
"note": "L24",
|
176 |
+
"name": "High",
|
177 |
+
"description": "",
|
178 |
+
"metricValue": "@{last_24_hours_high}"
|
179 |
+
},
|
180 |
+
"isCodeManaged": false,
|
181 |
+
"position": 2,
|
182 |
+
"parentId": "rgv1dgdrvgiosh42",
|
183 |
+
"handlers": {},
|
184 |
+
"visible": true
|
185 |
+
},
|
186 |
+
"df3mr8my8ivc8yrt": {
|
187 |
+
"id": "df3mr8my8ivc8yrt",
|
188 |
+
"type": "metric",
|
189 |
+
"content": {
|
190 |
+
"note": "L24",
|
191 |
+
"name": "Low",
|
192 |
+
"description": "",
|
193 |
+
"metricValue": "@{last_24_hours_low}"
|
194 |
+
},
|
195 |
+
"isCodeManaged": false,
|
196 |
+
"position": 4,
|
197 |
+
"parentId": "rgv1dgdrvgiosh42",
|
198 |
+
"handlers": {},
|
199 |
+
"visible": true
|
200 |
+
},
|
201 |
+
"9v92jyh672s5wjkg": {
|
202 |
+
"id": "9v92jyh672s5wjkg",
|
203 |
+
"type": "tab",
|
204 |
+
"content": {
|
205 |
+
"name": "Stock data"
|
206 |
+
},
|
207 |
+
"isCodeManaged": false,
|
208 |
+
"position": 1,
|
209 |
+
"parentId": "yzujnjalyh2s2x16",
|
210 |
+
"handlers": {},
|
211 |
+
"visible": true
|
212 |
+
},
|
213 |
+
"bha2uz0y2jr7eszp": {
|
214 |
+
"id": "bha2uz0y2jr7eszp",
|
215 |
+
"type": "separator",
|
216 |
+
"content": {},
|
217 |
+
"isCodeManaged": false,
|
218 |
+
"position": 1,
|
219 |
+
"parentId": "rgv1dgdrvgiosh42",
|
220 |
+
"handlers": {},
|
221 |
+
"visible": true
|
222 |
+
},
|
223 |
+
"nzp2whzndpknrk55": {
|
224 |
+
"id": "nzp2whzndpknrk55",
|
225 |
+
"type": "separator",
|
226 |
+
"content": {},
|
227 |
+
"isCodeManaged": false,
|
228 |
+
"position": 3,
|
229 |
+
"parentId": "rgv1dgdrvgiosh42",
|
230 |
+
"handlers": {},
|
231 |
+
"visible": true
|
232 |
+
},
|
233 |
+
"suu5ceib1bqj0si5": {
|
234 |
+
"id": "suu5ceib1bqj0si5",
|
235 |
+
"type": "columns",
|
236 |
+
"content": {},
|
237 |
+
"isCodeManaged": false,
|
238 |
+
"position": 0,
|
239 |
+
"parentId": "9v92jyh672s5wjkg",
|
240 |
+
"handlers": {},
|
241 |
+
"visible": true
|
242 |
+
},
|
243 |
+
"vyij4ox2ad95xyr9": {
|
244 |
+
"id": "vyij4ox2ad95xyr9",
|
245 |
+
"type": "column",
|
246 |
+
"content": {
|
247 |
+
"width": "1"
|
248 |
+
},
|
249 |
+
"isCodeManaged": false,
|
250 |
+
"position": 0,
|
251 |
+
"parentId": "suu5ceib1bqj0si5",
|
252 |
+
"handlers": {},
|
253 |
+
"visible": true
|
254 |
+
},
|
255 |
+
"chwivjdj78wyyi9x": {
|
256 |
+
"id": "chwivjdj78wyyi9x",
|
257 |
+
"type": "button",
|
258 |
+
"content": {
|
259 |
+
"text": "Analyze trends"
|
260 |
+
},
|
261 |
+
"isCodeManaged": false,
|
262 |
+
"position": 0,
|
263 |
+
"parentId": "1yuilwwrhm40gxtx",
|
264 |
+
"handlers": {
|
265 |
+
"wf-click": "generate_stock_analysis"
|
266 |
+
},
|
267 |
+
"visible": true
|
268 |
+
},
|
269 |
+
"km4vvfnq6bwlakmp": {
|
270 |
+
"id": "km4vvfnq6bwlakmp",
|
271 |
+
"type": "text",
|
272 |
+
"content": {
|
273 |
+
"text": "@{analysis}",
|
274 |
+
"useMarkdown": "yes"
|
275 |
+
},
|
276 |
+
"isCodeManaged": false,
|
277 |
+
"position": 4,
|
278 |
+
"parentId": "i23vdas64ziuiazm",
|
279 |
+
"handlers": {},
|
280 |
+
"visible": "show_analysis_text.visible"
|
281 |
+
},
|
282 |
+
"h72djsz1oqncb5ls": {
|
283 |
+
"id": "h72djsz1oqncb5ls",
|
284 |
+
"type": "section",
|
285 |
+
"content": {
|
286 |
+
"title": "Latest news"
|
287 |
+
},
|
288 |
+
"isCodeManaged": false,
|
289 |
+
"position": 1,
|
290 |
+
"parentId": "0p1levffmcf4xlpl",
|
291 |
+
"handlers": {},
|
292 |
+
"visible": true
|
293 |
+
},
|
294 |
+
"zinu9f9cyur23m66": {
|
295 |
+
"id": "zinu9f9cyur23m66",
|
296 |
+
"type": "repeater",
|
297 |
+
"content": {
|
298 |
+
"repeaterObject": "@{articles}",
|
299 |
+
"keyVariable": "itemId",
|
300 |
+
"valueVariable": "item"
|
301 |
+
},
|
302 |
+
"isCodeManaged": false,
|
303 |
+
"position": 0,
|
304 |
+
"parentId": "h72djsz1oqncb5ls",
|
305 |
+
"handlers": {},
|
306 |
+
"visible": true
|
307 |
+
},
|
308 |
+
"dbdmqg2z74k4frq4": {
|
309 |
+
"id": "dbdmqg2z74k4frq4",
|
310 |
+
"type": "columns",
|
311 |
+
"content": {
|
312 |
+
"cssClasses": ""
|
313 |
+
},
|
314 |
+
"isCodeManaged": false,
|
315 |
+
"position": 0,
|
316 |
+
"parentId": "zinu9f9cyur23m66",
|
317 |
+
"handlers": {},
|
318 |
+
"visible": true
|
319 |
+
},
|
320 |
+
"p13mw4f6rr4z8d47": {
|
321 |
+
"id": "p13mw4f6rr4z8d47",
|
322 |
+
"type": "column",
|
323 |
+
"content": {
|
324 |
+
"title": "",
|
325 |
+
"width": "1",
|
326 |
+
"isSticky": "yes",
|
327 |
+
"isCollapsible": "",
|
328 |
+
"startCollapsed": "",
|
329 |
+
"cssClasses": ""
|
330 |
+
},
|
331 |
+
"isCodeManaged": false,
|
332 |
+
"position": 0,
|
333 |
+
"parentId": "dbdmqg2z74k4frq4",
|
334 |
+
"handlers": {},
|
335 |
+
"visible": true
|
336 |
+
},
|
337 |
+
"tji08jpu1y52kzz1": {
|
338 |
+
"id": "tji08jpu1y52kzz1",
|
339 |
+
"type": "link",
|
340 |
+
"content": {
|
341 |
+
"url": "@{item.url}",
|
342 |
+
"text": "@{item.source}",
|
343 |
+
"primaryTextColor": "#1d53d3",
|
344 |
+
"cssClasses": "link"
|
345 |
+
},
|
346 |
+
"isCodeManaged": false,
|
347 |
+
"position": 1,
|
348 |
+
"parentId": "4avlmncllyffxniu",
|
349 |
+
"handlers": {},
|
350 |
+
"visible": true
|
351 |
+
},
|
352 |
+
"4avlmncllyffxniu": {
|
353 |
+
"id": "4avlmncllyffxniu",
|
354 |
+
"type": "section",
|
355 |
+
"content": {
|
356 |
+
"title": "@{itemId}",
|
357 |
+
"primaryTextColor": "#000000",
|
358 |
+
"containerBackgroundColor": "#f7f7f7",
|
359 |
+
"containerShadow": "5px 5px 5px 2px #f8f7f7"
|
360 |
+
},
|
361 |
+
"isCodeManaged": false,
|
362 |
+
"position": 0,
|
363 |
+
"parentId": "p13mw4f6rr4z8d47",
|
364 |
+
"handlers": {},
|
365 |
+
"visible": true
|
366 |
+
},
|
367 |
+
"w3wt3976ggvcuwrg": {
|
368 |
+
"id": "w3wt3976ggvcuwrg",
|
369 |
+
"type": "text",
|
370 |
+
"content": {
|
371 |
+
"text": "**@{item.published_at}**",
|
372 |
+
"alignment": "right",
|
373 |
+
"useMarkdown": "yes"
|
374 |
+
},
|
375 |
+
"isCodeManaged": false,
|
376 |
+
"position": 0,
|
377 |
+
"parentId": "4avlmncllyffxniu",
|
378 |
+
"handlers": {},
|
379 |
+
"visible": true
|
380 |
+
},
|
381 |
+
"1db76a00z7imlyz1": {
|
382 |
+
"id": "1db76a00z7imlyz1",
|
383 |
+
"type": "section",
|
384 |
+
"content": {
|
385 |
+
"title": "@{symbol} stock performance"
|
386 |
+
},
|
387 |
+
"isCodeManaged": false,
|
388 |
+
"position": 1,
|
389 |
+
"parentId": "18wepug77yr8m1iu",
|
390 |
+
"handlers": {},
|
391 |
+
"visible": true
|
392 |
+
},
|
393 |
+
"i23vdas64ziuiazm": {
|
394 |
+
"id": "i23vdas64ziuiazm",
|
395 |
+
"type": "section",
|
396 |
+
"content": {
|
397 |
+
"title": ""
|
398 |
+
},
|
399 |
+
"isCodeManaged": false,
|
400 |
+
"position": 0,
|
401 |
+
"parentId": "0p1levffmcf4xlpl",
|
402 |
+
"handlers": {},
|
403 |
+
"visible": true
|
404 |
+
},
|
405 |
+
"8dbcbgiukyg74dkb": {
|
406 |
+
"id": "8dbcbgiukyg74dkb",
|
407 |
+
"type": "columns",
|
408 |
+
"content": {},
|
409 |
+
"isCodeManaged": false,
|
410 |
+
"position": 3,
|
411 |
+
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
412 |
+
"handlers": {},
|
413 |
+
"visible": true
|
414 |
+
},
|
415 |
+
"0p1levffmcf4xlpl": {
|
416 |
+
"id": "0p1levffmcf4xlpl",
|
417 |
+
"type": "column",
|
418 |
+
"content": {
|
419 |
+
"width": "0.75"
|
420 |
+
},
|
421 |
+
"isCodeManaged": false,
|
422 |
+
"position": 0,
|
423 |
+
"parentId": "8dbcbgiukyg74dkb",
|
424 |
+
"handlers": {},
|
425 |
+
"visible": true
|
426 |
+
},
|
427 |
+
"334d69p14onyi9wq": {
|
428 |
+
"id": "334d69p14onyi9wq",
|
429 |
+
"type": "column",
|
430 |
+
"content": {
|
431 |
+
"width": "1"
|
432 |
+
},
|
433 |
+
"isCodeManaged": false,
|
434 |
+
"position": 1,
|
435 |
+
"parentId": "8dbcbgiukyg74dkb",
|
436 |
+
"handlers": {},
|
437 |
+
"visible": true
|
438 |
+
},
|
439 |
+
"yzujnjalyh2s2x16": {
|
440 |
+
"id": "yzujnjalyh2s2x16",
|
441 |
+
"type": "tabs",
|
442 |
+
"content": {},
|
443 |
+
"isCodeManaged": false,
|
444 |
+
"position": 0,
|
445 |
+
"parentId": "334d69p14onyi9wq",
|
446 |
+
"handlers": {},
|
447 |
+
"visible": true
|
448 |
+
},
|
449 |
+
"18wepug77yr8m1iu": {
|
450 |
+
"id": "18wepug77yr8m1iu",
|
451 |
+
"type": "tab",
|
452 |
+
"content": {
|
453 |
+
"name": "Performance"
|
454 |
+
},
|
455 |
+
"isCodeManaged": false,
|
456 |
+
"position": 0,
|
457 |
+
"parentId": "yzujnjalyh2s2x16",
|
458 |
+
"handlers": {}
|
459 |
+
},
|
460 |
+
"9eieaedqpr1ickbb": {
|
461 |
+
"id": "9eieaedqpr1ickbb",
|
462 |
+
"type": "section",
|
463 |
+
"content": {
|
464 |
+
"title": "Investment research options",
|
465 |
+
"cssClasses": "",
|
466 |
+
"containerBackgroundColor": "#e9d3fd"
|
467 |
+
},
|
468 |
+
"isCodeManaged": false,
|
469 |
+
"position": 2,
|
470 |
+
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
471 |
+
"handlers": {},
|
472 |
+
"visible": true
|
473 |
+
},
|
474 |
+
"1yuilwwrhm40gxtx": {
|
475 |
+
"id": "1yuilwwrhm40gxtx",
|
476 |
+
"type": "horizontalstack",
|
477 |
+
"content": {},
|
478 |
+
"isCodeManaged": false,
|
479 |
+
"position": 0,
|
480 |
+
"parentId": "9eieaedqpr1ickbb",
|
481 |
+
"handlers": {},
|
482 |
+
"visible": true
|
483 |
+
},
|
484 |
+
"1vyfwym5dfh07ihb": {
|
485 |
+
"id": "1vyfwym5dfh07ihb",
|
486 |
+
"type": "message",
|
487 |
+
"content": {
|
488 |
+
"message": "@{message}"
|
489 |
+
},
|
490 |
+
"isCodeManaged": false,
|
491 |
+
"position": 0,
|
492 |
+
"parentId": "i23vdas64ziuiazm",
|
493 |
+
"handlers": {},
|
494 |
+
"visible": true
|
495 |
+
},
|
496 |
+
"fwmg7b84wstpxs7m": {
|
497 |
+
"id": "fwmg7b84wstpxs7m",
|
498 |
+
"type": "button",
|
499 |
+
"content": {
|
500 |
+
"text": "1Y",
|
501 |
+
"buttonColor": "#BFCBFF",
|
502 |
+
"cssClasses": "",
|
503 |
+
"buttonTextColor": "#000000"
|
504 |
+
},
|
505 |
+
"isCodeManaged": false,
|
506 |
+
"position": 4,
|
507 |
+
"parentId": "g5mgb80xt38atz4f",
|
508 |
+
"handlers": {
|
509 |
+
"wf-click": "charts.handle_click"
|
510 |
+
},
|
511 |
+
"visible": true
|
512 |
+
},
|
513 |
+
"jcs5oslp27w5v52j": {
|
514 |
+
"id": "jcs5oslp27w5v52j",
|
515 |
+
"type": "button",
|
516 |
+
"content": {
|
517 |
+
"text": "5Y",
|
518 |
+
"buttonColor": "#BFCBFF",
|
519 |
+
"cssClasses": "",
|
520 |
+
"buttonTextColor": "#000000"
|
521 |
+
},
|
522 |
+
"isCodeManaged": false,
|
523 |
+
"position": 5,
|
524 |
+
"parentId": "g5mgb80xt38atz4f",
|
525 |
+
"handlers": {
|
526 |
+
"wf-click": "charts.handle_click"
|
527 |
+
},
|
528 |
+
"visible": true
|
529 |
+
},
|
530 |
+
"s2jsn9u5xb23hase": {
|
531 |
+
"id": "s2jsn9u5xb23hase",
|
532 |
+
"type": "tags",
|
533 |
+
"content": {
|
534 |
+
"tags": "{\n \"AAPL\": \"AAPL\",\n \"IBM\": \"IBM\",\n \"NVDA\": \"NVDA\",\n \"MSFT\": \"MSFT\",\n \"TSLA\": \"TSLA\"\n}"
|
535 |
+
},
|
536 |
+
"isCodeManaged": false,
|
537 |
+
"position": 0,
|
538 |
+
"parentId": "kr54hbg2r5fkhsct",
|
539 |
+
"handlers": {
|
540 |
+
"wf-tag-click": "stock_tags"
|
541 |
+
},
|
542 |
+
"visible": true
|
543 |
+
},
|
544 |
+
"kr54hbg2r5fkhsct": {
|
545 |
+
"id": "kr54hbg2r5fkhsct",
|
546 |
+
"type": "section",
|
547 |
+
"content": {
|
548 |
+
"title": "Select a stock ticker"
|
549 |
+
},
|
550 |
+
"isCodeManaged": false,
|
551 |
+
"position": 1,
|
552 |
+
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
553 |
+
"handlers": {},
|
554 |
+
"visible": true
|
555 |
+
},
|
556 |
+
"8yxe1itvlcq4zhpi": {
|
557 |
+
"id": "8yxe1itvlcq4zhpi",
|
558 |
+
"type": "tab",
|
559 |
+
"content": {
|
560 |
+
"name": "Income data"
|
561 |
+
},
|
562 |
+
"isCodeManaged": false,
|
563 |
+
"position": 2,
|
564 |
+
"parentId": "yzujnjalyh2s2x16",
|
565 |
+
"handlers": {},
|
566 |
+
"visible": true
|
567 |
+
},
|
568 |
+
"tmiso5qe0e0jfl4i": {
|
569 |
+
"id": "tmiso5qe0e0jfl4i",
|
570 |
+
"type": "dataframe",
|
571 |
+
"content": {
|
572 |
+
"dataframe": "@{income_statement_df}"
|
573 |
+
},
|
574 |
+
"isCodeManaged": false,
|
575 |
+
"position": 0,
|
576 |
+
"parentId": "8yxe1itvlcq4zhpi",
|
577 |
+
"handlers": {},
|
578 |
+
"visible": true
|
579 |
+
},
|
580 |
+
"x6p3vxia2xlpbbib": {
|
581 |
+
"id": "x6p3vxia2xlpbbib",
|
582 |
+
"type": "button",
|
583 |
+
"content": {
|
584 |
+
"text": "Visualize income statement"
|
585 |
+
},
|
586 |
+
"isCodeManaged": false,
|
587 |
+
"position": 1,
|
588 |
+
"parentId": "1yuilwwrhm40gxtx",
|
589 |
+
"handlers": {
|
590 |
+
"wf-click": "generate_income_analysis"
|
591 |
+
},
|
592 |
+
"visible": true
|
593 |
+
},
|
594 |
+
"oo7y10uo68z3ayf8": {
|
595 |
+
"id": "oo7y10uo68z3ayf8",
|
596 |
+
"type": "plotlygraph",
|
597 |
+
"content": {
|
598 |
+
"spec": "@{bar_graph}"
|
599 |
+
},
|
600 |
+
"isCodeManaged": false,
|
601 |
+
"position": 2,
|
602 |
+
"parentId": "i23vdas64ziuiazm",
|
603 |
+
"handlers": {
|
604 |
+
"plotly-click": "charts.update_bar_graph"
|
605 |
+
},
|
606 |
+
"visible": "show_bar_graph.visible"
|
607 |
+
},
|
608 |
+
"a8a854zgzdrcel9j": {
|
609 |
+
"id": "a8a854zgzdrcel9j",
|
610 |
+
"type": "dropdowninput",
|
611 |
+
"content": {
|
612 |
+
"label": "Output language",
|
613 |
+
"options": "@{output_language}"
|
614 |
+
},
|
615 |
+
"isCodeManaged": false,
|
616 |
+
"position": 3,
|
617 |
+
"parentId": "i23vdas64ziuiazm",
|
618 |
+
"handlers": {
|
619 |
+
"wf-option-change": "prompt_parameters_lang"
|
620 |
+
},
|
621 |
+
"visible": "show_analysis_text.language"
|
622 |
+
},
|
623 |
+
"1c3vvmgyhvkm9d6e": {
|
624 |
+
"id": "1c3vvmgyhvkm9d6e",
|
625 |
+
"type": "horizontalstack",
|
626 |
+
"content": {},
|
627 |
+
"isCodeManaged": false,
|
628 |
+
"position": 1,
|
629 |
+
"parentId": "i23vdas64ziuiazm",
|
630 |
+
"handlers": {},
|
631 |
+
"visible": "show_income_metrics.visible"
|
632 |
+
},
|
633 |
+
"e7kux7h89zec8cmh": {
|
634 |
+
"id": "e7kux7h89zec8cmh",
|
635 |
+
"type": "metric",
|
636 |
+
"content": {
|
637 |
+
"name": "Operating Margin",
|
638 |
+
"note": "",
|
639 |
+
"metricValue": "@{operating_margin}"
|
640 |
+
},
|
641 |
+
"isCodeManaged": false,
|
642 |
+
"position": 0,
|
643 |
+
"parentId": "1c3vvmgyhvkm9d6e",
|
644 |
+
"handlers": {},
|
645 |
+
"visible": true
|
646 |
+
},
|
647 |
+
"0u3afw3gbxbj8h1x": {
|
648 |
+
"id": "0u3afw3gbxbj8h1x",
|
649 |
+
"type": "separator",
|
650 |
+
"content": {},
|
651 |
+
"isCodeManaged": false,
|
652 |
+
"position": 1,
|
653 |
+
"parentId": "1c3vvmgyhvkm9d6e",
|
654 |
+
"handlers": {},
|
655 |
+
"visible": true
|
656 |
+
},
|
657 |
+
"yxm3uezkrgpl11fc": {
|
658 |
+
"id": "yxm3uezkrgpl11fc",
|
659 |
+
"type": "metric",
|
660 |
+
"content": {
|
661 |
+
"name": "Gross Margin",
|
662 |
+
"note": "",
|
663 |
+
"metricValue": "@{gross_margin}"
|
664 |
+
},
|
665 |
+
"isCodeManaged": false,
|
666 |
+
"position": 2,
|
667 |
+
"parentId": "1c3vvmgyhvkm9d6e",
|
668 |
+
"handlers": {},
|
669 |
+
"visible": true
|
670 |
+
},
|
671 |
+
"nmdddxrvpgirasj6": {
|
672 |
+
"id": "nmdddxrvpgirasj6",
|
673 |
+
"type": "metric",
|
674 |
+
"content": {
|
675 |
+
"name": "EBIDTA Margin",
|
676 |
+
"note": "",
|
677 |
+
"metricValue": "@{ebitda_margin}"
|
678 |
+
},
|
679 |
+
"isCodeManaged": false,
|
680 |
+
"position": 4,
|
681 |
+
"parentId": "1c3vvmgyhvkm9d6e",
|
682 |
+
"handlers": {},
|
683 |
+
"visible": true
|
684 |
+
},
|
685 |
+
"xlzf1vlkmxokw9yj": {
|
686 |
+
"id": "xlzf1vlkmxokw9yj",
|
687 |
+
"type": "separator",
|
688 |
+
"content": {},
|
689 |
+
"isCodeManaged": false,
|
690 |
+
"position": 3,
|
691 |
+
"parentId": "1c3vvmgyhvkm9d6e",
|
692 |
+
"handlers": {},
|
693 |
+
"visible": true
|
694 |
+
},
|
695 |
+
"c52e2wkln9shvcoq": {
|
696 |
+
"id": "c52e2wkln9shvcoq",
|
697 |
+
"type": "section",
|
698 |
+
"content": {
|
699 |
+
"title": "",
|
700 |
+
"containerBackgroundColor": "#FFE999"
|
701 |
+
},
|
702 |
+
"isCodeManaged": false,
|
703 |
+
"position": 0,
|
704 |
+
"parentId": "18wepug77yr8m1iu",
|
705 |
+
"handlers": {},
|
706 |
+
"visible": "demo_mode.visible"
|
707 |
+
},
|
708 |
+
"3knng5h0zv8i3xra": {
|
709 |
+
"id": "3knng5h0zv8i3xra",
|
710 |
+
"type": "text",
|
711 |
+
"content": {
|
712 |
+
"text": "@{tab_message}",
|
713 |
+
"useMarkdown": "yes"
|
714 |
+
},
|
715 |
+
"isCodeManaged": false,
|
716 |
+
"position": 0,
|
717 |
+
"parentId": "c52e2wkln9shvcoq",
|
718 |
+
"handlers": {},
|
719 |
+
"visible": ""
|
720 |
+
},
|
721 |
+
"rhomvmilcrm8f2r1": {
|
722 |
+
"id": "rhomvmilcrm8f2r1",
|
723 |
+
"type": "button",
|
724 |
+
"content": {
|
725 |
+
"text": "Summarize earnings"
|
726 |
+
},
|
727 |
+
"isCodeManaged": false,
|
728 |
+
"position": 2,
|
729 |
+
"parentId": "1yuilwwrhm40gxtx",
|
730 |
+
"handlers": {
|
731 |
+
"wf-click": "summarize_earnings"
|
732 |
+
},
|
733 |
+
"visible": true
|
734 |
+
},
|
735 |
+
"1o0ui3hahmjblams": {
|
736 |
+
"id": "1o0ui3hahmjblams",
|
737 |
+
"type": "text",
|
738 |
+
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
|
739 |
+
"content": {
|
740 |
+
"text": "Made with \u2764\ufe0f using [Writer Framework](https://github.com/writer/writer-framework/)",
|
741 |
+
"useMarkdown": "yes",
|
742 |
+
"alignment": "center"
|
743 |
+
},
|
744 |
+
"handlers": {},
|
745 |
+
"position": 4,
|
746 |
+
"visible": true
|
747 |
+
}
|
748 |
+
}
|
749 |
+
}
|
pyproject.toml
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[tool.poetry]
|
2 |
+
name = "writer-framework-default"
|
3 |
+
version = "0.1.0"
|
4 |
+
description = ""
|
5 |
+
authors = ["Your Name <[email protected]>"]
|
6 |
+
readme = "README.md"
|
7 |
+
|
8 |
+
[tool.poetry.dependencies]
|
9 |
+
python = "^3.10.0"
|
10 |
+
writer = {version = "^0.6.0"}
|
11 |
+
|
12 |
+
|
13 |
+
[build-system]
|
14 |
+
requires = ["poetry-core"]
|
15 |
+
build-backend = "poetry.core.masonry.api"
|