Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
},
"homepage": "https://github.com/moshcoder/moshcode#ticker",
"keywords": ["stocks", "equity", "research", "markets", "advis0r"]
},
{
"name": "crypto",
"description": "Crypto market data slash commands backed by advis0r.com: live prices, technical scores, order books, OHLCV history and sparklines across Alpaca's US crypto venue.",
"source": "./plugins/crypto",
"category": "productivity",
"author": {
"name": "moshcoder",
"url": "https://moshcode.sh"
},
"homepage": "https://github.com/moshcoder/moshcode#crypto",
"keywords": ["crypto", "bitcoin", "markets", "prices", "advis0r"]
}
]
}
45 changes: 43 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ or miss one that does. A test fails the build when it drifts.
| `moshcode tools` | tools | list workflow tools and installation status |
| `moshcode trade` | tools | look up markets and trade through Alpaca |
| `moshcode ticker` <br>`advisor` | tools | equity research from advis0r.com |
| `moshcode crypto` <br>`coins` | tools | crypto market data from advis0r.com |
| `moshcode plugin` <br>`plugins` | extend | install moshcode's slash commands into Claude Code |
| `moshcode commands` | script | list built-in moshscript commands |
| `moshcode completion` | extend | print a shell completion script |
Expand Down Expand Up @@ -238,6 +239,37 @@ delayed and which feed produced it. Scores labelled `offline` come from
deterministic rules rather than a model. It is a research aid, not advice, and
nothing under `ticker` can place an order.

### Crypto market data (`moshcode crypto`)

`crypto` is `ticker`'s sibling on the same host: advis0r's read-only crypto
routes over Alpaca's US crypto venue, which trades 24/7 and needs no extra
subscription.

```sh
moshcode crypto BTC # price, technicals, score, supply, order book
moshcode crypto lookup bitcoin # asset name → BTC/USD
moshcode crypto quote ETH-USD # latest trade + quote, spread in bps
moshcode crypto spark BTC ETH SOL # recent moves across pairs, as sparklines
moshcode crypto bars ETH-USD --timeframe 1Hour # historical OHLCV
moshcode crypto book BTC-USD --depth 5 # top of book, both sides
moshcode crypto assets # every supported pair
moshcode crypto open BTC # the shareable page
```

Pairs are accepted as `BTC`, `BTC-USD`, `BTC/USD` or `BTCUSD` — a bare asset
resolves to that asset's USD pair. `--json` gives the raw response, `/crypto …`
is the same facade in the pit, and `MOSHCODE_ADVISOR_URL` points it elsewhere.

Unlike a `ticker` report, this is a **live venue read**, not a stored snapshot —
there are no transcripts, no filings and no signals behind a crypto pair, and
the failure mode runs the other way: the price is accurate to the second and
stale by the time you act on it. Every response stamps when it was fetched.

The technical score counts venue-local liquidity, so it is **not comparable** to
an equity's score, and each response ships the `caveats` that say so. Prices are
Alpaca's US venue alone and can differ materially from other exchanges. Research
aid, not advice — and like `ticker`, nothing under `crypto` can place an order.

### Social posting from the pit

The pit can hand a prepared post to Bluesky or Nostr without storing either
Expand Down Expand Up @@ -340,19 +372,28 @@ inside your engine too:
```sh
moshcode plugin list # what the marketplace ships, and who can take it
moshcode plugin install # add the marketplace + install `ticker`
moshcode plugin install crypto # add the marketplace + install `crypto`
moshcode plugin remove ticker # take it back off
```

`ticker@moshcode` adds `/ticker`, `/signals`, `/research`, `/lookup`,
`/reports`, and `/discover` — the same advis0r research surface described above,
driven from inside a coding session. Restart the engine afterwards; a newly
installed plugin is not live in a session that is already running.
driven from inside a coding session.

`crypto@moshcode` adds `/crypto`, `/quote`, `/book`, `/bars`, `/spark`,
`/pairs`, and `/coin`. It ships separately because it is a different surface,
not a mode of the first: live venue reads instead of stored snapshots, and a
score that must not be ranked against an equity's.

Restart the engine after installing either; a newly installed plugin is not live
in a session that is already running.

The equivalent by hand:

```sh
claude plugin marketplace add moshcoder/moshcode
claude plugin install ticker@moshcode
claude plugin install crypto@moshcode
```

Claude Code is currently the only engine with a plugin primitive. The others are
Expand Down
8 changes: 8 additions & 0 deletions bin/moshcode.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { selfUpdateCommand } from "../src/selfupdate.mjs";
import { describeUninstall, uninstallPlan } from "../src/uninstall.mjs";
import { mcpCommand, pluginCommand, skillCommand } from "../src/integrations.mjs";
import { tickerCommand } from "../src/advisor.mjs";
import { cryptoCommand } from "../src/crypto.mjs";
import { canOpenBrowser, openBrowser } from "../src/open-url.mjs";
import { locate, tilde } from "../src/pwd.mjs";
import { createPrd, listPrds, authoringPrompt } from "../src/prd.mjs";
Expand Down Expand Up @@ -353,6 +354,13 @@ async function main() {
if (code) process.exitCode = code;
return;
}
if (cmd === "crypto" || cmd === "coins") {
const code = await cryptoCommand(rest, {
openUrl: (url) => canOpenBrowser() && openBrowser(url),
});
if (code) process.exitCode = code;
return;
}
if (cmd === "plugin" || cmd === "plugins") {
const code = await pluginCommand(rest);
if (code) process.exitCode = code;
Expand Down
13 changes: 13 additions & 0 deletions plugins/crypto/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
"name": "crypto",
"description": "Crypto market data slash commands backed by advis0r.com: live prices, technical scores, order books, OHLCV history and sparklines across Alpaca's US crypto venue.",
"version": "0.1.0",
"author": {
"name": "moshcoder",
"url": "https://moshcode.sh"
},
"homepage": "https://github.com/moshcoder/moshcode#crypto",
"license": "MIT",
"keywords": ["crypto", "bitcoin", "markets", "prices", "advis0r"]
}
66 changes: 66 additions & 0 deletions plugins/crypto/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# crypto — market data in your engine 🤘

Slash commands backed by [advis0r.com](https://advis0r.com/api/crypto): live
prices, technical scores, order books, OHLCV history and multi-pair sparklines
across Alpaca's US crypto venue.

| command | what it does |
| --- | --- |
| `/crypto BTC` | price, technicals, score, supply, order book |
| `/quote ETH-USD` | latest trade and quote, with the spread in bps |
| `/book BTC-USD` | top of the order book, both sides |
| `/bars ETH-USD` | historical OHLCV at any supported timeframe |
| `/spark BTC ETH SOL` | recent moves across pairs, ranked |
| `/pairs` | every supported pair, grouped by quote asset |
| `/coin bitcoin` | asset name → `BTC/USD` |

Pairs are accepted as `BTC`, `BTC-USD`, `BTC/USD` or `BTCUSD`. A bare asset
resolves to that asset's USD pair.

## Install

```bash
moshcode plugin install crypto
```

Or straight from Claude Code:

```bash
claude plugin marketplace add moshcoder/moshcode
claude plugin install crypto@moshcode
```

Restart the engine afterwards — a newly installed plugin is not live in a
session that is already running.

## How it works

Each command shells out to `moshcode crypto …`, which calls advis0r's public,
read-only API. No key, no login, no write routes. With `moshcode` absent, every
command falls back to `curl` against the same endpoints.

Point the commands at another instance with `MOSHCODE_ADVISOR_URL`.

## Why this is separate from `ticker`

They answer different questions from different data, and share only a hostname.
A `/ticker` report is a **stored snapshot** built from transcripts, SEC
fundamentals and extracted signals — its risk is a stale price read as a live
one. A `/crypto` report is a **live venue read** with no transcripts, no
filings and no signals — its risk is the opposite: a price that is accurate to
the second and stale by the time you act on it.

The scores are not comparable either. The crypto technical score counts
venue-local liquidity, so ranking a coin against an equity by score is
meaningless. Both surfaces ship their own `caveats`, and both commands are
instructed to print them.

## What this is not

A research aid, not advice. Prices are Alpaca's US crypto venue alone and can
differ materially from other exchanges. Crypto trades 24/7 with no circuit
breakers — there is no close, no premarket, and no halt.

Trading lives behind a different verb: `moshcode trade` wraps Alpaca, previews
orders by default, and requires an explicit `--submit`. Nothing in this plugin
can place an order.
35 changes: 35 additions & 0 deletions plugins/crypto/commands/bars.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
description: Historical crypto OHLCV for one pair, at any supported timeframe.
argument-hint: <PAIR> [timeframe]
allowed-tools: Bash(moshcode crypto:*), Bash(curl -sS https://advis0r.com/api/crypto/:*)
---

## Task

Pull historical bars for `$ARGUMENTS`.

```bash
moshcode crypto bars $ARGUMENTS --timeframe 1Day --limit 30 --json
```

Timeframes: `1Min`, `5Min`, `15Min`, `1Hour`, `1Day`, `1Week`. Add
`--start`/`--end` (ISO dates) to pin a window.

Fallback: `curl -sS "https://advis0r.com/api/crypto/bars?symbol=<PAIR>&timeframe=1Day&limit=30"`

## Reading the response

`bars` is keyed by canonical symbol (`"BTC/USD"`), each value an ascending array
of `{ timestamp, open, high, low, close, volume, vwap }`.

## Rules

- **`limit` is upstream's page size, not a cap on what returns.** The response
can hold more bars than you asked for. If you show a subset, say which subset
— "the 5 most recent of 17", never a silent truncation.
- Bars are ascending by time. Confirm the direction before calling a move.
- `volume` is base-asset units on Alpaca's US venue alone, not aggregate market
volume. Do not compare it to a CoinGecko or exchange-aggregate figure.
- Crypto bars are calendar-based and continuous — no gaps, no sessions, no
weekends. A "20-day" window here is not 20 trading sessions.
- End with the response's own `disclaimer`.
31 changes: 31 additions & 0 deletions plugins/crypto/commands/book.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
description: Top of the crypto order book, both sides, with the spread.
argument-hint: <PAIR>
allowed-tools: Bash(moshcode crypto:*), Bash(curl -sS https://advis0r.com/api/crypto/:*)
---

## Task

Show the order book for `$ARGUMENTS`.

```bash
moshcode crypto book $ARGUMENTS --depth 10 --json
```

Fallback: `curl -sS "https://advis0r.com/api/crypto/orderbook?symbol=$ARGUMENTS&depth=10"`

## Reading the response

`orderbooks[]` each carry a `timestamp`, `bids[]` and `asks[]`, every level a
`{ price, size }`. Bids descend from the best bid; asks ascend from the best ask.

## Rules

- Report the spread in basis points, not just in dollars — a $50 spread means
something different on BTC than on ETH.
- **Size is depth on one venue, not the market.** Do not describe the book as
"the market's" depth, and do not extrapolate what a large order would fill at.
- A book is a snapshot of an instant. Timestamp it.
- If one side is much thinner than the other, say so plainly rather than
reading it as a directional signal — it is a liquidity observation.
- End with the response's own `disclaimer`.
31 changes: 31 additions & 0 deletions plugins/crypto/commands/coin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
description: Find a crypto pair by asset name (bitcoin → BTC/USD).
argument-hint: <asset name>
allowed-tools: Bash(moshcode crypto:*), Bash(curl -sS https://advis0r.com/api/crypto/:*)
---

## Task

Resolve `$ARGUMENTS` to a tradable pair.

```bash
moshcode crypto lookup $ARGUMENTS --limit 10 --json
```

Fallback: `curl -sS "https://advis0r.com/api/crypto/lookup?q=<url-encoded>&limit=10"`

## Reading the response

`matches` is a list of `{ symbol, slug, base, quote, name }`.

## Rules

- One coin usually returns several pairs — `BTC/USD`, `BTC/USDC`, `BTC/USDT`.
Show them all and say which quote asset each settles in; default to the USD
pair unless the user asked otherwise.
- Watch for name collisions: a query can match a different coin whose name
merely contains the words ("bitcoin" also returns Bitcoin Cash). Say which
match is the one they meant.
- No match: say this venue lists no such pair, and do not invent a symbol. The
coin may exist and simply not be listed here — those are different answers.
- Offer `/crypto <PAIR>` for the match you land on.
50 changes: 50 additions & 0 deletions plugins/crypto/commands/crypto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
description: Research one crypto pair — price, technicals, score, supply and order book.
argument-hint: <PAIR>
allowed-tools: Bash(moshcode crypto:*), Bash(curl -sS https://advis0r.com/api/crypto/:*)
---

## Task

Pull the full report for `$ARGUMENTS` and summarize it for the user.

Run:

```bash
moshcode crypto $ARGUMENTS --json
```

If `moshcode` is not installed, fall back to the API directly:

```bash
curl -sS "https://advis0r.com/api/crypto/report?symbol=$ARGUMENTS"
```

Pairs are accepted as `BTC`, `BTC-USD`, `BTC/USD` or `BTCUSD`. A bare asset
resolves to that asset's USD pair.

## Reading the response

- `snapshot` is the live read: `latestTrade`, `latestQuote` (bid/ask),
`dailyBar`, `prevDailyBar`, and a `change` against yesterday's close.
- `technical` holds sma / ema / rsi14 / macd / bollinger / atr14 /
`relativeVolume` / `momentum` / `trend` / `volatilityRegime`.
- `technicalScore.score` is 0–100 with a `breakdown`. It is **technical only** —
there is no thesis, no transcript and no filing behind a crypto pair.
- `fundamentals` is CoinGecko supply data: market cap, rank, circulating and max
supply, 24h volume, all-time high. It is absent for many pairs.
- `caveats` are per-response and specific. Read them before quoting the score.

## Rules

- **These prices are Alpaca's US crypto venue alone.** Say so. They can differ
materially from Coinbase, Binance, or an aggregate index.
- Crypto trades 24/7 with no circuit breakers and no market close. Never
describe a crypto price as "at the close" or "premarket".
- State `generatedAt` / `fetchedAt`. This is a live read, so it goes stale in
seconds, not days — the opposite failure mode from a stored `/ticker` report.
- The score's liquidity component counts venue-local volume only, so it is
**not comparable** to an equity's score from `/ticker`. Do not rank the two
against each other.
- End with the response's own `disclaimer`. This is research, not advice.
- Link the shareable page: `https://advis0r.com/crypto/<PAIR>`.
31 changes: 31 additions & 0 deletions plugins/crypto/commands/pairs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
description: Every crypto pair advis0r can price, and which are trading.
allowed-tools: Bash(moshcode crypto:*), Bash(curl -sS https://advis0r.com/api/crypto/:*)
---

## Task

List the supported pairs.

```bash
moshcode crypto assets --json
```

Fallback: `curl -sS "https://advis0r.com/api/crypto/assets"`

## Reading the response

`assets[]` are `{ symbol, slug, base, quote, name, status }`. `slug` is the
URL-safe spelling (`BTC-USD`) used in paths; `symbol` is canonical (`BTC/USD`).
`status` is `live` or `idle`.

## Rules

- Group by `quote` asset. The same coin priced in USD, USDT and BTC are three
different markets with three different liquidity profiles.
- **`idle` means listed but not currently printing trades** — it is not the same
as unsupported. Show idle pairs, marked, rather than filtering them out.
- If the user was looking for a specific coin, use `/coin <name>` instead of
scanning this list for them.
- This is the coverage of one venue, not of crypto. A coin missing here is
missing *from Alpaca's US venue*.
Loading
Loading