forked from hummingbot/hummingbot
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathamm_trade_example.py
120 lines (108 loc) · 4.76 KB
/
amm_trade_example.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import asyncio
from hummingbot.client.settings import GatewayConnectionSetting
from hummingbot.core.event.events import TradeType
from hummingbot.core.gateway.gateway_http_client import GatewayHttpClient
from hummingbot.core.utils.async_utils import safe_ensure_future
from hummingbot.strategy.script_strategy_base import Decimal, ScriptStrategyBase
class AmmTradeExample(ScriptStrategyBase):
"""
This example shows how to call the /amm/trade Gateway endpoint to execute a swap transaction
"""
# swap params
connector_chain_network = "uniswap_ethereum_goerli"
trading_pair = {"WETH-DAI"}
side = "SELL"
order_amount = Decimal("0.01")
slippage_buffer = 0.01
markets = {
connector_chain_network: trading_pair
}
on_going_task = False
def on_tick(self):
# only execute once
if not self.on_going_task:
self.on_going_task = True
# wrap async task in safe_ensure_future
safe_ensure_future(self.async_task())
# async task since we are using Gateway
async def async_task(self):
base, quote = list(self.trading_pair)[0].split("-")
connector, chain, network = self.connector_chain_network.split("_")
if (self.side == "BUY"):
trade_type = TradeType.BUY
else:
trade_type = TradeType.SELL
# fetch current price
self.logger().info(f"POST /amm/price [ connector: {connector}, base: {base}, quote: {quote}, amount: {self.order_amount}, side: {self.side} ]")
priceData = await GatewayHttpClient.get_instance().get_price(
chain,
network,
connector,
base,
quote,
self.order_amount,
trade_type
)
self.logger().info(f"Price: {priceData['price']}")
self.logger().info(f"Amount: {priceData['amount']}")
# add slippage buffer to current price
if (self.side == "BUY"):
price = float(priceData['price']) * (1 + self.slippage_buffer)
else:
price = float(priceData['price']) * (1 - self.slippage_buffer)
self.logger().info(f"Swap Limit Price: {price}")
# fetch wallet address and print balances
gateway_connections_conf = GatewayConnectionSetting.load()
if len(gateway_connections_conf) < 1:
self.notify("No existing wallet.\n")
return
wallet = [w for w in gateway_connections_conf if w["chain"] == chain and w["connector"] == connector and w["network"] == network]
address = wallet[0]['wallet_address']
await self.get_balance(chain, network, address, base, quote)
# execute swap
self.logger().info(f"POST /amm/trade [ connector: {connector}, base: {base}, quote: {quote}, amount: {self.order_amount}, side: {self.side}, price: {price} ]")
tradeData = await GatewayHttpClient.get_instance().amm_trade(
chain,
network,
connector,
address,
base,
quote,
trade_type,
self.order_amount,
Decimal(price)
)
# poll for swap result and print resulting balances
await self.poll_transaction(chain, network, tradeData['txHash'])
await self.get_balance(chain, network, address, base, quote)
# fetch and print balance of base and quote tokens
async def get_balance(self, chain, network, address, base, quote):
self.logger().info(f"POST /network/balance [ address: {address}, base: {base}, quote: {quote} ]")
balanceData = await GatewayHttpClient.get_instance().get_balances(
chain,
network,
address,
[base, quote]
)
self.logger().info(f"Balances for {address}: {balanceData['balances']}")
# continuously poll for transaction until confirmed
async def poll_transaction(self, chain, network, txHash):
pending: bool = True
while pending is True:
self.logger().info(f"POST /network/poll [ txHash: {txHash} ]")
pollData = await GatewayHttpClient.get_instance().get_transaction_status(
chain,
network,
txHash
)
transaction_status = pollData.get("txStatus")
if transaction_status == 1:
self.logger().info(f"Trade with transaction hash {txHash} has been executed successfully.")
pending = False
elif transaction_status in [-1, 0, 2]:
self.logger().info(f"Trade is pending confirmation, Transaction hash: {txHash}")
await asyncio.sleep(2)
else:
self.logger().info(f"Unknown txStatus: {transaction_status}")
self.logger().info(f"{pollData}")
pending = False