Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
#
|
| 2 |
import pandas as pd
|
| 3 |
import firebase_admin
|
| 4 |
from firebase_admin import credentials, db
|
|
@@ -6,8 +6,6 @@ import os
|
|
| 6 |
import json
|
| 7 |
|
| 8 |
# --- CONFIGURATION ---
|
| 9 |
-
# IMPORTANT: This script uses the same environment variables as your agents.
|
| 10 |
-
# Ensure FIRESTORE_SA_KEY and FIREBASE_DB_URL are set.
|
| 11 |
SA_KEY_JSON = os.environ.get('FIRESTORE_SA_KEY')
|
| 12 |
DB_URL = os.environ.get('FIREBASE_DB_URL')
|
| 13 |
AGENT_SIGNALS_REF = 'signals_v2'
|
|
@@ -38,17 +36,24 @@ def fetch_data_from_firebase(ref_name):
|
|
| 38 |
|
| 39 |
df = pd.DataFrame.from_dict(data, orient='index')
|
| 40 |
|
| 41 |
-
#
|
|
|
|
| 42 |
if 'timestamp_entry' in df.columns: # For agent signals
|
| 43 |
-
|
| 44 |
elif 'timestamp_published' in df.columns: # For news sentiment
|
| 45 |
-
|
| 46 |
else:
|
| 47 |
print(f"❌ Timestamp column not found in '{ref_name}'.")
|
| 48 |
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
|
|
|
| 50 |
df = df.set_index('timestamp').sort_index()
|
| 51 |
-
print(f"✅ Fetched {len(df)} records from '{ref_name}'.")
|
| 52 |
return df
|
| 53 |
except Exception as e:
|
| 54 |
print(f"❌ Error fetching data from '{ref_name}': {e}")
|
|
@@ -70,9 +75,6 @@ def run_fusion_analysis():
|
|
| 70 |
# 2. Fuse the datasets using time
|
| 71 |
print("\n--- Fusing Agent Decisions with News Sentiment ---")
|
| 72 |
|
| 73 |
-
# This is the core logic: For each agent signal, find the most recent news
|
| 74 |
-
# that was published right before it (within a 30-minute tolerance).
|
| 75 |
-
# This checks if "news was available" and relevant at the time of the decision.
|
| 76 |
fused_df = pd.merge_asof(
|
| 77 |
left=agent_df,
|
| 78 |
right=news_df[['sentiment', 'confidence_score', 'headline']],
|
|
@@ -82,7 +84,6 @@ def run_fusion_analysis():
|
|
| 82 |
tolerance=pd.Timedelta(minutes=30)
|
| 83 |
)
|
| 84 |
|
| 85 |
-
# Drop signals where no recent news was available
|
| 86 |
fused_df.dropna(subset=['sentiment'], inplace=True)
|
| 87 |
|
| 88 |
if fused_df.empty:
|
|
@@ -111,21 +112,20 @@ def run_fusion_analysis():
|
|
| 111 |
|
| 112 |
# Analysis 3: Does trading in alignment with high-confidence news lead to better outcomes?
|
| 113 |
print("\n[Analysis 3: Trade PnL vs. News Sentiment Alignment]")
|
| 114 |
-
# Filter for signals that have already been evaluated (have a PnL value)
|
| 115 |
evaluated_trades = fused_df.dropna(subset=['pnl'])
|
| 116 |
-
evaluated_trades['pnl'] = pd.to_numeric(evaluated_trades['pnl'])
|
| 117 |
|
| 118 |
-
# Create an 'alignment' score
|
| 119 |
-
def calculate_alignment(row):
|
| 120 |
-
if (row['action'] == 'BUY' and row['sentiment'] == 'Bullish') or \
|
| 121 |
-
(row['action'] == 'SELL' and row['sentiment'] == 'Bearish'):
|
| 122 |
-
return 'Aligned'
|
| 123 |
-
elif (row['action'] == 'BUY' and row['sentiment'] == 'Bearish') or \
|
| 124 |
-
(row['action'] == 'SELL' and row['sentiment'] == 'Bullish'):
|
| 125 |
-
return 'Misaligned'
|
| 126 |
-
return 'Neutral'
|
| 127 |
-
|
| 128 |
if not evaluated_trades.empty:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
evaluated_trades['alignment'] = evaluated_trades.apply(calculate_alignment, axis=1)
|
| 130 |
pnl_by_alignment = evaluated_trades.groupby('alignment')['pnl'].mean()
|
| 131 |
print(pnl_by_alignment)
|
|
|
|
| 1 |
+
# fusion_analysis_v2_corrected.py
|
| 2 |
import pandas as pd
|
| 3 |
import firebase_admin
|
| 4 |
from firebase_admin import credentials, db
|
|
|
|
| 6 |
import json
|
| 7 |
|
| 8 |
# --- CONFIGURATION ---
|
|
|
|
|
|
|
| 9 |
SA_KEY_JSON = os.environ.get('FIRESTORE_SA_KEY')
|
| 10 |
DB_URL = os.environ.get('FIREBASE_DB_URL')
|
| 11 |
AGENT_SIGNALS_REF = 'signals_v2'
|
|
|
|
| 36 |
|
| 37 |
df = pd.DataFrame.from_dict(data, orient='index')
|
| 38 |
|
| 39 |
+
# Determine the correct timestamp column name
|
| 40 |
+
timestamp_col = ''
|
| 41 |
if 'timestamp_entry' in df.columns: # For agent signals
|
| 42 |
+
timestamp_col = 'timestamp_entry'
|
| 43 |
elif 'timestamp_published' in df.columns: # For news sentiment
|
| 44 |
+
timestamp_col = 'timestamp_published'
|
| 45 |
else:
|
| 46 |
print(f"❌ Timestamp column not found in '{ref_name}'.")
|
| 47 |
return pd.DataFrame()
|
| 48 |
+
|
| 49 |
+
# --- THIS IS THE FIX ---
|
| 50 |
+
# Drop any rows where the timestamp column is missing before processing.
|
| 51 |
+
df.dropna(subset=[timestamp_col], inplace=True)
|
| 52 |
+
# ---------------------
|
| 53 |
|
| 54 |
+
df['timestamp'] = pd.to_datetime(df[timestamp_col], utc=True)
|
| 55 |
df = df.set_index('timestamp').sort_index()
|
| 56 |
+
print(f"✅ Fetched and validated {len(df)} records from '{ref_name}'.")
|
| 57 |
return df
|
| 58 |
except Exception as e:
|
| 59 |
print(f"❌ Error fetching data from '{ref_name}': {e}")
|
|
|
|
| 75 |
# 2. Fuse the datasets using time
|
| 76 |
print("\n--- Fusing Agent Decisions with News Sentiment ---")
|
| 77 |
|
|
|
|
|
|
|
|
|
|
| 78 |
fused_df = pd.merge_asof(
|
| 79 |
left=agent_df,
|
| 80 |
right=news_df[['sentiment', 'confidence_score', 'headline']],
|
|
|
|
| 84 |
tolerance=pd.Timedelta(minutes=30)
|
| 85 |
)
|
| 86 |
|
|
|
|
| 87 |
fused_df.dropna(subset=['sentiment'], inplace=True)
|
| 88 |
|
| 89 |
if fused_df.empty:
|
|
|
|
| 112 |
|
| 113 |
# Analysis 3: Does trading in alignment with high-confidence news lead to better outcomes?
|
| 114 |
print("\n[Analysis 3: Trade PnL vs. News Sentiment Alignment]")
|
|
|
|
| 115 |
evaluated_trades = fused_df.dropna(subset=['pnl'])
|
|
|
|
| 116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
if not evaluated_trades.empty:
|
| 118 |
+
evaluated_trades['pnl'] = pd.to_numeric(evaluated_trades['pnl'])
|
| 119 |
+
|
| 120 |
+
def calculate_alignment(row):
|
| 121 |
+
if (row['action'] == 'BUY' and row['sentiment'] == 'Bullish') or \
|
| 122 |
+
(row['action'] == 'SELL' and row['sentiment'] == 'Bearish'):
|
| 123 |
+
return 'Aligned'
|
| 124 |
+
elif (row['action'] == 'BUY' and row['sentiment'] == 'Bearish') or \
|
| 125 |
+
(row['action'] == 'SELL' and row['sentiment'] == 'Bullish'):
|
| 126 |
+
return 'Misaligned'
|
| 127 |
+
return 'Neutral'
|
| 128 |
+
|
| 129 |
evaluated_trades['alignment'] = evaluated_trades.apply(calculate_alignment, axis=1)
|
| 130 |
pnl_by_alignment = evaluated_trades.groupby('alignment')['pnl'].mean()
|
| 131 |
print(pnl_by_alignment)
|