openpondai/agents/dca-agent
dca-agent
typescript
import { z } from "zod";
export const TEMPLATE_CONFIG_SCHEMA = {
type: "object",
"x-budget": {
modeField: "allocationMode",
defaultMode: "fixed",
title: "Budget & allocation",
description: "DCA starters use fixed USD sizing across the configured basket.",
modes: {
fixed: {
fields: ["amountUsd"],
},
},
},
properties: {
configVersion: {
type: "number",
title: "Config version",
description: "Internal version for dca-agent defaults.",
readOnly: true,
"x-hidden": true,
"x-section": "Meta",
"x-order": 1000,
},
platform: {
type: "string",
enum: ["hyperliquid"],
title: "Platform",
description: "Execution venue for this strategy.",
readOnly: true,
"x-hidden": true,
"x-section": "Meta",
"x-order": 1001,
},
signalType: {
type: "string",
enum: ["dca"],
title: "Strategy type",
description: "Internal strategy identifier.",
readOnly: true,
"x-hidden": true,
"x-section": "Meta",
"x-order": 1002,
},
allocationMode: {
type: "string",
enum: ["fixed"],
title: "Allocation mode",
description: "Canonical sizing mode for this template.",
readOnly: true,
"x-hidden": true,
"x-section": "Meta",
"x-order": 1003,
},
asset: {
type: "string",
title: "Primary asset",
description: "Fallback base asset when no explicit basket symbols are configured.",
"x-section": "Strategy",
"x-order": 1,
},
amountUsd: {
type: "number",
title: "Fixed amount",
description: "USD budget allocated to each DCA cycle.",
minimum: 1,
"x-unit": "USD",
"x-format": "currency",
"x-step": 1,
"x-section": "Strategy",
"x-order": 2,
},
schedule: {
type: "object",
title: "Schedule",
description: "Cron and notification settings.",
"x-section": "Schedule",
properties: {
cron: {
type: "string",
title: "Cron expression",
description: "Cron expression for automated runs.",
"x-order": 1,
},
enabled: {
type: "boolean",
title: "Enabled",
description: "Enable scheduled runs.",
"x-order": 2,
},
notifyEmail: {
type: "boolean",
title: "Notify email",
description: "Send an email after scheduled runs.",
"x-order": 3,
},
},
},
resolution: {
type: "string",
enum: ["1", "5", "15", "30", "60", "240", "1D", "1W"],
title: "Price resolution",
description: "Bar timeframe used when simulating schedule-aware backtests.",
"x-section": "Backtest",
"x-order": 1,
},
countBack: {
type: "number",
title: "Bars to fetch",
description: "Historical bars fetched for simulation windows.",
minimum: 50,
maximum: 5000,
"x-step": 1,
"x-section": "Backtest",
"x-order": 2,
},
dca: {
type: "object",
title: "Basket",
description: "Weighted market basket for recurring DCA buys.",
"x-section": "Basket",
properties: {
preset: {
type: "string",
title: "Preset",
description: "Optional preset label for the basket.",
"x-order": 1,
},
symbols: {
type: "array",
title: "Symbol weights",
description:
"Exact symbol + weight entries for the DCA basket. Use exact spot pairs for spot entries, for example HYPE-USDC.",
items: {
type: "object",
properties: {
symbol: { type: "string", title: "Symbol" },
weight: { type: "number", title: "Weight" },
},
},
"x-order": 2,
},
slippageBps: {
type: "number",
title: "Basket slippage",
description: "Max slippage for DCA execution.",
minimum: 0,
maximum: 5000,
"x-unit": "bps",
"x-format": "bps",
"x-step": 1,
"x-order": 3,
},
},
},
execution: {
type: "object",
title: "Execution",
description: "Live trading controls and routing.",
"x-section": "Execution",
properties: {
enabled: {
type: "boolean",
title: "Execution enabled",
description: "Submit live DCA orders when runs execute.",
"x-order": 1,
},
environment: {
type: "string",
enum: ["testnet", "mainnet"],
title: "Environment",
description: "Execution environment for Hyperliquid.",
"x-enumLabels": ["Testnet", "Mainnet"],
"x-order": 2,
},
symbol: {
type: "string",
title: "Execution symbol",
description:
"Optional exact Hyperliquid symbol override. Use BASE-QUOTE or BASE/QUOTE for spot, bare BASE for perps, or dex:BASE for HIP-3.",
"x-order": 3,
},
leverage: {
type: "number",
title: "Leverage",
description: "Target leverage for perpetual execution.",
minimum: 1,
maximum: 50,
"x-unit": "x",
"x-step": 1,
"x-order": 4,
},
slippageBps: {
type: "number",
title: "Execution slippage",
description: "Max slippage override for live orders.",
minimum: 0,
maximum: 500,
"x-unit": "bps",
"x-format": "bps",
"x-step": 1,
"x-order": 5,
},
},
},
},
} as const;
export const configSchema = z
.object({
platform: z.literal("hyperliquid").optional(),
asset: z.string().min(1).optional(),
signalType: z.literal("dca").optional(),
allocationMode: z.literal("fixed").optional(),
amountUsd: z.number().positive().optional(),
schedule: z
.object({
cron: z.string().min(1).optional(),
enabled: z.boolean().optional(),
notifyEmail: z.boolean().optional(),
})
.optional(),
resolution: z.enum(["1", "5", "15", "30", "60", "240", "1D", "1W"]).optional(),
countBack: z.number().int().min(50).max(5000).optional(),
execution: z
.object({
enabled: z.boolean().optional(),
environment: z.enum(["testnet", "mainnet"]).optional(),
symbol: z.string().optional(),
leverage: z.number().positive().optional(),
slippageBps: z.number().min(0).max(500).optional(),
})
.optional(),
dca: z
.object({
preset: z.string().optional(),
symbols: z
.array(
z.union([
z.string().min(1),
z.object({
symbol: z.string().min(1),
weight: z.number().positive().optional(),
}),
]),
)
.optional(),
slippageBps: z.number().min(0).max(5000).optional(),
})
.optional(),
})
.partial();