Playwright X scraper, daily notes, feed analysis
This commit is contained in:
@ -1,62 +1,66 @@
|
||||
# 2026-02-09
|
||||
# 2026-02-09 — Monday
|
||||
|
||||
## Market Watch Launch Day
|
||||
- GARP paper trading simulator went live
|
||||
- 9 AM systemd timer fired but crashed (scanner returns list, code expected dict) — fixed
|
||||
- Manual run at 10:49 AM — **7 positions opened**:
|
||||
- DUOL (57 shares @ $116.35)
|
||||
- ALLY (156 shares @ $42.65)
|
||||
- JHG (138 shares @ $48.21)
|
||||
- INCY (61 shares @ $108.69)
|
||||
- PINS (332 shares @ $20.06)
|
||||
- EXEL (152 shares @ $43.80)
|
||||
- CART (187 shares @ $35.49)
|
||||
- ~$46.5K deployed, ~$53.5K cash remaining
|
||||
- Portal live at marketwatch.local:8889
|
||||
- Multiplayer game engine working — "GARP Challenge" game created
|
||||
## X Feed Analysis Day
|
||||
Major session analyzing Polymarket/crypto tweets D J forwarded from X feed.
|
||||
|
||||
## Super Bowl Results (from last night)
|
||||
- Seahawks 36, Patriots 13
|
||||
- kch123 copy-trade sim: ALL 5 positions won, +$728 on $1K bankroll (+72.8%)
|
||||
- kch123 himself probably cleared ~$2M profit on this game
|
||||
- Two weeks straight of wins for kch123 (60-0 last week + Super Bowl sweep)
|
||||
### Tweets Investigated
|
||||
1. **@browomo weather edge** — Pilot METAR data for Polymarket weather bets
|
||||
- Wallet `0x594edB9112f...`: Claimed +$27K, actual **-$13,103** (387 losses, 51 wins)
|
||||
- Verdict: SCAM/engagement bait
|
||||
|
||||
## Craigslist Account (from yesterday)
|
||||
- Registered: case-lgn@protonmail.com, Nashville area
|
||||
- Password set, credentials saved to .credentials/craigslist.env
|
||||
- User ID: 405642144
|
||||
- D J not ready for listings yet (needs photos)
|
||||
2. **@ArchiveExplorer planktonXD** — "Buy everything under 5 cents"
|
||||
- Wallet `0x4ffe49ba2a4c...`: Claimed +$104K, actual **-$9,517** (3090 losses, 1368 wins, 37% win rate)
|
||||
- Verdict: SCAM/engagement bait
|
||||
|
||||
## D J Interests
|
||||
- Looking at queen Murphy beds on Craigslist
|
||||
- Wants to get rid of an old mattress (options discussed: Metro Nashville bulky pickup, free CL listing, dump)
|
||||
- Interested in Olympics men's hockey (USA in Group C, games start Feb 11)
|
||||
- Expanding analysis beyond Polymarket into crypto and stocks
|
||||
- Goal: find market gaps to offset AI service costs ($200/mo Claude + infra)
|
||||
- Getting crypto signals on Telegram, wants to forward them for analysis
|
||||
- Asked about Tiiny AI (kickstarter AI hardware, 80GB unified memory, NPU) as potential Claude replacement
|
||||
3. **@krajekis BTC 15-min LONG** — "+700% monthly, 1 trade/day at 9AM"
|
||||
- Backtested 25 days: 52% win rate (coin flip), strategy loses 76% of capital
|
||||
- Verdict: FABRICATED results
|
||||
|
||||
## Stock Screener Built
|
||||
- GARP filters automated via yfinance (free, no API key)
|
||||
- S&P 500 + S&P 400 MidCap scan (~902 tickers)
|
||||
- Initial S&P 500 scan found 4: BAC, CFG, FITB, INCY
|
||||
- Expanded scan found 22 total candidates
|
||||
- Top non-bank picks: PINS, FSLR, PGR, NEM, ALLY
|
||||
- Deep dive sub-agent ran on all 4 original picks
|
||||
4. **@noisyb0y1 15-min arb** — "$99K in a day"
|
||||
- Wallet `0xE594336603F4...`: Real strategy (buying both sides), actual PnL ~$9K not $99K
|
||||
- Combined costs $0.70-$0.95 on some markets = genuine arb edge
|
||||
- Verdict: INFLATED numbers, but strategy has merit → bookmarked for scanner
|
||||
|
||||
## X Post Analysis: @Shelpid_WI3M / anoin123
|
||||
- Wallet 0x96489abc... is real, +$1.59M PnL, 216 trades
|
||||
- BUT: concentrated single-thesis bet (NO on Iran strikes), not diversified alpha
|
||||
- Post is a shill for PolyCopyBot (Telegram copy-trading bot)
|
||||
- Verdict: real wallet, misleading narrative, exists to sell bot subscriptions
|
||||
5. **5 more wallets** — spawned sub-agent to research @IH2P, Super Bowl trader, NegRisk arb, Elon insider, $270→$244K bot
|
||||
|
||||
## Tiiny AI Analysis
|
||||
- 80GB LPDDR5X, ARM + NPU (160 TOPS), 18-40 tok/s, 30W
|
||||
- Kickstarter vaporware — doesn't exist yet
|
||||
- Would blow away D J's current 22GB VRAM setup IF it ships
|
||||
- Recommended waiting for real reviews, not pre-ordering
|
||||
### Pattern Identified
|
||||
- Fintwit Polymarket accounts follow identical template: big $ claim → wallet → product shill
|
||||
- Products being shilled: Clawdbots, Moltbook, Bullpen (affiliate/paid promos)
|
||||
- Real money is in selling engagement, not trading
|
||||
- Wallets are cherry-picked; PnL claims conflate position value with profit
|
||||
|
||||
## Lessons
|
||||
- Scanner run_scan() returns list, not dict — caused systemd crash on first real run
|
||||
- Always test the full pipeline end-to-end before relying on timers
|
||||
- yfinance is reliable and free for fundamental data, no API key needed
|
||||
### Built Today
|
||||
- **Crypto signals pipeline** (`projects/crypto-signals/`)
|
||||
- Signal parser for Telegram JSON exports
|
||||
- Price fetcher (Binance US API)
|
||||
- Backtester with Polymarket fee awareness
|
||||
- Ready for D J's Telegram group export
|
||||
|
||||
- **Polymarket 15-min arb scanner** — systemd timer every 2 min
|
||||
- Scans active Up or Down markets
|
||||
- Checks orderbooks for combined < $1.00
|
||||
- Paper trades and Telegram alerts
|
||||
- Finding: markets are tight at steady state, arb windows likely during volatility
|
||||
|
||||
- **Playwright installed** — replaced flaky CDP websocket approach
|
||||
- `connect_over_cdp('http://localhost:9222')` works with existing Chrome session
|
||||
- X feed scraper working via Playwright
|
||||
|
||||
- **PowerInfer multi-GPU cron** — weekly Monday check for feature support
|
||||
|
||||
### Day-of-Week Stock Strategy
|
||||
- D J's friend suggested buy Friday/Monday, sell midweek
|
||||
- Backtested 5 years of SPY: Monday is strongest day (+0.114%, 62% win rate)
|
||||
- Buy Mon Open → Sell Wed Close: 56% win rate, +0.265% avg, $10K→$17.8K
|
||||
- But buy & hold still wins: $10K→$19K
|
||||
- Verdict: weak edge, needs additional filters to be useful
|
||||
|
||||
### Infrastructure
|
||||
- Polymarket fee structure documented: 15-min markets have taker fees, max 1.56% at 50/50
|
||||
- Fee formula: `shares × price × 0.25 × (price × (1-price))²`
|
||||
- Binance international is geo-blocked; Binance US works
|
||||
|
||||
### Pending
|
||||
- D J sending Telegram crypto signal group export (Option 2: JSON export)
|
||||
- Signal provider uses VWAP-based strategy
|
||||
- Sub-agent researching 5 more wallets
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"last_check": "2026-02-09T20:27:59.790122+00:00",
|
||||
"last_check": "2026-02-09T23:25:59.773254+00:00",
|
||||
"total_tracked": 3100,
|
||||
"new_this_check": 0
|
||||
}
|
||||
155
projects/feed-hunter/x_cookies.json
Normal file
155
projects/feed-hunter/x_cookies.json
Normal file
@ -0,0 +1,155 @@
|
||||
[
|
||||
{
|
||||
"name": "guest_id_marketing",
|
||||
"value": "v1%3A177052493168164632",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "guest_id_ads",
|
||||
"value": "v1%3A177052493168164632",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "guest_id",
|
||||
"value": "v1%3A177052493168164632",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "personalization_id",
|
||||
"value": "\"v1_6O8SSA4FCcIXzFzq4cql3A==\"",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "__cuid",
|
||||
"value": "7ec0f8364ef9466bb4d5e5398de60a7a",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": false,
|
||||
"httpOnly": false,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "guest_id_marketing",
|
||||
"value": "v1%3A177052493360013497",
|
||||
"domain": ".twitter.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "guest_id_ads",
|
||||
"value": "v1%3A177052493360013497",
|
||||
"domain": ".twitter.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "personalization_id",
|
||||
"value": "\"v1_0RdWTpuTILka/W8MwiVsGQ==\"",
|
||||
"domain": ".twitter.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "guest_id",
|
||||
"value": "v1%3A177052493360013497",
|
||||
"domain": ".twitter.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "g_state",
|
||||
"value": "{\"i_l\":0,\"i_ll\":1770524933853,\"i_b\":\"/335bZxZT54Tkc2wThT5DEH5v8hDZyhbe/JOl6uvF+k\",\"i_e\":{\"enable_itp_optimization\":0}}",
|
||||
"domain": "x.com",
|
||||
"path": "/",
|
||||
"secure": false,
|
||||
"httpOnly": false,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "kdt",
|
||||
"value": "Y9jfWROysXsnZyHwlffVbs8jvBJabIN4RGlZYFHP",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": true,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "auth_token",
|
||||
"value": "219b71a535b96ef9f978612a48cf81a462643ee3",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": true,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "ct0",
|
||||
"value": "e2c61ad6ce7115f2d8acd2062dc5c9a377140d9b570f871d9b25847f2d7a36fe512a424a359775d73a11a5a0a5154b6623b0021992a2b7f1e094d5ac5ee65cfeaf8ac87de09b7dcfc48f28a5b6dd15dc",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "twid",
|
||||
"value": "u%3D741482516",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "lang",
|
||||
"value": "en",
|
||||
"domain": "x.com",
|
||||
"path": "/",
|
||||
"secure": false,
|
||||
"httpOnly": false,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "external_referer",
|
||||
"value": "vC8TI7P7q9UHtLBqrmGBr3bhFoPD7nVN|0|8e8t2xd8A2w%3D",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": false,
|
||||
"sameSite": "Lax"
|
||||
},
|
||||
{
|
||||
"name": "__cf_bm",
|
||||
"value": "UjX5M.SqXScrW4zZ_GhiubhCXhv.8SI8uU7MkZCGT24-1770678794.1374662-1.0.1.1-4x.1srI8Lir7aTkBYJxMGMZQ2E3.EZKgF5S_gLeoAQzEUvIFZQTLQNxhFfiiVNNaXbfZ8HgKEPtSTvpaglXpnCo9COtawFeKPtaKmENpRj5V3mP0EOhtt4w_MpLhHekN",
|
||||
"domain": ".x.com",
|
||||
"path": "/",
|
||||
"secure": true,
|
||||
"httpOnly": true,
|
||||
"sameSite": "Lax"
|
||||
}
|
||||
]
|
||||
249
projects/feed-hunter/x_scraper_pw.py
Normal file
249
projects/feed-hunter/x_scraper_pw.py
Normal file
@ -0,0 +1,249 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
X/Twitter Feed Scraper using Playwright
|
||||
Scrapes specific accounts for trading-related posts.
|
||||
Uses saved Chrome session cookies for authentication.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
ACCOUNTS = [
|
||||
"browomo", "ArchiveExplorer", "noisyb0y1", "krajekis",
|
||||
"Shelpid_WI3M", "polyaboretum", "0xashensoul",
|
||||
]
|
||||
|
||||
TRADING_KEYWORDS = [
|
||||
"polymarket", "trade", "profit", "wallet", "arbitrage", "signal",
|
||||
"crypto", "bitcoin", "ethereum", "solana", "strategy", "edge",
|
||||
"bet", "position", "stock", "market", "pnl", "alpha",
|
||||
"$", "usdc", "defi", "token", "copy", "whale", "degen",
|
||||
"short", "long", "bullish", "bearish", "portfolio",
|
||||
]
|
||||
|
||||
DATA_DIR = Path(__file__).parent.parent / "data" / "x-feed"
|
||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
COOKIE_FILE = Path(__file__).parent / "x_cookies.json"
|
||||
TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")
|
||||
TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "6443752046")
|
||||
|
||||
|
||||
def send_telegram(message):
|
||||
if not TELEGRAM_BOT_TOKEN:
|
||||
print(f"[ALERT] {message}")
|
||||
return
|
||||
import urllib.request
|
||||
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
||||
data = json.dumps({"chat_id": TELEGRAM_CHAT_ID, "text": message, "parse_mode": "HTML"}).encode()
|
||||
req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"})
|
||||
try:
|
||||
urllib.request.urlopen(req, timeout=10)
|
||||
except Exception as e:
|
||||
print(f"Telegram error: {e}")
|
||||
|
||||
|
||||
def save_cookies(context):
|
||||
cookies = context.cookies()
|
||||
COOKIE_FILE.write_text(json.dumps(cookies, indent=2))
|
||||
print(f"Saved {len(cookies)} cookies")
|
||||
|
||||
|
||||
def load_cookies(context):
|
||||
if COOKIE_FILE.exists():
|
||||
cookies = json.loads(COOKIE_FILE.read_text())
|
||||
context.add_cookies(cookies)
|
||||
print(f"Loaded {len(cookies)} cookies")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def export_cookies_from_chrome():
|
||||
"""One-time: grab cookies from the running Chrome debug instance."""
|
||||
import http.client, websocket as ws_mod
|
||||
conn = http.client.HTTPConnection("localhost", 9222)
|
||||
conn.request("GET", "/json")
|
||||
tabs = json.loads(conn.getresponse().read())
|
||||
|
||||
x_tab = None
|
||||
for t in tabs:
|
||||
if "x.com" in t.get("url", ""):
|
||||
x_tab = t
|
||||
break
|
||||
|
||||
if not x_tab:
|
||||
print("No X tab found in Chrome debug")
|
||||
return []
|
||||
|
||||
ws = ws_mod.create_connection(x_tab["webSocketDebuggerUrl"], timeout=10)
|
||||
ws.send(json.dumps({"id": 1, "method": "Network.getAllCookies"}))
|
||||
result = json.loads(ws.recv())
|
||||
all_cookies = result.get("result", {}).get("cookies", [])
|
||||
ws.close()
|
||||
|
||||
# Filter for x.com cookies and convert to Playwright format
|
||||
x_cookies = []
|
||||
for c in all_cookies:
|
||||
if "x.com" in c.get("domain", "") or "twitter.com" in c.get("domain", ""):
|
||||
x_cookies.append({
|
||||
"name": c["name"],
|
||||
"value": c["value"],
|
||||
"domain": c["domain"],
|
||||
"path": c.get("path", "/"),
|
||||
"secure": c.get("secure", False),
|
||||
"httpOnly": c.get("httpOnly", False),
|
||||
"sameSite": c.get("sameSite", "Lax"),
|
||||
})
|
||||
|
||||
COOKIE_FILE.write_text(json.dumps(x_cookies, indent=2))
|
||||
print(f"Exported {len(x_cookies)} X cookies from Chrome")
|
||||
return x_cookies
|
||||
|
||||
|
||||
def scrape_account(page, account, max_scroll=5):
|
||||
"""Scrape recent posts from a single account."""
|
||||
posts = []
|
||||
|
||||
try:
|
||||
page.goto(f"https://x.com/{account}", wait_until="networkidle", timeout=15000)
|
||||
except:
|
||||
try:
|
||||
page.goto(f"https://x.com/{account}", wait_until="domcontentloaded", timeout=10000)
|
||||
page.wait_for_timeout(3000)
|
||||
except Exception as e:
|
||||
print(f" Failed to load @{account}: {e}")
|
||||
return posts
|
||||
|
||||
seen_texts = set()
|
||||
|
||||
for scroll in range(max_scroll):
|
||||
articles = page.query_selector_all("article")
|
||||
|
||||
for article in articles:
|
||||
try:
|
||||
text = article.inner_text()[:800]
|
||||
# Deduplicate
|
||||
sig = text[:100]
|
||||
if sig in seen_texts:
|
||||
continue
|
||||
seen_texts.add(sig)
|
||||
|
||||
# Extract links
|
||||
links = article.query_selector_all("a")
|
||||
urls = [l.get_attribute("href") for l in links if l.get_attribute("href")]
|
||||
|
||||
posts.append({
|
||||
"account": account,
|
||||
"text": text,
|
||||
"urls": urls[:5],
|
||||
"scraped_at": datetime.now(timezone.utc).isoformat(),
|
||||
})
|
||||
except:
|
||||
continue
|
||||
|
||||
# Scroll down
|
||||
page.evaluate("window.scrollBy(0, 1500)")
|
||||
page.wait_for_timeout(1500)
|
||||
|
||||
return posts
|
||||
|
||||
|
||||
def is_trading_related(text):
|
||||
text_lower = text.lower()
|
||||
return any(kw in text_lower for kw in TRADING_KEYWORDS)
|
||||
|
||||
|
||||
def main():
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
print(f"=== X Feed Scraper (Playwright) ===")
|
||||
print(f"Time: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}")
|
||||
|
||||
# Export cookies from Chrome if we don't have them yet
|
||||
if not COOKIE_FILE.exists():
|
||||
print("No cookies found — exporting from Chrome debug session...")
|
||||
export_cookies_from_chrome()
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
context = browser.new_context(
|
||||
user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
viewport={"width": 1280, "height": 900},
|
||||
)
|
||||
|
||||
load_cookies(context)
|
||||
page = context.new_page()
|
||||
|
||||
all_posts = []
|
||||
trading_posts = []
|
||||
|
||||
for account in ACCOUNTS:
|
||||
print(f"\nScraping @{account}...", end=" ", flush=True)
|
||||
posts = scrape_account(page, account)
|
||||
print(f"{len(posts)} posts")
|
||||
|
||||
for post in posts:
|
||||
all_posts.append(post)
|
||||
if is_trading_related(post["text"]):
|
||||
trading_posts.append(post)
|
||||
|
||||
browser.close()
|
||||
|
||||
print(f"\n{'='*50}")
|
||||
print(f"Total posts: {len(all_posts)}")
|
||||
print(f"Trading-related: {len(trading_posts)}")
|
||||
|
||||
# Save results
|
||||
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M")
|
||||
out_file = DATA_DIR / f"scan-{timestamp}.json"
|
||||
out_file.write_text(json.dumps({
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"total_posts": len(all_posts),
|
||||
"trading_posts": len(trading_posts),
|
||||
"posts": trading_posts,
|
||||
}, indent=2))
|
||||
print(f"Saved to {out_file}")
|
||||
|
||||
# Check for new posts we haven't seen before
|
||||
seen_file = DATA_DIR / "seen_posts.json"
|
||||
seen = set()
|
||||
if seen_file.exists():
|
||||
try:
|
||||
seen = set(json.loads(seen_file.read_text()))
|
||||
except:
|
||||
pass
|
||||
|
||||
new_posts = []
|
||||
for post in trading_posts:
|
||||
sig = post["text"][:150]
|
||||
if sig not in seen:
|
||||
new_posts.append(post)
|
||||
seen.add(sig)
|
||||
|
||||
seen_file.write_text(json.dumps(list(seen)[-5000:])) # Keep last 5000
|
||||
|
||||
if new_posts:
|
||||
print(f"\n🔔 {len(new_posts)} NEW trading posts!")
|
||||
for post in new_posts[:5]:
|
||||
lines = post["text"].split("\n")
|
||||
author = f"@{post['account']}"
|
||||
snippet = post["text"][:200].replace("\n", " ")
|
||||
print(f"\n {author}: {snippet}")
|
||||
|
||||
# Alert on Telegram
|
||||
msg = f"🔍 <b>New from {author}</b>\n\n{snippet[:300]}"
|
||||
if post.get("urls"):
|
||||
x_urls = [u for u in post["urls"] if "x.com" in u or "twitter.com" in u]
|
||||
if x_urls:
|
||||
msg += f"\n\n{x_urls[0]}"
|
||||
send_telegram(msg)
|
||||
else:
|
||||
print("\nNo new trading posts since last scan.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,18 +1,10 @@
|
||||
{
|
||||
"cash": 53477.43000000002,
|
||||
"cash": 60255.30020874026,
|
||||
"positions": {
|
||||
"DUOL": {
|
||||
"shares": 57,
|
||||
"avg_cost": 116.35,
|
||||
"current_price": 116.35,
|
||||
"entry_date": "2026-02-09T10:55:58.243598",
|
||||
"entry_reason": "GARP signal: PE=14.65, FwdPE=14.71, RevGr=41.1%, EPSGr=1114.3%, RSI=23.44",
|
||||
"trailing_stop": 104.715
|
||||
},
|
||||
"ALLY": {
|
||||
"shares": 156,
|
||||
"avg_cost": 42.65,
|
||||
"current_price": 42.65,
|
||||
"current_price": 42.040000915527344,
|
||||
"entry_date": "2026-02-09T10:55:58.244488",
|
||||
"entry_reason": "GARP signal: PE=18.0, FwdPE=6.76, RevGr=12.0%, EPSGr=265.4%, RSI=53.23",
|
||||
"trailing_stop": 38.385
|
||||
@ -20,7 +12,7 @@
|
||||
"JHG": {
|
||||
"shares": 138,
|
||||
"avg_cost": 48.21,
|
||||
"current_price": 48.21,
|
||||
"current_price": 48.20000076293945,
|
||||
"entry_date": "2026-02-09T10:55:58.245351",
|
||||
"entry_reason": "GARP signal: PE=9.22, FwdPE=9.96, RevGr=61.3%, EPSGr=243.6%, RSI=68.71",
|
||||
"trailing_stop": 43.389
|
||||
@ -28,31 +20,31 @@
|
||||
"INCY": {
|
||||
"shares": 61,
|
||||
"avg_cost": 108.69,
|
||||
"current_price": 108.69,
|
||||
"current_price": 109.02999877929688,
|
||||
"entry_date": "2026-02-09T10:55:58.246289",
|
||||
"entry_reason": "GARP signal: PE=18.42, FwdPE=13.76, RevGr=20.0%, EPSGr=290.7%, RSI=63.48",
|
||||
"trailing_stop": 97.821
|
||||
"trailing_stop": 98.12699890136719
|
||||
},
|
||||
"PINS": {
|
||||
"shares": 332,
|
||||
"avg_cost": 20.06,
|
||||
"current_price": 20.06,
|
||||
"current_price": 20.139999389648438,
|
||||
"entry_date": "2026-02-09T10:55:58.247262",
|
||||
"entry_reason": "GARP signal: PE=7.04, FwdPE=10.61, RevGr=16.8%, EPSGr=225.0%, RSI=19.14",
|
||||
"trailing_stop": 18.054
|
||||
"trailing_stop": 18.125999450683594
|
||||
},
|
||||
"EXEL": {
|
||||
"shares": 152,
|
||||
"avg_cost": 43.8,
|
||||
"current_price": 43.8,
|
||||
"current_price": 43.95000076293945,
|
||||
"entry_date": "2026-02-09T10:55:58.252764",
|
||||
"entry_reason": "GARP signal: PE=18.4, FwdPE=12.76, RevGr=10.8%, EPSGr=72.5%, RSI=50.12",
|
||||
"trailing_stop": 39.42
|
||||
"trailing_stop": 39.555000686645506
|
||||
},
|
||||
"CART": {
|
||||
"shares": 187,
|
||||
"avg_cost": 35.49,
|
||||
"current_price": 35.49,
|
||||
"current_price": 35.150001525878906,
|
||||
"entry_date": "2026-02-09T10:55:58.254418",
|
||||
"entry_reason": "GARP signal: PE=19.5, FwdPE=9.05, RevGr=10.2%, EPSGr=21.1%, RSI=37.75",
|
||||
"trailing_stop": 31.941000000000003
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
[
|
||||
{
|
||||
"date": "2026-02-09",
|
||||
"total_value": 100000.0,
|
||||
"total_pnl": 0.0,
|
||||
"pnl_pct": 0.0,
|
||||
"cash": 53477.43,
|
||||
"num_positions": 7
|
||||
"total_value": 100055.9,
|
||||
"total_pnl": 55.9,
|
||||
"pnl_pct": 0.06,
|
||||
"cash": 60255.3,
|
||||
"num_positions": 6
|
||||
}
|
||||
]
|
||||
@ -61,5 +61,16 @@
|
||||
"cost": 6636.63,
|
||||
"reason": "GARP signal: PE=19.5, FwdPE=9.05, RevGr=10.2%, EPSGr=21.1%, RSI=37.75",
|
||||
"timestamp": "2026-02-09T10:55:58.254721"
|
||||
},
|
||||
{
|
||||
"action": "SELL",
|
||||
"ticker": "DUOL",
|
||||
"shares": 57,
|
||||
"price": 118.91000366210938,
|
||||
"proceeds": 6777.87,
|
||||
"realized_pnl": 145.92,
|
||||
"entry_price": 116.35,
|
||||
"reason": "No longer passes GARP filter",
|
||||
"timestamp": "2026-02-09T15:36:18.884898"
|
||||
}
|
||||
]
|
||||
@ -194,5 +194,117 @@
|
||||
"ticker": "WTFC",
|
||||
"reason": "RSI too high (72.6 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:18.885237",
|
||||
"action": "SELL",
|
||||
"ticker": "DUOL",
|
||||
"reason": "No longer passes GARP filter",
|
||||
"details": {
|
||||
"success": true,
|
||||
"ticker": "DUOL",
|
||||
"shares": 57,
|
||||
"price": 118.91000366210938,
|
||||
"proceeds": 6777.87,
|
||||
"realized_pnl": 145.92
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.302964",
|
||||
"action": "SKIP",
|
||||
"ticker": "VLY",
|
||||
"reason": "RSI too high (78.3 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.303492",
|
||||
"action": "SKIP",
|
||||
"ticker": "FHN",
|
||||
"reason": "RSI too high (72.4 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.304721",
|
||||
"action": "SKIP",
|
||||
"ticker": "FNB",
|
||||
"reason": "RSI too high (71.0 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.305710",
|
||||
"action": "SKIP",
|
||||
"ticker": "SSB",
|
||||
"reason": "RSI too high (89.0 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.306687",
|
||||
"action": "SKIP",
|
||||
"ticker": "WBS",
|
||||
"reason": "RSI too high (82.0 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.307754",
|
||||
"action": "SKIP",
|
||||
"ticker": "ONB",
|
||||
"reason": "RSI too high (77.6 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.308706",
|
||||
"action": "SKIP",
|
||||
"ticker": "WAL",
|
||||
"reason": "RSI too high (71.7 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.309624",
|
||||
"action": "SKIP",
|
||||
"ticker": "ZION",
|
||||
"reason": "RSI too high (73.3 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.310657",
|
||||
"action": "SKIP",
|
||||
"ticker": "CFG",
|
||||
"reason": "RSI too high (78.5 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.311641",
|
||||
"action": "SKIP",
|
||||
"ticker": "UBSI",
|
||||
"reason": "RSI too high (77.5 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.312722",
|
||||
"action": "SKIP",
|
||||
"ticker": "EWBC",
|
||||
"reason": "RSI too high (78.6 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.313689",
|
||||
"action": "SKIP",
|
||||
"ticker": "FITB",
|
||||
"reason": "Too close to 52wk high (1.9% away)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.314689",
|
||||
"action": "SKIP",
|
||||
"ticker": "BAC",
|
||||
"reason": "RSI too high (78.1 > 70)",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2026-02-09T15:36:19.315714",
|
||||
"action": "SKIP",
|
||||
"ticker": "WTFC",
|
||||
"reason": "RSI too high (70.2 > 70)",
|
||||
"details": {}
|
||||
}
|
||||
]
|
||||
@ -1,356 +1,338 @@
|
||||
{
|
||||
"date": "2026-02-09",
|
||||
"timestamp": "2026-02-09T10:55:58.242176",
|
||||
"timestamp": "2026-02-09T15:36:18.290971",
|
||||
"total_scanned": 902,
|
||||
"candidates_found": 21,
|
||||
"candidates_found": 20,
|
||||
"candidates": [
|
||||
{
|
||||
"ticker": "DUOL",
|
||||
"price": 116.35,
|
||||
"market_cap": 5378552832,
|
||||
"market_cap_b": 5.4,
|
||||
"trailing_pe": 14.65,
|
||||
"forward_pe": 14.71,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 41.1,
|
||||
"earnings_growth": 1114.3,
|
||||
"roe": 36.2,
|
||||
"quick_ratio": 2.6,
|
||||
"debt_to_equity": 7.4,
|
||||
"rsi": 23.44,
|
||||
"week52_high": 544.93,
|
||||
"pct_from_52wk_high": 78.6,
|
||||
"score": -100.83
|
||||
},
|
||||
{
|
||||
"ticker": "ALLY",
|
||||
"price": 42.65,
|
||||
"market_cap": 13158768640,
|
||||
"market_cap_b": 13.2,
|
||||
"trailing_pe": 18.0,
|
||||
"forward_pe": 6.76,
|
||||
"price": 42.04,
|
||||
"market_cap": 12969046016,
|
||||
"market_cap_b": 13.0,
|
||||
"trailing_pe": 17.74,
|
||||
"forward_pe": 6.66,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 12.0,
|
||||
"earnings_growth": 265.4,
|
||||
"roe": 5.8,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 53.23,
|
||||
"rsi": 49.52,
|
||||
"week52_high": 47.27,
|
||||
"pct_from_52wk_high": 9.8,
|
||||
"score": -20.98
|
||||
"pct_from_52wk_high": 11.1,
|
||||
"score": -21.08
|
||||
},
|
||||
{
|
||||
"ticker": "JHG",
|
||||
"price": 48.21,
|
||||
"market_cap": 7447323136,
|
||||
"price": 48.2,
|
||||
"market_cap": 7445763584,
|
||||
"market_cap_b": 7.4,
|
||||
"trailing_pe": 9.22,
|
||||
"forward_pe": 9.96,
|
||||
"forward_pe": 9.95,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 61.3,
|
||||
"earnings_growth": 243.6,
|
||||
"roe": 16.2,
|
||||
"quick_ratio": 69.46,
|
||||
"debt_to_equity": 6.5,
|
||||
"rsi": 68.71,
|
||||
"rsi": 68.18,
|
||||
"week52_high": 49.42,
|
||||
"pct_from_52wk_high": 2.4,
|
||||
"score": -20.529999999999998
|
||||
"pct_from_52wk_high": 2.5,
|
||||
"score": -20.54
|
||||
},
|
||||
{
|
||||
"ticker": "INCY",
|
||||
"price": 108.69,
|
||||
"market_cap": 21338314752,
|
||||
"market_cap_b": 21.3,
|
||||
"trailing_pe": 18.42,
|
||||
"forward_pe": 13.76,
|
||||
"price": 109.03,
|
||||
"market_cap": 21405063168,
|
||||
"market_cap_b": 21.4,
|
||||
"trailing_pe": 18.48,
|
||||
"forward_pe": 13.81,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 20.0,
|
||||
"earnings_growth": 290.7,
|
||||
"roe": 30.4,
|
||||
"quick_ratio": 2.86,
|
||||
"debt_to_equity": 0.9,
|
||||
"rsi": 63.48,
|
||||
"rsi": 64.03,
|
||||
"week52_high": 112.29,
|
||||
"pct_from_52wk_high": 3.2,
|
||||
"score": -17.310000000000002
|
||||
"pct_from_52wk_high": 2.9,
|
||||
"score": -17.259999999999998
|
||||
},
|
||||
{
|
||||
"ticker": "PINS",
|
||||
"price": 20.06,
|
||||
"market_cap": 13635989504,
|
||||
"market_cap_b": 13.6,
|
||||
"trailing_pe": 7.04,
|
||||
"forward_pe": 10.61,
|
||||
"price": 20.14,
|
||||
"market_cap": 13693783040,
|
||||
"market_cap_b": 13.7,
|
||||
"trailing_pe": 7.07,
|
||||
"forward_pe": 10.66,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 16.8,
|
||||
"earnings_growth": 225.0,
|
||||
"roe": 51.5,
|
||||
"quick_ratio": 8.14,
|
||||
"debt_to_equity": 4.3,
|
||||
"rsi": 19.14,
|
||||
"rsi": 19.93,
|
||||
"week52_high": 40.38,
|
||||
"pct_from_52wk_high": 50.3,
|
||||
"score": -13.57
|
||||
"pct_from_52wk_high": 50.1,
|
||||
"score": -13.52
|
||||
},
|
||||
{
|
||||
"ticker": "VLY",
|
||||
"price": 13.72,
|
||||
"market_cap": 7647972352,
|
||||
"price": 13.7,
|
||||
"market_cap": 7639607296,
|
||||
"market_cap_b": 7.6,
|
||||
"trailing_pe": 13.58,
|
||||
"forward_pe": 9.2,
|
||||
"trailing_pe": 13.56,
|
||||
"forward_pe": 9.19,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 38.3,
|
||||
"earnings_growth": 66.3,
|
||||
"roe": 7.8,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 78.6,
|
||||
"rsi": 78.34,
|
||||
"week52_high": 13.79,
|
||||
"pct_from_52wk_high": 0.5,
|
||||
"score": -1.2600000000000002
|
||||
"pct_from_52wk_high": 0.7,
|
||||
"score": -1.27
|
||||
},
|
||||
{
|
||||
"ticker": "FHN",
|
||||
"price": 26.33,
|
||||
"market_cap": 12967198720,
|
||||
"market_cap_b": 13.0,
|
||||
"trailing_pe": 14.08,
|
||||
"forward_pe": 11.23,
|
||||
"price": 26.03,
|
||||
"market_cap": 12817018880,
|
||||
"market_cap_b": 12.8,
|
||||
"trailing_pe": 13.92,
|
||||
"forward_pe": 11.1,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 23.7,
|
||||
"earnings_growth": 74.9,
|
||||
"roe": 10.9,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 76.1,
|
||||
"rsi": 72.36,
|
||||
"week52_high": 26.56,
|
||||
"pct_from_52wk_high": 0.8,
|
||||
"score": 1.37
|
||||
"pct_from_52wk_high": 2.0,
|
||||
"score": 1.2399999999999993
|
||||
},
|
||||
{
|
||||
"ticker": "FNB",
|
||||
"price": 19.05,
|
||||
"market_cap": 6822501376,
|
||||
"price": 18.92,
|
||||
"market_cap": 6775944192,
|
||||
"market_cap_b": 6.8,
|
||||
"trailing_pe": 12.21,
|
||||
"forward_pe": 9.73,
|
||||
"trailing_pe": 12.13,
|
||||
"forward_pe": 9.67,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 26.4,
|
||||
"earnings_growth": 56.5,
|
||||
"roe": 8.7,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 71.92,
|
||||
"rsi": 70.99,
|
||||
"week52_high": 19.14,
|
||||
"pct_from_52wk_high": 0.4,
|
||||
"score": 1.4400000000000004
|
||||
"pct_from_52wk_high": 1.1,
|
||||
"score": 1.38
|
||||
},
|
||||
{
|
||||
"ticker": "SSB",
|
||||
"price": 107.67,
|
||||
"market_cap": 10821986304,
|
||||
"price": 107.18,
|
||||
"market_cap": 10773236736,
|
||||
"market_cap_b": 10.8,
|
||||
"trailing_pe": 13.68,
|
||||
"forward_pe": 10.18,
|
||||
"trailing_pe": 13.62,
|
||||
"forward_pe": 10.13,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 53.2,
|
||||
"earnings_growth": 30.9,
|
||||
"roe": 10.7,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 92.25,
|
||||
"rsi": 89.03,
|
||||
"week52_high": 108.46,
|
||||
"pct_from_52wk_high": 0.7,
|
||||
"score": 1.7699999999999996
|
||||
"pct_from_52wk_high": 1.2,
|
||||
"score": 1.7200000000000006
|
||||
},
|
||||
{
|
||||
"ticker": "WBS",
|
||||
"price": 73.28,
|
||||
"market_cap": 11818547200,
|
||||
"price": 73.21,
|
||||
"market_cap": 11808063488,
|
||||
"market_cap_b": 11.8,
|
||||
"trailing_pe": 12.42,
|
||||
"forward_pe": 9.79,
|
||||
"trailing_pe": 12.41,
|
||||
"forward_pe": 9.78,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 18.2,
|
||||
"earnings_growth": 53.4,
|
||||
"roe": 10.8,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 82.13,
|
||||
"rsi": 82.05,
|
||||
"week52_high": 73.5,
|
||||
"pct_from_52wk_high": 0.3,
|
||||
"score": 2.6299999999999994
|
||||
},
|
||||
{
|
||||
"ticker": "WAL",
|
||||
"price": 96.21,
|
||||
"market_cap": 10588263424,
|
||||
"market_cap_b": 10.6,
|
||||
"trailing_pe": 11.02,
|
||||
"forward_pe": 8.09,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 16.6,
|
||||
"earnings_growth": 32.9,
|
||||
"roe": 13.5,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 71.81,
|
||||
"week52_high": 96.94,
|
||||
"pct_from_52wk_high": 0.8,
|
||||
"score": 3.1399999999999997
|
||||
"pct_from_52wk_high": 0.4,
|
||||
"score": 2.6199999999999997
|
||||
},
|
||||
{
|
||||
"ticker": "ONB",
|
||||
"price": 25.93,
|
||||
"market_cap": 10132744192,
|
||||
"market_cap_b": 10.1,
|
||||
"trailing_pe": 14.49,
|
||||
"forward_pe": 9.04,
|
||||
"price": 25.67,
|
||||
"market_cap": 10031142912,
|
||||
"market_cap_b": 10.0,
|
||||
"trailing_pe": 14.34,
|
||||
"forward_pe": 8.95,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 41.4,
|
||||
"earnings_growth": 17.2,
|
||||
"roe": 9.0,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 81.24,
|
||||
"rsi": 77.64,
|
||||
"week52_high": 26.17,
|
||||
"pct_from_52wk_high": 1.9,
|
||||
"score": 3.09
|
||||
},
|
||||
{
|
||||
"ticker": "WAL",
|
||||
"price": 96.08,
|
||||
"market_cap": 10573956096,
|
||||
"market_cap_b": 10.6,
|
||||
"trailing_pe": 11.01,
|
||||
"forward_pe": 8.08,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 16.6,
|
||||
"earnings_growth": 32.9,
|
||||
"roe": 13.5,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 71.66,
|
||||
"week52_high": 96.99,
|
||||
"pct_from_52wk_high": 0.9,
|
||||
"score": 3.1799999999999997
|
||||
"score": 3.13
|
||||
},
|
||||
{
|
||||
"ticker": "EXEL",
|
||||
"price": 43.8,
|
||||
"market_cap": 11791070208,
|
||||
"price": 43.95,
|
||||
"market_cap": 11831451648,
|
||||
"market_cap_b": 11.8,
|
||||
"trailing_pe": 18.4,
|
||||
"forward_pe": 12.76,
|
||||
"trailing_pe": 18.47,
|
||||
"forward_pe": 12.8,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 10.8,
|
||||
"earnings_growth": 72.5,
|
||||
"roe": 30.6,
|
||||
"quick_ratio": 3.5,
|
||||
"debt_to_equity": 8.2,
|
||||
"rsi": 50.12,
|
||||
"rsi": 51.02,
|
||||
"week52_high": 49.62,
|
||||
"pct_from_52wk_high": 11.7,
|
||||
"score": 4.43
|
||||
"pct_from_52wk_high": 11.4,
|
||||
"score": 4.470000000000001
|
||||
},
|
||||
{
|
||||
"ticker": "ZION",
|
||||
"price": 65.29,
|
||||
"market_cap": 9640263680,
|
||||
"price": 65.16,
|
||||
"market_cap": 9621069824,
|
||||
"market_cap_b": 9.6,
|
||||
"trailing_pe": 10.86,
|
||||
"forward_pe": 9.99,
|
||||
"trailing_pe": 10.84,
|
||||
"forward_pe": 9.97,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 13.6,
|
||||
"earnings_growth": 31.4,
|
||||
"roe": 13.5,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 74.03,
|
||||
"rsi": 73.29,
|
||||
"week52_high": 66.18,
|
||||
"pct_from_52wk_high": 1.3,
|
||||
"score": 5.49
|
||||
"pct_from_52wk_high": 1.5,
|
||||
"score": 5.470000000000001
|
||||
},
|
||||
{
|
||||
"ticker": "CART",
|
||||
"price": 35.49,
|
||||
"market_cap": 9349425152,
|
||||
"price": 35.15,
|
||||
"market_cap": 9259855872,
|
||||
"market_cap_b": 9.3,
|
||||
"trailing_pe": 19.5,
|
||||
"forward_pe": 9.05,
|
||||
"trailing_pe": 19.31,
|
||||
"forward_pe": 8.97,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 10.2,
|
||||
"earnings_growth": 21.1,
|
||||
"roe": 15.3,
|
||||
"quick_ratio": 3.33,
|
||||
"debt_to_equity": 1.0,
|
||||
"rsi": 37.75,
|
||||
"rsi": 36.01,
|
||||
"week52_high": 53.5,
|
||||
"pct_from_52wk_high": 33.7,
|
||||
"score": 5.92
|
||||
"pct_from_52wk_high": 34.3,
|
||||
"score": 5.84
|
||||
},
|
||||
{
|
||||
"ticker": "CFG",
|
||||
"price": 68.17,
|
||||
"market_cap": 29278072832,
|
||||
"market_cap_b": 29.3,
|
||||
"trailing_pe": 17.66,
|
||||
"forward_pe": 10.82,
|
||||
"price": 67.7,
|
||||
"market_cap": 29076213760,
|
||||
"market_cap_b": 29.1,
|
||||
"trailing_pe": 17.54,
|
||||
"forward_pe": 10.75,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 10.7,
|
||||
"earnings_growth": 35.9,
|
||||
"roe": 7.2,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 80.86,
|
||||
"rsi": 78.47,
|
||||
"week52_high": 68.65,
|
||||
"pct_from_52wk_high": 0.7,
|
||||
"score": 6.16
|
||||
"pct_from_52wk_high": 1.4,
|
||||
"score": 6.09
|
||||
},
|
||||
{
|
||||
"ticker": "UBSI",
|
||||
"price": 45.32,
|
||||
"market_cap": 6316939264,
|
||||
"price": 45.06,
|
||||
"market_cap": 6280699392,
|
||||
"market_cap_b": 6.3,
|
||||
"trailing_pe": 13.86,
|
||||
"forward_pe": 12.03,
|
||||
"trailing_pe": 13.78,
|
||||
"forward_pe": 11.96,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 22.1,
|
||||
"earnings_growth": 32.1,
|
||||
"roe": 8.9,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 80.0,
|
||||
"rsi": 77.51,
|
||||
"week52_high": 45.93,
|
||||
"pct_from_52wk_high": 1.3,
|
||||
"score": 6.61
|
||||
"pct_from_52wk_high": 1.9,
|
||||
"score": 6.54
|
||||
},
|
||||
{
|
||||
"ticker": "EWBC",
|
||||
"price": 123.19,
|
||||
"market_cap": 16949170176,
|
||||
"price": 122.56,
|
||||
"market_cap": 16862490624,
|
||||
"market_cap_b": 16.9,
|
||||
"trailing_pe": 12.94,
|
||||
"forward_pe": 11.24,
|
||||
"trailing_pe": 12.87,
|
||||
"forward_pe": 11.18,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 21.6,
|
||||
"earnings_growth": 21.3,
|
||||
"roe": 15.9,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 79.27,
|
||||
"rsi": 78.61,
|
||||
"week52_high": 123.82,
|
||||
"pct_from_52wk_high": 0.5,
|
||||
"score": 6.949999999999999
|
||||
"pct_from_52wk_high": 1.0,
|
||||
"score": 6.890000000000001
|
||||
},
|
||||
{
|
||||
"ticker": "FITB",
|
||||
"price": 54.38,
|
||||
"market_cap": 48944635904,
|
||||
"price": 54.33,
|
||||
"market_cap": 48899633152,
|
||||
"market_cap_b": 48.9,
|
||||
"trailing_pe": 15.41,
|
||||
"forward_pe": 11.09,
|
||||
"trailing_pe": 15.39,
|
||||
"forward_pe": 11.08,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 11.5,
|
||||
"earnings_growth": 20.8,
|
||||
"roe": 12.2,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 66.02,
|
||||
"rsi": 65.77,
|
||||
"week52_high": 55.36,
|
||||
"pct_from_52wk_high": 1.8,
|
||||
"score": 7.859999999999999
|
||||
"pct_from_52wk_high": 1.9,
|
||||
"score": 7.85
|
||||
},
|
||||
{
|
||||
"ticker": "BAC",
|
||||
"price": 56.43,
|
||||
"market_cap": 412079849472,
|
||||
"market_cap_b": 412.1,
|
||||
"price": 56.41,
|
||||
"market_cap": 411933769728,
|
||||
"market_cap_b": 411.9,
|
||||
"trailing_pe": 14.81,
|
||||
"forward_pe": 11.38,
|
||||
"peg_ratio": null,
|
||||
@ -359,28 +341,28 @@
|
||||
"roe": 10.2,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 78.3,
|
||||
"rsi": 78.1,
|
||||
"week52_high": 57.55,
|
||||
"pct_from_52wk_high": 1.9,
|
||||
"pct_from_52wk_high": 2.0,
|
||||
"score": 7.970000000000001
|
||||
},
|
||||
{
|
||||
"ticker": "WTFC",
|
||||
"price": 159.71,
|
||||
"market_cap": 10696563712,
|
||||
"market_cap_b": 10.7,
|
||||
"trailing_pe": 14.0,
|
||||
"forward_pe": 11.91,
|
||||
"price": 158.57,
|
||||
"market_cap": 10620212224,
|
||||
"market_cap_b": 10.6,
|
||||
"trailing_pe": 13.9,
|
||||
"forward_pe": 11.82,
|
||||
"peg_ratio": null,
|
||||
"revenue_growth": 10.5,
|
||||
"earnings_growth": 19.4,
|
||||
"roe": 12.1,
|
||||
"quick_ratio": null,
|
||||
"debt_to_equity": null,
|
||||
"rsi": 72.56,
|
||||
"rsi": 70.23,
|
||||
"week52_high": 162.96,
|
||||
"pct_from_52wk_high": 2.0,
|
||||
"score": 8.92
|
||||
"pct_from_52wk_high": 2.7,
|
||||
"score": 8.83
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user