openpondai/agents/hip4-edge-bot
OpenTool app
typescript
import {
buildHyperliquidMarketIdentity,
extractHyperliquidOrderIds,
fetchHyperliquidSizeDecimals,
fetchHyperliquidTickSize,
formatHyperliquidMarketablePrice,
formatHyperliquidOrderSize,
placeHyperliquidOrder,
type HyperliquidEnvironment,
type HyperliquidOrderResponse,
} from "opentool/adapters/hyperliquid";
import { store } from "opentool/store";
import type { WalletFullContext } from "opentool/wallet";
import type { Hip4EdgeBotConfig } from "../config";
import type { Hip4EdgeCandidate, Hip4EdgeExecutionResult } from "./types";
function clampOutcomePrice(value: string) {
const numeric = Number.parseFloat(value);
if (!Number.isFinite(numeric) || numeric <= 0) return value;
if (numeric >= 1) return "0.9999";
return value;
}
export async function executeHip4EdgeCandidate(params: {
config: Hip4EdgeBotConfig;
environment: HyperliquidEnvironment;
walletContext: WalletFullContext;
candidate: Hip4EdgeCandidate;
budgetUsd: number;
}): Promise<Hip4EdgeExecutionResult> {
const sizeDecimals = await fetchHyperliquidSizeDecimals({
environment: params.environment,
symbol: params.candidate.marketDataCoin,
});
const tick = await fetchHyperliquidTickSize({
environment: params.environment,
symbol: params.candidate.marketDataCoin,
});
const price = clampOutcomePrice(
formatHyperliquidMarketablePrice({
mid: params.candidate.ask,
side: "buy",
slippageBps: params.config.execution.slippageBps,
tick,
szDecimals: sizeDecimals,
marketType: "perp",
}),
);
const priceNumber = Number.parseFloat(price);
const rawSize = Number.isFinite(priceNumber) && priceNumber > 0 ? params.budgetUsd / priceNumber : 0;
const size = formatHyperliquidOrderSize(rawSize, sizeDecimals);
if (size === "0") {
return {
side: params.candidate.side,
marketDataCoin: params.candidate.marketDataCoin,
price,
size,
budgetUsd: params.budgetUsd,
};
}
const orderResponse = await placeHyperliquidOrder({
wallet: params.walletContext,
environment: params.environment,
orders: [
{
symbol: params.candidate.marketDataCoin,
side: "buy",
price,
size,
tif: "FrontendMarket",
reduceOnly: false,
},
],
});
const orderIds = extractHyperliquidOrderIds([
orderResponse as unknown as {
response?: {
data?: {
statuses?: Array<Record<string, unknown>>;
};
};
},
]);
const marketIdentity = buildHyperliquidMarketIdentity({
environment: params.environment,
symbol:
params.candidate.market.roundKey ??
`${params.candidate.market.underlying}-${params.candidate.side}`,
rawSymbol: params.candidate.marketDataCoin,
isSpot: false,
base: `${params.candidate.market.underlying}-${params.candidate.side.toUpperCase()}`,
quote: "USDC",
});
if (marketIdentity) {
await store({
source: "hyperliquid",
ref:
orderIds.cloids[0] ??
orderIds.oids[0] ??
`hip4-edge-bot-${Date.now()}-${params.candidate.marketDataCoin}`,
status: "submitted",
walletAddress: params.walletContext.address,
action: "order",
notional: size,
network:
params.environment === "mainnet"
? "hyperliquid"
: "hyperliquid-testnet",
market: marketIdentity,
metadata: {
strategy: "hip4-edge-bot",
side: params.candidate.side,
marketDataCoin: params.candidate.marketDataCoin,
outcomeId: params.candidate.market.outcomeId,
seriesKey: params.candidate.seriesKey,
roundKey: params.candidate.roundKey,
ask: params.candidate.ask,
fairProbability: params.candidate.fairProbability,
edge: params.candidate.edge,
roi: params.candidate.roi,
calculation: params.candidate.calculation,
price,
size,
budgetUsd: params.budgetUsd,
cloid: orderIds.cloids[0] ?? null,
orderIds,
orderResponse,
orderResponses: [orderResponse],
},
});
}
return {
side: params.candidate.side,
marketDataCoin: params.candidate.marketDataCoin,
price,
size,
budgetUsd: params.budgetUsd,
orderIds,
orderResponse: orderResponse as HyperliquidOrderResponse,
};
}