Instantly share code, notes, and snippets.
Last active
May 19, 2026 13:47
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save alonsosilvaallende/5e8f2be65d46dfd9fa10ce6c6e9764db to your computer and use it in GitHub Desktop.
Share in Success Evaluation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # /// script | |
| # dependencies = [ | |
| # "altair==6.1.0", | |
| # "curl-cffi==0.15.0", | |
| # "ipython==9.13.0", | |
| # "marimo", | |
| # "matplotlib==3.10.9", | |
| # "polars==1.40.1", | |
| # "pyarrow==24.0.0", | |
| # "yfinance==1.3.0", | |
| # ] | |
| # requires-python = ">=3.13" | |
| # /// | |
| import marimo | |
| __generated_with = "0.23.5" | |
| app = marimo.App(width="medium") | |
| @app.cell | |
| def _(): | |
| import marimo as mo | |
| import pyarrow as pa | |
| import polars as pl | |
| import yfinance as yf | |
| import curl_cffi | |
| from datetime import datetime | |
| from zoneinfo import ZoneInfo | |
| import time | |
| return ZoneInfo, curl_cffi, datetime, mo, pl, time, yf | |
| @app.cell | |
| def _(mo): | |
| monthly_investment = mo.ui.number(value=225, label="Monthly investment:") | |
| rfr = mo.ui.number(value=1.5, label="Taux Livret A (%):") | |
| mo.hstack([monthly_investment, rfr], justify="start", gap=1) | |
| return monthly_investment, rfr | |
| @app.cell | |
| def _(mo, monthly_investment, rfr): | |
| total_investment = 12 * monthly_investment.value | |
| risk_free_return = total_investment * rfr.value / 100 | |
| mo.md(f"Total investment: {total_investment:,.0f} € → Risk free return: {risk_free_return:,.2f} €".replace(',',' ')) | |
| return (total_investment,) | |
| @app.cell | |
| def _(mo, total_investment): | |
| extra_expectation = total_investment / 2 | |
| mo.md(f"Expected gross return: {extra_expectation:,.2f} €".replace(",", " ")) | |
| return (extra_expectation,) | |
| @app.cell | |
| def _(curl_cffi, time): | |
| def get_net_before_taxes(annual_gross_salary): | |
| url = "https://mon-entreprise.urssaf.fr/api/v1/evaluate" | |
| payload = { | |
| "expressions": [ | |
| "salarié . rémunération . net . à payer avant impôt", | |
| "salarié . coût total employeur", | |
| ], | |
| "situation": { | |
| "salarié . contrat": "'CDI'", | |
| "salarié . contrat . statut cadre": "oui", | |
| "salarié . rémunération . brut": { | |
| "valeur": annual_gross_salary, | |
| "unité": "€/an" | |
| } | |
| } | |
| } | |
| max_retries = 3 | |
| for attempt in range(max_retries): | |
| try: | |
| r = curl_cffi.post(url, json=payload, impersonate="chrome") | |
| r.raise_for_status() | |
| return r.json()["evaluate"][0]["nodeValue"], r.json()["evaluate"][1]["nodeValue"] | |
| except: | |
| print(f"Tentative {attempt + 1} échouée") | |
| if attempt < max_retries - 1: | |
| time.sleep(1) | |
| else: | |
| print("Échec définitif.") | |
| return (get_net_before_taxes,) | |
| @app.cell | |
| def _(mo): | |
| monthly_gross_salary = mo.ui.number(value=4_000, label="Monthly gross salary (€):") | |
| return (monthly_gross_salary,) | |
| @app.cell | |
| def _(monthly_gross_salary): | |
| annual_gross_salary = 12 * monthly_gross_salary.value | |
| return (annual_gross_salary,) | |
| @app.cell | |
| def _(mo, monthly_gross_salary): | |
| mo.hstack([monthly_gross_salary, mo.md(f"Annual gross salary: {12*monthly_gross_salary.value:,.2f} €".replace(",", " "))], justify="start", gap=1) | |
| return | |
| @app.cell | |
| def _(annual_gross_salary, extra_expectation, get_net_before_taxes): | |
| from concurrent.futures import ThreadPoolExecutor | |
| grosses = [annual_gross_salary, annual_gross_salary + extra_expectation] | |
| with ThreadPoolExecutor() as executor: | |
| results = list(executor.map(get_net_before_taxes, grosses)) | |
| return ThreadPoolExecutor, results | |
| @app.cell | |
| def _(mo, results): | |
| mo.md(f"Expected net return before taxes: {12*(results[1][0] - results[0][0]):,.2f} € (*amount paid by Nokia: {12*(results[1][1] - results[0][1]):,.2f} €*)".replace(",", " ")) | |
| return | |
| @app.cell | |
| def _(mo): | |
| tax_brackets = {"0%": 0, "11%": 11, "30%": 30, "41%": 41, "45%": 45} | |
| marginal_tax_bracket = mo.ui.radio(options=tax_brackets, value="30%", inline=True, label="Taux marginal d'imposition:") | |
| marginal_tax_bracket | |
| return (marginal_tax_bracket,) | |
| @app.cell | |
| def _(ThreadPoolExecutor, get_net_before_taxes, marginal_tax_bracket): | |
| def get_diff(annual_gross_salary, extra): | |
| grosses = [annual_gross_salary, annual_gross_salary + extra] | |
| with ThreadPoolExecutor() as executor: | |
| results = list(executor.map(get_net_before_taxes, grosses)) | |
| return 12*(results[1][0] - results[0][0])*(1 - .9 * marginal_tax_bracket.value/100) | |
| return (get_diff,) | |
| @app.cell | |
| def _(extra_expectation, get_diff, monthly_gross_salary): | |
| print(f"Expected net return after taxes: {get_diff(12*monthly_gross_salary.value, extra_expectation):,.2f} €".replace(",", " ")) | |
| return | |
| @app.cell | |
| def _(marginal_tax_bracket, mo, results): | |
| mo.md(f"Expected net return after taxes: {12*(results[1][0] - results[0][0])*(1 - (1-.1) *marginal_tax_bracket.value/100):,.2f} €".replace(',',' ')) | |
| return | |
| @app.cell | |
| def _(pl, yf): | |
| nokia = yf.Ticker("NOKIA.HE") | |
| pd_data = nokia.history(period="max", interval="1d") | |
| data = pl.from_pandas(pd_data, include_index=True) | |
| return (data,) | |
| @app.cell | |
| def _(data): | |
| print(data.head(3)) | |
| return | |
| @app.cell | |
| def _(data): | |
| import matplotlib.pyplot as plt | |
| plt.plot(data["Date"], data["Close"]) | |
| plt.title("Nokia stock value over time") | |
| plt.show() | |
| return | |
| @app.cell | |
| def _(): | |
| import altair as alt | |
| return (alt,) | |
| @app.cell | |
| def _(alt, data): | |
| # --- Selection --- | |
| label = alt.selection_point( | |
| encodings=['x'], # limit selection to x-axis value | |
| on='mouseover', # select on mouseover events | |
| nearest=True, # select data point nearest the cursor | |
| empty='none' # empty selection includes no data points | |
| ) | |
| # --- Base chart --- | |
| base = alt.Chart(data).encode( | |
| x=alt.X('Date:T', axis=alt.Axis(title='Date')) | |
| ) | |
| # --- Main line --- | |
| line = base.mark_line(color='steelblue').encode( | |
| y=alt.Y('Close:Q', axis=alt.Axis(title='Close Price (€)')) | |
| ) | |
| # --- Vertical rule on hover --- | |
| rule = alt.Chart(data).mark_rule(color='#aaa').encode( | |
| x=alt.X('Date:T') | |
| ).transform_filter(label) | |
| # --- Circle marker on nearest point --- | |
| circle = base.mark_circle(size=80, color='steelblue').encode( | |
| y=alt.Y('Close:Q'), | |
| opacity=alt.condition(label, alt.value(1), alt.value(0)), | |
| tooltip=['Date:T', 'Close:Q'] | |
| ).add_params(label) | |
| # --- Text label (white stroke background for readability) --- | |
| text_bg = base.mark_text( | |
| align='left', dx=5, dy=-10, | |
| stroke='white', strokeWidth=2 | |
| ).encode( | |
| y=alt.Y('Close:Q'), | |
| text=alt.Text('Close:Q', format='.2f') | |
| ).transform_filter(label) | |
| # --- Text label (foreground) --- | |
| text_fg = base.mark_text( | |
| align='left', dx=5, dy=-10 | |
| ).encode( | |
| y=alt.Y('Close:Q'), | |
| text=alt.Text('Close:Q', format='.2f') | |
| ).transform_filter(label) | |
| # --- Combine all layers --- | |
| chart = alt.layer( | |
| line, | |
| rule, | |
| circle, | |
| text_bg, | |
| text_fg, | |
| data=data | |
| ).properties( | |
| title='Nokia Stock Value Over Time', | |
| width=700, | |
| height=400 | |
| ) | |
| return | |
| @app.cell | |
| def _(): | |
| # chart | |
| return | |
| @app.cell | |
| def _(data, pl): | |
| print(data.select( | |
| pl.col("Close").log().diff().mean() | |
| ).item() * 272) | |
| return | |
| @app.cell | |
| def _(data, pl): | |
| print(data.select( | |
| pl.col("Close").log().diff().std() | |
| ).item() * (272 ** .5)) | |
| return | |
| @app.cell | |
| def _(data): | |
| last_stock_value = data.item(row=-1, column="Close") | |
| print(last_stock_value) | |
| return | |
| @app.cell | |
| def _(ZoneInfo, data, datetime, pl): | |
| from typing import Literal | |
| def get_stock_value_by_date( | |
| date: str, | |
| col: Literal["Open", "High", "Low", "Close", "Volume", "Dividends", "Stock Splits"] = "Close" | |
| ) -> float: | |
| splitted_date = date.split("-") | |
| year = int(splitted_date[0]) | |
| month = int(splitted_date[1]) | |
| day = int(splitted_date[2]) | |
| target_date = datetime( | |
| year, month, day, | |
| tzinfo=ZoneInfo("Europe/Helsinki") | |
| ) | |
| return data.filter(pl.col("Date")>= target_date).sort("Date").select(col).item(0, 0) | |
| return (get_stock_value_by_date,) | |
| @app.cell | |
| def _(get_stock_value_by_date): | |
| print(get_stock_value_by_date("2026-05-14", "Close")) | |
| return | |
| @app.cell | |
| def _(get_stock_value_by_date): | |
| print(225 * 3 / get_stock_value_by_date("2026-04-27", "Close")) | |
| return | |
| @app.cell | |
| def _(get_stock_value_by_date, monthly_investment, total_investment): | |
| def evaluate_share_in_success_by_year(year): | |
| value_purchase_date_1st_quarter = get_stock_value_by_date(f"{year }-10-27") | |
| value_purchase_date_2nd_quarter = get_stock_value_by_date(f"{year+1}-01-27") | |
| value_purchase_date_3rd_quarter = get_stock_value_by_date(f"{year+1}-04-27") | |
| value_purchase_date_4th_quarter = get_stock_value_by_date(f"{year+1}-07-27") | |
| value_sell_date = get_stock_value_by_date(f"{year+1}-09-01") | |
| gain = ( | |
| (3 * monthly_investment.value / value_purchase_date_1st_quarter) + | |
| (3 * monthly_investment.value / value_purchase_date_2nd_quarter) + | |
| (3 * monthly_investment.value / value_purchase_date_3rd_quarter) + | |
| (3 * monthly_investment.value / value_purchase_date_4th_quarter) | |
| ) * value_sell_date | |
| extra = gain * 0.5 | |
| return gain - total_investment, extra | |
| return (evaluate_share_in_success_by_year,) | |
| @app.cell | |
| def _(get_stock_value_by_date): | |
| value_purchase_date_1st_quarter_2025_2026 = get_stock_value_by_date(f"2025-10-26") | |
| value_purchase_date_2nd_quarter_2025_2026 = get_stock_value_by_date(f"2026-02-01") | |
| value_purchase_date_3rd_quarter_2025_2026 = get_stock_value_by_date(f"2026-04-27") | |
| return ( | |
| value_purchase_date_1st_quarter_2025_2026, | |
| value_purchase_date_2nd_quarter_2025_2026, | |
| value_purchase_date_3rd_quarter_2025_2026, | |
| ) | |
| @app.cell | |
| def _(data): | |
| stock_value_last_date = data.item(row=-1, column="Close") | |
| print(stock_value_last_date) | |
| return (stock_value_last_date,) | |
| @app.cell | |
| def _(stock_value_last_date): | |
| value_purchase_date_4th_quarter_2025_2026 = stock_value_last_date | |
| value_sell_date_2025_2026 = stock_value_last_date | |
| return value_purchase_date_4th_quarter_2025_2026, value_sell_date_2025_2026 | |
| @app.cell | |
| def _(monthly_investment, value_purchase_date_1st_quarter_2025_2026): | |
| print(monthly_investment.value / value_purchase_date_1st_quarter_2025_2026) | |
| return | |
| @app.cell | |
| def _(monthly_investment, value_purchase_date_2nd_quarter_2025_2026): | |
| print(monthly_investment.value / value_purchase_date_2nd_quarter_2025_2026) | |
| return | |
| @app.cell | |
| def _(monthly_investment, value_purchase_date_3rd_quarter_2025_2026): | |
| print(monthly_investment.value / value_purchase_date_3rd_quarter_2025_2026) | |
| return | |
| @app.cell | |
| def _( | |
| monthly_investment, | |
| total_investment, | |
| value_purchase_date_1st_quarter_2025_2026, | |
| value_purchase_date_2nd_quarter_2025_2026, | |
| value_purchase_date_3rd_quarter_2025_2026, | |
| value_purchase_date_4th_quarter_2025_2026, | |
| value_sell_date_2025_2026, | |
| ): | |
| gain_2025_2026 = ( | |
| (3 * monthly_investment.value / value_purchase_date_1st_quarter_2025_2026) + | |
| (3 * monthly_investment.value / value_purchase_date_2nd_quarter_2025_2026) + | |
| (3 * monthly_investment.value / value_purchase_date_3rd_quarter_2025_2026) + | |
| (3 * monthly_investment.value / value_purchase_date_4th_quarter_2025_2026) | |
| ) * value_sell_date_2025_2026 | |
| print(gain_2025_2026-total_investment) | |
| return (gain_2025_2026,) | |
| @app.cell | |
| def _(gain_2025_2026): | |
| extra_2025_2026 = gain_2025_2026 * 0.5 | |
| print(extra_2025_2026) | |
| return (extra_2025_2026,) | |
| @app.cell | |
| def _(gain_2025_2026, marginal_tax_bracket, total_investment): | |
| gain_after_taxes_2025_2026 = (gain_2025_2026-total_investment)*(1 - .9 * marginal_tax_bracket.value/100) | |
| print(gain_after_taxes_2025_2026) | |
| return (gain_after_taxes_2025_2026,) | |
| @app.cell | |
| def _( | |
| annual_gross_salary, | |
| extra_2025_2026, | |
| gain_after_taxes_2025_2026, | |
| get_diff, | |
| ): | |
| total_gain_after_taxes_2025_2026 = gain_after_taxes_2025_2026 + get_diff(annual_gross_salary, extra_2025_2026) | |
| print(total_gain_after_taxes_2025_2026) | |
| return | |
| @app.cell | |
| def _( | |
| evaluate_share_in_success_by_year, | |
| extra_2025_2026, | |
| gain_2025_2026, | |
| total_investment, | |
| ): | |
| di = {} | |
| for _year in range(2_000, 2_025): | |
| a, b = evaluate_share_in_success_by_year(_year) | |
| di[f"{_year}"] = [a, b] | |
| di["2025"] = [gain_2025_2026-total_investment, extra_2025_2026] | |
| return (di,) | |
| @app.cell | |
| def _(di, pl): | |
| df = pl.from_dict(di).transpose(include_header=True, column_names=["PnL", "extra"]) | |
| return (df,) | |
| @app.cell | |
| def _(df, marginal_tax_bracket, pl): | |
| df1 = df.with_columns( | |
| pl.col("PnL").map_elements(lambda x: x* (1- .9 * marginal_tax_bracket.value / 100) if x >=0 else x).alias("PnL_after_tax") | |
| ) | |
| return (df1,) | |
| @app.cell | |
| def _(annual_gross_salary, df1, get_diff, pl): | |
| df2 = df1.with_columns( | |
| pl.col("extra").map_elements(lambda x: get_diff(annual_gross_salary, x)).alias("extra_after_tax") | |
| ) | |
| return (df2,) | |
| @app.cell | |
| def _(df2, pl): | |
| df3 = df2.with_columns( | |
| (pl.col("PnL_after_tax") + pl.col("extra_after_tax")).alias("return_after_tax") | |
| ) | |
| return (df3,) | |
| @app.cell | |
| def _(df3, pl, total_investment): | |
| df4 = df3.with_columns( | |
| (100*(pl.col("return_after_tax")/total_investment)).alias("return_rate_after_tax(%)") | |
| ) | |
| return (df4,) | |
| @app.cell | |
| def _(df4, mo): | |
| with mo.redirect_stdout(): | |
| for i, year in enumerate([y for y in range(2_000,2_025)]): | |
| print(f"Share in Success {year}-{year+1}: {df4.item(row=i, column='return_after_tax'):,.2f} €, return rate: {df4.item(row=i, column='return_rate_after_tax(%)'):,.2f}%") | |
| print(f"Share in Success 2025-2026 (estimated): {df4.item(row=-1, column='return_after_tax'):,.2f} €, return rate: {df4.item(row=-1, column='return_rate_after_tax(%)'):,.2f}%") | |
| return | |
| @app.cell | |
| def _(df4, pl): | |
| print(f"Average return: {df4.select( | |
| pl.col("return_after_tax").mean() | |
| ).item():,.0f} €".replace(',',' ')) | |
| return | |
| @app.cell | |
| def _(df4, pl): | |
| print(f"Average return rate: {df4.select( | |
| pl.col("return_rate_after_tax(%)").mean() | |
| ).item():,.2f}%".replace(',',' ')) | |
| return | |
| @app.cell | |
| def _(df4, pl): | |
| print(f"Median return: {df4.select( | |
| pl.col("return_after_tax").median() | |
| ).item():,.0f} €".replace(',',' ')) | |
| return | |
| @app.cell | |
| def _(df4, pl): | |
| print(f"Median return rate: {df4.select( | |
| pl.col("return_rate_after_tax(%)").median() | |
| ).item():,.2f}%".replace(',',' ')) | |
| return | |
| @app.cell | |
| def _(): | |
| return | |
| @app.cell | |
| def _(): | |
| return | |
| @app.cell | |
| def _(): | |
| return | |
| if __name__ == "__main__": | |
| app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment