aggiunta produzione csv per QUO

This commit is contained in:
fredmaloggia
2025-12-30 06:56:10 +01:00
parent d5b66f79dc
commit 4f22b85ac8

View File

@@ -125,6 +125,26 @@ def validate_returns_frame(df_returns: pd.DataFrame, threshold: float = 0.2):
cols = ", ".join([f"{c} ({v:.0%})" for c, v in high_na.items()])
print(f"[warn] Colonne con >{threshold:.0%} di NaN prima del fill: {cols}")
# ---------------------------------
# Utility per mappare Asset Class -> NEO
# ---------------------------------
def map_neo_asset_class(asset_class: str) -> str:
"""Mappa l'Asset Class in un valore compatibile NEO."""
if not asset_class:
return ""
value = asset_class.strip().lower()
if "azion" in value:
return "Equity"
if "obblig" in value:
return "Fixed Income"
if "immobil" in value:
return "Real Estate"
if "metalli" in value or "materie" in value:
return "Commodities"
if "cript" in value or "crypto" in value:
return "Crypto"
return asset_class
# ---------------------------------
# Utility per R^2 sullequity line
# ---------------------------------
@@ -346,6 +366,8 @@ except SQLAlchemyError as e:
# =========================
template_path = os.path.join(INPUT_DIR, 'Template_Guardian.xls')
template_df = pd.read_excel(template_path)
template_neo_path = os.path.join(INPUT_DIR, 'Template NEO.csv')
template_neo_df = pd.read_csv(template_neo_path, sep=';', dtype=str).fillna("")
file_path = os.path.join(INPUT_DIR, 'Universo per ottimizzatore.xlsx')
df = pd.read_excel(
@@ -402,6 +424,8 @@ riskfree_rate = 0.02
optimized_weights = pd.DataFrame()
per_asset_metrics = {}
export_rows = []
export_rows_neo = []
neo_portfolio_name = "VAR6_5Y"
for (years, target_vol), name in volatility_targets.items():
period_start_date = end_date - pd.DateOffset(years=years)
@@ -537,6 +561,33 @@ for (years, target_vol), name in volatility_targets.items():
output_df = results_full_df.reindex(columns=template_cols)
export_rows.append(output_df)
# --- File CSV NEO (uno per portafoglio) ---
if name == neo_portfolio_name:
template_neo_cols = list(template_neo_df.columns)
if not template_neo_df.empty:
template_neo_defaults = template_neo_df.iloc[0].to_dict()
else:
template_neo_defaults = {col: "" for col in template_neo_cols}
neo_rows = []
for isin, weight in weights.items():
if weight > 0:
row = dict(template_neo_defaults)
row['Asset class'] = "Equity"
row['InstrumentType'] = row.get('InstrumentType') or "ISIN"
row['Instrument'] = isin
row['Currency'] = row.get('Currency') or "EUR"
row['Side'] = row.get('Side') or "Buy"
row['Quantity'] = round(float(weight * 0.95), 4)
row['Price'] = ""
neo_rows.append(row)
neo_full_df = pd.DataFrame(neo_rows, columns=template_neo_cols)
if neo_full_df.empty:
output_neo_df = pd.DataFrame(columns=template_neo_cols)
else:
output_neo_df = neo_full_df.reindex(columns=template_neo_cols)
export_rows_neo.append(output_neo_df)
# --- Pie chart asset allocation: salva in Output senza mostrare ---
asset_allocations = {asset: 0 for asset in asset_class_limits}
for isin, weight in weights.items():
@@ -689,3 +740,14 @@ with pd.ExcelWriter(combined_path, engine='openpyxl', mode='w') as writer:
combined_df = template_df.copy()
combined_df.to_excel(writer, sheet_name='Pesi Ottimizzati', index=False)
print(f"Pesi ottimizzati salvati in un unico file/sheet: '{combined_path}'.")
# =========================
# EXPORT CSV NEO
# =========================
neo_combined_path = os.path.join(OUTPUT_DIR, f"{date_tag} Pesi ottimizzati NEO.csv")
if export_rows_neo:
neo_combined_df = pd.concat(export_rows_neo, ignore_index=True)
else:
neo_combined_df = pd.DataFrame(columns=template_neo_df.columns)
neo_combined_df.to_csv(neo_combined_path, sep=';', index=False)
print(f"Pesi ottimizzati NEO salvati in un unico CSV: '{neo_combined_path}'.")