gaurv007 commited on
Commit
9dc18cd
·
verified ·
1 Parent(s): b59d9a6

Upload alpha_factory/infra/factor_store.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. alpha_factory/infra/factor_store.py +25 -13
alpha_factory/infra/factor_store.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Factor Store — DuckDB + Parquet persistence for all alphas.
3
  Single source of truth for every alpha ever submitted.
4
  """
5
  import duckdb
@@ -80,6 +80,8 @@ class FactorStore:
80
  iteration: int = 1,
81
  ):
82
  """Insert a new alpha candidate (before BRAIN results arrive)."""
 
 
83
  self.conn.execute("""
84
  INSERT OR REPLACE INTO alphas (alpha_id, expression, neutralization, decay,
85
  fields_used, operators_used, archetype, theme, anomaly_tag,
@@ -91,17 +93,24 @@ class FactorStore:
91
 
92
  def update_metrics(self, alpha_id: str, metrics: BrainMetrics, fitness_score: float):
93
  """Update alpha with BRAIN simulation results."""
94
- self.conn.execute("""
95
- UPDATE alphas SET
96
- sharpe_full = ?, sharpe_is = ?, sharpe_os = ?,
97
- fitness_brain = ?, turnover = ?, returns_total = ?,
98
- max_drawdown = ?, yearly_sharpe = ?, yearly_returns = ?,
99
- margin_pct = ?, fitness_score = ?
100
- WHERE alpha_id = ?
101
- """, [metrics.sharpe_full, metrics.sharpe_is, metrics.sharpe_os,
102
- metrics.fitness, metrics.turnover, metrics.returns,
103
- metrics.max_drawdown, metrics.yearly_sharpe, metrics.yearly_returns,
104
- metrics.margin_pct, fitness_score, alpha_id])
 
 
 
 
 
 
 
105
 
106
  def update_verdict(self, alpha_id: str, verdict: Verdict, memo: str = ""):
107
  """Set the final verdict for an alpha."""
@@ -144,8 +153,11 @@ class FactorStore:
144
 
145
  def count_consecutive_kills(self) -> int:
146
  """Count consecutive kills from most recent (for kill switch)."""
 
147
  results = self.conn.execute("""
148
- SELECT verdict FROM alphas ORDER BY submitted_at DESC LIMIT 50
 
 
149
  """).fetchall()
150
  count = 0
151
  for r in results:
 
1
  """
2
+ Factor Store — DuckDB persistence for all alphas.
3
  Single source of truth for every alpha ever submitted.
4
  """
5
  import duckdb
 
80
  iteration: int = 1,
81
  ):
82
  """Insert a new alpha candidate (before BRAIN results arrive)."""
83
+ # NOTE: All SQL uses parameterized queries (? placeholders) to prevent injection.
84
+ # The expression field is user-controlled (from LLM output) but is passed as a param.
85
  self.conn.execute("""
86
  INSERT OR REPLACE INTO alphas (alpha_id, expression, neutralization, decay,
87
  fields_used, operators_used, archetype, theme, anomaly_tag,
 
93
 
94
  def update_metrics(self, alpha_id: str, metrics: BrainMetrics, fitness_score: float):
95
  """Update alpha with BRAIN simulation results."""
96
+ # Wrap in transaction for atomicity
97
+ self.conn.execute("BEGIN TRANSACTION")
98
+ try:
99
+ self.conn.execute("""
100
+ UPDATE alphas SET
101
+ sharpe_full = ?, sharpe_is = ?, sharpe_os = ?,
102
+ fitness_brain = ?, turnover = ?, returns_total = ?,
103
+ max_drawdown = ?, yearly_sharpe = ?, yearly_returns = ?,
104
+ margin_pct = ?, fitness_score = ?
105
+ WHERE alpha_id = ?
106
+ """, [metrics.sharpe_full, metrics.sharpe_is, metrics.sharpe_os,
107
+ metrics.fitness, metrics.turnover, metrics.returns,
108
+ metrics.max_drawdown, metrics.yearly_sharpe, metrics.yearly_returns,
109
+ metrics.margin_pct, fitness_score, alpha_id])
110
+ self.conn.execute("COMMIT")
111
+ except Exception:
112
+ self.conn.execute("ROLLBACK")
113
+ raise
114
 
115
  def update_verdict(self, alpha_id: str, verdict: Verdict, memo: str = ""):
116
  """Set the final verdict for an alpha."""
 
153
 
154
  def count_consecutive_kills(self) -> int:
155
  """Count consecutive kills from most recent (for kill switch)."""
156
+ # Use rowid as tiebreaker for deterministic ordering when timestamps are equal
157
  results = self.conn.execute("""
158
+ SELECT verdict FROM alphas
159
+ ORDER BY submitted_at DESC, rowid DESC
160
+ LIMIT 50
161
  """).fetchall()
162
  count = 0
163
  for r in results: