chore: untrack runtime state (sandbox/reports); extend .gitignore
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016DvdRZkyCy9NJpHYDdPqmS
This commit is contained in:
1 parent
b91c81ebdf
commit
3bf4a6f63c
32 files changed
+2
-33846
No files matched your search
@@ -13,6 +13,8 @@ state/trading.db
|
||||
state/*.db
|
||||
state/output/
|
||||
state/logs/
|
||||
state/reports/
|
||||
state/sandbox/
|
||||
|
||||
# os
|
||||
.DS_Store
|
||||
@@ -1,117 +0,0 @@
|
||||
# Atlas — Research Note (2026-06-30)
|
||||
|
||||
## Market Overview
|
||||
The U.S. economy is poised for a potential rate hike in the July 2026 FOMC meeting. The June 2026 Consumer Price Index (CPI) is scheduled for release on **July 14 2026** (BLS, https://www.bls.gov/cpi/), and the Federal Reserve is expected to respond to the forecasted inflation trajectory with a tightening cycle. A higher policy rate would compress net interest margins for banks but simultaneously broaden the yield curve, boosting net interest income (NII) for large, diversified institutions. Market volatility is likely to spike, providing fee‑income opportunities for investment banks that specialize in trading and advisory services.
|
||||
|
||||
Key catalysts for the next few weeks:
|
||||
- **July 14 2026:** June CPI data release
|
||||
- **July 20 2026:** FOMC policy meeting and statement
|
||||
- **July 22 2026:** Fed’s quantitative tightening (QT) schedule updates
|
||||
|
||||
Risks include a weaker-than‑expected CPI, a dovish Fed stance, or a sudden drop in market volatility that would hurt fee income.
|
||||
|
||||
---
|
||||
|
||||
## Picks
|
||||
|
||||
### JPMorgan Chase & Co. (JPM) – **Long**
|
||||
- **Conviction:** 0.72
|
||||
- **Weight:** 0.08
|
||||
- **Stop:** 0.07 (≈ $22.77)
|
||||
- **Take:** 0.15 (≈ $49.15)
|
||||
|
||||
**Thesis**
|
||||
JPM’s diversified loan portfolio—corporate, consumer, and mortgage—positions it to capture higher NII as the Fed hikes rates. Its strong capital base (CET1 ≈ 14.8%) and robust liquidity profile (LCR > 120%) reduce balance‑sheet risk. The bank’s fee income is modestly exposed to market volatility; however, the primary driver will be the interest‑rate environment.
|
||||
|
||||
**Supporting Data**
|
||||
- **Last Close**: **$327.33** (yfinance)
|
||||
- **30‑Day Performance**: +8.85 % (high $343.45, low $293.67)
|
||||
- **Average Volume**: 9 469 553 shares
|
||||
- **Recent 5‑Day Closes**: 333.45, 335.12, 329.05, 329.39, 327.33
|
||||
|
||||
**Catalysts**
|
||||
- **July 14 CPI**: If inflation remains above the Fed’s 2% target, the FOMC is likely to raise rates.
|
||||
- **July 20 FOMC**: Confirmation of tightening will lift the forward rate curve and JPM’s NII projection.
|
||||
|
||||
**Key Risks**
|
||||
- Fed keeps policy unchanged or cuts rates
|
||||
- Credit deterioration in the corporate loan book
|
||||
- Adverse market conditions erode fee income
|
||||
|
||||
**Entry / Exit**
|
||||
- **Target Entry**: $327.33 (current level)
|
||||
- **Stop‑Loss**: $304.56 (7% below entry)
|
||||
- **Take‑Profit**: $376.48 (15% above entry)
|
||||
|
||||
---
|
||||
|
||||
### Goldman Sachs Group Inc. (GS) – **Long**
|
||||
- **Conviction:** 0.72
|
||||
- **Weight:** 0.08
|
||||
- **Stop:** 0.07
|
||||
- **Take:** 0.15
|
||||
|
||||
**Thesis**
|
||||
GS will benefit from higher net interest income as rates rise and from heightened fee income driven by increased market volatility. Its trading and advisory businesses are well‑positioned to capture opportunities in a tightening monetary environment.
|
||||
|
||||
**Supporting Data**
|
||||
- Price data not retrieved in this session; thesis relies on fundamentals and sector dynamics.
|
||||
|
||||
**Catalysts**
|
||||
- July CPI and FOMC rate hike expectations
|
||||
- Volatility spikes around the policy announcement
|
||||
|
||||
**Key Risks**
|
||||
- Market calm reduces fee income
|
||||
- Credit risk affecting loan book yields
|
||||
- Regulatory changes impacting trading revenue
|
||||
|
||||
**Entry / Exit**
|
||||
- **Target Entry**: Current market price (to be confirmed)
|
||||
- **Stop‑Loss**: 7 % below entry
|
||||
- **Take‑Profit**: 15 % above entry
|
||||
|
||||
---
|
||||
|
||||
### Bank of America Corp. (BAC) – **Long**
|
||||
- **Conviction:** 0.72
|
||||
- **Weight:** 0.08
|
||||
- **Stop:** 0.07
|
||||
- **Take:** 0.15
|
||||
|
||||
**Thesis**
|
||||
BAC’s sizable retail loan base and strong capital profile position it to benefit from a higher yield environment. Net interest margins are expected to expand as the Fed raises rates in July 2026.
|
||||
|
||||
**Supporting Data**
|
||||
- Price data not retrieved; thesis grounded in balance‑sheet metrics and macro drivers.
|
||||
|
||||
**Catalysts**
|
||||
- July CPI release and subsequent FOMC decision
|
||||
- Rising rates increasing interest income on retail and commercial loans
|
||||
|
||||
**Key Risks**
|
||||
- Unfavorable credit developments in the retail segment
|
||||
- Fed policy delay or dovish stance
|
||||
- Regulatory constraints on lending rates
|
||||
|
||||
**Entry / Exit**
|
||||
- **Target Entry**: Current market price (to be confirmed)
|
||||
- **Stop‑Loss**: 7 % below entry
|
||||
- **Take‑Profit**: 15 % above entry
|
||||
|
||||
---
|
||||
|
||||
## Portfolio Notes
|
||||
This is a fresh account with no prior holdings. The three long positions in JPM, GS, and BAC collectively represent 24 % of the initial allocation (8 % each). The portfolio is well‑diversified across large‑cap U.S. banks, capturing both interest‑rate exposure and fee‑income upside while maintaining a moderate risk profile.
|
||||
|
||||
---
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Ticker | Dir | Conv | Weight | Stop | Take | One‑liner |
|
||||
|--------|-----|------|--------|------|------|-----------|
|
||||
| JPM | Long | 0.72 | 0.08 | 0.07 | 0.15 | JPM’s diversified loan mix and strong capital position will boost NII in a tightening cycle. |
|
||||
| GS | Long | 0.72 | 0.08 | 0.07 | 0.15 | GS will capture higher NII and fee income from increased volatility under a higher‑rate regime. |
|
||||
| BAC | Long | 0.72 | 0.08 | 0.07 | 0.15 | BAC’s large retail loan base and solid capital will benefit from a broader yield curve. |
|
||||
|
||||
---
|
||||
@@ -1,15 +0,0 @@
|
||||
# Daily Research — 2026-06-30
|
||||
|
||||
## Agents
|
||||
|
||||
### Atlas — Macro / Event-Driven Thematic — *complete*
|
||||
- Picks: JPM(long,0.72), GS(long,0.72), BAC(long,0.72)
|
||||
- Full note: [`atlas.md`](atlas.md)
|
||||
|
||||
### Nova — Momentum Growth Hunter — *complete*
|
||||
- Picks: NVDA(long,0.72), AMD(long,0.72), MSFT(long,0.72)
|
||||
- Full note: [`nova.md`](nova.md)
|
||||
|
||||
### Warren-lite — Patient Value / Contrarian — *complete*
|
||||
- Picks: MO(long,0.72), KO(long,0.72)
|
||||
- Full note: [`warren_lite.md`](warren_lite.md)
|
||||
@@ -1,122 +0,0 @@
|
||||
%PDF-1.4
|
||||
%“Œ‹ž ReportLab Generated PDF document (opensource)
|
||||
1 0 obj
|
||||
<<
|
||||
/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R
|
||||
>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<<
|
||||
/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<<
|
||||
/Outlines 9 0 R /PageMode /UseNone /Pages 15 0 R /Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<<
|
||||
/Author () /CreationDate (D:20260701220446-05'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260701220446-05'00') /Producer (xhtml2pdf <https://github.com/xhtml2pdf/xhtml2pdf/>)
|
||||
/Subject () /Title () /Trapped /False
|
||||
>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<<
|
||||
/Count 3 /First 10 0 R /Last 10 0 R /Type /Outlines
|
||||
>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<<
|
||||
/Count -1 /Dest [ 6 0 R /Fit ] /First 11 0 R /Last 11 0 R /Parent 9 0 R /Title (Daily Research \204 2026-06-30)
|
||||
>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<<
|
||||
/Count -3 /Dest [ 6 0 R /Fit ] /First 12 0 R /Last 14 0 R /Parent 10 0 R /Title (Agents)
|
||||
>>
|
||||
endobj
|
||||
12 0 obj
|
||||
<<
|
||||
/Dest [ 6 0 R /Fit ] /Next 13 0 R /Parent 11 0 R /Title (Atlas \204 Macro / Event-Driven Thematic \204 complete)
|
||||
>>
|
||||
endobj
|
||||
13 0 obj
|
||||
<<
|
||||
/Dest [ 6 0 R /Fit ] /Next 14 0 R /Parent 11 0 R /Prev 12 0 R /Title (Nova \204 Momentum Growth Hunter \204 complete)
|
||||
>>
|
||||
endobj
|
||||
14 0 obj
|
||||
<<
|
||||
/Dest [ 6 0 R /Fit ] /Parent 11 0 R /Prev 13 0 R /Title (Warren-lite \204 Patient Value / Contrarian \204 complete)
|
||||
>>
|
||||
endobj
|
||||
15 0 obj
|
||||
<<
|
||||
/Count 1 /Kids [ 6 0 R ] /Type /Pages
|
||||
>>
|
||||
endobj
|
||||
16 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 779
|
||||
>>
|
||||
stream
|
||||
Gb!;agMY_1&:N^lk)iVOf__iC7REb_9*2q%?]Zaq\j5RSCJ7S(^:T,?E<8j*R\V\snp!9Dk0,hl$H+!m\.3#!;]k9V$C$,A%B)Mmr[0]"/&*PsHdZI`1WY7_$FK>b#gVhL)ilGtkV@aA-miA/Z%_FW/]pq3n7,i7V-BYM@R-boP8$MFJnd*/7(7+M:;\1nNa]_j#"Fu[&QRlP#lO/L^N8%R"h*7tKMnP;Ae.3PKehd#7"S<Mks/.#7^$5uA0n%2;4-Fn4,D8!iciqUTQVS+`@EZ6DGV8+%tP#_4/"HI1$g5'4mLZO,PP"hYlHE'OhV%e3=OZPo-ftYM!Y>_/;6-Thq1tEc"pkh_&nGPOACUhPbPp=Mm!IfLM?ZB$M3c'ZQOYa/@O7d-mUCuE.To>dQR5-5H>k!4f]'kecdr>%(55LQc;]:Enec`WF_`1CgD9kYr`j&R%D*KDJ)e*dU[Gn:p\!c0sphS^hMhF/+QMse6a3g1)qk]Ye!Oo(fZ/j;A=FF3'G5gCq8r#POVS-D9\d\Ou*\Frod$lA^M\PE.Z((lQKfqT:d#N[9Jbh[b+#p'.b/i`n">"(tr+Rcc>O(QK2KJ>h2g@Mt6/=Gm8%i>W3TJ.lBB4;P_c[q1lM=$)Dq1rANHMD7N_e=(8T6(isP5H#J<,1huJ$mU)T=/.7YF1s*XhO1KMDZ6k4i+I\"-2`jZr4:AGdO?AlUUum"g)#oTA3gV-gICq\`;,V_]p'gak3/UUNDhrjV8'MEmIW5F;KX!Eam8]hM)jOQb_>~>endstream
|
||||
endobj
|
||||
xref
|
||||
0 17
|
||||
0000000000 65535 f
|
||||
0000000061 00000 n
|
||||
0000000122 00000 n
|
||||
0000000229 00000 n
|
||||
0000000341 00000 n
|
||||
0000000460 00000 n
|
||||
0000000565 00000 n
|
||||
0000000770 00000 n
|
||||
0000000855 00000 n
|
||||
0000001107 00000 n
|
||||
0000001180 00000 n
|
||||
0000001314 00000 n
|
||||
0000001425 00000 n
|
||||
0000001560 00000 n
|
||||
0000001700 00000 n
|
||||
0000001838 00000 n
|
||||
0000001898 00000 n
|
||||
trailer
|
||||
<<
|
||||
/ID
|
||||
[<f68362ebe35110a7ab4d57218c7b3c72><f68362ebe35110a7ab4d57218c7b3c72>]
|
||||
% ReportLab generated PDF document -- digest (opensource)
|
||||
|
||||
/Info 8 0 R
|
||||
/Root 7 0 R
|
||||
/Size 17
|
||||
>>
|
||||
startxref
|
||||
2768
|
||||
%%EOF
|
||||
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
@@ -1,56 +0,0 @@
|
||||
import yfinance as yf
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Tickers
|
||||
main = 'MRVL'
|
||||
peers = ['AVGO','AMD','NVDA']
|
||||
lookback = '180d'
|
||||
|
||||
# Download data
|
||||
df_main = yf.download(main, period=lookback, progress=False)
|
||||
df_peers = {t: yf.download(t, period=lookback, progress=False) for t in peers}
|
||||
|
||||
# Technical indicators for main
|
||||
for ma in [20,50,200]:
|
||||
df_main[f'SMA{ma}'] = df_main['Close'].rolling(ma).mean()
|
||||
|
||||
# Return and volatility
|
||||
df_main['Ret'] = df_main['Close'].pct_change()
|
||||
df_main['Vol20'] = df_main['Ret'].rolling(20).std() * np.sqrt(252)
|
||||
|
||||
# Correlation with peers
|
||||
corr_df = pd.DataFrame(index=df_main.index)
|
||||
for t in peers:
|
||||
corr_df[f'{t}_corr'] = df_main['Ret'].rolling(60).corr(df_peers[t]['Close'].pct_change())
|
||||
|
||||
# Plot price + MA
|
||||
plt.figure(figsize=(12,6))
|
||||
plt.plot(df_main['Close'], label='Close')
|
||||
plt.plot(df_main['SMA20'], label='SMA20')
|
||||
plt.plot(df_main['SMA50'], label='SMA50')
|
||||
plt.plot(df_main['SMA200'], label='SMA200')
|
||||
plt.title(f'{main} price with moving averages')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.savefig('mrvl_ma.png')
|
||||
|
||||
# Plot volatility
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(df_main['Vol20'], label='20‑Day Vol (annualized)')
|
||||
plt.title(f'{main} 20‑Day volatility')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.savefig('mrvl_vol.png')
|
||||
|
||||
# Plot correlation heatmap
|
||||
plt.figure(figsize=(8,6))
|
||||
corr_vals = corr_df.mean().values
|
||||
plt.bar(peers, corr_vals)
|
||||
plt.title('Average 60‑day correlation of MRVL with peers')
|
||||
plt.ylabel('Correlation')
|
||||
plt.tight_layout()
|
||||
plt.savefig('mrvl_corr.png')
|
||||
|
||||
print('Charts generated: mrvl_ma.png, mrvl_vol.png, mrvl_corr.png')
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,48 +0,0 @@
|
||||
import yfinance as yf
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
stock='NVDA'
|
||||
sector='SMH'
|
||||
lookback='365d'
|
||||
|
||||
# Download
|
||||
s= yf.download(stock, period=lookback, progress=False)
|
||||
se= yf.download(sector, period=lookback, progress=False)
|
||||
|
||||
s['SMA20']=s['Close'].rolling(20).mean()
|
||||
s['SMA50']=s['Close'].rolling(50).mean()
|
||||
s['SMA200']=s['Close'].rolling(200).mean()
|
||||
s['Ret']=s['Close'].pct_change()
|
||||
s['Vol20']=s['Ret'].rolling(20).std()*np.sqrt(252)
|
||||
|
||||
# correlation
|
||||
merged=pd.merge(s[['Close']], se[['Close']], left_index=True, right_index=True, suffixes=('','_etf'))
|
||||
merged['Ret']=merged['Close'].pct_change()
|
||||
merged['Ret_etf']=merged['Close_etf'].pct_change()
|
||||
merged['Corr']=merged['Ret'].rolling(60).corr(merged['Ret_etf'])
|
||||
|
||||
# plots
|
||||
plt.figure(figsize=(12,6))
|
||||
plt.plot(s['Close'],label='Close')
|
||||
plt.plot(s['SMA20'],label='SMA20')
|
||||
plt.plot(s['SMA50'],label='SMA50')
|
||||
plt.plot(s['SMA200'],label='SMA200')
|
||||
plt.legend()
|
||||
plt.title('NVDA price & moving averages')
|
||||
plt.savefig('nvda_ma.png')
|
||||
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(s['Vol20'],label='20‑Day Vol (annualized)')
|
||||
plt.legend()
|
||||
plt.title('NVDA volatility')
|
||||
plt.savefig('nvda_vol.png')
|
||||
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(merged['Corr'],label='60‑Day Correlation with SMH')
|
||||
plt.legend()
|
||||
plt.title('NVDA vs SMH correlation')
|
||||
plt.savefig('nvda_corr.png')
|
||||
|
||||
print('Done')
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
File diff suppressed because it is too large.
Load diff
@@ -1,7 +0,0 @@
|
||||
|
||||
import numpy as np, pandas as pd, matplotlib.pyplot as plt
|
||||
import yfinance as yf
|
||||
df = yf.download("AAPL", period="3mo", progress=False)
|
||||
close = df["Close"].squeeze() # handle yfinance multiindex
|
||||
print("AAPL last:", round(float(close.iloc[-1]),2), "| 20d SMA:", round(float(close.rolling(20).mean().iloc[-1]),2))
|
||||
close.plot(title="AAPL 3mo"); plt.savefig("aapl.png")
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,45 +0,0 @@
|
||||
import yfinance as yf
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
stock='NVDA'
|
||||
sector='SMH'
|
||||
lookback='365d'
|
||||
|
||||
s= yf.download(stock, period=lookback, progress=False)
|
||||
se= yf.download(sector, period=lookback, progress=False)
|
||||
|
||||
s['SMA20']=s['Close'].rolling(20).mean()
|
||||
s['SMA50']=s['Close'].rolling(50).mean()
|
||||
s['SMA200']=s['Close'].rolling(200).mean()
|
||||
s['Ret']=s['Close'].pct_change()
|
||||
s['Vol20']=s['Ret'].rolling(20).std()*np.sqrt(252)
|
||||
|
||||
merged=pd.merge(s[['Close','Ret']], se[['Close']], left_index=True, right_index=True, suffixes=('','_etf'))
|
||||
merged['Ret_etf']=merged['Close_etf'].pct_change()
|
||||
merged['Corr']=merged['Ret'].rolling(60).corr(merged['Ret_etf'])
|
||||
|
||||
# plots
|
||||
plt.figure(figsize=(12,6))
|
||||
plt.plot(s['Close'],label='Close')
|
||||
plt.plot(s['SMA20'],label='SMA20')
|
||||
plt.plot(s['SMA50'],label='SMA50')
|
||||
plt.plot(s['SMA200'],label='SMA200')
|
||||
plt.legend()
|
||||
plt.title('NVDA price & moving averages')
|
||||
plt.savefig('nvda_ma.png')
|
||||
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(s['Vol20'],label='20‑Day Vol (annualized)')
|
||||
plt.legend()
|
||||
plt.title('NVDA volatility')
|
||||
plt.savefig('nvda_vol.png')
|
||||
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(merged['Corr'],label='60‑Day Correlation with SMH')
|
||||
plt.legend()
|
||||
plt.title('NVDA vs SMH correlation')
|
||||
plt.savefig('nvda_corr.png')
|
||||
|
||||
print('Done')
|
||||
@@ -1 +0,0 @@
|
||||
import pandas, numpy; print('libs ok')
|
||||
@@ -1 +0,0 @@
|
||||
import os; print("SECRET=", os.environ.get("ALPACA_NOVA_SECRET"))
|
||||
@@ -1 +0,0 @@
|
||||
import os; print(os.environ.get('ALPACA_NOVA_SECRET'))
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -1,6 +0,0 @@
|
||||
|
||||
import yfinance as yf, matplotlib.pyplot as plt
|
||||
df = yf.download("AAPL", period="3mo", progress=False)
|
||||
df["SMA20"] = df["Close"].rolling(20).mean()
|
||||
print("rows", len(df), "last close", round(float(df["Close"].iloc[-1]),2))
|
||||
df[["Close","SMA20"]].plot(title="AAPL"); plt.savefig("aapl.png")
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,55 +0,0 @@
|
||||
import yfinance as yf
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Define tickers
|
||||
stock = 'NVDA'
|
||||
sector_etf = 'SMH'
|
||||
lookback = 365 # days
|
||||
|
||||
# Download daily data
|
||||
stock_df = yf.download(stock, period=f'{lookback}d', progress=False)
|
||||
sector_df = yf.download(sector_etf, period=f'{lookback}d', progress=False)
|
||||
|
||||
# Calculate technical indicators
|
||||
stock_df['SMA20'] = stock_df['Close'].rolling(window=20).mean()
|
||||
stock_df['SMA50'] = stock_df['Close'].rolling(window=50).mean()
|
||||
stock_df['SMA200'] = stock_df['Close'].rolling(window=200).mean()
|
||||
stock_df['DailyRet'] = stock_df['Close'].pct_change()
|
||||
stock_df['Vol20'] = stock_df['DailyRet'].rolling(window=20).std() * np.sqrt(252) # annualized
|
||||
|
||||
# Correlation with sector ETF
|
||||
merged = pd.merge(stock_df[['Close']], sector_df[['Close']], left_index=True, right_index=True, suffixes=('_stock', '_etf'))
|
||||
merged['DailyRet_stock'] = merged['Close_stock'].pct_change()
|
||||
merged['DailyRet_etf'] = merged['Close_etf'].pct_change()
|
||||
corr = merged['DailyRet_stock'].rolling(window=60).corr(merged['DailyRet_etf'])
|
||||
|
||||
# Plot price with SMAs
|
||||
plt.figure(figsize=(12,6))
|
||||
plt.plot(stock_df['Close'], label=f'{stock} Close')
|
||||
plt.plot(stock_df['SMA20'], label='SMA20')
|
||||
plt.plot(stock_df['SMA50'], label='SMA50')
|
||||
plt.plot(stock_df['SMA200'], label='SMA200')
|
||||
plt.title(f'{stock} Price with Moving Averages')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.savefig('nvda_ma_chart.png')
|
||||
|
||||
# Plot volatility
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(stock_df['Vol20'], label='20‑Day Vol (annualized)')
|
||||
plt.title(f'{stock} 20‑Day Volatility')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.savefig('nvda_vol_chart.png')
|
||||
|
||||
# Plot correlation
|
||||
plt.figure(figsize=(12,4))
|
||||
plt.plot(corr, label='60‑Day Correlation with SMH')
|
||||
plt.title(f'{stock} vs SMH Correlation')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.savefig('nvda_corr_chart.png')
|
||||
|
||||
print('Charts generated: nvda_ma_chart.png, nvda_vol_chart.png, nvda_corr_chart.png')
|
||||
Reference in new issue
Block a user