Install
$ agentstack add skill-wauputr4-financial-astrology-skills-financial-astrology-pattern-search ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Financial Astrology Pattern Search
Overview
Use this skill to repeat the Bitcoin astrology-cycle experiment on other financial assets: crypto pairs, ETFs, indices, commodities, FX, or individual equities. The goal is not to produce deterministic trading signals. The goal is to dogfood hermetic-alpha-library, discover candidate timing patterns, and separate interesting hypotheses from cherry-picked noise.
Core idea:
- Fetch daily OHLCV candles for one or more assets.
- Generate planetary positions for the same date range.
- Scan astrological aspects as event windows.
- Collapse each active multi-day aspect window into its nearest-exact day.
- Compare forward returns after those exact days against the asset's own baseline return.
- Validate with chronological train/test splits and, when possible, cross-asset checks.
- Report findings as exploratory hypotheses with limitations and disclaimers.
When to Use
Use when the user asks to:
- “Cari pola astrology di ETH/SPY/gold/etc.”
- “Coba siklus besar untuk asset lain.”
- “Bandingin pattern BTC dengan saham/ETF/komoditas.”
- “Bikin kalender teori 2026–2028 untuk asset X.”
- “Cari pressure / trigger / release cycle di market.”
- “Dogfood hermetic-alpha-library ke data investasi lain.”
Do not use for:
- Live trading advice or entry/exit recommendations.
- Backtests that ignore transaction costs, slippage, liquidity, or risk management.
- Claims of causality from astrology to price movement.
- Publishing confident predictions without sample size, baseline, and validation caveats.
Quick Setup
Prefer a throwaway workspace so the repo state stays clean.
TMP=$(mktemp -d /tmp/hermetic-alpha-asset-search.XXXXXX)
git clone https://github.com/wauputr4/hermetic-alpha-library "$TMP"
cd "$TMP"
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -U pip
python3 -m pip install -e ".[dev]"
python3 -m pytest -q
If the repo already exists locally, reuse it, but still verify tests/imports before trusting results:
cd /path/to/hermetic-alpha-library
. .venv/bin/activate # or create it first
PYTHONPATH=src python3 - 0`)
- event min/max
- train edge vs baseline
- test edge vs baseline
Always compare an event against **the same asset's baseline** and same date range. Do not compare ETH event returns to BTC baseline, etc.
### Train/test split
Use chronological validation:
- Long crypto history: train through `2020-12-31`, test after.
- ETFs/equities with longer history: train through a reasonable midpoint or regime boundary, then test.
- Short assets: use 60/40 chronological split, but label the result weak.
Scoring heuristic:
```text
train_edge = train_avg_return - baseline_avg_return
test_edge = test_avg_return - baseline_avg_return
same_direction = train_edge and test_edge have same sign
robustness_score = average absolute edge if same_direction, otherwise negative disagreement penalty
A pattern is more interesting if:
- Train and test edges point in the same direction.
- Median return agrees with average direction.
- Bullish percentage is directionally consistent.
- Event count is not tiny.
- It appears across related assets or at least does not invert badly out-of-sample.
Cross-Asset Workflow
For multiple assets, do not simply rank the best feature per asset and call it a theory. Use staged validation.
Stage 1 — Discover per asset
Run the exact-event search for each asset independently.
Output per asset:
- top robust bullish features
- weakest robust / bearish features
- theme aggregation by planet, aspect, pair, and horizon
- counts: candles, raw aspect days, exact windows, features scored
Stage 2 — Compare common themes
Group features into themes:
- planet tag:
saturn,venus,pluto - aspect tag:
opposition,conjunction, etc. - pair tag:
venus_pluto,jupiter_saturn - planet-aspect tag:
saturn_conjunction,venus_opposition - horizon tag:
h7,h30,h90
Look for themes where direction and horizon make conceptual sense across assets, e.g.:
- risk-on crypto responds to
venus_oppositiondifferently from defensive bonds saturnhard/conjunction themes may behave as pressure/cooldown in risk assetsmarsinner aspects may act more like short-term triggers than long-term regimes
Stage 3 — Validate an anchored theory
If BTC suggests a theory, test it on other assets without re-selecting features.
Example anchored theory from the BTC experiment:
venusopposition withmars/jupiter/saturn/uranus/pluto→ possible release/risk-on windowsmarsconjunction/trine withsun/mercury/venus→ possible short-term triggerssaturnconjunction with personal planets → pressure/caution windowsmercury_venusconjunction/sextile → cooldown candidates
For each new asset, classify windows using the same rules and measure returns. Do not optimize the rules per asset unless it is explicitly a second-stage exploratory pass.
Minimal Generic Script Skeleton
Use this as a starting point. Customize ASSETS, START, TRAIN_END, and output paths.
from __future__ import annotations
from collections import defaultdict
from dataclasses import dataclass
from datetime import date, timedelta, timezone
import json, math, statistics
from hermetic_alpha.astro import SwissEphemerisAdapter, generate_planet_positions, scan_aspect_series
from hermetic_alpha.labels import add_candle_forward_returns
from hermetic_alpha.market.providers import YahooFinanceProvider
ASSETS = ["BTC-USD", "ETH-USD", "SPY", "QQQ", "GLD", "TLT"]
BODIES = ["moon", "sun", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"]
ASPECTS = ["conjunction", "opposition", "trine", "square", "sextile"]
ASPECT_ORBS = {a: 2.5 for a in ASPECTS}
HORIZONS = [3, 7, 14, 30, 60, 90]
START = "2014-09-17"
TRAIN_END = "2020-12-31"
MIN_TRAIN_EVENTS = 3
MIN_TEST_EVENTS = 2
@dataclass(frozen=True)
class WindowEvent:
feature: str
start_idx: int
end_idx: int
exact_idx: int
min_orb: float
max_strength: float
def pct(x):
return None if x is None else round(x * 100, 3)
def valid(v):
return isinstance(v, (int, float)) and math.isfinite(float(v))
def feature_key(e):
a, b = sorted([e.body_a, e.body_b])
return f"{a}_{b}_{e.aspect}"
def ret(labels, idx, h):
if idx = len(labels):
return None
v = labels[idx].get(f"return_{h}d")
return float(v) if valid(v) else None
def block_to_event(feature, block):
exact_idx, exact_e = min(block, key=lambda x: (x[1].orb, x[0]))
return WindowEvent(
feature=feature,
start_idx=block[0][0],
end_idx=block[-1][0],
exact_idx=exact_idx,
min_orb=float(exact_e.orb),
max_strength=max(float(e.strength) for _, e in block),
)
def build_window_events(events, timestamp_to_idx):
by_feature = defaultdict(list)
for e in events:
idx = timestamp_to_idx.get(e.timestamp)
if idx is not None:
by_feature[feature_key(e)].append((idx, e))
out = []
for feature, rows in by_feature.items():
rows = sorted(rows, key=lambda x: x[0])
block, prev = [], None
for idx, e in rows:
if prev is None or idx 0 for v in vals) / len(vals)),
}
def score_feature(feature, events, labels, candles, train_cut_idx, baseline):
train = [e for e in events if e.exact_idx train_cut_idx]
if len(train) = 0 and test_edge >= 0) or (train_edge best:
best = (robustness, h)
if not horizons:
return None
best_h = best[1]
return {
"feature": feature,
"event_count": len(events),
"train_events": len(train),
"test_events": len(test),
"first_exact": candles[events[0].exact_idx].timestamp.date().isoformat(),
"last_exact": candles[events[-1].exact_idx].timestamp.date().isoformat(),
"best_horizon": best_h,
"best_robustness_score_pp": horizons[best_h]["robustness_score_pp"],
"best_train_edge_pp": horizons[best_h]["train_edge_pp"],
"best_test_edge_pp": horizons[best_h]["test_edge_pp"],
"horizons": horizons,
}
def run_asset(asset):
provider = YahooFinanceProvider(timeout=30)
candles = provider.fetch_daily(asset, START, date.today().isoformat())
labels = add_candle_forward_returns(candles, HORIZONS)
timestamp_to_idx = {c.timestamp: i for i, c in enumerate(candles)}
train_cut_idx = max(i for i, c in enumerate(candles) if c.timestamp.date().isoformat() =20% drawdown cycle.
- Bull: days outside active peak-to-bottom bear declines.
- Peak window: ±30 trading days around major peaks.
- Bottom window: ±30 trading days around major bottoms.
- Optional one-sided labels: `pre_peak_30td` and `post_bottom_30td`.
2. Generate astrology events exactly as usual: scan aspects, group consecutive active days, choose nearest-exact date, and map non-trading exact dates to the next available trading day within a documented lag.
3. Aggregate events into class-level buckets rather than only exact features:
- `planet:*`, `aspect:*`, `planet_aspect:*`, `pair:*`
- hard/soft aspect families
- outer-outer, outer-personal, personal-personal pair families
- existing theory themes such as Saturn pressure, Jupiter–Uranus major, Mercury–Venus cooldown, etc.
4. For each bucket and market-state label, compute enrichment metrics:
- event count, observed events inside label, event rate, base day share, edge in percentage points, lift, and approximate binomial z-score.
5. Report as **enrichment / coincidence research**, not prediction. Major peak and bottom labels are hindsight-defined; freeze any candidate themes before using them in future calendars.
Requester-facing summary guidance:
- Use the conversation language for chat summaries unless the requester asks otherwise.
- Use simple buckets: `bull / constructive`, `bear / pressure`, `peak-risk`, `bottom / reversal`.
- State that SPX bull enrichment is less distinctive because SPX is mostly bull by baseline; often the useful signal is which pressure themes cluster around bear/peak windows.
- Include caveats: hindsight labels, multiple testing, small outer-planet samples, and need to validate against SPY/ES/Nasdaq/Dow.
## Calendar / Forecast Workflow
Only build a future calendar after a theory is defined and validated enough to be worth watching.
1. Convert robust historical themes into explicit classification rules.
2. Generate future planetary aspects for a fixed period, e.g. `2026-01-01` to `2028-12-31`.
3. Collapse windows and pick exact dates.
4. Assign categories such as:
- `bullish_release`
- `bullish_trigger`
- `pressure_warning`
- `cooldown_warning`
- `mixed_watch`
5. Add a legend explaining horizon: short trigger `3–14d`, release `7–30d`, pressure `30–90d`.
6. State clearly that this is a **watchlist / theory calendar**, not a trade plan.
## Reporting Format
For research-paper artifacts, use English by default unless the requester explicitly requests another language. Chat progress/final summaries may follow the conversation language, but the Markdown/PDF paper body and GitHub Discussion should default to English for broader reuse.
Recommended structure:
```markdown
## Eksperimen yang gw jalankan
- Asset: ...
- Periode: ...
- Aspect: ...
- Orb: ...
- Horizon: ...
- Train/test: ...
## Baseline asset
- Avg return 7d/30d/90d: ...
## Temuan paling menarik
1. Feature/theme: ...
- Event count: ...
- Train edge: ...
- Test edge: ...
- Avg/median/bullish%: ...
- Interpretasi: ...
## Yang harus dicurigai
- Sample kecil / multiple testing / regime berubah / Yahoo data bukan audit-grade.
## Teori kerja
- Pressure: ...
- Trigger: ...
- Release: ...
## Next step
- Validate ke asset lain / bikin calendar / tulis artikel.
Disclaimer: bukan financial advice; ini eksplorasi data dan dogfood library.
Comprehensive publishable research package
When the requester asks for comprehensive research, especially “format md, pdf, publish di discussion repository”, produce a repo-ready package rather than only a chat summary:
- Write a full Markdown paper with YAML frontmatter, executive summary, data/methodology, baseline, feature-level tables, theme-level interpretation, caveats, next steps, and disclaimer.
- Generate a PDF from the Markdown via the
pandoc-pdf-generationskill. For wide result tables, prefer landscape A4, small font, DejaVu Sans/Mono, TOC, and numbered sections. - Verify the PDF artifact: check file type/size and use an available PDF inspection tool such as
mutool info/mutool draw -F txtwhenpdfinfoorpdftotextare unavailable. - Commit the Markdown and PDF under a stable repo path such as
research/-/README.mdplus the PDF file. - Publish or update a GitHub Discussion that links to the committed Markdown, PDF, and commit. Before creating a new discussion, list/search recent repo discussions for the same asset/topic; if a relevant discussion already exists, update it or add a clear follow-up comment instead of duplicating threads. Include the full paper body or a substantial excerpt so the discussion is readable without downloading artifacts.
- Verify publication with real outputs: Discussion URL, HTTP 200 for discussion/README/PDF links, body length or fetched title, commit SHA, PDF file type/size/page count, and test/import result where possible.
- In the final chat response, send clickable Markdown links and attach the local
.mdand.pdfwhen the platform supports native file delivery. Do not merely print local paths in backticks when a native attachment mechanism is available. - If the requester says the result is “kurang komprehensif” or reminds you to “bikin discussion/update”, treat it as a workflow correction: expand the paper substantially, commit/update repo artifacts, create or update the GitHub Discussion, verify all links return HTTP 200, then resend or attach the updated MD/PDF artifacts.
For article-style outputs in a casual Indonesian voice:
- Use
gw/Lonaturally. - Explain why the experiment is interesting even for skeptics.
- Avoid claiming “astrology predicts price”. Prefer “event windows can be tested statistically”.
- Mention limitations before readers over-trust the pattern.
- Close with practical reflection or a question, not a trading call.
Anti-Overfitting Rules
Always enforce these:
- No one-line miracle claims. Every finding needs period, sample size, horizon, baseline, and train/test direction.
- Do not optimize everything at once. If you tune bodies, orbs, aspects, horizons, and split dates until it looks good, label it exploratory.
- Collapse windows. Do not count every active aspect day as an independent event.
- Keep Moon separate. Moon creates many events and can dominate counts.
- Prefer robust direction over highest average. One giant return can inflate averages.
- Check medians. If average is strong but median is weak/opposite, say so.
- Use same-asset baseline. Different assets have different drift and volatility.
- Cross-asset validation beats prettier charts. A pattern found on BTC is more credible if tested unchanged on ETH/SPY/GLD/TLT.
- No causal language. Use “correlated with”, “coincided with”, “candidate”, “watchlist”.
- No trading advice. Never present as buy/sell/short/long instruction.
Common Pitfalls
- Yahoo symbols fail silently or have odd histories. Verify actual candle count and first/last dates for every asset.
- Equity calendars skip weekends/holidays. Map aspect timestamps to candle timestamps; if no candle exists, skip or map explicitly with a documented rule.
- Multiple testing creates false positives. Treat top features as hypotheses until validated out-of-sample.
- Small event counts are fragile. Outer-planet aspects can have very few samples. Report them as narrative hyp
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: wauputr4
- Source: wauputr4/financial-astrology-skills
- License: MIT
- Homepage: https://www.skills.sh/wauputr4/financial-astrology-skills
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.