openpondai/agents/hyperliquid-delta-neutral
OpenTool app
typescript
import type { DeltaNeutralConfig } from "./config";
import type { DeltaNeutralHistoricalFundingRatePoint } from "./runtime/types";
const DEFAULT_OPENPOND_BASE_URL = "https://api.openpond.ai";
function resolveBaseUrl(): string | null {
const raw = process.env.BASE_URL ?? DEFAULT_OPENPOND_BASE_URL;
if (typeof raw !== "string") return null;
const trimmed = raw.trim();
if (!trimmed) return null;
return trimmed.replace(/\/$/, "");
}
function resolveApiKey(): string | null {
const raw = process.env.OPENPOND_API_KEY;
if (typeof raw !== "string") return null;
const trimmed = raw.trim();
return trimmed.length > 0 ? trimmed : null;
}
type FundingPointResponse = {
time?: string;
rateBps?: number;
};
export async function loadDeltaNeutralHistoricalFundingRates(params: {
config: DeltaNeutralConfig;
timeframeStart: string;
timeframeEnd: string;
}): Promise<DeltaNeutralHistoricalFundingRatePoint[]> {
const baseUrl = resolveBaseUrl();
const apiKey = resolveApiKey();
if (!baseUrl || !apiKey) return [];
const startMs = Date.parse(params.timeframeStart);
const endMs = Date.parse(params.timeframeEnd);
if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs <= startMs) {
return [];
}
const url = new URL(`${baseUrl}/apps/hyperliquid/funding-rates`);
url.searchParams.set("environment", params.config.environment);
url.searchParams.set("symbol", params.config.perpAsset.trim().toUpperCase());
url.searchParams.set("startMs", String(startMs));
url.searchParams.set("endMs", String(endMs));
const response = await fetch(url.toString(), {
method: "GET",
headers: {
"openpond-api-key": apiKey,
accept: "application/json",
},
});
if (!response.ok) {
throw new Error(`Funding history request failed (${response.status}).`);
}
const data = (await response.json().catch(() => null)) as
| {
points?: FundingPointResponse[];
}
| null;
const points = Array.isArray(data?.points) ? data.points : [];
return points
.map((point) => {
if (!point || typeof point.time !== "string" || !Number.isFinite(point.rateBps)) {
return null;
}
return {
time: point.time,
rateBps: point.rateBps,
};
})
.filter((point): point is DeltaNeutralHistoricalFundingRatePoint => Boolean(point));
}