[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ml-vs-llm-signal-generators":3,"blog-all-posts":327},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"slug":10,"date":11,"author":12,"category":13,"tags":14,"cover":20,"body":21,"_type":321,"_id":322,"_source":323,"_file":324,"_stem":325,"_extension":326},"\u002Fblog\u002Fml-vs-llm-signal-generators","blog",false,"","ML vs LLM as Signal Generators: Eight Dimensions Where the Choice Is Already Made","ML vs LLM as a trading signal generator, broken down across eight dimensions: cost shape, failure mode, reproducibility, interpretability, and the one row where the LLM actually wins.","ml-vs-llm-signal-generators","2026-05-25","StratCraft","insights",[15,16,17,18,19],"ai","trading","llm","machine-learning","signals","\u002Fblog\u002Fml-vs-llm-signal-generators.svg",{"type":22,"children":23,"toc":313},"root",[24,47,52,64,71,83,95,101,105,110,115,142,160,184,190,195,214,220,225,244,250,255,291,303,308],{"type":25,"tag":26,"props":27,"children":28},"element","p",{},[29,32,39,41],{"type":30,"value":31},"text","After the ",{"type":25,"tag":33,"props":34,"children":36},"a",{"href":35},"\u002Fblog\u002Fllm-trading-strategies-clone-problem",[37],{"type":30,"value":38},"twenty-clones post",{"type":30,"value":40},", the question I kept getting was the same one: ",{"type":25,"tag":42,"props":43,"children":44},"em",{},[45],{"type":30,"value":46},"fine, if the LLM is a confident intern, what should generate the signal instead?",{"type":25,"tag":26,"props":48,"children":49},{},[50],{"type":30,"value":51},"The honest answer is boring. For the part of the stack that turns market state into a number — long, short, flat, size — you almost always want classical ML, not an LLM. Not because ML is \"smarter.\" Because trading pays for a specific set of properties, and those are exactly the properties an LLM gives up.",{"type":25,"tag":26,"props":53,"children":54},{},[55,57,62],{"type":30,"value":56},"So instead of arguing it, here is the comparison one row at a time. Eight dimensions. For each one: the ML answer, the LLM answer, and how decisive the gap is ",{"type":25,"tag":42,"props":58,"children":59},{},[60],{"type":30,"value":61},"for signal generation specifically",{"type":30,"value":63},".",{"type":25,"tag":65,"props":66,"children":68},"h2",{"id":67},"the-question-people-actually-mean",[69],{"type":30,"value":70},"The question people actually mean",{"type":25,"tag":26,"props":72,"children":73},{},[74,76,81],{"type":30,"value":75},"\"Which is better, ML or LLM?\" is the wrong question, the same way \"which LLM is best for trading?\" is the wrong question. Better at ",{"type":25,"tag":42,"props":77,"children":78},{},[79],{"type":30,"value":80},"what",{"type":30,"value":82},"? A signal generator has a job description: take the current state of the market, emit a position. Do it millions of times across a backtest. Do it the same way every time so the backtest means something. Do it cheaply enough that density does not bankrupt you. Do it in a way a risk officer can read.",{"type":25,"tag":26,"props":84,"children":85},{},[86,88,93],{"type":30,"value":87},"Score the two families against ",{"type":25,"tag":42,"props":89,"children":90},{},[91],{"type":30,"value":92},"that",{"type":30,"value":94}," job, and most rows are not close.",{"type":25,"tag":65,"props":96,"children":98},{"id":97},"eight-dimensions-one-row-at-a-time",[99],{"type":30,"value":100},"Eight dimensions, one row at a time",{"type":25,"tag":102,"props":103,"children":104},"ml-vs-llm-matrix",{},[],{"type":25,"tag":26,"props":106,"children":107},{},[108],{"type":30,"value":109},"The scores underneath are 0-5 per row: a strength-of-verdict rubric, not a benchmark (more on why below). Add them up the way the figure does, weighted by how decisive each dimension is, and the structure heavily favors ML for this job. The LLM column is not losing on technicalities. It is losing on the dimensions trading actually pays for: cost shape, reproducibility, interpretability, and a failure mode you can see coming.",{"type":25,"tag":26,"props":111,"children":112},{},[113],{"type":30,"value":114},"A few of these deserve more than a table cell.",{"type":25,"tag":26,"props":116,"children":117},{},[118,124,126,133,135,140],{"type":25,"tag":119,"props":120,"children":121},"strong",{},[122],{"type":30,"value":123},"Cost shape (rows 03–04).",{"type":30,"value":125}," This is the one people underestimate. An HMM or a gradient-boosted model pays its heavy compute once, in ",{"type":25,"tag":127,"props":128,"children":130},"code",{"className":129},[],[131],{"type":30,"value":132},"fit()",{"type":30,"value":134},". After that a signal costs microseconds on the same CPU running the backtest. An LLM has no \"trained once\" stage that you own — every signal request pays full inference again, in seconds, on a GPU, metered per token. Ten years of one-minute bars is a few million signals. Do that math with per-token billing ",{"type":25,"tag":42,"props":136,"children":137},{},[138],{"type":30,"value":139},"before",{"type":30,"value":141}," you commit.",{"type":25,"tag":26,"props":143,"children":144},{},[145,150,152,158],{"type":25,"tag":119,"props":146,"children":147},{},[148],{"type":30,"value":149},"Reproducibility (row 07).",{"type":30,"value":151}," A backtest you run on Monday should match the one you run on Friday. With ML that is free: same input, same output. With an LLM you are fighting temperature, top-p, and silent model-version drift. You can claw some of it back with ",{"type":25,"tag":127,"props":153,"children":155},{"className":154},[],[156],{"type":30,"value":157},"temperature=0",{"type":30,"value":159}," and version pinning, but \"some\" is not \"all,\" and a backtest you cannot reproduce is a story, not evidence.",{"type":25,"tag":26,"props":161,"children":162},{},[163,168,170,175,177,182],{"type":25,"tag":119,"props":164,"children":165},{},[166],{"type":30,"value":167},"Failure mode (row 05).",{"type":30,"value":169}," ML fails ",{"type":25,"tag":42,"props":171,"children":172},{},[173],{"type":30,"value":174},"slowly and loudly",{"type":30,"value":176}," — concept drift over weeks, and the remediation is a re-fit you can schedule. An LLM fails ",{"type":25,"tag":42,"props":178,"children":179},{},[180],{"type":30,"value":181},"per call",{"type":30,"value":183}," — a hallucinated field, a malformed number — so every single response needs a parser and a retry path. One of these failure modes you monitor. The other you babysit.",{"type":25,"tag":65,"props":185,"children":187},{"id":186},"why-i-am-not-putting-accuracy-numbers-on-this",[188],{"type":30,"value":189},"Why I am not putting accuracy numbers on this",{"type":25,"tag":26,"props":191,"children":192},{},[193],{"type":30,"value":194},"You will notice there is no \"ML is 23% more accurate\" number anywhere. That is deliberate.",{"type":25,"tag":26,"props":196,"children":197},{},[198,200,205,207,212],{"type":30,"value":199},"The accuracy gap between a fitted model and a base LLM on signal generation is real, but the number depends entirely on the task, frequency, asset, horizon, and metric. Pin a number to it and the only response you get is ",{"type":25,"tag":42,"props":201,"children":202},{},[203],{"type":30,"value":204},"\"that is not the experiment I would run.\"",{"type":30,"value":206}," Pin the structure instead, and the response is ",{"type":25,"tag":42,"props":208,"children":209},{},[210],{"type":30,"value":211},"\"now I see why one fits and the other does not.\"",{"type":30,"value":213}," Structure travels; a single benchmark does not.",{"type":25,"tag":65,"props":215,"children":217},{"id":216},"the-one-row-where-the-llm-actually-wins",[218],{"type":30,"value":219},"The one row where the LLM actually wins",{"type":25,"tag":26,"props":221,"children":222},{},[223],{"type":30,"value":224},"Row 08 is not a courtesy. There is a real job the LLM wins outright, and it matters: turning unstructured text into structured fields. An earnings transcript into a sentiment vector. A news wire into event tags. A SEC filing into a set of features. ML needs heavy NLP scaffolding just to start that; the LLM does it out of the box.",{"type":25,"tag":26,"props":226,"children":227},{},[228,230,235,237,242],{"type":30,"value":229},"But look at ",{"type":25,"tag":42,"props":231,"children":232},{},[233],{"type":30,"value":234},"where",{"type":30,"value":236}," that job sits. It is ",{"type":25,"tag":119,"props":238,"children":239},{},[240],{"type":30,"value":241},"upstream",{"type":30,"value":243}," of the signal generator, not the signal generator itself. The LLM builds features. Something else turns features into a position.",{"type":25,"tag":65,"props":245,"children":247},{"id":246},"where-this-leaves-a-serious-stack",[248],{"type":30,"value":249},"Where this leaves a serious stack",{"type":25,"tag":26,"props":251,"children":252},{},[253],{"type":30,"value":254},"Once you stop asking \"ML or LLM?\" and start asking \"which tool for which layer?\", the picture resolves into three layers and three different tools:",{"type":25,"tag":256,"props":257,"children":258},"blockquote",{},[259,269,279],{"type":25,"tag":26,"props":260,"children":261},{},[262,264],{"type":30,"value":263},"natural language → structured features → ",{"type":25,"tag":119,"props":265,"children":266},{},[267],{"type":30,"value":268},"LLM",{"type":25,"tag":26,"props":270,"children":271},{},[272,274],{"type":30,"value":273},"structured features → signal pack → ",{"type":25,"tag":119,"props":275,"children":276},{},[277],{"type":30,"value":278},"ML",{"type":25,"tag":26,"props":280,"children":281},{},[282,284,289],{"type":30,"value":283},"signal pack → portfolio allocation → ",{"type":25,"tag":119,"props":285,"children":286},{},[287],{"type":30,"value":288},"neither",{"type":30,"value":290}," (that layer is an optimizer)",{"type":25,"tag":26,"props":292,"children":293},{},[294,296,301],{"type":30,"value":295},"Each layer has a right tool, and picking the wrong one is its own failure mode. But the most expensive mistake on the table right now is putting the LLM in the ",{"type":25,"tag":42,"props":297,"children":298},{},[299],{"type":30,"value":300},"middle",{"type":30,"value":302}," layer — making it the signal generator — where it competes with ML on the seven dimensions it loses.",{"type":25,"tag":26,"props":304,"children":305},{},[306],{"type":30,"value":307},"LLM upstream. ML in the engine room. The clone problem from last time was really just this mistake wearing a different costume: an LLM doing a job that belongs one layer up.",{"type":25,"tag":26,"props":309,"children":310},{},[311],{"type":30,"value":312},"What does your split look like? If you are running an LLM somewhere in the signal path, I am curious which layer it sits in — and what catches it when it is wrong.",{"title":7,"searchDepth":314,"depth":314,"links":315},2,[316,317,318,319,320],{"id":67,"depth":314,"text":70},{"id":97,"depth":314,"text":100},{"id":186,"depth":314,"text":189},{"id":216,"depth":314,"text":219},{"id":246,"depth":314,"text":249},"markdown","content:blog:ml-vs-llm-signal-generators.md","content","blog\u002Fml-vs-llm-signal-generators.md","blog\u002Fml-vs-llm-signal-generators","md",[328,330],{"title":8,"slug":10,"date":11,"author":12,"category":13,"tags":329,"cover":20},[15,16,17,18,19],{"title":331,"slug":332,"date":333,"author":12,"category":13,"tags":334,"cover":336},"I Asked an LLM to Generate 20 Trading Strategies. 14 Were the Same Thing.","llm-trading-strategies-clone-problem","2026-05-15",[15,16,17,335],"backtesting","\u002Fbanner.png"]