Skip to content

Commit 399aefd

Browse files
committed
code refactor
1 parent 7ce8b23 commit 399aefd

17 files changed

Lines changed: 1086 additions & 324 deletions

generate_weekly_report.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# generate_weekly_report.py (SCRIPT MASTER)
2+
"""
3+
Script master per generare il report settimanale completo
4+
"""
5+
from scripts.reports.generate_weekly_signals_report import generate_weekly_report
6+
from scripts.pipeline.update_db import update_daily_prices
7+
import sys
8+
from datetime import datetime
9+
10+
def main():
11+
"""
12+
Orchestrazione completa:
13+
1. Aggiorna i prezzi nel DB
14+
2. Genera il report settimanale
15+
"""
16+
print("🚀 AVVIO GENERAZIONE REPORT SETTIMANALE")
17+
print("=" * 50)
18+
19+
try:
20+
21+
generate_weekly_report()
22+
print()
23+
24+
print("🎉 OPERAZIONE COMPLETATA CON SUCCESSO!")
25+
print(f"⏰ Completato alle: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
26+
27+
except Exception as e:
28+
print(f"❌ ERRORE DURANTE L'ESECUZIONE: {e}")
29+
sys.exit(1)
30+
31+
if __name__ == "__main__":
32+
main()

scripts/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# scripts/__init__.py
2+
"""
3+
Trading Bot Scripts Package
4+
5+
Moduli principali:
6+
- utils: Utilities condivise (GCP, DB, Data, Trading)
7+
- trading: Generazione segnali e strategie
8+
- reports: Generazione report
9+
- pipeline: Aggiornamento dati
10+
"""
11+
12+
__version__ = "1.0.0"
13+
__author__ = "Trading Bot Team"
14+

scripts/pipeline/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# scripts/pipeline/__init__.py
2+
"""
3+
Pipeline Package
4+
5+
Moduli:
6+
- update_db: Aggiornamento quotidiano database
7+
"""
8+
9+
from .update_db import update_daily_prices
10+
11+
__all__ = ['update_daily_prices']

scripts/pipeline/update_db.py

Lines changed: 65 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,73 @@
1-
import gspread
2-
from google.oauth2.service_account import Credentials
3-
from google.cloud import secretmanager
4-
import pandas as pd
1+
# scripts/pipeline/update_db.py (REFACTORED)
52
from datetime import datetime
6-
import json
7-
import psycopg2
8-
import yfinance as yf
93

10-
# --- 1. Leggi il JSON della SA dal Secret Manager ---
11-
SECRET_NAME = "projects/trading-469418/secrets/service_account/versions/latest"
12-
client_sm = secretmanager.SecretManagerServiceClient()
13-
response = client_sm.access_secret_version(name=SECRET_NAME)
14-
service_account_info = json.loads(response.payload.data.decode("UTF-8"))
4+
# Import delle utilities
5+
from ..utils.gcp_utils import GoogleSheetsManager
6+
from ..utils.data_utils import download_yfinance_data, prepare_db_batch
7+
from ..utils.db_utils import DatabaseManager
158

16-
SCOPES = [
17-
"https://www.googleapis.com/auth/spreadsheets",
18-
"https://www.googleapis.com/auth/drive"
19-
]
20-
21-
creds = Credentials.from_service_account_info(service_account_info, scopes=SCOPES)
22-
client = gspread.authorize(creds)
23-
24-
# --- 2. Apri lo Sheet ---
9+
# Configurazioni
2510
SPREADSHEET_ID = '1Uh3S3YCyvupZ5yZh2uDi0XYGaZIkEkupxsYed6xRxgA'
26-
sheet = client.open_by_key(SPREADSHEET_ID)
27-
worksheet = sheet.sheet1
28-
29-
# --- 3. Leggi i ticker dallo Sheet ---
30-
data = worksheet.get_all_records()
31-
df_sheet = pd.DataFrame(data)
32-
tickers = df_sheet['Ticker'].dropna().unique().tolist()
33-
34-
print(f"Trovati {len(tickers)} ticker nello Sheet.")
3511

36-
# --- 4. Scarica i prezzi odierni con yfinance ---
37-
today = datetime.today().strftime('%Y-%m-%d')
38-
prices = yf.download(tickers, period="1d", interval="1d", group_by="ticker", auto_adjust=True, progress=False)
39-
40-
# Normalizza i dati in lista di dizionari per l'inserimento
41-
records = []
42-
for ticker in tickers:
12+
def update_daily_prices():
13+
"""
14+
Aggiorna i prezzi giornalieri nel database con i dati più recenti
15+
"""
16+
print("🔄 Inizio aggiornamento prezzi giornalieri...")
17+
18+
# --- 1. Setup Google Sheets e recupero ticker ---
19+
print("📊 Recupero ticker da Google Sheets...")
20+
sheets_manager = GoogleSheetsManager()
21+
tickers = sheets_manager.get_tickers_from_sheet(SPREADSHEET_ID)
22+
print(f"✅ Trovati {len(tickers)} ticker nello Sheet.")
23+
24+
if not tickers:
25+
print("❌ Nessun ticker trovato. Operazione interrotta.")
26+
return
27+
28+
# --- 2. Download dati da yfinance ---
29+
print("📈 Download dati odierni da yfinance...")
4330
try:
44-
df_t = prices[ticker] if len(tickers) > 1 else prices
45-
df_t = df_t[['Open', 'High', 'Low', 'Close', 'Volume']].reset_index()
46-
df_t['Ticker'] = ticker
47-
df_t.rename(columns={
48-
'Date': 'date',
49-
'Open': 'open',
50-
'High': 'high',
51-
'Low': 'low',
52-
'Close': 'close',
53-
'Volume': 'volume',
54-
'Ticker': 'ticker'
55-
}, inplace=True)
56-
records.extend(df_t.to_dict(orient='records'))
31+
df_prices = download_yfinance_data(tickers, period="1d", interval="1d")
32+
print(f"✅ Righe pronte da inserire: {len(df_prices)}")
33+
34+
if df_prices.empty:
35+
print("❌ Nessun dato scaricato. Operazione interrotta.")
36+
return
37+
5738
except Exception as e:
58-
print(f"Errore con {ticker}: {e}")
59-
60-
df_prices = pd.DataFrame(records)
61-
print(f"Righe pronte da inserire: {len(df_prices)}")
62-
63-
# --- 5. Leggi i secret del DB ---
64-
SECRET_DB_NAME = "projects/trading-469418/secrets/db_info/versions/latest"
65-
response_db = client_sm.access_secret_version(name=SECRET_DB_NAME)
66-
db_info = json.loads(response_db.payload.data.decode("UTF-8"))
67-
68-
conn = psycopg2.connect(
69-
host=db_info["DB_HOST"],
70-
port=db_info["DB_PORT"],
71-
database=db_info["DB_NAME"],
72-
user=db_info["DB_USER"],
73-
password=db_info["DB_PASSWORD"]
74-
)
75-
cursor = conn.cursor()
76-
77-
# --- 6. Inserisci/aggiorna dati nella tabella universe ---
78-
insert_query = """
79-
INSERT INTO universe (date, ticker, open, high, low, close, volume)
80-
VALUES (%s, %s, %s, %s, %s, %s, %s)
81-
ON CONFLICT (date, ticker) DO UPDATE
82-
SET open = EXCLUDED.open,
83-
high = EXCLUDED.high,
84-
low = EXCLUDED.low,
85-
close = EXCLUDED.close,
86-
volume = EXCLUDED.volume;
87-
"""
88-
89-
batch = [
90-
(row['date'].date(), row['ticker'], row['open'], row['high'], row['low'], row['close'], row['volume'])
91-
for _, row in df_prices.iterrows()
92-
]
93-
94-
cursor.executemany(insert_query, batch)
95-
conn.commit()
96-
cursor.close()
97-
conn.close()
39+
print(f"❌ Errore nel download dati: {e}")
40+
return
41+
42+
# --- 3. Preparazione dati per DB ---
43+
print("🔧 Preparazione dati per inserimento...")
44+
batch_data = prepare_db_batch(df_prices)
45+
46+
if not batch_data:
47+
print("❌ Nessun dato valido da inserire.")
48+
return
49+
50+
# --- 4. Inserimento in database ---
51+
print("💾 Inserimento dati nel database...")
52+
try:
53+
db_manager = DatabaseManager()
54+
55+
# Usa DO UPDATE per aggiornare dati esistenti (prezzi possono cambiare durante il giorno)
56+
conflict_resolution = """DO UPDATE
57+
SET open = EXCLUDED.open,
58+
high = EXCLUDED.high,
59+
low = EXCLUDED.low,
60+
close = EXCLUDED.close,
61+
volume = EXCLUDED.volume"""
62+
63+
rows_processed = db_manager.insert_batch_universe(batch_data, conflict_resolution)
64+
print(f"✅ {rows_processed} righe inserite/aggiornate su PostgreSQL")
65+
66+
except Exception as e:
67+
print(f"❌ Errore nell'inserimento database: {e}")
68+
return
69+
70+
print("🎉 Aggiornamento completato con successo!")
9871

99-
print(f"{len(batch)} righe inserite/aggiornate su PostgreSQL")
72+
if __name__ == "__main__":
73+
update_daily_prices()

scripts/reports/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# scripts/reports/__init__.py
2+
"""
3+
Reports Package
4+
5+
Moduli:
6+
- generate_weekly_signals_report: Report settimanale completo
7+
"""
8+
9+
from .generate_weekly_signals_report import generate_weekly_report
10+
11+
__all__ = ['generate_weekly_report']

0 commit comments

Comments
 (0)