prabalGaur commited on
Commit
fbf3bf1
·
verified ·
1 Parent(s): b461061

Upload community_contributions/chrys/sources/alpha_vantage.py with huggingface_hub

Browse files
community_contributions/chrys/sources/alpha_vantage.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Alpha Vantage adapter for stocks and indices."""
2
+ import requests
3
+
4
+ from models import AssetData
5
+
6
+ API_URL = "https://www.alphavantage.co/query"
7
+
8
+
9
+ def fetch_alpha_vantage(symbol: str, api_key: str) -> AssetData | None:
10
+ if not api_key:
11
+ return None
12
+ try:
13
+ # Quote
14
+ q = requests.get(
15
+ API_URL,
16
+ params={"function": "GLOBAL_QUOTE", "symbol": symbol, "apikey": api_key},
17
+ timeout=15,
18
+ )
19
+ q.raise_for_status()
20
+ qj = q.json()
21
+ quote = qj.get("Global Quote", {})
22
+ if not quote:
23
+ return None
24
+ price = float(quote.get("05. price", 0) or 0)
25
+ change_pct = quote.get("10. change percent", "0%").strip("%") or "0"
26
+ try:
27
+ change_val = float(change_pct)
28
+ except ValueError:
29
+ change_val = 0.0
30
+ change_24h = f"{change_val:+.2f}%" if change_val else "0%"
31
+
32
+ # Daily time series for OHLCV and 52w
33
+ t = requests.get(
34
+ API_URL,
35
+ params={
36
+ "function": "TIME_SERIES_DAILY",
37
+ "symbol": symbol,
38
+ "outputsize": "compact",
39
+ "apikey": api_key,
40
+ },
41
+ timeout=15,
42
+ )
43
+ t.raise_for_status()
44
+ tj = t.json()
45
+ series = tj.get("Time Series (Daily)", {})
46
+ if not series:
47
+ return AssetData(
48
+ asset=symbol,
49
+ price=price,
50
+ change_24h=change_24h,
51
+ volume_ratio=1.0,
52
+ ohlcv_14=[],
53
+ ohlcv_50=[],
54
+ high_52w=price,
55
+ low_52w=price,
56
+ )
57
+ # Sort by date descending
58
+ dates = sorted(series.keys(), reverse=True)
59
+ ohlcv_50 = []
60
+ for d in dates[:50]:
61
+ v = series[d]
62
+ ohlcv_50.append({
63
+ "t": d,
64
+ "o": float(v.get("1. open", 0)),
65
+ "h": float(v.get("2. high", 0)),
66
+ "l": float(v.get("3. low", 0)),
67
+ "c": float(v.get("4. close", 0)),
68
+ "v": int(float(v.get("5. volume", 0))),
69
+ })
70
+ ohlcv_14 = ohlcv_50[:14]
71
+ if len(ohlcv_50) < 20:
72
+ vol_avg_20 = sum(x["v"] for x in ohlcv_50) / len(ohlcv_50) if ohlcv_50 else 1
73
+ else:
74
+ vol_avg_20 = sum(x["v"] for x in ohlcv_50[:20]) / 20
75
+ last_vol = ohlcv_50[0]["v"] if ohlcv_50 else 1
76
+ volume_ratio = last_vol / vol_avg_20 if vol_avg_20 else 1.0
77
+ highs = [x["h"] for x in ohlcv_50]
78
+ lows = [x["l"] for x in ohlcv_50]
79
+ high_52w = max(highs) if highs else price
80
+ low_52w = min(lows) if lows else price
81
+ return AssetData(
82
+ asset=symbol,
83
+ price=price,
84
+ change_1h="", # AV daily only
85
+ change_24h=change_24h,
86
+ volume_ratio=round(volume_ratio, 2),
87
+ ohlcv_14=ohlcv_14,
88
+ ohlcv_50=ohlcv_50,
89
+ high_52w=high_52w,
90
+ low_52w=low_52w,
91
+ )
92
+ except Exception:
93
+ return None