mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-10 00:38:07 +00:00
Adding a strategy meant editing six places that had to agree: the StrategyId union and a parallel Set in args.ts, STRATEGY_LABELS and a nine-branch STRATEGY_FACTORIES in strategy-runner.ts, plus an inline id union and BASE_STRATEGIES in App.tsx. runEngine's type parameter was additionally bounded by a union of all nine snapshot types. They had already drifted: the CLI gated basis on isBasisSupportedExchangeId while the menu checked only isBasisStrategyEnabled, so the menu offered basis on exchanges where startStrategy would throw. - strategy-ids.ts: the id list and alias parsing, dependency-free so CLI arg parsing does not pull in every engine. - registry.ts: one definition per strategy (labels, symbol, engine factory, and a single unavailableReason both the menu and the runner consult), keyed by a total Record so a new id will not compile until it is defined. - StrategyEngine/StrategySnapshot interfaces replace the snapshot union; runEngine now depends only on the contract. All nine engines already satisfied it — no engine changed. - App.tsx keeps only the id -> Ink view map, also a total Record. Menu order preserved. 8 new tests, one pinning menu/CLI availability agreement. 234 pass; tsc clean. -242 lines.
45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
/**
|
|
* The canonical list of strategies. Dependency-free on purpose: CLI argument
|
|
* parsing imports this without dragging in every engine and its config.
|
|
*
|
|
* Adding a strategy starts here; `strategy/registry.ts` then fails to compile
|
|
* until the new id has a definition.
|
|
*/
|
|
/** Order is the interactive menu's order. */
|
|
export const STRATEGY_IDS = [
|
|
"trend",
|
|
"swing",
|
|
"guardian",
|
|
"maker",
|
|
"maker-points",
|
|
"grid",
|
|
"offset-maker",
|
|
"liquidity-maker",
|
|
"basis",
|
|
] as const;
|
|
|
|
export type StrategyId = (typeof STRATEGY_IDS)[number];
|
|
|
|
/** Spellings accepted on the command line beyond the canonical ids. */
|
|
const STRATEGY_ALIASES: Record<string, StrategyId> = {
|
|
offset: "offset-maker",
|
|
offsetmaker: "offset-maker",
|
|
makerpoints: "maker-points",
|
|
maker_points: "maker-points",
|
|
liquidity: "liquidity-maker",
|
|
liquiditymaker: "liquidity-maker",
|
|
liquidity_maker: "liquidity-maker",
|
|
};
|
|
|
|
export function isStrategyId(value: string): value is StrategyId {
|
|
return (STRATEGY_IDS as readonly string[]).includes(value);
|
|
}
|
|
|
|
/** @returns the strategy the input names, or null when it names none. */
|
|
export function parseStrategyId(raw: string): StrategyId | null {
|
|
const normalized = raw.trim().toLowerCase();
|
|
if (!normalized) return null;
|
|
if (isStrategyId(normalized)) return normalized;
|
|
return STRATEGY_ALIASES[normalized] ?? null;
|
|
}
|