2Branches0Tags
GL
glucryptoSync production with master template updates
dc969c112 days ago54Commits
typescript
import { resolveHyperliquidMaxPerRunUsd, } from "opentool/adapters/hyperliquid"; import { TEMPLATE_CONFIG_DEFAULTS, TEMPLATE_CONFIG_ENV_VAR, TEMPLATE_CONFIG_VERSION, } from "./defaults"; import { configSchema, TEMPLATE_CONFIG_SCHEMA } from "./schema"; import type { DeltaNeutralConfig } from "./types"; export const DELTA_NEUTRAL_TEMPLATE_CONFIG = { version: TEMPLATE_CONFIG_VERSION, schema: TEMPLATE_CONFIG_SCHEMA, defaults: TEMPLATE_CONFIG_DEFAULTS, envVar: TEMPLATE_CONFIG_ENV_VAR, }; export function readConfig(): DeltaNeutralConfig { const defaultSchedule = TEMPLATE_CONFIG_DEFAULTS.schedule ?? { cron: "0 * * * *", enabled: false, notifyEmail: false, }; const raw = process.env[TEMPLATE_CONFIG_ENV_VAR]; if (!raw) { const targetNotionalUsd = TEMPLATE_CONFIG_DEFAULTS.targetNotionalUsd; const hedgeRatio = TEMPLATE_CONFIG_DEFAULTS.hedgeRatio; const maxPerRunUsd = resolveHyperliquidMaxPerRunUsd(targetNotionalUsd, hedgeRatio); const deltaDriftUsd = (targetNotionalUsd * TEMPLATE_CONFIG_DEFAULTS.deltaDriftPct) / 100; return { ...TEMPLATE_CONFIG_DEFAULTS, maxPerRunUsd, deltaDriftUsd, }; } try { const parsed = configSchema.parse(JSON.parse(raw)); const merged = { ...TEMPLATE_CONFIG_DEFAULTS, ...parsed, spotAsset: parsed.spotAsset ?? TEMPLATE_CONFIG_DEFAULTS.spotAsset, perpAsset: parsed.perpAsset ?? TEMPLATE_CONFIG_DEFAULTS.perpAsset, schedule: { cron: parsed.schedule?.cron ?? defaultSchedule.cron, enabled: parsed.schedule?.enabled ?? defaultSchedule.enabled, notifyEmail: parsed.schedule?.notifyEmail ?? defaultSchedule.notifyEmail, }, }; const targetNotionalUsd = Number.isFinite(merged.targetNotionalUsd) ? merged.targetNotionalUsd : TEMPLATE_CONFIG_DEFAULTS.targetNotionalUsd; const hedgeRatio = Number.isFinite(merged.hedgeRatio) ? merged.hedgeRatio : TEMPLATE_CONFIG_DEFAULTS.hedgeRatio; const deltaDriftPct = Number.isFinite(merged.deltaDriftPct) ? merged.deltaDriftPct : TEMPLATE_CONFIG_DEFAULTS.deltaDriftPct; const computedDeltaDriftUsd = (targetNotionalUsd * deltaDriftPct) / 100; return { ...merged, allocationMode: "target_notional", spotAsset: merged.spotAsset, perpAsset: merged.perpAsset, deltaDriftPct, maxPerRunUsd: resolveHyperliquidMaxPerRunUsd(targetNotionalUsd, hedgeRatio), deltaDriftUsd: computedDeltaDriftUsd, }; } catch { const targetNotionalUsd = TEMPLATE_CONFIG_DEFAULTS.targetNotionalUsd; const hedgeRatio = TEMPLATE_CONFIG_DEFAULTS.hedgeRatio; const maxPerRunUsd = resolveHyperliquidMaxPerRunUsd(targetNotionalUsd, hedgeRatio); const deltaDriftUsd = (targetNotionalUsd * TEMPLATE_CONFIG_DEFAULTS.deltaDriftPct) / 100; return { ...TEMPLATE_CONFIG_DEFAULTS, maxPerRunUsd, deltaDriftUsd, }; } } export function resolveScheduleConfig(config: DeltaNeutralConfig) { const schedule = config.schedule ?? TEMPLATE_CONFIG_DEFAULTS.schedule; if (!schedule || !schedule.cron) return undefined; return { cron: schedule.cron, enabled: schedule.enabled, notifyEmail: schedule.notifyEmail, }; } export function resolveProfileAssets(config: DeltaNeutralConfig) { const assetSymbols = Array.from( new Set( [config.spotAsset, config.perpAsset] .map((value) => value.trim()) .filter((value) => value.length > 0), ), ); if (assetSymbols.length === 0) { return []; } return [ { venue: "hyperliquid" as const, chain: config.environment === "testnet" ? ("hyperliquid-testnet" as const) : ("hyperliquid" as const), assetSymbols, }, ]; }