Free investment calculators — no signup required
StockAverager logoStockAverager
No API key · OpenAPI 3.1 · Free

Stock Averager API

The maths behind every calculator on this site, available as JSON. Stateless, unauthenticated, and deterministic — you supply the numbers, it returns the arithmetic. Nothing is stored.

Getting started

Every operation is a POST with a JSON body. There is no authentication, no API key and no signup. Responses are application/json; errors are RFC 9457 problem details.

curl -X POST https://www.stockaverager.com/api/v1/cagr \
  -H "Content-Type: application/json" \
  -d '{"initialValue": 12000, "finalValue": 31000, "years": 7}'

When to use this API

Good fit

  • Working out a position's new average cost, cost basis or break-even including fees
  • Projecting a monthly plan, a lump sum, or a withdrawal schedule at an assumed return
  • Turning a start and end value into a comparable annualised rate
  • Pricing a single option and reading its Delta, Gamma, Theta and Vega

Wrong tool

  • Quotes, tickers or historical prices — there is no market data here at all
  • Placing trades, tracking a portfolio, or reading account data
  • Personalised financial or tax advice — see the disclaimer
  • Jurisdiction-exact tax figures

Authentication and limits

None. The API is public and unauthenticated because every operation is a pure function over numbers you send — there is no account, no stored data and no per-caller state to protect. CORS is open, so browser-based clients can call it directly. There is no enforced rate limit today; please keep to roughly 60 requests a minute. If that has to change, it will be announced on this page before it is enforced.

Endpoints

8 operations. Each has a stable operationId, typed parameters and a response schema, so the spec can be loaded directly as LLM function-calling tool definitions.

POST/api/v1/average-downPosition

Shares needed to reach a target average price

operationId: calculateAverageDown

Given an existing position and the current market price, returns how many additional shares to buy to bring the average cost down to a target, and the resulting position. The target must sit strictly between the current price and the original price — no share count reaches an average below the price you are buying at.

Interactive equivalent: /tools/stock-averager

Request body

FieldTypeConstraintsDescription
sharesnumber> 0Shares currently held.
originalPricenumber> 0Average price already paid per share.
currentPricenumber> 0Current market price per share.
targetAveragePricenumber> 0Average price per share you want to reach.

Result fields

FieldTypeConstraintsDescription
additionalSharesnumber—Shares to buy at currentPrice to reach the target average.
additionalInvestmentnumber—Cash required for those shares.
newTotalSharesnumber—Shares held afterwards.
newTotalInvestmentnumber—Total cash invested afterwards.
newAveragePricenumber—Resulting average cost per share.

Example

curl -X POST https://www.stockaverager.com/api/v1/average-down \
  -H "Content-Type: application/json" \
  -d '{"shares":100,"originalPrice":80,"currentPrice":50,"targetAveragePrice":65}'
POST/api/v1/cost-basisPosition

Average cost basis across purchase lots

operationId: calculateCostBasis

Average-cost basis for a position built from several purchases, including per-lot fees. Use this before computing a gain, a break-even or a tax liability on a position bought in tranches.

Interactive equivalent: /tools/stock-averager/cost-basis-calculator

Request body

FieldTypeConstraintsDescription
lotsarray of objects≥ 1 item(s), ≤ 500 itemsOne entry per purchase lot, in any order.

Result fields

FieldTypeConstraintsDescription
totalSharesnumber—Shares held across every lot.
totalInvestednumber—Cash invested across every lot, fees included.
averageCostPerSharenumber—Cost basis per share.

Example

curl -X POST https://www.stockaverager.com/api/v1/cost-basis \
  -H "Content-Type: application/json" \
  -d '{"lots":[{"shares":100,"price":50,"fees":0},{"shares":100,"price":50,"fees":0}]}'
POST/api/v1/sipProjection

Future value of a monthly investment plan

operationId: calculateSip

Compounds a fixed monthly contribution at an assumed annual return. The return is an assumption you supply, not a forecast — no market data is involved.

Interactive equivalent: /tools/sip-calculator

Request body

FieldTypeConstraintsDescription
monthlyInvestmentnumber> 0Amount invested every month.
expectedAnnualReturnnumber> 0, ≤ 50Assumed annual return, as a percentage.
yearsnumber> 0, ≤ 50Contribution period in years.

Result fields

FieldTypeConstraintsDescription
futureValuenumber—Projected value at the end of the period.
totalInvestmentnumber—Sum of every contribution.
totalReturnsnumber—futureValue minus totalInvestment.

Example

curl -X POST https://www.stockaverager.com/api/v1/sip \
  -H "Content-Type: application/json" \
  -d '{"monthlyInvestment":500,"expectedAnnualReturn":12,"years":10}'
POST/api/v1/lumpsumProjection

Future value of a one-time investment

operationId: calculateLumpsum

Compounds a single deposit at an assumed annual return and returns the year-by-year path. Use calculateSip instead when money goes in on a schedule.

Interactive equivalent: /tools/lumpsum-calculator

Request body

FieldTypeConstraintsDescription
amountnumber> 0Amount invested once, up front.
expectedAnnualReturnnumber> 0, ≤ 50Assumed annual return, as a percentage.
yearsinteger> 0, ≤ 50Holding period in whole years.

Result fields

FieldTypeConstraintsDescription
futureValuenumber—Projected value at the end of the period.
totalReturnsnumber—futureValue minus the amount invested.
wealthGainPercentnumber—Total return as a percentage of the amount invested.
yearlyBreakdownarray of objects—Value and cumulative return at the end of each year, in order.

Example

curl -X POST https://www.stockaverager.com/api/v1/lumpsum \
  -H "Content-Type: application/json" \
  -d '{"amount":10000,"expectedAnnualReturn":9,"years":15}'
POST/api/v1/swpProjection

How long a corpus survives fixed withdrawals

operationId: calculateSwp

Draws a fixed amount every month while the remaining balance keeps compounding, and reports when the corpus runs out. Capped at 600 months (50 years); if the withdrawal is smaller than the growth, `depleted` is false and the corpus survives the cap.

Interactive equivalent: /tools/swp-calculator

Request body

FieldTypeConstraintsDescription
initialInvestmentnumber> 0Starting corpus.
monthlyWithdrawalnumber> 0Amount withdrawn every month.
expectedAnnualReturnnumber> 0, ≤ 50Assumed annual return on the remaining balance, as a percentage.

Result fields

FieldTypeConstraintsDescription
withdrawalMonthsnumber—Months of withdrawals before the corpus is exhausted, or 600 if it survives the cap.
totalWithdrawalsnumber—Total cash withdrawn over that period.
remainingBalancenumber—Balance left at the end.
totalInterestEarnednumber—Growth earned across the period.
depletedboolean—True when the corpus ran out before the 600-month cap.

Example

curl -X POST https://www.stockaverager.com/api/v1/swp \
  -H "Content-Type: application/json" \
  -d '{"initialInvestment":500000,"monthlyWithdrawal":3000,"expectedAnnualReturn":8}'
POST/api/v1/cagrReturn

Compound annual growth rate

operationId: calculateCagr

The annualised rate implied by a start value, an end value and a holding period. Use it to compare investments held for different lengths of time. For uneven cash flows in and out, CAGR is the wrong measure — IRR is.

Interactive equivalent: /tools/cagr-calculator

Request body

FieldTypeConstraintsDescription
initialValuenumber> 0Value at the start of the period.
finalValuenumber> 0Value at the end of the period.
yearsnumber> 0, ≤ 100Holding period in years.

Result fields

FieldTypeConstraintsDescription
cagrPercentnumber—Compound annual growth rate, as a percentage.
absoluteReturnnumber—finalValue minus initialValue.
totalGrowthPercentnumber—Total return over the whole period, as a percentage.

Example

curl -X POST https://www.stockaverager.com/api/v1/cagr \
  -H "Content-Type: application/json" \
  -d '{"initialValue":12000,"finalValue":31000,"years":7}'
POST/api/v1/break-evenPosition

Break-even price including fees

operationId: calculateBreakEven

The selling price at which a position covers its cost once buy-side and sell-side charges are included. On small positions the fee impact is often larger than it looks.

Interactive equivalent: /tools/break-even-calculator

Request body

FieldTypeConstraintsDescription
sharesnumber> 0Shares held.
purchasePricenumber> 0Price paid per share.
buyFeesnumber≥ 0, optionalTotal charges on the purchase.
sellFeesnumber≥ 0, optionalTotal charges expected on the sale.

Result fields

FieldTypeConstraintsDescription
breakEvenPricenumber—Price per share that covers cost and all charges.
totalCostnumber—Cash spent acquiring the position, buy fees included.
totalFeesnumber—Buy plus sell charges.
feeImpactnumber—How far fees push the break-even above the purchase price.

Example

curl -X POST https://www.stockaverager.com/api/v1/break-even \
  -H "Content-Type: application/json" \
  -d '{"shares":100,"purchasePrice":50,"buyFees":10,"sellFees":10}'
POST/api/v1/options/greeksOptions

Black-Scholes price and Greeks for one option

operationId: calculateOptionGreeks

Prices a single European option with Black-Scholes and returns its sensitivities. Theta is per calendar day and Vega is per one percentage point of implied volatility, matching how desks quote them. Requires a volatility input — there is no market data behind this, so supply the implied volatility you want to model.

Interactive equivalent: /tools/options-greeks-calculator

Request body

FieldTypeConstraintsDescription
spotPricenumber> 0Current price of the underlying.
strikePricenumber> 0Strike price of the option.
daysToExpirynumber> 0, ≤ 3650Calendar days until expiry.
volatilityPercentnumber> 0, ≤ 500Implied volatility, as an annualised percentage.
riskFreeRatePercentnumber≥ 0, ≤ 100Annual risk-free rate, as a percentage.
optionTypestringcall | putWhich side to price.

Result fields

FieldTypeConstraintsDescription
optionPricenumber—Theoretical premium per share.
deltanumber—Change in premium per 1 unit move in the underlying.
gammanumber—Change in delta per 1 unit move in the underlying.
thetanumber—Premium lost per calendar day, all else equal.
veganumber—Premium change per 1 percentage point of implied volatility.
intrinsicValuenumber—Value if exercised now.
timeValuenumber—optionPrice minus intrinsicValue.

Example

curl -X POST https://www.stockaverager.com/api/v1/options/greeks \
  -H "Content-Type: application/json" \
  -d '{"spotPrice":147,"strikePrice":150,"daysToExpiry":30,"volatilityPercent":28,"riskFreeRatePercent":4,"optionType":"call"}'

Errors

Errors follow RFC 9457 problem details and are served as application/problem+json. Beyond the standard fields, every response carries a stable code to branch on and a hint describing the fix; validation failures add a per-field errors array.

CodeStatusMeaning
malformed_json400The body could not be parsed as JSON.
operation_not_found404No operation is published at that path.
method_not_allowed405Operations are POST only; the index is GET only.
validation_failed422One or more fields failed validation. See errors[].
calculation_impossible422Fields are individually valid but cannot be solved together.
internal_error500The calculation failed unexpectedly. Safe to retry once.
{
  "type": "https://www.stockaverager.com/docs#errors-validation-failed",
  "title": "Request failed validation",
  "status": 422,
  "detail": "1 field could not be accepted. See \"errors\" for each one.",
  "code": "validation_failed",
  "hint": "Fix the listed fields and retry.",
  "errors": [
    {
      "field": "years",
      "code": "range",
      "message": "\"years\" must be greater than 0 and at most 50, received 0.",
      "hint": "Adjust \"years\" so it is greater than 0 and at most 50."
    }
  ]
}

For AI agents

The spec at /openapi.json is OpenAPI 3.1 with a unique operationId, a description and typed schemas on every operation, which is what function-calling formats need. Site-wide guidance lives in /llms.txt and /agent-instructions.md. Every page on this site also serves Markdown from the same URL — send Accept: text/markdown or append .md to any path.