import { Agent, type AgentContext, type CurrentPosition } from "@circuitorg/agent-sdk";
const BUY_SIZE = 0.01; // ETH to buy each cycle
async function run(agent: AgentContext): Promise<void> {
// Check available balance
const balances = await agent.platforms.hyperliquid.balances();
if (!balances.success || !balances.data) {
await agent.log(balances.error || "Failed to fetch balances", { error: true });
return;
}
const withdrawable = parseFloat(balances.data.perp.withdrawable);
await agent.log(`Withdrawable balance: $${withdrawable.toFixed(2)}`);
if (withdrawable < 20) {
await agent.log("Not enough balance to place order");
return;
}
// Check existing positions
const positions = await agent.platforms.hyperliquid.positions();
if (positions.success && positions.data) {
for (const pos of positions.data) {
await agent.log(`Open: ${pos.symbol} ${pos.side} ${pos.size} @ ${pos.entryPrice} (PnL: ${pos.unrealizedPnl})`);
}
}
// Place a market buy for ETH perps
// price acts as slippage limit for market orders — set above current market price
const order = await agent.platforms.hyperliquid.placeOrder({
symbol: "ETH",
side: "buy",
size: BUY_SIZE,
price: 10000, // Max price willing to pay (slippage limit)
market: "perp",
type: "market"
});
if (order.success && order.data) {
await agent.log(`Order placed: ${order.data.orderId} (${order.data.status})`);
// Track total buys in memory
const prev = await agent.memory.get("totalBuys");
const count = prev.success && prev.data ? parseInt(prev.data.value) + 1 : 1;
await agent.memory.set("totalBuys", count.toString());
await agent.log(`Total buy orders placed: ${count}`);
} else {
await agent.log(order.error || "Order failed", { error: true });
}
}
async function unwind(agent: AgentContext, positions: CurrentPosition[]): Promise<void> {
// Close all open perp positions
const openPositions = await agent.platforms.hyperliquid.positions();
if (!openPositions.success || !openPositions.data || openPositions.data.length === 0) {
await agent.log("No open positions to close");
return;
}
for (const pos of openPositions.data) {
const closeSide = pos.side === "long" ? "sell" : "buy";
const closeOrder = await agent.platforms.hyperliquid.placeOrder({
symbol: pos.symbol,
side: closeSide,
size: parseFloat(pos.size),
price: closeSide === "sell" ? 0.01 : 999999, // Aggressive slippage limit to ensure fill
market: "perp",
type: "market",
reduceOnly: true
});
if (closeOrder.success && closeOrder.data) {
await agent.log(`Closed ${pos.symbol} ${pos.side}: ${closeOrder.data.status}`);
} else {
await agent.log(`Failed to close ${pos.symbol}: ${closeOrder.error}`, { error: true });
}
}
}
const agent = new Agent({
runFunction: run,
unwindFunction: unwind,
});
export default agent.getExport();