Skip to content
Join the waitlistWaitlist

Freqtrade

Put Guard in front of Freqtrade's Hyperliquid exchange through ccxt_config. The exact config keys.

Freqtrade trades Hyperliquid through ccxt. Its exchange.ccxt_config is passed to both of Freqtrade’s ccxt instances (sync and async), so the ccxt override goes there.

  • Read the setup journey and start Guard in paper mode.
  • Keep your real account address. Give the bot a Guard client key, while the API wallet key stays inside Guard.
  • Check the network and isolated-margin requirements in this guide. These integration instructions are planned and not verified against a released Guard yet.
"trading_mode": "futures",
"margin_mode": "isolated",
"exchange": {
"name": "hyperliquid",
"walletAddress": "0xYourAccountAddress",
"privateKey": "0x…API wallet key…",
"privateKey": "0x…client key from Guard…",
"ccxt_config": {
"urls": {"api": {"public": "http://127.0.0.1:8547", "private": "http://127.0.0.1:8547"},
"test": {"public": "http://127.0.0.1:8547", "private": "http://127.0.0.1:8547"}},
"options": {"builderFee": false, "refSet": true}
}
}

The keys to merge into Freqtrade’s config.json (the rest of your config stays as it is):

{
"trading_mode": "futures",
"margin_mode": "isolated",
"exchange": {
"name": "hyperliquid",
"walletAddress": "0xYourAccountAddress",
"privateKey": "0x...",
"ccxt_config": {
"urls": {
"api": {"public": "http://127.0.0.1:8547", "private": "http://127.0.0.1:8547"},
"test": {"public": "http://127.0.0.1:8547", "private": "http://127.0.0.1:8547"}
},
"options": {"builderFee": false, "refSet": true}
}
}
}
KeyValueSource
trading_modefuturesHyperliquid’s perps; Freqtrade configuration reference
margin_modeisolatedrequired. Freqtrade sends updateLeverage before every entry and every stop, and Guard refuses cross margin
exchange.namehyperliquidFreqtrade exchange notes
exchange.walletAddressyour main account address, 0x + 40 hex digits, not the API wallet’s. Freqtrade passes it to ccxt as walletAddress, the user of its account queriesFreqtrade exchange notes
exchange.privateKeythe Guard client key, 0x + 64 hex digits. Freqtrade passes it to ccxt as privateKey, which signs every request. Freqtrade’s notes say to use an API wallet key here; behind Guard, the client key takes its placeFreqtrade exchange notes
exchange.ccxt_config.urlsGuard’s URL, for api and testFreqtrade configuration reference; ccxt sign(), set_sandbox_mode()
exchange.ccxt_config.optionsbuilderFee: false, refSet: true; never approvedBuilderFee: trueccxt initialize_client(); why: ccxt guide

Freqtrade’s notes also show ccxt_config.options.vaultAddress and subAccountAddress for vaults and sub-accounts. Guard’s support for those is not built.

Guard needs the stop with the entry. Freqtrade sends the entry first and, with stoploss_on_exchange, places its stop after the entry has filled, in a request of its own.

Under Guard’s default rules (stop = "attach" in guard.toml) that works: Guard attaches its own reduce-only market stop to the entry, 2% away (default_stop_distance), and sizes the entry from it. When Freqtrade’s stop-limit arrives, it rests beside Guard’s stop but never replaces it, since a stop-limit may not fill. Freqtrade’s later stop moves (cancel and replace of its own stop-limit) pass. With stop = "refuse", Freqtrade’s entries are refused (no_protective_stop).

So behind Guard a Freqtrade trade is sized from Guard’s stop distance, not from Freqtrade’s stoploss. Set default_stop_distance to the stop you want Guard to size from.

Freqtrade has its own protections (stoploss, max open trades, StoplossGuard and others). Keep them. Guard is the layer that still holds when Freqtrade’s own logic fails or its config is wrong.

Example. A config change sets stake_amount ten times too high. Freqtrade sends an order worth 30,000 on an account of 2,000. Guard sizes it from its stop 2% away: the trade may lose at most 2% of 2,000, so 40, at the stop, costs included (4.5 + 1 basis points per side, 0.11% for the round trip). That allows about 40 / (0.02 + 0.0011) ≈ 1,896 of value, and the trade opens at about that size, less if other positions use the open-risk or leverage room. Freqtrade’s next status shows the smaller filled amount.

In dry_run mode Freqtrade simulates its own orders and sends none, so Guard sees nothing to judge. To see Guard’s decisions without risk, run Freqtrade live against a Guard in paper mode.

The reply uses Hyperliquid’s response format. Check the returned status and order size rather than assuming the requested size was accepted. A refusal includes a readable reason and a veto code; a smaller accepted order reflects the rule that bound its size. Paper mode sends no venue order. Test this path before using testnet.

This page as plain Markdown, for people and LLMs: /docs/integrations/freqtrade.md