← ansem
how it works

how it works

a trading style explained in interviews is a set of heuristics. to run it without a person, each heuristic has to become a number and a comparison. ansem's engine is the translation: every rule ansem has stated in public becomes an explicit gate, a score, or a size, and a position is only opened when all of them agree. the model reads, the engine decides, the wallet signs. below is how each rule is encoded.

the gates

the gates are hard filters. a name that fails any gate is never considered, no matter how good it looks. these encode the rules ansem states as absolutes: skip the lowest caps, wait for survival, concentrate.

// the gates. a candidate must clear every one to be eligible.// these are the non negotiable rules, stated as code. interface Candidate {  mint: string;  symbolAgeSlots: number;     // slots since first liquidity  marketCapUsd: number;  drawdownFromAth: number;    // 0 to 1, peak to current  recoveredFromFloor: boolean;  liquidityUsd: number;} const MIN_MARKET_CAP = 5_000_000;   // past the death plateauconst MIN_AGE_SLOTS = 1_296_000;    // roughly a week of survivalconst MIN_LIQUIDITY = 250_000;      // exitable, not a trapconst MAX_OPEN_POSITIONS = 6;       // conviction over breadth function passesGates(c: Candidate, openPositions: number): boolean {  // the lowest caps are rejected outright. survival is the signal.  if (c.marketCapUsd < MIN_MARKET_CAP) return false;   // a name must have survived its first collapse and re established.  // a project still in its initial vertical has not proven anything.  if (c.symbolAgeSlots < MIN_AGE_SLOTS) return false;  if (c.drawdownFromAth > 0.5 && !c.recoveredFromFloor) return false;   // liquidity deep enough that the position can actually be exited.  if (c.liquidityUsd < MIN_LIQUIDITY) return false;   // concentration is a rule, not a preference. the book stays small.  if (openPositions >= MAX_OPEN_POSITIONS) return false;   return true;}

the score

among names that clear the gates, the model scores conviction. this is where ansem's read of attention and narrative becomes a number. the model is asked for a probability, and the probability is the conviction.

// the score. the model reads the market the way the method reads it:// narrative, attention, flow, structure. it returns one number. async function scoreConviction(c: Candidate, context: MarketContext) {  const res = await fetch("https://api.anthropic.com/v1/messages", {    method: "POST",    headers: {      "x-api-key": ANTHROPIC_KEY,      "anthropic-version": "2023-06-01",      "content-type": "application/json",    },    body: JSON.stringify({      model: "claude-fable-5",      max_tokens: 400,      system:        "you score conviction in a solana name the way a disciplined " +        "trader does: weigh narrative strength, where attention is " +        "flowing, whether the chart structure confirms, and whether the " +        "name is early in a rotation or late. return json only: " +        '{"conviction": <0 to 1>, "rotation": "early" | "mid" | "late", ' +        '"thesis": <one sentence>}. conviction is the probability this ' +        "name outperforms over the horizon. if the read is weak, say so " +        "with a low number. do not inflate.",      messages: [{ role: "user", content: JSON.stringify({ c, context }) }],    }),  });  const data = await res.json();  return JSON.parse(data.content[0].text) as {    conviction: number;    rotation: "early" | "mid" | "late";    thesis: string;  };}

the size

conviction sets size. the method sizes hard when it believes and small when it does not, but never large enough that one wrong call ends the book. ansem scales by conviction, discounts late rotations, and caps every position.

// the size. conviction in, fraction of the book out, hard ceiling on top.// sizing is how the method survives being wrong, which it expects to be. const MAX_POSITION = 0.15;   // no single name over this share of the bookconst BASE = 0.40;           // conviction-to-size scaler function positionSize(  conviction: number,  rotation: "early" | "mid" | "late",): number {  // late rotations are discounted. the method rotates toward early flow.  const rotationMult = rotation === "early" ? 1.0    : rotation === "mid" ? 0.6    : 0.3;   // conviction below the threshold is no position at all.  if (conviction < 0.55) return 0;   // size scales with conviction past the threshold, then gets capped.  const raw = (conviction - 0.55) * BASE * rotationMult;  return Math.min(raw, MAX_POSITION);}

the journal write

before a single token moves, the decision is written. this is the part of the method that made the trader, the written review, turned into an insert only commit. nothing is signed until the rationale exists, and nothing is ever edited after.

// the journal write. the rationale is committed before the swap.// the table has no update path and no delete path. the record is fixed. async function commitAndTrade(c: Candidate, score: Score, size: number) {  // 1. write the entry first. if this fails, no trade happens.  const entry = await db.insert("journal", {    mint: c.mint,    opened_at: Date.now(),    conviction: score.conviction,    rotation: score.rotation,    thesis: score.thesis,        // the one line, recorded before acting    size_fraction: size,    outcome: null,               // scored later, never overwritten  });   // 2. the correct size for no conviction is zero. most names end here.  if (size === 0) return { entry, traded: false };   // 3. only now does anything move. the agent signs its own swap.  const lamports = Math.floor((await bookValue()) * size);  const sig = await jupiterSwap(AGENT, c.mint, lamports, "buy");  await db.update("journal", entry.id, { tx_sig: sig });   return { entry, traded: true, sig };}

the loop runs the four steps in order, every cycle: gate the universe down to eligible names, score conviction with the model, size by conviction and rotation, write the rationale, then sign. a scorer wakes after each horizon and marks every open entry against what the market did, appending the result to a row it never edits. the rules are fixed in code, the wallet signs for itself, and no person sits in the path. the method was always public. this is the method, made literal.