Source code for finstmt.resolver.history
from typing import Dict, List
import pandas as pd
from sympy import Eq, IndexedBase, sympify
from finstmt.combined.statements import FinancialStatements
from finstmt.resolver.base import ResolverBase
from finstmt.resolver.solve import solve_equations, sympy_dict_to_results_dict
[docs]class StatementsResolver(ResolverBase):
[docs] def to_statements(self, **kwargs) -> FinancialStatements:
if self.solve_eqs:
solutions_dict = solve_equations(self.solve_eqs, self.subs_dict)
else:
solutions_dict = self.subs_dict
new_results = sympy_dict_to_results_dict(
solutions_dict,
pd.DatetimeIndex(self.stmts.dates),
self.stmts.all_config_items,
)
all_results = pd.concat(list(new_results.values()), axis=1).T
inc_df = self.stmts.income_statements.__class__.from_df(
all_results,
self.stmts.income_statements.config.items,
disp_unextracted=False,
)
bs_df = self.stmts.balance_sheets.__class__.from_df(
all_results, self.stmts.balance_sheets.config.items, disp_unextracted=False
)
obj = FinancialStatements(inc_df, bs_df, calculate=False, **kwargs)
return obj
@property
def t_indexed_eqs(self) -> List[Eq]:
config_managers = [
self.stmts.income_statements.config.items,
self.stmts.balance_sheets.config.items,
]
all_eqs = []
for config_manage in config_managers:
for config in config_manage:
lhs = sympify(
config.key + "[t]", locals=self.stmts.config.sympy_namespace
)
if config.expr_str is not None:
rhs = self.stmts.config.expr_for(config.key)
eq = Eq(lhs, rhs)
all_eqs.append(eq)
return all_eqs
@property
def all_eqs(self) -> List[Eq]:
t_eqs = self.t_indexed_eqs
out_eqs = []
subs_dict = self.sympy_subs_dict
for period in range(self.num_periods):
this_t_eqs = []
for eq in t_eqs:
period_eq = eq.subs({self.t: period})
if period_eq.lhs in subs_dict:
# Already have data for this, no need to calculate
continue
this_t_eqs.append(period_eq)
out_eqs.extend(this_t_eqs)
return out_eqs
@property
def num_periods(self) -> int:
return len(self.stmts.dates)
@property
def sympy_subs_dict(self) -> Dict[IndexedBase, float]:
nper = self.num_periods
subs_dict = {}
for config in self.stmts.all_config_items:
key = config.key
for period in range(nper):
t_key = f"{key}[{period}]"
lhs = sympify(t_key, locals=self.stmts.config.sympy_namespace)
value = getattr(self.stmts, key).iloc[period]
if config.expr_str is not None and value == 0:
# Don't have a value but it can be calculated, calculate it by not adding to substitutions
continue
subs_dict[lhs] = value
return subs_dict