import { brent, expandBracket } from "./brent";
import type { ForwardArgs, Pricer, SolvableKey } from "./types";
/** Starting brackets; widened automatically if the root lies outside. */
export const DEFAULT_BRACKETS: Record<SolvableKey, [number, number]> = {
spot: [1, 20_000],
rate: [-0.1, 0.2],
fundingSpread: [-0.1, 0.1],
allIn: [0, 1.5],
divScale: [0, 3],
eqlSpread: [-0.1, 0.1],
};
/**
* Generic inverse solver: finds x such that pricer({...base, [key]: x}) = target.
*
* implied(fairSyntheticPrice, "fundingSpread", -45.5, args) // funding from a synthetic
* implied(fairTRFSpread, "fundingSpread", 62.5, args) // funding from a TRF
* implied(fairSyntheticPrice, "allIn", -45.5, args) // all-in from a synthetic
*/
export function implied(
pricer: Pricer,
key: SolvableKey,
target: number,
base: ForwardArgs,
opts: { bracket?: [number, number]; tol?: number } = {},
): number {
const f = (x: number) => pricer({ ...base, [key]: x }) - target;
const [lo, hi] = opts.bracket ?? DEFAULT_BRACKETS[key];
const [a, b] = expandBracket(f, lo, hi);
return brent(f, a, b, opts.tol ?? 1e-14);
}