> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.zeustrade.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Example bot

> A full cycle: approvals, a market open with its receipt, take profit and stop loss, partial and full close, ZLP deposit and withdrawal.

This cycle runs in the SDK's own integration test on the ZEUS test network. Run it with a dedicated wallet that holds some USDC and a little ETH for gas and keeper fees.

```ts cycle.ts theme={null}
import { LiquidityLocked, type Zeus } from '@zeustrade/sdk'

export interface CycleStep {
  step: string
  detail: Record<string, unknown>
}

const plain = (value: unknown) => JSON.parse(JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? v.toString() : v)))

export async function runCycle(zeus: Zeus, log: (step: CycleStep) => void, market = 'ETH/USD'): Promise<CycleStep[]> {
  const steps: CycleStep[] = []
  const record = (step: string, detail: unknown) => {
    const entry = { step, detail: plain(detail) }
    steps.push(entry)
    log(entry)
  }

  const status = await zeus.setup.status()
  if (!status.ready) record('approvePlugins', { hashes: await zeus.setup.approvePlugins() })
  if ((await zeus.setup.allowance('USDC')) < 1_000_000_000n) record('approveToken trading', { hash: await zeus.setup.approveToken('USDC') })
  if ((await zeus.setup.allowance('USDC', 'liquidity')) < 1_000_000_000n) {
    record('approveToken liquidity', { hash: await zeus.setup.approveToken('USDC', undefined, 'liquidity') })
  }

  const open = await zeus.trade.marketOpen({ market, side: 'long', collateral: 20, payToken: 'USDC', leverage: 5, slippage: 0.5 })
  record('marketOpen', open)

  const fill = Number(open.fillPrice)
  const takeProfit = await zeus.orders.takeProfit({ market, side: 'long', triggerPrice: (fill * 1.05).toFixed(2) })
  record('takeProfit', takeProfit)
  const stopLoss = await zeus.orders.stopLoss({ market, side: 'long', triggerPrice: (fill * 0.95).toFixed(2) })
  record('stopLoss', stopLoss)

  const [position] = (await zeus.account.positions()).filter((p) => p.market === market && p.side === 'long')
  record('position', position)
  const half = (Number(position!.size) / 2).toFixed(2)
  // Closes take the collateral back as ETH: a swap into USDC can hit the Vault's USDC buffer
  record('partialClose', await zeus.trade.marketClose({ market, side: 'long', size: half, receiveToken: 'ETH', slippage: 0.5 }))
  record('fullClose', await zeus.trade.marketClose({ market, side: 'long', receiveToken: 'ETH', slippage: 0.5 }))

  for (const order of [takeProfit, stopLoss]) {
    await zeus.orders.cancel({ kind: order.kind, orderIndex: order.orderIndex }).then(
      (hash) => record('cancelOrder', { orderIndex: order.orderIndex, hash }),
      (error: Error) => record('cancelOrder', { orderIndex: order.orderIndex, skipped: error.message })
    )
  }

  const deposit = await zeus.lp.deposit({ token: 'USDC', amount: 10, minZlp: 0 })
  record('lpDeposit', deposit)
  // Fresh ZLP stays locked for the deposit cooldown, so the request may have to wait
  await zeus.lp.requestWithdrawal({ zlpAmount: deposit.zlpAmount }).then(
    (hash) => record('requestWithdrawal', { hash }),
    (error: unknown) => {
      if (!(error instanceof LiquidityLocked)) throw error
      record('requestWithdrawal', { lockedUntilCooldown: true })
    }
  )
  return steps
}
```

Call it with a client and a logger:

```ts bot.ts theme={null}
import { Zeus } from '@zeustrade/sdk'
import { runCycle } from './cycle'

const zeus = new Zeus({
  network: 'base-sepolia',
  rpcUrl: 'https://sepolia.base.org',
  privateKey: process.env.PRIVATE_KEY as `0x${string}`
})

await runCycle(zeus, ({ step, detail }) => console.log(step, JSON.stringify(detail)))
```

The source is in the [examples folder](https://github.com/zeustrade/zeus-sdk/tree/main/examples).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.