gaurv007 commited on
Commit
edca7d5
·
verified ·
1 Parent(s): 2e0c39f

Upload alpha_factory/config.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. alpha_factory/config.py +102 -0
alpha_factory/config.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Configuration — all settings in one place.
3
+ Environment variables override defaults.
4
+ """
5
+ from pydantic import BaseModel, Field
6
+ from pathlib import Path
7
+ import os
8
+
9
+
10
+ class LLMConfig(BaseModel):
11
+ """LLM serving configuration."""
12
+ microfish_model: str = "Qwen/Qwen2.5-1.5B-Instruct"
13
+ tinyfish_model: str = "Qwen/Qwen2.5-3B-Instruct"
14
+ mediumfish_model: str = "Qwen/Qwen2.5-7B-Instruct"
15
+ bigfish_model: str = "Qwen/Qwen2.5-72B-Instruct"
16
+ base_url: str = Field(default="http://localhost:8000/v1", description="vLLM / Ollama endpoint")
17
+ api_key: str = "dummy"
18
+ temperature_generation: float = 0.7
19
+ temperature_compilation: float = 0.1
20
+ temperature_critique: float = 0.3
21
+ max_tokens: int = 4096
22
+
23
+
24
+ class BrainConfig(BaseModel):
25
+ """WorldQuant BRAIN API configuration."""
26
+ api_url: str = "https://api.worldquantbrain.com"
27
+ region: str = "USA"
28
+ universe: str = "TOP3000"
29
+ delay: int = 1
30
+ truncation: float = 0.08
31
+ pasteurization: str = "ON"
32
+ nan_handling: str = "OFF"
33
+ max_concurrent: int = 4
34
+ submit_interval_sec: float = 15.0
35
+
36
+
37
+ class KillSwitches(BaseModel):
38
+ """Hard circuit breakers — non-negotiable."""
39
+ daily_brain_submissions_max: int = 200
40
+ consecutive_lint_fail_max: int = 10
41
+ consecutive_kill_verdict_max: int = 30
42
+ daily_llm_token_budget: int = 5_000_000
43
+ max_credits_per_family: int = 3
44
+
45
+
46
+ class FitnessWeights(BaseModel):
47
+ """Fitness function coefficients. Calibrate with hand-rankings after 20+ alphas."""
48
+ sharpe_os: float = 1.0
49
+ is_os_gap_penalty: float = 0.5
50
+ worst_year_penalty: float = 1.0
51
+ crowding_penalty: float = 0.3
52
+ turnover_penalty: float = 0.2
53
+ turnover_threshold: float = 0.40
54
+ drawdown_penalty: float = 0.1
55
+ drawdown_threshold: float = 0.05
56
+ novelty_bonus: float = 0.4
57
+
58
+
59
+ class Paths(BaseModel):
60
+ """All filesystem paths."""
61
+ root: Path = Path(os.getenv("AF_ROOT", "."))
62
+ data: Path = Field(default=None)
63
+ factor_store: Path = Field(default=None)
64
+ prompts: Path = Field(default=None)
65
+ logs: Path = Field(default=None)
66
+
67
+ def model_post_init(self, __context):
68
+ if self.data is None:
69
+ self.data = self.root / "data"
70
+ if self.factor_store is None:
71
+ self.factor_store = self.root / "factor_store"
72
+ if self.prompts is None:
73
+ self.prompts = self.root / "prompts"
74
+ if self.logs is None:
75
+ self.logs = self.root / "logs"
76
+ # Ensure directories exist
77
+ for p in [self.data, self.factor_store, self.factor_store / "alphas",
78
+ self.prompts, self.prompts / "templates", self.logs]:
79
+ p.mkdir(parents=True, exist_ok=True)
80
+
81
+
82
+ class Config(BaseModel):
83
+ """Master configuration."""
84
+ llm: LLMConfig = LLMConfig()
85
+ brain: BrainConfig = BrainConfig()
86
+ kill: KillSwitches = KillSwitches()
87
+ fitness: FitnessWeights = FitnessWeights()
88
+ paths: Paths = Paths()
89
+
90
+ # Pipeline settings
91
+ batch_size: int = 10 # alphas per batch
92
+ max_iterations_per_family: int = 3
93
+ correlation_threshold: float = 0.65
94
+ min_sharpe_local_sim: float = 1.0
95
+ min_info_value_sign_sweep: float = 0.3
96
+
97
+
98
+ def load_config() -> Config:
99
+ """Load config with env var overrides."""
100
+ return Config(
101
+ paths=Paths(root=Path(os.getenv("AF_ROOT", ".")))
102
+ )