cryman38 commited on
Commit
3c7ad8d
·
verified ·
1 Parent(s): 41c7c5f

Upload 17 files

Browse files
app.py CHANGED
@@ -4,35 +4,40 @@ from interface.rebalancing_interface import (
4
  output as rebalancing_output,
5
  update_output as rebalancing_update_output,
6
  examples as rebalancing_examples,
7
- component_rows as rebalancing_component_rows
 
8
  )
9
  from interface.share_price_trend_interface import (
10
  input as share_price_trend_inputs,
11
  output as share_price_trend_output,
12
  update_output as share_price_trend_update_output,
13
  examples as share_price_trend_examples,
14
- component_rows as share_price_trend_component_rows
 
15
  )
16
  from interface.dollar_cost_averaging_interface import (
17
  input as dollar_cost_averaging_inputs,
18
  output as dollar_cost_averaging_output,
19
  update_output as dollar_cost_averaging_update_output,
20
  examples as dollar_cost_averaging_examples,
21
- component_rows as dollar_cost_averaging_component_rows
 
22
  )
23
  from interface.retirement_planning_interface import (
24
  input as retirement_planning_inputs,
25
  output as retirement_planning_output,
26
  update_output as retirement_update_output,
27
  examples as retirement_planning_examples,
28
- component_rows as retirement_planning_component_rows,
 
29
  )
 
30
 
31
  tabs_configuration = [
32
- ("🚀 Re-Balancing Calculator", rebalancing_inputs, rebalancing_output, rebalancing_update_output, rebalancing_examples, rebalancing_component_rows),
33
- ("📈 Share Price Trend", share_price_trend_inputs, share_price_trend_output, share_price_trend_update_output, share_price_trend_examples, share_price_trend_component_rows),
34
- ("📉 Dollar Cost Averaging Calculator", dollar_cost_averaging_inputs, dollar_cost_averaging_output, dollar_cost_averaging_update_output, dollar_cost_averaging_examples, dollar_cost_averaging_component_rows),
35
- ("🎯 Retirement Planning", retirement_planning_inputs, retirement_planning_output, retirement_update_output, retirement_planning_examples, retirement_planning_component_rows),
36
  ]
37
 
38
  def initial_load(*args):
@@ -48,7 +53,18 @@ def initial_load(*args):
48
  return (rebalancing_results, share_price_trend_results, dollar_cost_averaging_results, retirement_results)
49
 
50
  MARKDOWN = """
51
- # TuneIt 🔥
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  """
54
  # Helper function to add buttons
@@ -87,8 +103,9 @@ def render_components(component_rows):
87
  else:
88
  row.render()
89
 
90
- def create_tab(tab_name, inputs, outputs, update_fn, examples, component_rows):
91
- with gr.TabItem(tab_name):
 
92
  with gr.Row():
93
  with gr.Column(elem_classes="input", scale=1):
94
  render_components(component_rows)
@@ -100,11 +117,12 @@ def create_tab(tab_name, inputs, outputs, update_fn, examples, component_rows):
100
  on_change(inputs, update_fn, outputs)
101
 
102
  with gr.Blocks(css='style.css') as demo:
103
- # gr.Markdown(MARKDOWN)
104
  with gr.Column(elem_id="col-container"):
105
  with gr.Tabs():
106
  for tab in tabs_configuration:
107
  create_tab(*tab)
 
108
 
109
  # demo.load(
110
  # initial_load,
 
4
  output as rebalancing_output,
5
  update_output as rebalancing_update_output,
6
  examples as rebalancing_examples,
7
+ component_rows as rebalancing_component_rows,
8
+ header as rebalancing_title
9
  )
10
  from interface.share_price_trend_interface import (
11
  input as share_price_trend_inputs,
12
  output as share_price_trend_output,
13
  update_output as share_price_trend_update_output,
14
  examples as share_price_trend_examples,
15
+ component_rows as share_price_trend_component_rows,
16
+ header as share_price_trend_title
17
  )
18
  from interface.dollar_cost_averaging_interface import (
19
  input as dollar_cost_averaging_inputs,
20
  output as dollar_cost_averaging_output,
21
  update_output as dollar_cost_averaging_update_output,
22
  examples as dollar_cost_averaging_examples,
23
+ component_rows as dollar_cost_averaging_component_rows,
24
+ header as dollar_cost_averaging_title
25
  )
26
  from interface.retirement_planning_interface import (
27
  input as retirement_planning_inputs,
28
  output as retirement_planning_output,
29
  update_output as retirement_update_output,
30
  examples as retirement_planning_examples,
31
+ component_rows as retirement_planning_component_rows,
32
+ header as retirement_planning_title
33
  )
34
+ from interface.about_interface import render_about_tab # "Support Us" 탭 추가
35
 
36
  tabs_configuration = [
37
+ ("🚀", rebalancing_inputs, rebalancing_output, rebalancing_update_output, rebalancing_examples, rebalancing_component_rows, rebalancing_title),
38
+ ("📈", share_price_trend_inputs, share_price_trend_output, share_price_trend_update_output, share_price_trend_examples, share_price_trend_component_rows, share_price_trend_title),
39
+ ("📉", dollar_cost_averaging_inputs, dollar_cost_averaging_output, dollar_cost_averaging_update_output, dollar_cost_averaging_examples, dollar_cost_averaging_component_rows, dollar_cost_averaging_title),
40
+ ("💸", retirement_planning_inputs, retirement_planning_output, retirement_update_output, retirement_planning_examples, retirement_planning_component_rows, retirement_planning_title),
41
  ]
42
 
43
  def initial_load(*args):
 
53
  return (rebalancing_results, share_price_trend_results, dollar_cost_averaging_results, retirement_results)
54
 
55
  MARKDOWN = """
56
+ # TuneIt 🔥 Investment Toolkit
57
+
58
+ Welcome to the **TuneIt Investment Toolkit**! This all-in-one platform is designed to help you optimize your financial strategies, whether you're balancing your portfolio, analyzing market trends, planning for retirement, or maximizing dividends.
59
+
60
+ Explore the tools below:
61
+
62
+ - `🚀 Re-Balancing Calculator`: Adjust your portfolio to maintain your desired asset allocation.
63
+ - `📈 Share Price Trend`: Analyze historical share price movements.
64
+ - `📉 Dollar Cost Averaging Calculator`: Assess the benefits of spreading out your investments.
65
+ - `💸 Dividend-Based Retirement Planning`: Calculate the investment required to achieve a dividend-based income stream during retirement.
66
+
67
+ Dive into each tool to enhance your investment decisions and secure your financial future.
68
 
69
  """
70
  # Helper function to add buttons
 
103
  else:
104
  row.render()
105
 
106
+ def create_tab(tab_name, inputs, outputs, update_fn, examples, component_rows, header):
107
+ with gr.Tab(tab_name):
108
+ gr.Markdown(header)
109
  with gr.Row():
110
  with gr.Column(elem_classes="input", scale=1):
111
  render_components(component_rows)
 
117
  on_change(inputs, update_fn, outputs)
118
 
119
  with gr.Blocks(css='style.css') as demo:
120
+ gr.Markdown(MARKDOWN, elem_id="col-container")
121
  with gr.Column(elem_id="col-container"):
122
  with gr.Tabs():
123
  for tab in tabs_configuration:
124
  create_tab(*tab)
125
+ render_about_tab() # "Support Us" 탭 추가
126
 
127
  # demo.load(
128
  # initial_load,
interface/about_interface.py CHANGED
@@ -504,10 +504,11 @@ def render_about_tab():
504
 
505
  [![Donate with PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=M8SBRC396DPBW)
506
 
507
- Or, if you prefer, you can also support us through Toss at:
508
 
509
- <a href="https://toss.me/eichijei" target="_blank">
510
- <img src="https://static.toss.im/logos/png/1x/logo-toss.png" alt="Donate with Toss" style="width: 150px;">
511
  </a>
512
  """)
513
 
 
 
504
 
505
  [![Donate with PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=M8SBRC396DPBW)
506
 
507
+ Or, if you prefer, you can also support us through KakaoPay at:
508
 
509
+ <a href="https://qr.kakaopay.com/Ej7jF6o7B" target="_blank">
510
+ <img src="https://t1.kakaocdn.net/pay_brand_admin/file/NvAxmhwMItNT4J2Uq1Rxt/ic-pfm.png" alt="Donate with KakaoPay" style="width: 150px;">
511
  </a>
512
  """)
513
 
514
+
interface/dollar_cost_averaging_interface.py CHANGED
@@ -1,12 +1,15 @@
1
  import gradio as gr
2
  from modules.dollar_cost_averaging import dollar_cost_averaging
3
 
 
 
 
 
4
  examples = [
5
  ["AAPL", 200, 9000, 560, 20000]
6
  ]
7
 
8
  # Define the inputs
9
- title = gr.Markdown("<h2 style='margin: 5px'>Dollar Cost Averaging Calculator</h2>")
10
  stock_code = gr.Textbox(label="Stock Code", value="368590")
11
  first_purchase = gr.Markdown("<h3 class='h3_title'>FIRST PURCHASE</h3>")
12
  old_price = gr.Number(label="Old Price", value=18153)
 
1
  import gradio as gr
2
  from modules.dollar_cost_averaging import dollar_cost_averaging
3
 
4
+ header = """
5
+ # 📉 Dollar Cost Averaging Calculator
6
+ Use this calculator to evaluate the potential benefits of dollar-cost averaging as part of your investment strategy. Spread your investments over time to reduce risk.
7
+ """
8
  examples = [
9
  ["AAPL", 200, 9000, 560, 20000]
10
  ]
11
 
12
  # Define the inputs
 
13
  stock_code = gr.Textbox(label="Stock Code", value="368590")
14
  first_purchase = gr.Markdown("<h3 class='h3_title'>FIRST PURCHASE</h3>")
15
  old_price = gr.Number(label="Old Price", value=18153)
interface/rebalancing_interface.py CHANGED
@@ -2,6 +2,10 @@ import gradio as gr
2
  from modules.rebalancing import rebalancing_tool
3
  from modules.utils import currency_codes, current_time
4
 
 
 
 
 
5
  examples = [
6
  ["KRW", "458730 KRW 769 [4],\n368590 KRW 122 [1],", 0],
7
  ["KRW", "SCHD USD 9.044802 [8],\nQQQ USD 0.404082 [2],",0],
 
2
  from modules.rebalancing import rebalancing_tool
3
  from modules.utils import currency_codes, current_time
4
 
5
+ header = """
6
+ # 🚀 Re-Balancing Calculator
7
+ Re-balancing your portfolio can help you stay aligned with your investment goals. Use this calculator to determine the necessary adjustments to your current asset allocation.
8
+ """
9
  examples = [
10
  ["KRW", "458730 KRW 769 [4],\n368590 KRW 122 [1],", 0],
11
  ["KRW", "SCHD USD 9.044802 [8],\nQQQ USD 0.404082 [2],",0],
interface/retirement_planning_interface.py CHANGED
@@ -1,13 +1,15 @@
1
  import gradio as gr
2
  from modules.retirement_planning import retirement_planning
3
 
 
 
 
4
  # Define examples for retirement planning
5
  examples = [
6
  [38, 55, 85, 2000000, 3.0, 10000000, 1500000, 0, True, 8, 8, 3.3, 3.3]
7
  ]
8
 
9
  # Define the input components
10
- title = gr.Markdown("<h2 style='margin: 5px'>Dividend-Based Retirement Planning Calculator</h2>")
11
  title_1 = gr.Markdown("<h3 class='h3_title'>Profile</h3>")
12
  current_age = gr.Slider(label="Current Age (15-60 Years)", value=38, minimum=15, maximum=60, step=1)
13
  retirement_age = gr.Slider(label="Retirement Age (Upto 70 Years)", value=55, minimum=15, maximum=70, step=1)
@@ -27,7 +29,7 @@ post_retirement_dividend_yield = gr.Number(label="Dividend Yield (Post-retiremen
27
 
28
  input = [current_age, retirement_age, life_expectancy, monthly_income_required, inflation_rate, initial_investment, monthly_contribution, annual_increase_in_monthly_contribution, reinvest_dividends, pre_retirement_dividend_growth, post_retirement_dividend_growth, pre_retirement_dividend_yield, post_retirement_dividend_yield]
29
  output = gr.HTML()
30
- component_rows = [title,
31
  title_1, [current_age, retirement_age, life_expectancy],[monthly_income_required, inflation_rate],
32
  title_2, [initial_investment, monthly_contribution, annual_increase_in_monthly_contribution], [reinvest_dividends],
33
  title_3, [pre_retirement_dividend_growth, post_retirement_dividend_growth], [pre_retirement_dividend_yield, post_retirement_dividend_yield]
 
1
  import gradio as gr
2
  from modules.retirement_planning import retirement_planning
3
 
4
+ header = """# 💸 Dividend-Based Retirement Planning Calculator
5
+ Plan your retirement around dividend income. This calculator helps you estimate how much you need to invest to generate a desired amount of annual income through dividends, ensuring a stable and predictable income stream during your retirement years.
6
+ """
7
  # Define examples for retirement planning
8
  examples = [
9
  [38, 55, 85, 2000000, 3.0, 10000000, 1500000, 0, True, 8, 8, 3.3, 3.3]
10
  ]
11
 
12
  # Define the input components
 
13
  title_1 = gr.Markdown("<h3 class='h3_title'>Profile</h3>")
14
  current_age = gr.Slider(label="Current Age (15-60 Years)", value=38, minimum=15, maximum=60, step=1)
15
  retirement_age = gr.Slider(label="Retirement Age (Upto 70 Years)", value=55, minimum=15, maximum=70, step=1)
 
29
 
30
  input = [current_age, retirement_age, life_expectancy, monthly_income_required, inflation_rate, initial_investment, monthly_contribution, annual_increase_in_monthly_contribution, reinvest_dividends, pre_retirement_dividend_growth, post_retirement_dividend_growth, pre_retirement_dividend_yield, post_retirement_dividend_yield]
31
  output = gr.HTML()
32
+ component_rows = [
33
  title_1, [current_age, retirement_age, life_expectancy],[monthly_income_required, inflation_rate],
34
  title_2, [initial_investment, monthly_contribution, annual_increase_in_monthly_contribution], [reinvest_dividends],
35
  title_3, [pre_retirement_dividend_growth, post_retirement_dividend_growth], [pre_retirement_dividend_yield, post_retirement_dividend_yield]
interface/share_price_trend_interface.py CHANGED
@@ -1,13 +1,16 @@
1
  import gradio as gr
2
  from modules.share_price_trend import share_price_trend, gradio_interface
3
 
 
 
 
 
4
  examples = [
5
  ["AAPL,GOOGL,MSFT", 90],
6
  ["SCHD,QQQ", 365]
7
  ]
8
 
9
  # Define Gradio components for inputs
10
- title = gr.Markdown("<h2 style='margin: 5px'>Share Price Trend</h2>")
11
  stock_codes = gr.Textbox(
12
  label="Stock Codes",
13
  # info="Enter stock codes separated by comma.",
@@ -18,8 +21,7 @@ period = gr.Slider(
18
  label="Number of Days",
19
  value=365,
20
  minimum=7,
21
- step = 1,
22
- randomize = True
23
  )
24
 
25
  # Define output component
 
1
  import gradio as gr
2
  from modules.share_price_trend import share_price_trend, gradio_interface
3
 
4
+ header = """
5
+ # 📈 Share Price Trend
6
+ Track the trends in share prices over time. This tool helps you analyze historical price movements to inform your investment decisions.
7
+ """
8
  examples = [
9
  ["AAPL,GOOGL,MSFT", 90],
10
  ["SCHD,QQQ", 365]
11
  ]
12
 
13
  # Define Gradio components for inputs
 
14
  stock_codes = gr.Textbox(
15
  label="Stock Codes",
16
  # info="Enter stock codes separated by comma.",
 
21
  label="Number of Days",
22
  value=365,
23
  minimum=7,
24
+ step = 1
 
25
  )
26
 
27
  # Define output component
modules/rebalancing.py CHANGED
@@ -248,7 +248,7 @@ def generate_rebalancing_analysis(portfolio, target_ratios, total_value, main_cu
248
  <tbody>
249
  {''.join(
250
  f"<tr>"
251
- f"<td><span class='highlight-black'>{adj['stock_code'].upper()}</span></td>"
252
  f"<td>{format_value(adj['current_value'])}</td>"
253
  f"<td>{adj['current_value_pct'] * 100:.1f}%</td>"
254
  f"<td style='text-align: center !important;'><span class='highlight-edit'>{adj['target_weight'] * 100:.0f}%</span></td>"
 
248
  <tbody>
249
  {''.join(
250
  f"<tr>"
251
+ f"<td>{adj['stock_code'].upper()}</td>"
252
  f"<td>{format_value(adj['current_value'])}</td>"
253
  f"<td>{adj['current_value_pct'] * 100:.1f}%</td>"
254
  f"<td style='text-align: center !important;'><span class='highlight-edit'>{adj['target_weight'] * 100:.0f}%</span></td>"
modules/utils.py CHANGED
@@ -73,7 +73,7 @@ def get_color_for_label(index, color_map, num_labels):
73
  color_map_storage[index] = cmap(1 - index / (num_labels - 1))
74
  return color_map_storage[index]
75
 
76
- def plot_donut_chart(data, color_map='Blues', font_path='Quicksand-Regular.ttf', legend_fontsize=30):
77
  # 데이터 필터링: 비중이 0이 아닌 항목만 추출
78
  filtered_data = {k: v for k, v in data.items() if v > 0}
79
 
 
73
  color_map_storage[index] = cmap(1 - index / (num_labels - 1))
74
  return color_map_storage[index]
75
 
76
+ def plot_donut_chart(data, color_map='Blues', font_path='./font/Quicksand-Regular.ttf', legend_fontsize=30):
77
  # 데이터 필터링: 비중이 0이 아닌 항목만 추출
78
  filtered_data = {k: v for k, v in data.items() if v > 0}
79
 
style.css CHANGED
@@ -19,6 +19,17 @@
19
  @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;700&display=swap');
20
  @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');
21
  @import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap');
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  :root {
24
  --background-color-light: #ffffff;
@@ -165,6 +176,10 @@
165
  border-collapse: collapse;
166
  }
167
 
 
 
 
 
168
  .table-container th, .table-container td {
169
  border: 1px solid #ddd;
170
  padding: 8px;
@@ -183,6 +198,7 @@
183
  position: sticky;
184
  left: 0;
185
  z-index: 1;
 
186
  }
187
 
188
  .table-container th:first-child {
 
19
  @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;700&display=swap');
20
  @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');
21
  @import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap');
22
+ /* @font-face {
23
+ font-family: 'Paperlogy Light';
24
+ src: url('/file=font/Paperlogy/Paperlogy-3Light.ttf') format('truetype');
25
+ font-weight: normal;
26
+ font-style: normal;
27
+ }
28
+
29
+ body {
30
+ font-family: 'Paperlogy Light', sans-serif;
31
+ } */
32
+
33
 
34
  :root {
35
  --background-color-light: #ffffff;
 
176
  border-collapse: collapse;
177
  }
178
 
179
+ .table-container td {
180
+ text-align: end;
181
+ }
182
+
183
  .table-container th, .table-container td {
184
  border: 1px solid #ddd;
185
  padding: 8px;
 
198
  position: sticky;
199
  left: 0;
200
  z-index: 1;
201
+ text-align: left;
202
  }
203
 
204
  .table-container th:first-child {