Spaces:
Runtime error
Runtime error
Upload folder using huggingface_hub
Browse files
README.md
CHANGED
|
@@ -59,6 +59,8 @@ DEEPSEEK_API_KEY=your_deepseek_key_here
|
|
| 59 |
GOOGLE_API_KEY=your_google_key_here
|
| 60 |
XAI_API_KEY=your_grok_key_here
|
| 61 |
|
|
|
|
|
|
|
| 62 |
# Optional: For HuggingFace local mode
|
| 63 |
HF_TOKEN=your_huggingface_token_here
|
| 64 |
|
|
|
|
| 59 |
GOOGLE_API_KEY=your_google_key_here
|
| 60 |
XAI_API_KEY=your_grok_key_here
|
| 61 |
|
| 62 |
+
# Optional: FMP key for extracting date
|
| 63 |
+
FMP_API_KEY=your_fmp_key_here
|
| 64 |
# Optional: For HuggingFace local mode
|
| 65 |
HF_TOKEN=your_huggingface_token_here
|
| 66 |
|
app.py
CHANGED
|
@@ -20,6 +20,7 @@ from utils import (
|
|
| 20 |
resolve_market_to_ticker,
|
| 21 |
validate_date_range,
|
| 22 |
validate_ticker_symbol,
|
|
|
|
| 23 |
save_strategy_to_file,
|
| 24 |
yf_interval_info,
|
| 25 |
YF_INTERVALS,
|
|
@@ -93,6 +94,12 @@ def execute_python(code, market_name, data_source, interval, start_date, end_dat
|
|
| 93 |
return err, [], None, None
|
| 94 |
replay_interval = fmp_interval
|
| 95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
# Fetch data once and pass to run_bt
|
| 97 |
status_msg = ""
|
| 98 |
progress(0, desc="Fetching data")
|
|
|
|
| 20 |
resolve_market_to_ticker,
|
| 21 |
validate_date_range,
|
| 22 |
validate_ticker_symbol,
|
| 23 |
+
validate_fmp_key,
|
| 24 |
save_strategy_to_file,
|
| 25 |
yf_interval_info,
|
| 26 |
YF_INTERVALS,
|
|
|
|
| 94 |
return err, [], None, None
|
| 95 |
replay_interval = fmp_interval
|
| 96 |
|
| 97 |
+
# Validate FMP API key if FMP is selected
|
| 98 |
+
if source_lower == "fmp":
|
| 99 |
+
is_valid, error_msg = validate_fmp_key()
|
| 100 |
+
if not is_valid:
|
| 101 |
+
return error_msg, [], None, None
|
| 102 |
+
|
| 103 |
# Fetch data once and pass to run_bt
|
| 104 |
status_msg = ""
|
| 105 |
progress(0, desc="Fetching data")
|
utils.py
CHANGED
|
@@ -21,6 +21,7 @@ __all__ = [
|
|
| 21 |
"resolve_market_to_ticker",
|
| 22 |
"validate_date_range",
|
| 23 |
"validate_ticker_symbol",
|
|
|
|
| 24 |
"save_strategy_to_file",
|
| 25 |
"yf_interval_info",
|
| 26 |
"YF_INTERVALS",
|
|
@@ -101,7 +102,7 @@ def validate_date_range(selected_start: str, selected_end: str, current_date_str
|
|
| 101 |
|
| 102 |
def validate_ticker_symbol(tckr_symbl: str, data_source: str = "yahoofinance") -> str:
|
| 103 |
"""Validate a ticker symbol using either FMP or yfinance based on the data source.
|
| 104 |
-
|
| 105 |
Raises ValueError on invalid tickers or if the provider fails to respond.
|
| 106 |
"""
|
| 107 |
source = (data_source or "").lower()
|
|
@@ -129,6 +130,25 @@ def validate_ticker_symbol(tckr_symbl: str, data_source: str = "yahoofinance") -
|
|
| 129 |
except Exception:
|
| 130 |
raise ValueError(f"❌ Error: Unable to validate ticker symbol '{tckr_symbl}'.")
|
| 131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
YF_INTERVALS = ["1m", "5m", "15m", "30m", "1h", "1d"]
|
| 133 |
|
| 134 |
# Map YF intervals to FMP intervals (None = not supported)
|
|
|
|
| 21 |
"resolve_market_to_ticker",
|
| 22 |
"validate_date_range",
|
| 23 |
"validate_ticker_symbol",
|
| 24 |
+
"validate_fmp_key",
|
| 25 |
"save_strategy_to_file",
|
| 26 |
"yf_interval_info",
|
| 27 |
"YF_INTERVALS",
|
|
|
|
| 102 |
|
| 103 |
def validate_ticker_symbol(tckr_symbl: str, data_source: str = "yahoofinance") -> str:
|
| 104 |
"""Validate a ticker symbol using either FMP or yfinance based on the data source.
|
| 105 |
+
|
| 106 |
Raises ValueError on invalid tickers or if the provider fails to respond.
|
| 107 |
"""
|
| 108 |
source = (data_source or "").lower()
|
|
|
|
| 130 |
except Exception:
|
| 131 |
raise ValueError(f"❌ Error: Unable to validate ticker symbol '{tckr_symbl}'.")
|
| 132 |
|
| 133 |
+
|
| 134 |
+
def validate_fmp_key() -> tuple[bool, str]:
|
| 135 |
+
"""Validate FMP API key. Returns (is_valid, error_message)."""
|
| 136 |
+
# Check if key exists
|
| 137 |
+
api_key = os.getenv('FMP_API_KEY')
|
| 138 |
+
if not api_key:
|
| 139 |
+
return False, "❌ FMP_API_KEY environment variable not set. Please add it to your .env file."
|
| 140 |
+
|
| 141 |
+
# Test with lightweight API call
|
| 142 |
+
try:
|
| 143 |
+
fmp = FMP()
|
| 144 |
+
result = fmp.get_quote('SPY')
|
| 145 |
+
if result:
|
| 146 |
+
return True, ""
|
| 147 |
+
else:
|
| 148 |
+
return False, "❌ FMP API key is invalid. Please check your FMP_API_KEY in .env file."
|
| 149 |
+
except Exception as e:
|
| 150 |
+
return False, f"❌ FMP API validation failed: {str(e)}. Please check your FMP_API_KEY."
|
| 151 |
+
|
| 152 |
YF_INTERVALS = ["1m", "5m", "15m", "30m", "1h", "1d"]
|
| 153 |
|
| 154 |
# Map YF intervals to FMP intervals (None = not supported)
|