I build trading systems.
Real capital. Verifiable numbers.
I am a high school senior in Boulder, Colorado. Over the last year I built three programs that trade markets on their own, one of them with real money in it. Every number on this site links to the file that produced it.
Three years of building bots. One year of learning why they matter.
Three years ago I wrote my first program that tried to trade a market. It was supposed to spot underpriced items on Roblox and buy them faster than a human could. It lost me forty dollars in one weekend and taught me nothing except that markets are harder than I thought.
Everything I have built since then has been an attempt to understand why. CounterSnipe taught me that the difference between an idea that looks profitable on paper and one that survives with real money in it is a stack of unglamorous safety rules. The prediction bot taught me that being wrong about your own strategy is worth more than being right, because being wrong forces you to instrument, log, and iterate. copy-trader taught me that the right number of weeks to trade a strategy you have not validated is zero.
I want to study finance because the people I most want to learn from ask "what is your edge" before they ask "what is your return." I already ask my own systems that question every day, and I want to keep doing this work at a level and with a rigor that I cannot reach on my own.
CounterSnipe
Counter-Strike 2 is a video game. Its cosmetic weapon skins trade on real online marketplaces (CSFloat, Steam, Buff) with tens of millions of dollars in daily volume. Prices are set by humans typing numbers, and humans make mistakes. CounterSnipe is a program I wrote that watches those marketplaces around the clock, spots when someone has listed a skin below its fair market value, buys it automatically, and re-lists it at the correct price. It currently runs with $1,424 of my real money and averages a 14.1% return per completed trade.
A program that runs on a rented server around the clock. Every few minutes it pulls fresh listings from every major CS2 skin marketplace, scores each one against a valuation model I wrote, and if the price is low enough to leave room for profit after fees, it buys through CSFloat. Once Steam releases the item from its seven-day trade hold, the program re-lists it at the current floor price minus one cent so it sells first.
The single rule that keeps it alive: never sell below what I paid. If the market crashes on an item, the program holds it until the price recovers instead of dumping at a loss. Every buy also runs through a stack of safety gates that check things like inventory concentration, category exposure, and drawdown limits, and any single tripwire can kill the whole system with one command.
This is the only one of my three systems that runs with real money. It has taught me more about how live markets actually behave than anything else I have built.
I had been playing CS2 for four years and I kept noticing the same pattern: whenever Buff (a Chinese marketplace) went down for maintenance, sellers who only used Buff would rush to list on CSFloat instead, and those listings were often priced below the current Steam price because sellers had not updated their reference prices. In April I wrote a manual script that pinged me on Discord when this happened. In May I made the buying automatic. In June I connected real capital, and everything got harder.
Sticker prices are the trap. Some CS2 skins have small collectible stickers applied to them, and older stickers used to be worth a lot but most no longer are. My first live losses came from buying skins where the seller had priced in a sticker as if it was still worth $40 when the real market value was closer to $2. I rewrote the valuation code to look up each sticker’s actual last-30-day sale price on Buff instead of trusting the listed price. My failure rate dropped from 22.9% to 12.5% in two days.
Float is overrated. Sticker mispricing is where the edge lives.
Most online guides tell you the important variable for CS2 skin arbitrage is float, a hidden number between 0 and 1 that describes how worn the skin looks. Lower float means cleaner appearance and higher price. I found that low-float chase-buys are actually the worst trades because dozens of other bots are also scanning that band and the profit gets competed away in milliseconds. My actual profitable trades cluster in the mid-float range (0.15 to 0.25) where the visual difference is negligible but retail sellers still discount the item as if it looked worse. Combined with correctly-valued stickers, that band is where retail sellers consistently misprice their inventory. Full analysis in the audit report linked below.
The core safety gate. Every purchase must clear all four checks before a buy fires.
// src/safety/gates.ts
export function canBuy(item: Listing, portfolio: Portfolio): GateResult {
// 1. Never let one category dominate the book
if (portfolio.categoryExposure(item.category) > 0.35) {
return { ok: false, reason: 'category_cap' };
}
// 2. Freeze buying if today's realized P&L is red past a threshold
if (portfolio.dailyPnL < -MAX_DAILY_LOSS) {
return { ok: false, reason: 'drawdown_pause' };
}
// 3. Reject any listing whose sticker value cannot be verified
if (item.stickerCapture > 0 && !item.stickersVerified) {
return { ok: false, reason: 'unverified_stickers' };
}
// 4. Reject if projected sale margin does not clear fees plus 5%
const netMargin = item.projectedSale - item.askPrice - item.fees;
if (netMargin / item.askPrice < 0.05) {
return { ok: false, reason: 'margin_too_thin' };
}
return { ok: true };
}- Steam Market API documentation — Official Valve API used for cross-market price verification.
- CSFloat API — Primary listing feed and execution venue.
- Sharpe (1966) — Mutual Fund Performance — Sharpe ratio is used inside the P&L auditing scripts to compare weekly performance.
PandaXPanther Prediction Bot
Kalshi and Polymarket are legal online markets where people can bet real money on the outcome of future events: "will the Fed cut rates in July," "will the Chiefs win Sunday," "will BTC hit $100k by year end." Because these markets are relatively new, prices sometimes lag or overreact compared to established sportsbooks and financial exchanges. My prediction bot watches for those gaps and simulates trades against them. It currently runs in paper mode, meaning it uses a simulated bankroll rather than my real money, while I collect enough evidence that its strategies actually work.
Four separate betting strategies run at the same time against Kalshi and Polymarket. The most important one, sports contract-line value, works like this: I pull the current Kalshi price for a game (say the Chiefs at $0.62 to win), and separately pull the same game’s odds from Pinnacle, the largest sportsbook in the world. Pinnacle’s odds get converted into a fair probability by removing their built-in profit margin, giving me a "true" probability of the Chiefs winning. If Kalshi’s price and Pinnacle’s fair probability disagree by more than three cents, the bot places a paper bet on the mispriced side.
The most important research moment in this project was catching a bias I did not expect. My first version placed both YES and NO bets whenever it saw a mispricing. When I sat down with the trade log I discovered the YES bets were winning 20% of the time while the NO bets were winning 50%. Same strategy, same math, same fill logic. The only difference was which side of the contract I bought. This matches published research on prediction market bias: retail traders systematically overpay for YES outcomes on positively-framed questions. I gated the bot to only place NO bets and the win rate stabilized.
Everything runs paper first. A hard bankroll stop at $900 has never fired. Bet sizes are calibrated using the Kelly criterion, a formula from information theory that tells you the mathematically optimal fraction of your bankroll to risk on each trade given its edge. Every strategy has a kill switch I can trigger from anywhere.
After the 2024 election I read academic papers describing systematic biases in prediction markets and became convinced I could measure those biases in my own data instead of trusting a paper written five years ago. The first version was a Python script that just logged price divergences between Kalshi and Pinnacle for two weeks before I ever tried to place an order.
I originally thought bad execution was the problem. I discovered it was actually the timing. Prediction markets have very thin liquidity many hours before a game starts, then thicken up as the game approaches. When I plotted how often my paper orders would have filled against how many hours were left before kickoff, I saw a clean inflection: fill rate was 42% at six hours out and 93% at ninety minutes out. I gated the strategy to only fire between eight hours and thirty minutes pre-game, and the whole system got quieter and more accurate at the same time.
Retail prediction markets are biased toward YES. I measured it in my own trades.
Academic research going back to Rothschild (2009) and continuing through the 2024 election documents that retail prediction-market traders overpay for YES outcomes on positively-framed questions, especially in sports and politics. My v3.5 log gave me a clean natural experiment. The strategy fired 33 YES bets and 33 NO bets over the same window, using the same fair-value model against the same events. YES bets won 20% of the time. NO bets won 50%. Nothing else was different. The academic finding was reproducible in my own paper trades, and the fix (only bet the side that buys the mispricing) has held for every trade since I gated it.
The NO-only gate. This is the single line of logic that turned a losing bot into a winning one.
// src/strategy/sports_clv.ts
function shouldFire(signal: Signal): boolean {
const edge = Math.abs(signal.kalshiMid - signal.pinnacleFair);
if (edge < MIN_EDGE_THRESHOLD) return false; // 3 cent minimum
if (signal.hoursToGame < 0.5 || signal.hoursToGame > 8) return false;
if (signal.side === 'YES') return false; // v3.6 gate
if (signal.priceUsd < 0.25 || signal.priceUsd > 0.80) return false;
return true;
}- Rothschild (2009) — Forecasting Elections: Comparing Prediction Markets, Polls, and Their Biases — Documents systematic YES-bias in Iowa Electronic Markets, the earliest public prediction market.
- Wolfers & Zitzewitz (2004) — Prediction Markets — Foundational NBER paper on prediction market pricing efficiency.
- Kelly (1956) — A New Interpretation of Information Rate — The bet-sizing formula used by the position sizer.
- Thorp (1997) — The Kelly Criterion in Blackjack, Sports Betting, and the Stock Market — Practical treatment of Kelly for bounded bankrolls.
copy-trader
Hyperliquid is a cryptocurrency exchange where every trader’s wallet activity is public. This is unusual: on Robinhood or Coinbase you cannot see what anyone else is buying. On Hyperliquid you can. copy-trader is a program that pulls three months of trading history for the top wallets on the exchange, ranks them by how disciplined their returns look (using risk-adjusted metrics from academic finance), and simulates copying the top five. It is a research project with no real money attached, and it will stay that way until the paper simulation proves selection is skillful.
The program runs in two stages. Stage one pulls the last 90 days of trades for every wallet in the seed list, then computes five performance statistics: Sharpe ratio, maximum drawdown, win rate, profit factor, and a weighted composite score. Only the top scoring wallets get promoted to the active watchlist. Stage two subscribes to those wallets over a real-time connection and mirrors each of their trades into a simulated paper account, applying risk rules that would apply in real life (maximum position size, maximum leverage, funding-rate filters, and a daily-loss circuit breaker).
The starting list of wallets is not chosen randomly. I pulled all 38,125 accounts from Hyperliquid’s public leaderboard, then filtered on five criteria at once: account size between $50k and $10M (excludes both toy accounts and market-movers), all-time profit above $1M, positive 30-day AND 7-day profit, volume-to-equity ratio below 20,000x (excludes high-frequency market-makers who profit from rebates rather than direction), and lifetime ROI below 500,000% (excludes anomalous tiny-seed accounts). The result is 20 wallets that represent the top of what a reasonably-capitalized retail trader could plausibly imitate.
There is no live trading code in this project. There are no private keys anywhere in the repo. The system is read-only by design. Stage three, actual execution, does not exist and will not be built until paper mode proves the selection layer works over four to eight weeks. Discipline is the point.
In December 2025 I lost $180 copy-trading a Twitter perpetual-futures account. It turned out to be a marketing wallet that only posted its winners. I wanted a version of copy-trading that ranked traders by evidence rather than by follower count.
My first version ranked wallets by raw 90-day return. Predictably this ranked reckless traders above disciplined ones because leverage inflates ROI. When I rewrote scoring around Sharpe ratio and maximum drawdown, the ranking flipped dramatically: the top wallet by return dropped to rank 14 by composite score. The metric you sort on decides which strategy you are actually copying, and I had been unintentionally copying gamblers.
Survivorship bias is a feature of copy-trading, not a bug.
The 20 seed wallets are all positive over 90 days. At first glance this looks like data mining, the same mistake that made hedge fund performance studies overestimate returns for decades (see Brown, Goetzmann, Ibbotson, and Ross on this). But in copy-trading you are inherently choosing from wallets that already survived. You cannot copy a wallet that went to zero last month because it is no longer on the leaderboard. My universe reflects exactly the choice set a real copy-trader faces. What the backtest measures is whether my scoring layer picks the right wallets from a survivor-biased population, not whether the wallets themselves are magic.
The composite score. Weights are what turned "who returned the most" into "who trades well."
# scorer/metrics.py
def composite_score(fills):
sharpe = sharpe_ratio(daily_returns(fills))
max_dd = max_drawdown(equity_curve(fills))
win_rate = wins(fills) / len(fills)
pf = profit_factor(fills)
# Higher Sharpe good, deeper drawdown bad.
return (
0.40 * clamp(sharpe / 3.0, 0, 1)
+ 0.30 * (1 - clamp(max_dd / 0.50, 0, 1))
+ 0.15 * clamp(win_rate, 0, 1)
+ 0.15 * clamp(pf / 3.0, 0, 1)
)- Sharpe (1966) — Mutual Fund Performance — Origin of the Sharpe ratio, the risk-adjusted return metric used as the primary ranking signal.
- Brown, Goetzmann, Ibbotson & Ross (1992) — Survivorship Bias in Performance Studies — Canonical treatment of why looking only at surviving accounts overstates returns. Directly addressed in the research finding above.
- Sharpe (1994) — The Sharpe Ratio — The 1994 reformulation used in scorer/metrics.py.
The receipts table.
Everything below is reproducible from real logs and real repo files. Nothing has been annualized, projected, or extrapolated. Where a system does not yet have enough sample size for a stat, I label it as insufficient sample rather than invent a number.
These numbers refresh nightly.
The site rebuilds every night at 06:00 UTC via a GitHub Actions workflow. Commit counts and the Hyperliquid cohort ROI regenerate against real APIs. Every number here is reproducible.
The next version of every system.
Each of these three systems has a version I have already sketched. Not marketing copy. Actual issues I have opened against my own repos.
Ship the "trade-up" classifier. In CS2, ten worn skins can be combined into one new skin whose value depends on the average condition of the inputs. This is a math problem I can solve with a small supervised model trained on Buff sales data. Currently those decisions are manual approvals from me. I want to backtest the classifier on eight months of history before I let it fire on real money.
Make the NO-only gate adapt over time. The 2.5x edge YES bets versus NO bets is not a constant. It should shrink as the market prices in the bias, especially close to game time and in high-volume markets. I want to model the gate threshold as a function of how much liquidity is in the book and how far out from the event we are, rather than treating it as a fixed rule.
Stress-test the scoring weights. The composite score currently weights Sharpe ratio at 40%, drawdown at 30%, and win rate + profit factor at 15% each. I picked those weights by intuition. I want to sweep them across a grid, measure how much the top-five ranking changes when the weights change, and defend a final choice on the basis of ranking stability rather than a guess.
A single risk dashboard for all three systems. Right now each one alerts to its own Discord channel and holds its own kill switch. I want one page that sums exposure and P&L across the whole fleet, with a fleet-wide circuit breaker that halts every bot if aggregate drawdown crosses a floor.
The non-trading track record.
Everything below has a certificate, a bracket, or a roster.
If anything looks too neat, ask me. I will show you the log.
Every metric on this page cites a file, a commit, or a live URL. I built this because a Common App activity slot can hold 150 characters and the story is longer than that.