-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdex_bot.py
147 lines (120 loc) · 4.41 KB
/
dex_bot.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
Author: Alvosec
Website: https://alvosec.com
Email: info@alvosec.com
Caution: This script is provided for educational purposes only.
Use it at your own risk and exercise caution when trading
with real funds. We advise starting with a small balance
to gain experience with bot trading and understand the risks involved.
"""
import os
import json
import requests
from pyeoskit import eosapi, wallet
from math import pow
import argparse
import configparser
# Load private key and username from config file
config = configparser.ConfigParser()
config.read('config.ini')
PRIVATE_KEY = config.get('credentials', 'private_key')
USERNAME = config.get('credentials', 'username')
# Keep your private key safe and follow our blog at https://alvosec.com/blog
wallet.import_key(USERNAME, PRIVATE_KEY)
eosapi.set_node('https://mainnet-rpc.api.protondex.com')
# Use the username dynamically
permission = {USERNAME: 'active'}
url = "https://mainnet.api.protondex.com/dex/v1/orders/submit"
headers = {"content-type": "application/json", "Accept-Charset": "UTF-8"}
# User can change to other token_contract and symbol
BID_TOKEN_CONTRACT = 'xtokens'
BID_TOKEN_SYMBOL = 'XBTC'
BID_TOKEN_PRECISION = 8
ASK_TOKEN_CONTRACT = 'xmd.token'
ASK_TOKEN_SYMBOL = 'XMD'
ASK_TOKEN_PRECISION = 6
# More about MetalX at https://docs.metalx.com/
MARKET_ID = 2 # Unique ID of market
FILL_TYPE = 1 # IOC (Immediate-Or-Cancel)
parser = argparse.ArgumentParser(description='Buy or sell XMD or XBTC')
parser.add_argument('action', choices=['buy', 'sell'], help='Specify the action (buy or sell) If (buy) is used script will purchase XBTC using XMD. If (sell) is used then XBTC will be sold to XMD.')
parser.add_argument('--panic-sell', action='store_true', help='Flag to perform panic sell')
parser.add_argument('--percentage', type=int, choices=[25, 50, 75, 100], default=100, help='Percentage of total balance to buy/sell (25, 50, 75, 100)')
args = parser.parse_args()
if args.action == 'buy':
ORDER_TYPE = 1
ORDER_SIDE = 1 # Buy (1)
TOKEN_CONTRACT = ASK_TOKEN_CONTRACT
TOKEN_SYMBOL = ASK_TOKEN_SYMBOL
TOKEN_PRECISION = ASK_TOKEN_PRECISION
else:
ORDER_TYPE = 1
ORDER_SIDE = 2 # Sell (2)
TOKEN_CONTRACT = BID_TOKEN_CONTRACT
TOKEN_SYMBOL = BID_TOKEN_SYMBOL
TOKEN_PRECISION = BID_TOKEN_PRECISION
account_balance_url = "https://mainnet.api.protondex.com/dex/v1/account/balances"
balance_response = requests.get(f"{account_balance_url}?account={USERNAME}")
balance_data = balance_response.json()
ORDER_AMOUNT = None
for balance_item in balance_data.get("data", []):
if balance_item.get("currency") == TOKEN_SYMBOL:
ORDER_AMOUNT = int(float(balance_item.get("amount")) * pow(10, TOKEN_PRECISION))
break
if ORDER_AMOUNT is None or ORDER_AMOUNT == 0:
print(f"Error: {TOKEN_SYMBOL} balance not found or insufficient balance.")
exit(1)
percentage_to_use = args.percentage / 100.0
buy_amount = int(ORDER_AMOUNT * percentage_to_use)
if args.panic_sell and args.action == 'sell':
ORDER_AMOUNT = buy_amount
else:
ORDER_AMOUNT = buy_amount
args1 = {
'from': USERNAME,
'to': 'dex',
'quantity': f'{ORDER_AMOUNT / pow(10, TOKEN_PRECISION):.{TOKEN_PRECISION}f} {TOKEN_SYMBOL}',
'memo': ''
}
args2 = {
'market_id': MARKET_ID,
'account': USERNAME,
'order_type': ORDER_TYPE,
'order_side': ORDER_SIDE,
'fill_type': FILL_TYPE,
'bid_symbol': {
'sym': f'{BID_TOKEN_PRECISION},{BID_TOKEN_SYMBOL}',
'contract': BID_TOKEN_CONTRACT
},
'ask_symbol': {
'sym': f'{ASK_TOKEN_PRECISION},{ASK_TOKEN_SYMBOL}',
'contract': ASK_TOKEN_CONTRACT
},
'referrer': '',
'quantity': ORDER_AMOUNT,
'price': 1 if args.action == 'sell' else int(9223372036854775806),
'trigger_price': 0
}
args3 = {
'q_size': 20,
'show_error_msg': 0
}
a1 = [TOKEN_CONTRACT, 'transfer', args1, permission]
a2 = ['dex', 'placeorder', args2, permission]
a3 = ['dex', 'process', args3, permission]
info = eosapi.get_info()
final_tx = eosapi.generate_packed_transaction(
[a1, a2, a3],
60,
info['last_irreversible_block_id'],
info['chain_id']
)
mtx = json.loads(final_tx)
print(f"Quantity: {ORDER_AMOUNT / pow(10, TOKEN_PRECISION):.{TOKEN_PRECISION}f} {TOKEN_SYMBOL}")
payload = {
"serialized_tx_hex": mtx["packed_trx"],
"signatures": mtx["signatures"]
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
print(data)