1Branch0Tags
GL
glucryptouse HIP-4 series key identity
e149f868 days ago3Commits
typescript
import { buildHyperliquidProfileAssets } from "opentool/adapters/hyperliquid"; import { DEFAULT_AMOUNT_USD, DEFAULT_SERIES_PERIOD, DEFAULT_SERIES_SETTLEMENT_SLOT, DEFAULT_UNDERLYING, TEMPLATE_CONFIG_DEFAULTS, TEMPLATE_CONFIG_ENV_VAR, TEMPLATE_CONFIG_VERSION, } from "./defaults"; import { configSchema, TEMPLATE_CONFIG_SCHEMA } from "./schema"; import type { Hip4EdgeBotConfig, Hip4EdgeSide, Hip4ModelWindow, } from "./types"; function parseJson(value: string | null | undefined) { if (!value) return null; try { return JSON.parse(value) as unknown; } catch { return null; } } function clamp(value: number, min: number, max: number) { return Math.min(max, Math.max(min, value)); } export function normalizeUnderlying(value: string | null | undefined) { const trimmed = value?.trim().toUpperCase() ?? ""; return trimmed || DEFAULT_UNDERLYING; } function normalizeKeyPart(value: string) { return value .trim() .toLowerCase() .replace(/[^a-z0-9._-]+/g, "-") .replace(/^-+|-+$/g, ""); } function normalizeOptionalSeriesKey(value: string | null | undefined) { const trimmed = value?.trim(); return trimmed || null; } function buildDefaultSeriesKey(params: { environment: "mainnet" | "testnet"; underlying: string; }) { return [ "hip4", normalizeKeyPart(params.environment), normalizeKeyPart(params.underlying), "price-binary", "above", DEFAULT_SERIES_PERIOD, `settles-${DEFAULT_SERIES_SETTLEMENT_SLOT}`, ].join(":"); } function normalizeAllowedSides(value: Hip4EdgeSide[] | undefined) { const sides = new Set<Hip4EdgeSide>(); for (const side of value ?? TEMPLATE_CONFIG_DEFAULTS.risk.allowedSides) { if (side === "yes" || side === "no") sides.add(side); } return sides.size > 0 ? Array.from(sides) : TEMPLATE_CONFIG_DEFAULTS.risk.allowedSides; } export const HIP4_EDGE_BOT_TEMPLATE_CONFIG = { version: TEMPLATE_CONFIG_VERSION, schema: TEMPLATE_CONFIG_SCHEMA, defaults: TEMPLATE_CONFIG_DEFAULTS, envVar: TEMPLATE_CONFIG_ENV_VAR, }; export function readConfig(): Hip4EdgeBotConfig { const parsed = configSchema.safeParse(parseJson(process.env[TEMPLATE_CONFIG_ENV_VAR])); const input = parsed.success ? parsed.data : {}; const amountUsd = input.amountUsd ?? DEFAULT_AMOUNT_USD; const maxPerRunUsd = input.maxPerRunUsd ?? amountUsd; const underlying = normalizeUnderlying(input.model?.underlying); const environment = input.execution?.environment ?? TEMPLATE_CONFIG_DEFAULTS.execution.environment; const seriesKey = normalizeOptionalSeriesKey(input.model?.seriesKey) ?? buildDefaultSeriesKey({ environment, underlying }); return { configVersion: TEMPLATE_CONFIG_VERSION, platform: "hyperliquid", signalType: "hip4-edge", allocationMode: "fixed", amountUsd, maxPerRunUsd, schedule: { cron: input.schedule?.cron ?? TEMPLATE_CONFIG_DEFAULTS.schedule.cron, enabled: input.schedule?.enabled ?? TEMPLATE_CONFIG_DEFAULTS.schedule.enabled, notifyEmail: input.schedule?.notifyEmail ?? TEMPLATE_CONFIG_DEFAULTS.schedule.notifyEmail, }, model: { underlying, seriesKey, selectedModel: (input.model?.selectedModel as Hip4ModelWindow | undefined) ?? TEMPLATE_CONFIG_DEFAULTS.model.selectedModel, depthUsd: Math.max( input.model?.depthUsd ?? TEMPLATE_CONFIG_DEFAULTS.model.depthUsd, amountUsd, ), includeExpired: input.model?.includeExpired ?? TEMPLATE_CONFIG_DEFAULTS.model.includeExpired, }, risk: { minEdgePct: input.risk?.minEdgePct ?? TEMPLATE_CONFIG_DEFAULTS.risk.minEdgePct, minRoiPct: input.risk?.minRoiPct ?? TEMPLATE_CONFIG_DEFAULTS.risk.minRoiPct, maxAsk: clamp(input.risk?.maxAsk ?? TEMPLATE_CONFIG_DEFAULTS.risk.maxAsk, 0.01, 1), minAskDepthUsd: input.risk?.minAskDepthUsd ?? TEMPLATE_CONFIG_DEFAULTS.risk.minAskDepthUsd, ...(typeof input.risk?.maxHoursToExpiry === "number" ? { maxHoursToExpiry: input.risk.maxHoursToExpiry } : {}), allowedSides: normalizeAllowedSides(input.risk?.allowedSides), maxTradesPerRun: input.risk?.maxTradesPerRun ?? TEMPLATE_CONFIG_DEFAULTS.risk.maxTradesPerRun, oneTradePerRoundSide: input.risk?.oneTradePerRoundSide ?? TEMPLATE_CONFIG_DEFAULTS.risk.oneTradePerRoundSide, }, execution: { enabled: input.execution?.enabled ?? TEMPLATE_CONFIG_DEFAULTS.execution.enabled, environment, slippageBps: input.execution?.slippageBps ?? TEMPLATE_CONFIG_DEFAULTS.execution.slippageBps, }, }; } export function resolveScheduleConfig(config: Hip4EdgeBotConfig) { return config.schedule; } export function resolveProfileAssets(config: Hip4EdgeBotConfig) { return buildHyperliquidProfileAssets({ environment: config.execution.environment, assets: [{ assetSymbols: [config.model.underlying] }], }); }