Position sizer
@qtrader/position-sizer
Work out how many shares to buy before you click. Fixed-fractional, ATR (volatility) based, and capped fractional-Kelly sizing, plus a portfolio heat check that totals the risk across open positions and tells you if a new trade fits. Not financial advice.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1{
- 2 "name": "position-sizer",
- 3 "owner": "qtrader",
- 4 "version": "1.0.0",
- 5 "type": "skill",
- 6 "description": "Work out how many shares to buy before you click. Fixed-fractional, ATR (volatility) based, and capped fractional-Kelly sizing, plus a portfolio heat check that totals the risk across open positions and tells you if a new trade fits. Not financial advice.",
- 7 "category": "trading",
- 8 "license": "MIT",
- 9 "compat": ["claude-code"],
- 10 "permissions": {
- 11 "shell": ["node scripts/size.mjs", "node scripts/selftest.mjs"],
- 12 "files": { "read": ["./data/**"], "write": ["./out/**"] }
- 13 },
- 14 "tests": {
- 15 "cases": [
- 16 {
- 17 "name": "sizing and heat match the hand calculations",
- 18 "inputs": {},
- 19 "checks": [{ "type": "command_exits_zero", "command": "node scripts/selftest.mjs" }]
- 20 },
- 21 {
- 22 "name": "fixed-fractional sizing writes JSON",
- 23 "inputs": {},
- 24 "checks": [
- 25 {
- 26 "type": "command_exits_zero",
- 27 "command": "node scripts/size.mjs fixed --equity 50000 --risk-pct 1 --entry 100 --stop 95 --out out/fixed.json"
- 28 },
- 29 {
- 30 "type": "output_matches_schema",
- 31 "path": "out/fixed.json",
- 32 "schema": {
- 33 "type": "object",
- 34 "required": ["method", "side", "shares", "dollar_risk"],
- 35 "properties": { "side": { "const": "long" }, "shares": { "const": 100 }, "dollar_risk": { "const": 500 } }
- 36 }
- 37 }
- 38 ]
- 39 },
- 40 {
- 41 "name": "heat check flags a missing stop and an oversized add",
- 42 "inputs": {
- 43 "data/positions.csv": "symbol,side,qty,entry,stop,price\nAAA,long,100,50,46,52\nBBB,long,200,30,31,35\nCCC,short,50,80,84,\nDDD,long,150,20,,\nEEE,long,300,40,37,41\n"
- 44 },
- 45 "checks": [
- 46 {
- 47 "type": "command_exits_zero",
- 48 "command": "node scripts/size.mjs heat --equity 100000 --positions data/positions.csv --add FFF,long,120,25,23 --out out/heat.json"
- 49 },
- 50 {
- 51 "type": "output_matches_schema",
- 52 "path": "out/heat.json",
- 53 "schema": {
- 54 "type": "object",
- 55 "required": ["status", "total_risk", "positions", "proposed"],
- 56 "properties": {
- 57 "status": { "const": "OK" },
- 58 "total_risk": { "const": 5800 },
- 59 "positions": { "type": "array", "minItems": 5, "maxItems": 5 },
- 60 "proposed": { "type": "object", "properties": { "fits": { "const": false }, "max_qty_that_fits": { "const": 100 } } }
- 61 }
- 62 }
- 63 },
- 64 { "type": "file_contains", "path": "out/heat.json", "text": "NO STOP: full value at risk" }
- 65 ]
- 66 }
- 67 ]
- 68 }
- 69}
