primo commit

This commit is contained in:
fredmaloggia
2026-01-05 19:15:03 +01:00
commit f707b9c95b
61 changed files with 2928 additions and 0 deletions

202
pricer/db.py Normal file
View File

@@ -0,0 +1,202 @@
from typing import Any, Dict, Iterable, List, Tuple
import pyodbc
from decimal import Decimal
from .config import get_connection_string
from . import models
def _rows_to_dicts(cursor, rows):
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in rows]
def _normalize_keys(row: Dict[str, Any]) -> Dict[str, Any]:
normalized = {}
for k, v in row.items():
if isinstance(v, Decimal):
normalized[k.lower()] = float(v)
else:
normalized[k.lower()] = v
return normalized
class SqlDataAccess:
def load_data(self, stored_proc: str, params: Dict[str, Any], connection_string: str):
placeholders = ", ".join([f"@{k}=?" for k in params.keys()])
sql = f"EXEC {stored_proc} {placeholders}" if placeholders else f"EXEC {stored_proc}"
values = list(params.values())
with pyodbc.connect(connection_string) as conn:
cur = conn.cursor()
cur.execute(sql, values)
rows = cur.fetchall()
return _rows_to_dicts(cur, rows)
class SqlQuery:
def __init__(self, connection_string: str):
self._connection_string = connection_string
self._db = SqlDataAccess()
def get_hist_price_ul(self, isin: str, num_prezzi_eod: int):
rows = self._db.load_data(
"pricer_ULPrices1",
{"Isin": isin, "numPrezzi": num_prezzi_eod},
self._connection_string,
)
return [
models.HistPriceULModel(
id_underlyings=r["idunderlyings"],
sottostante=r["sottostante"],
px_close=r["px_close"],
px_date=r["px_date"],
)
for r in map(_normalize_keys, rows)
]
def get_details_ul(self, isin: str):
rows = self._db.load_data(
"pricer_ULDetails",
{"Isin": isin},
self._connection_string,
)
return [
models.DetailsULModel(
id_underlyings=r["idunderlyings"],
sottostante=r["sottostante"],
maturity_date=r.get("maturitydate"),
last_price=r["lastprice"],
strike=r["strike"],
spot_price_normalized=r["spotpricenormalized"],
dividend=r["dividend"],
volatility=r["volatility"],
days_to_maturity=r.get("daystomaturity", 0),
tasso_interesse=r.get("tassointeresse", 0.0),
)
for r in map(_normalize_keys, rows)
]
def get_details_event(self, isin: str):
rows = self._db.load_data(
"pricer_EventDetails",
{"Isin": isin},
self._connection_string,
)
return [
models.DetailsEventModel(
days_to_obs=r["daystoobs"],
days_to_ex_date=r.get("daystoexdate", 0),
days_to_obs_y_fract=r["daystoobsyfract"],
coupon_value=r["couponvalue"],
coupon_trigger=r["coupontrigger"],
autocall_value=r["autocallvalue"],
autocall_trigger=r["autocalltrigger"],
memory=r["memory"],
)
for r in map(_normalize_keys, rows)
]
def get_details_event_exdate(self, isin: str):
rows = self._db.load_data(
"pricer_EventDetails_ExDate",
{"Isin": isin},
self._connection_string,
)
return [
models.DetailsEventModel(
days_to_obs=r.get("daystoobs", 0),
days_to_ex_date=r["daystoexdate"],
days_to_obs_y_fract=r.get("daystoobsyfract", 0.0),
coupon_value=r.get("couponvalue", 0.0),
coupon_trigger=r.get("coupontrigger", 0.0),
autocall_value=r.get("autocallvalue", 0.0),
autocall_trigger=r.get("autocalltrigger", 0.0),
memory=r.get("memory", 0),
)
for r in map(_normalize_keys, rows)
]
def get_details_ctf(self, isin: str):
rows = self._db.load_data(
"pricer_CTFDetails",
{"Isin": isin},
self._connection_string,
)
return [
models.DetailsCTFModel(
tasso_interesse=r["tassointeresse"],
days_to_maturity=r["daystomaturity"],
pdi_style=r["pdi_style"],
pdi_strike=r["pdi_strike"],
pdi_barrier=r["pdi_barrier"],
capital_value=r["capitalvalue"],
nominal_amount=r["nominalamount"],
bid=r["bid"],
ask=r["ask"],
last_date_price=r["lastdateprice"],
coupon_in_memory=r["couponinmemory"],
prot_min_val=r["protminval"],
air_bag=r["airbag"],
fattore_airbag=r["fattoreairbag"],
one_star=r["onestar"],
trigger_onestar=r["triggeronestar"],
twin_win=r["twinwin"],
sigma=r["sigma"],
relief=r["relief"],
domino=r["domino"],
category=r["category"],
cap=r["cap"],
leva=r["leva"],
)
for r in map(_normalize_keys, rows)
]
def get_isin_universe(self):
rows = self._db.load_data(
"pricer_LoadISINUniverse",
{},
self._connection_string,
)
values = []
for row in rows:
if isinstance(row, dict):
if len(row) == 1:
values.append(next(iter(row.values())))
else:
values.append(row)
else:
values.append(row)
return values
def check_isin(self, isin: str):
rows = self._db.load_data(
"pricer_CheckISIN1",
{"Isin": isin},
self._connection_string,
)
values = []
for row in rows:
if isinstance(row, dict):
if len(row) == 1:
values.append(next(iter(row.values())))
else:
values.append(row)
else:
values.append(row)
return values
def bulk_update_certificates(self, table_name: str, list_fair_values: List[models.FairValues]) -> None:
if not list_fair_values:
return
sql = f"UPDATE {table_name} SET FairValue = ? WHERE ISIN = ?"
data = [(fv.fair_value, fv.isin) for fv in list_fair_values]
with pyodbc.connect(self._connection_string) as conn:
cur = conn.cursor()
cur.executemany(sql, data)
conn.commit()
def default_sql_query():
return SqlQuery(get_connection_string("FirstSolutionDB"))