-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathapp.py
More file actions
128 lines (111 loc) · 4.94 KB
/
Copy pathapp.py
File metadata and controls
128 lines (111 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import os
if os.environ.get("TESTING") == "1":
from unittest.mock import MagicMock
import pandas as pd
import okama as _ok
from tests.mocks.okama_mock import (
get_mock_namespaces,
mock_symbols_in_namespace,
PicklableAsset,
PicklableAssetList,
PicklablePortfolio,
PicklableInflation,
PicklableRate,
PicklableIndicator,
_CashflowParameters,
_RebalanceStrategy,
)
_ok.assets_namespaces = get_mock_namespaces()
_ok.namespaces = {ns: f"Mock {ns} namespace" for ns in get_mock_namespaces()}
_ok.symbols_in_namespace = mock_symbols_in_namespace
_ok.search = MagicMock(return_value=pd.DataFrame({"symbol": [], "name": []}))
_ok.Portfolio = lambda *a, **kw: PicklablePortfolio()
_ok.Rebalance = lambda *a, **kw: _RebalanceStrategy(**{k: v for k, v in kw.items() if k == "period"})
_ok.AssetList = PicklableAssetList
_ok.IndexationStrategy = lambda pf, *a, **kw: _CashflowParameters()
_ok.PercentageStrategy = lambda pf, *a, **kw: _CashflowParameters()
_ok.VanguardDynamicSpending = lambda *a, **kw: _CashflowParameters()
_ok.CutWithdrawalsIfDrawdown = lambda *a, **kw: _CashflowParameters()
_ok.TimeSeriesStrategy = lambda pf, *a, **kw: _CashflowParameters()
_ok.Asset = PicklableAsset
_ok.Inflation = PicklableInflation
_ok.Rate = PicklableRate
_ok.Indicator = PicklableIndicator
import dash
from dash import html, dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import plotly.io as pio
import navigation
import footer
pio.templates.default = "plotly_white"
app = dash.Dash(
__name__,
use_pages=True,
update_title="Loading okama ...",
external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.BOOTSTRAP],
# Required: pages create components dynamically (grids, export buttons/downloads,
# constructor rows), so callbacks legitimately reference ids absent at load time.
suppress_callback_exceptions=True,
)
# Yandex.Metrika <noscript> pixel. The live counter is the JS in assets/yandex.js, but the
# Yandex installation validator fetches the raw HTML without running JS and only sees
# <script src=".../yandex.js"> — the counter number 52900222 is absent from the static markup,
# so it reports CS_ERR_UNKNOWN. Embedding the standard noscript pixel here puts the counter id
# into the served HTML. This is a JS-disabled fallback only; it does NOT duplicate the JS
# counter (a <noscript> body renders solely when JavaScript is off).
app.index_string = """<!DOCTYPE html>
<html lang="en">
<head>
{%metas%}
<title>{%title%}</title>
{%favicon%}
{%css%}
</head>
<body>
<noscript><div><img src="https://mc.yandex.ru/watch/52900222"
style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<script type="application/ld+json">
{"@context":"https://schema.org","@graph":[
{"@type":"Organization","name":"okama","url":"https://okama.io/",
"logo":"https://okama.io/assets/logo.png"},
{"@type":"WebApplication","name":"okama","url":"https://okama.io/",
"applicationCategory":"FinanceApplication","operatingSystem":"Web",
"offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},
"description":"Investment portfolio analysis: efficient frontier, backtesting, asset comparison, macro data."}
]}
</script>
<!--[if IE]><script>
alert("Dash v2.7+ does not support Internet Explorer. Please use a newer browser.");
</script><![endif]-->
{%app_entry%}
<footer>
{%config%}
{%scripts%}
{%renderer%}
</footer>
</body>
</html>"""
server = app.server
import common # noqa: E402 — must be after TESTING block patches okama
from common.stale_callbacks import register_stale_callback_guard # noqa: E402
from common.seo import register_seo_head # noqa: E402
common.cache.init_app(server) # centralised; previously called per-controls-file
register_stale_callback_guard(server) # stale post-deploy clients get 204, not 500
register_seo_head(server) # per-page <title>/canonical/og:image in static HTML for crawlers
app.layout = html.Div([dcc.Store(id="store"), navigation.navbar, dash.page_container, footer.footer()])
app.clientside_callback(
"""
function(trigger) {
// can use any prop to trigger this callback - we just want to store the info on startup
const inner_width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
const inner_height = window.innerHeight|| document.documentElement.clientHeight|| document.body.clientHeight;
const screenInfo = {height :screen.height, width: screen.width, in_width: inner_width, in_height: inner_height};
return screenInfo
}
""",
Output("store", "data"),
Input("store", "data"),
)
if __name__ == "__main__":
app.run(debug=True, port=8050)