From 0679dca1067b4aef76c4e6e8297fbd089d06500e Mon Sep 17 00:00:00 2001 From: Tvishi Agarwal Date: Sun, 12 Apr 2026 20:13:22 +0000 Subject: [PATCH] givdatav1 --- __pycache__/generate.cpython-312.pyc | Bin 0 -> 33213 bytes generate.py | 105 +++++++++++++++++++-------- index.html | 13 +++- 3 files changed, 82 insertions(+), 36 deletions(-) create mode 100644 __pycache__/generate.cpython-312.pyc diff --git a/__pycache__/generate.cpython-312.pyc b/__pycache__/generate.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed8ec128b3b77037a697d05c2a2892c707b22d5c GIT binary patch literal 33213 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 IW02wh7s?6hMF0Q* literal 0 HcmV?d00001 diff --git a/generate.py b/generate.py index 0acab2c..c997c2e 100644 --- a/generate.py +++ b/generate.py @@ -83,6 +83,35 @@ BOND_ETFS = { "GOVT": {"name": "US Total Treasury", "country": "US", "duration": "mixed"}, } +# ─── EODHD GOVERNMENT BONDS ───────────────────────────────────────────────── +EODHD_BONDS = { + "US2Y.GBOND": {"key": "us2y", "label": "US 2Y", "country": "US"}, + "US10Y.GBOND": {"key": "us10y", "label": "US 10Y", "country": "US"}, + "US30Y.GBOND": {"key": "us30y", "label": "US 30Y", "country": "US"}, + "UK2Y.GBOND": {"key": "uk2y", "label": "UK 2Y", "country": "UK"}, + "UK10Y.GBOND": {"key": "uk10y", "label": "UK 10Y", "country": "UK"}, + "UK30Y.GBOND": {"key": "uk30y", "label": "UK 30Y", "country": "UK"}, + "DE2Y.GBOND": {"key": "de2y", "label": "Germany 2Y", "country": "Eurozone"}, + "DE10Y.GBOND": {"key": "de10y", "label": "Germany 10Y", "country": "Eurozone"}, + "DE30Y.GBOND": {"key": "de30y", "label": "Germany 30Y", "country": "Eurozone"}, + "JP2Y.GBOND": {"key": "jp2y", "label": "Japan 2Y", "country": "Japan"}, + "JP10Y.GBOND": {"key": "jp10y", "label": "Japan 10Y", "country": "Japan"}, + "JP30Y.GBOND": {"key": "jp30y", "label": "Japan 30Y", "country": "Japan"}, + "IT2Y.GBOND": {"key": "it2y", "label": "Italy 2Y", "country": "Eurozone"}, + "IT10Y.GBOND": {"key": "it10y", "label": "Italy 10Y", "country": "Eurozone"}, + "FR10Y.GBOND": {"key": "fr10y", "label": "France 10Y", "country": "Eurozone"}, + "ES10Y.GBOND": {"key": "es10y", "label": "Spain 10Y", "country": "Eurozone"}, + "CA2Y.GBOND": {"key": "ca2y", "label": "Canada 2Y", "country": "Canada"}, + "CA10Y.GBOND": {"key": "ca10y", "label": "Canada 10Y", "country": "Canada"}, + "AU2Y.GBOND": {"key": "au2y", "label": "Australia 2Y", "country": "Australia"}, + "AU10Y.GBOND": {"key": "au10y", "label": "Australia 10Y", "country": "Australia"}, + "NZ2Y.GBOND": {"key": "nz2y", "label": "New Zealand 2Y", "country": "New Zealand"}, + "NZ10Y.GBOND": {"key": "nz10y", "label": "New Zealand 10Y", "country": "New Zealand"}, + "SW10Y.GBOND": {"key": "ch10y", "label": "Switzerland 10Y", "country": "Switzerland"}, + "SE10Y.GBOND": {"key": "se10y", "label": "Sweden 10Y", "country": "Sweden"}, + "NO10Y.GBOND": {"key": "no10y", "label": "Norway 10Y", "country": "Norway"}, +} + # ─── COMMODITY TICKERS ─────────────────────────────────────────────────────── COMMODITIES = { "GC=F": {"key": "gold", "name": "Gold", "unit": "$/oz"}, @@ -140,25 +169,36 @@ FX_PAIRS = { } -def fetch_gov_data(endpoint, params=None): - """Fetch data from the government API.""" +def fetch_eodhd_eod(symbol): + """Fetch latest EOD data from EODHD for a bond/rate symbol.""" if not GOV_KEY: - print(" GOV API key missing") return None - - if params is None: - params = {} - try: - base_url = "https://YOUR-GOV-API-ENDPOINT-HERE" - params["api_key"] = GOV_KEY - - r = requests.get(base_url + endpoint, params=params, timeout=15) + url = f"https://eodhd.com/api/eod/{symbol}" + params = {"api_token": GOV_KEY, "fmt": "json", "order": "d", "limit": 2} + r = requests.get(url, params=params, timeout=15) r.raise_for_status() - return r.json() - + data = r.json() + if not isinstance(data, list) or len(data) < 1: + return None + latest = data[0] + prev = data[1] if len(data) >= 2 else None + value = latest.get("close") + prev_value = prev.get("close") if prev else None + change = round(value - prev_value, 4) if value is not None and prev_value is not None else None + pct_change = ( + round((value - prev_value) / prev_value * 100, 4) + if value is not None and prev_value is not None and prev_value != 0 + else None + ) + return { + "value": value, + "change": change, + "pct_change": pct_change, + "date": latest.get("date"), + } except Exception as e: - print(f" Government API error ({endpoint}): {e}") + print(f" EODHD error ({symbol}): {e}") return None @@ -477,6 +517,7 @@ def main(): "macro": {}, "sentiment": {}, "scenarios": {}, + "gov_bonds": {}, } # 1. US YIELD CURVE from FRED (most reliable) @@ -663,24 +704,23 @@ def main(): }] print(f" Final calendar rows: {len(output['calendar'])}") - # 11. Government API data - print("\n[11] Fetching government data...") - gov_data = fetch_gov_data("/some/endpoint", params={"country": "US"}) - if gov_data: - output["policy_rates"]["US"] = gov_data.get("policy_rate") - - output["macro"]["US"] = { - "cpi": f"{gov_data.get('cpi_yoy')}%" if gov_data.get("cpi_yoy") is not None else "\u2014", - "cpiP": "\u2014", - "gdp": f"{gov_data.get('gdp_qoq')}%" if gov_data.get("gdp_qoq") is not None else "\u2014", - "gdpT": "QoQ", - "unemp": f"{gov_data.get('unemployment')}%" if gov_data.get("unemployment") is not None else "\u2014", - "unempT": "latest", - "stance": "\u2014", - "last": "\u2014", - "next": "\u2014", - "pricing": "\u2014", - } + # 11. Government bonds (EODHD) + print("\n[11] Fetching government bonds from EODHD...") + if GOV_KEY: + for symbol, info in EODHD_BONDS.items(): + result = fetch_eodhd_eod(symbol) + if result: + result["label"] = info["label"] + result["country"] = info["country"] + output["gov_bonds"][info["key"]] = result + v = result["value"] + c = result.get("change") + chg_str = f" ({c:+.3f})" if c is not None else "" + print(f" {info['label']}: {v}%{chg_str}") + time.sleep(0.3) # Rate limit + print(f" Fetched {len(output['gov_bonds'])} bonds") + else: + print(" EODHD API key not set — skipping government bonds") # Write output output_path = Path(OUTPUT_FILE) @@ -696,6 +736,7 @@ def main(): print(f" FX: {len(output['fx'])} pairs") print(f" News: {len(output['news'])} articles") print(f" Calendar: {len(output['calendar'])} events") + print(f" Gov bonds: {len(output['gov_bonds'])} instruments") print(f"{'=' * 60}") diff --git a/index.html b/index.html index e16c04f..8e7f8a4 100644 --- a/index.html +++ b/index.html @@ -35,6 +35,7 @@ const pOf={US:"DXY",Eurozone:"EURUSD",UK:"GBPUSD",Japan:"USDJPY",Switzerland:"US const nKw={US:["fed","fomc","treasury","dollar","powell","nonfarm"],Eurozone:["ecb","lagarde","eurozone","bund"],UK:["boe","bailey","gilt","sterling","uk gdp","uk cpi"],Japan:["boj","ueda","yen","jgb","japan"],Switzerland:["snb","swiss","franc"],Australia:["rba","aussie","australia"],Canada:["boc","canada","loonie"],"New Zealand":["rbnz","kiwi","new zealand"],Sweden:["riksbank","sweden"],Norway:["norges","norway"],Brazil:["bcb","brazil","real"],Mexico:["banxico","mexico","peso"],"South Africa":["sarb","south africa","rand"],India:["rbi","india","rupee"],"South Korea":["bok","korea","won"],Turkey:["cbrt","turkey","lira"],Poland:["nbp","poland","zloty"]}; const MD={}; +const bondPfx={"US":["us"],"UK":["uk"],"Eurozone":["de","it","fr","es"],"Japan":["jp"],"Canada":["ca"],"Australia":["au"],"New Zealand":["nz"],"Switzerland":["ch"],"Sweden":["se"],"Norway":["no"]}; @@ -221,8 +222,9 @@ function Scenarios({risk,yld,g10,em,cmd}){ function CorrMx(){return
30-Day Correlation Matrix

Correlation data not available — requires a live feed
} /* ═══ DEEP DIVE ═══════════════════════════════════════════════════ */ -function Deep({ctry,g10,em,yld,news,nL,risk,macro,policyRates}){ +function Deep({ctry,g10,em,yld,news,nL,risk,macro,policyRates,govBonds}){ const ccy=cOf[ctry],fp=[...g10,...em].find(x=>x.pair===pOf[ctry]),y=yld[ctry]||{},tpl=RT.find(x=>x.c===ctry),m=macro?.[ctry]||{},cbRate=policyRates?.[ctry]??null; + const pfxList=bondPfx[ctry]||[];const cBonds=Object.entries(govBonds||{}).filter(([k])=>pfxList.some(p=>k.startsWith(p))).map(([k,v])=>({key:k,...v})); const kws=nKw[ctry]||[ccy.toLowerCase()];const cN=news.filter(n=>kws.some(kw=>(n.headline||"").toLowerCase().includes(kw)));const dN=cN.length>=2?cN:news; const ce=Object.entries(y).filter(([k,v])=>v!=null&&k.startsWith("y")).map(([k,v])=>[k.replace("y","").toUpperCase(),v]); const [ai,setAi]=useState(null); @@ -252,6 +254,7 @@ function Deep({ctry,g10,em,yld,news,nL,risk,macro,policyRates}){ } : null, macro: m, riskBar: risk, + govBonds: cBonds, headlines: dN.slice(0, 8).map(n => ({ headline: n.headline, source: n.source, @@ -435,6 +438,8 @@ function Deep({ctry,g10,em,yld,news,nL,risk,macro,policyRates}){ + {cBonds.length>0&&
🏦 Government Bonds
C.b},{k:"value",l:"Yield %",rn:r=>r.value!=null?Number(r.value).toFixed(3):"\u2014"},{k:"change",l:"Chg (bp)",rn:r=>r.change!=null?fb(r.change*100):"\u2014",cl:r=>cc(r.change)},{k:"date",l:"Date",a:"left",cl:()=>C.txM}]} rows={cBonds} sm/>
} +
Central Bank
@@ -508,14 +513,14 @@ function App(){ const [rL,sRL]=useState(false);const [cal,sCal]=useState([]);const [cL,sCL]=useState(false);const [news,sNews]=useState([]);const [nL,sNL]=useState(false); const [cmd,sCmd]=useState({gold:{},wti:{},brent:{}});const [ld,sLd]=useState(false);const [lr,sLR]=useState(null); const [etfs,setEtfs]=useState({});const [vol,setVol]=useState({});const [bondEtfs,setBondEtfs]=useState({}); - const [macro,setMacro]=useState({});const [policyRates,setPolicyRates]=useState({}); + const [macro,setMacro]=useState({});const [policyRates,setPolicyRates]=useState({});const [govBonds,setGovBonds]=useState({}); const svK=useCallback(nk=>{setKeys(nk);Object.entries(nk).forEach(([k,v])=>sk(k,v))},[]); const load=useCallback(async()=>{ sLd(true); try{ const data=await fData(); setEtfs(data.etfs||{});setVol(data.volatility||{});setBondEtfs(data.bond_etfs||{}); - setMacro(data.macro||{});setPolicyRates(data.policy_rates||{}); + setMacro(data.macro||{});setPolicyRates(data.policy_rates||{});setGovBonds(data.gov_bonds||{}); const mapFx=defs=>defs.map(d=>{const x=data.fx?.[d.p];return{pair:d.p,spot:x?.price??null,d1:x?.d1_pct??null,w1:x?.w1_pct??null,m1:x?.m1_pct??null,ytd:null}}); sG10(mapFx(G10));sEM(mapFx(EMP));sFxL(true); const mappedYields={}; @@ -544,7 +549,7 @@ function App(){ {sec==="commod"&&
Commodities
} {sec==="scenarios"&&} {sec==="corr"&&
} - {sec==="deep"&&
{RT.map(c=>)}
} + {sec==="deep"&&
{RT.map(c=>)}
} {sec==="cal"&&
Economic Calendar
}
FX RADAR v4 · {fxL?"Live":"..."}