Skip to content
SlashClone
Made by@qtrader

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.

SkillTradingv1.0.0 (latest)Tested
Activity
New: be the first to try it

Real output from this kit

How this works

  1. It is a skill: written instructions Claude reads when your request matches what the skill is for. You do not call it by name; just ask for the task.
  2. While it works, it reads and changes files in the places it lists, nowhere else.
  3. It runs these commands on your computer: node scripts/size.mjs, node scripts/selftest.mjs.
  4. Nothing runs until you choose to use it, and you can remove it any time.

SKILL.md

Position sizer

Size comes from risk, not conviction. Every method here answers one question: if the stop is hit, how much of the account is lost? The script does the arithmetic so nothing is rounded the wrong way under pressure.

This is a calculator, not advice. It never says whether to take a trade.

Inputs to ask for

  • Equity: account value the user sizes against (net liquidation value, not buying power).
  • Risk per trade: percent of equity to lose if stopped. Default suggestion 1%; 0.5% for new or volatile strategies. Above 2% per trade, say plainly that it is aggressive.
  • Entry and stop, or ATR and a multiple, or a price CSV to compute ATR.
  • Max position size as a percent of equity, if the user has one (default 100%, which means no leverage).
  • For heat: a positions CSV symbol,side,qty,entry,stop,price (price optional, stop may be blank).

Steps

  1. Pick the method from what the user has:

    • Has a chart-based stop: fixed.
    • Wants the stop set by volatility: atr.
    • Has a track record and asks about Kelly: kelly, then show the fixed-fractional size next to it.
    • Already holds positions: always run heat before adding a new one.
  2. Run it.

    node scripts/size.mjs fixed --equity 50000 --risk-pct 1 --entry 100 --stop 95 --max-position-pct 25
    node scripts/size.mjs atr --equity 50000 --risk-pct 1 --prices data/XYZ-1Day.csv --atr-period 14 --atr-mult 2
    node scripts/size.mjs atr --equity 50000 --risk-pct 1 --atr 2.4 --entry 100 --side short
    node scripts/size.mjs kelly --trades data/trades.csv --fraction 0.5 --cap 0.05 --equity 50000 --entry 100 --stop 95
    node scripts/size.mjs heat --equity 100000 --positions data/positions.csv --max-heat-pct 6 --max-risk-pct 2 --add XYZ,long,120,25,23

    Add --json for JSON or --out out/size.json to save it. Exit code 2 means bad input; the message says which flag.

  3. Report with the template below. Always give shares, stop, dollar risk, percent of equity, and position value.
  4. Flag anything the script noted: a cap that bound, a size that rounds to 0, a position with no stop, a single trade over the per-trade limit, or total heat over the limit.

How each method works

  • Fixed fractional: shares = floor(equity x risk% / |entry - stop|), then capped so shares x entry stays under the max position percent.
  • ATR: Wilder ATR (first value is the average of the first N true ranges, then smoothed). Stop = entry minus (long) or plus (short) mult x ATR, then fixed-fractional. With --prices, entry defaults to the last close.
  • Kelly: f* = p - (1 - p) / b, where p is the win rate and b is average win / average loss. Here f is the share of equity at risk to the stop, not the position size. The script uses half Kelly by default and caps it at 5% of equity at risk. Full Kelly assumes the stats are exact; they never are, and it produces deep drawdowns. Under 30 trades, say the estimate is noisy.
  • Heat: for each position, qty x distance from the current price (or entry) to the stop. No stop means the whole position value counts. Total heat is compared to the limit (default 6%), each position to the per-trade limit (default 2%). For a proposed add, it reports the largest size that keeps both limits.

Output template

**XYZ long: 100 shares at 100.00, stop 95.00**
Risk $500 (1.00% of $50,000) | Position $10,000 (20% of equity)
Portfolio heat after this trade: 4.3% of 6% limit. Fits.
Notes: none
Not financial advice.

Guardrails

  • Never round shares up. The script floors; keep it that way.
  • Never suggest moving a stop further away to get a bigger size. Size follows the stop, not the reverse.
  • Do not place orders. If the user wants to place one, hand off to the alpaca-connector kit and its confirmation rules.
  • If equity, entry, or stop is missing, ask. Do not guess prices.

README.md

position-sizer

Know your size before you click buy. This kit turns your account size, risk per trade, and stop into a share count, with fixed-fractional, ATR-based, and capped Kelly methods, and checks your total open risk ("portfolio heat") before you add a new position.

Who it is for: discretionary and systematic traders who want a consistent, written-down sizing rule instead of a gut feel.

Not financial advice. It is a calculator; it never tells you whether to take a trade.

Example

node scripts/size.mjs heat --equity 100000 --positions examples/positions.csv --add FFF,long,120,25,23
Portfolio heat: 5.80% of equity at risk ($5,800.00) | limit 6.00% | OK
Symbol  Side   Qty      Ref      Stop     Risk $       Risk %   Flags
AAA     long   100      52       46            600.00    0.60%
BBB     long   200      35       31            800.00    0.80%  stop locks in profit vs entry
CCC     short  50       80       84            200.00    0.20%
DDD     long   150      20       -           3,000.00    3.00%  NO STOP: full value at risk; over 2% single-trade limit
EEE     long   300      41       37          1,200.00    1.20%
Proposed FFF x120: risk $240.00 (0.24%), heat after 6.04%. Does not fit. Max that fits: 100 shares.

Hand check (verify it yourself)

  • Fixed fractional: equity 50,000, risk 1%, entry 100, stop 95. Risk budget 500, per-share risk 5, so 100 shares, a 10,000 position (20% of equity). With a 15% max position: floor(7,500 / 100) = 75 shares.
  • ATR(3) on examples/prices.csv. True ranges: 1.0 (first bar, high - low), 0.8, 1.1, 0.8, 1.7 (12 - 10.3 beats 12 - 10.5). Seed = (1.0 + 0.8 + 1.1) / 3 = 0.966667. Then (0.966667 x 2 + 0.8) / 3 = 0.911111, then (0.911111 x 2 + 1.7) / 3 = 1.174074. With 2 x ATR, stop = 11.8 - 2.348148 = 9.451852. With 10,000 equity at 1%: floor(100 / 2.348148) = 42 shares.
  • Kelly: win rate 0.55, payoff 1.5. f* = 0.55 - 0.45 / 1.5 = 0.25. Half Kelly = 12.5% of equity at risk, which the default 5% cap cuts to 5%. From examples/trades.csv (3 wins averaging 216.67, 3 losses averaging 83.33): p = 0.5, b = 2.6, f* = 0.5 - 0.5 / 2.6 = 0.3077.
  • Heat: AAA 100 x (52 - 46) = 600. BBB 200 x (35 - 31) = 800. CCC short 50 x (84 - 80) = 200. DDD has no stop: 150 x 20 = 3,000. EEE 300 x (41 - 37) = 1,200. Total 5,800 = 5.8% of 100,000. Room left 0.2% = 200, so FFF with a 2-point stop fits at most 100 shares.

node scripts/selftest.mjs checks every number above.

Opinionated defaults

  • Kelly is half Kelly capped at 5% of equity at risk. Full Kelly assumes you know your edge exactly, and you do not.
  • Heat limit 6% of equity, single-trade limit 2%. Change them with --max-heat-pct and --max-risk-pct.
  • Shares always round down.

What it can access

  • Reads CSVs you point it at in data/, writes JSON to out/ when you pass --out.
  • Runs only its own scripts with Node. No network, no keys, no broker access.

Setup

Node 22 or newer. Nothing to install.

Files

  • README.md
  • SKILL.md
  • examples/positions.csv
  • examples/prices.csv
  • examples/trades.csv
  • kit.json
  • scripts/selftest.mjs
  • scripts/size.mjs

Did it work?

0worked for them0did not work

Sign in to say whether it worked for you.

Nobody has said yet. Tried it? Tell the next person.