|
1 | 1 | import argparse |
2 | | - |
| 2 | +from ast import List |
3 | 3 | import example_utils |
4 | | - |
5 | 4 | from hyperliquid.utils import constants |
| 5 | +from hyperliquid.utils.signing import OrderRequest |
6 | 6 |
|
7 | 7 |
|
8 | 8 | def main(): |
9 | 9 | parser = argparse.ArgumentParser(description="basic_tpsl") |
10 | 10 | parser.add_argument("--is_buy", action="store_true") |
11 | 11 | args = parser.parse_args() |
12 | 12 |
|
13 | | - address, info, exchange = example_utils.setup(constants.TESTNET_API_URL, skip_ws=True) |
14 | | - |
15 | | - is_buy = args.is_buy |
16 | | - # Place an order that should execute by setting the price very aggressively |
17 | | - order_result = exchange.order("ETH", is_buy, 0.02, 2500 if is_buy else 1500, {"limit": {"tif": "Gtc"}}) |
18 | | - print(order_result) |
19 | | - |
20 | | - # Place a stop order |
21 | | - stop_order_type = {"trigger": {"triggerPx": 1600 if is_buy else 2400, "isMarket": True, "tpsl": "sl"}} |
22 | | - stop_result = exchange.order("ETH", not is_buy, 0.02, 1500 if is_buy else 2500, stop_order_type, reduce_only=True) |
23 | | - print(stop_result) |
24 | | - |
25 | | - # Cancel the order |
26 | | - if stop_result["status"] == "ok": |
27 | | - status = stop_result["response"]["data"]["statuses"][0] |
28 | | - if "resting" in status: |
29 | | - cancel_result = exchange.cancel("ETH", status["resting"]["oid"]) |
30 | | - print(cancel_result) |
31 | | - |
32 | | - # Place a tp order |
33 | | - tp_order_type = {"trigger": {"triggerPx": 1600 if is_buy else 2400, "isMarket": True, "tpsl": "tp"}} |
34 | | - tp_result = exchange.order("ETH", not is_buy, 0.02, 2500 if is_buy else 1500, tp_order_type, reduce_only=True) |
35 | | - print(tp_result) |
36 | | - |
37 | | - # Cancel the order |
38 | | - if tp_result["status"] == "ok": |
39 | | - status = tp_result["response"]["data"]["statuses"][0] |
40 | | - if "resting" in status: |
41 | | - cancel_result = exchange.cancel("ETH", status["resting"]["oid"]) |
42 | | - print(cancel_result) |
| 13 | + address, info, exchange = example_utils.setup(constants.MAINNET_API_URL, skip_ws=True) |
| 14 | + |
| 15 | + market = "SOL" |
| 16 | + position_is_long = args.is_buy |
| 17 | + quantity = 1 |
| 18 | + px = 184.80 |
| 19 | + tp = px * 1.05 # take profit at +4% |
| 20 | + sl = px * 0.95 # stop loss at -4% |
| 21 | + |
| 22 | + orders: List[OrderRequest] = [ |
| 23 | + { |
| 24 | + "coin": market, |
| 25 | + "is_buy": position_is_long, |
| 26 | + "sz": quantity, |
| 27 | + "limit_px": px, |
| 28 | + # "order_type": {"limit": {"tif": "Gtc"}}, |
| 29 | + "order_type": {"limit": {"tif": "Ioc"}}, |
| 30 | + "reduce_only": False, |
| 31 | + }, |
| 32 | + { |
| 33 | + "coin": market, |
| 34 | + "is_buy": not position_is_long, |
| 35 | + "sz": quantity, |
| 36 | + "limit_px": tp, |
| 37 | + "order_type": { |
| 38 | + "trigger": { |
| 39 | + "isMarket": True, |
| 40 | + "triggerPx": tp, |
| 41 | + "tpsl": "tp", |
| 42 | + } |
| 43 | + }, |
| 44 | + "reduce_only": True, |
| 45 | + }, |
| 46 | + { |
| 47 | + "coin": market, |
| 48 | + "is_buy": not position_is_long, |
| 49 | + "sz": quantity, |
| 50 | + "limit_px": sl, |
| 51 | + "order_type": { |
| 52 | + "trigger": { |
| 53 | + "isMarket": True, |
| 54 | + "triggerPx": sl, |
| 55 | + "tpsl": "sl", |
| 56 | + } |
| 57 | + }, |
| 58 | + "reduce_only": True, |
| 59 | + }, |
| 60 | + ] |
| 61 | + resp = exchange.bulk_orders(orders, grouping="normalTpsl") |
| 62 | + |
| 63 | + if resp["status"] == "ok": |
| 64 | + for status in resp["response"]["data"]["statuses"]: |
| 65 | + try: |
| 66 | + filled = status["filled"] |
| 67 | + print(f"{position_is_long} Order #{filled["oid"]} filled {filled["totalSz"]} @{filled["avgPx"]}") |
| 68 | + except KeyError: |
| 69 | + print(f'Error: {status["error"]}') |
43 | 70 |
|
44 | 71 |
|
45 | 72 | if __name__ == "__main__": |
|
0 commit comments