added extend symbol change for ws
This commit is contained in:
@@ -3,50 +3,51 @@ from dotenv import load_dotenv
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import urllib
|
||||
from urllib import parse
|
||||
|
||||
from eth_account.messages import encode_typed_data
|
||||
from eth_account import Account
|
||||
from eth_account.datastructures import SignedMessage
|
||||
|
||||
load_dotenv()
|
||||
|
||||
user = os.getenv("RABBY_WALLET")
|
||||
signer = os.getenv("ASTER_API_WALLET_ADDRESS")
|
||||
private_key = os.getenv("ASTER_API_PRIVATE_KEY")
|
||||
USER: str = os.getenv(key="RABBY_WALLET") # ty:ignore[invalid-assignment]
|
||||
SIGNER: str = os.getenv(key="ASTER_API_WALLET_ADDRESS") # ty:ignore[invalid-assignment]
|
||||
PRIVATE_KEY: str = os.getenv(key="ASTER_API_PRIVATE_KEY") # ty:ignore[invalid-assignment]
|
||||
|
||||
_last_ms = 0
|
||||
_i = 0
|
||||
|
||||
async def post_authenticated_url(req: dict) -> dict:
|
||||
typed_data = {
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{"name": "name", "type": "string"},
|
||||
{"name": "version", "type": "string"},
|
||||
{"name": "chainId", "type": "uint256"},
|
||||
{"name": "verifyingContract", "type": "address"}
|
||||
],
|
||||
"Message": [
|
||||
{ "name": "msg", "type": "string" }
|
||||
]
|
||||
},
|
||||
"primaryType": "Message",
|
||||
"domain": {
|
||||
"name": "AsterSignTransaction",
|
||||
"version": "1",
|
||||
"chainId": 1666,
|
||||
"verifyingContract": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"message": {
|
||||
"msg": "$msg"
|
||||
async def post_authenticated_url(req: dict) -> list | dict:
|
||||
typed_data: dict = {
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{"name": "name", "type": "string"},
|
||||
{"name": "version", "type": "string"},
|
||||
{"name": "chainId", "type": "uint256"},
|
||||
{"name": "verifyingContract", "type": "address"}
|
||||
],
|
||||
"Message": [
|
||||
{ "name": "msg", "type": "string" },
|
||||
]
|
||||
},
|
||||
"primaryType": "Message",
|
||||
"domain": {
|
||||
"name": "AsterSignTransaction",
|
||||
"version": "1",
|
||||
"chainId": 1666,
|
||||
"verifyingContract": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"message": {
|
||||
"msg": "$msg"
|
||||
}
|
||||
}
|
||||
}
|
||||
headers = {
|
||||
|
||||
headers: dict[str, str] = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': 'PythonApp/1.0'
|
||||
}
|
||||
host = 'https://fapi.asterdex.com'
|
||||
|
||||
host: str = 'https://fapi.asterdex.com'
|
||||
|
||||
def get_nonce():
|
||||
_nonce_lock = threading.Lock()
|
||||
@@ -71,38 +72,34 @@ async def post_authenticated_url(req: dict) -> dict:
|
||||
)
|
||||
return Account.sign_message(message, private_key=private_key)
|
||||
|
||||
async def send_by_url(req):
|
||||
async def send_by_url(req) -> list | dict: # ty:ignore[invalid-return-type]
|
||||
my_dict = req['params'].copy()
|
||||
url = host + req['url']
|
||||
method = req['method']
|
||||
|
||||
my_dict['nonce'] = str(get_nonce())
|
||||
my_dict['user'] = user
|
||||
my_dict['signer'] = signer
|
||||
my_dict['nonce'] = str(object=get_nonce())
|
||||
my_dict['user'] = USER
|
||||
my_dict['signer'] = SIGNER
|
||||
|
||||
param = urllib.parse.urlencode(my_dict)
|
||||
param: str = parse.urlencode(query=my_dict)
|
||||
|
||||
typed_data['message']['msg'] = param
|
||||
signed = sign_typed_data(typed_data, private_key)
|
||||
signed: SignedMessage = sign_typed_data(data=typed_data, private_key=PRIVATE_KEY)
|
||||
|
||||
full_url = url + '?' + param + '&signature=' + signed.signature.hex()
|
||||
# print(full_url)
|
||||
full_url: str = url + '?' + param + '&signature=' + signed.signature.hex()
|
||||
|
||||
if method == 'GET':
|
||||
res = requests.get(full_url, headers=headers)
|
||||
res: requests.Response = requests.get(url=full_url, headers=headers)
|
||||
# print(res.status_code, res.text)
|
||||
return res.json()
|
||||
elif method == 'POST':
|
||||
res = requests.post(full_url, headers=headers)
|
||||
# print(res.status_code, res.text)
|
||||
res: requests.Response = requests.post(url=full_url, headers=headers)
|
||||
return res.json()
|
||||
elif method == 'PUT':
|
||||
res = requests.put(full_url, headers=headers)
|
||||
# print(res.status_code, res.text)
|
||||
res: requests.Response = requests.put(url=full_url, headers=headers)
|
||||
return res.json()
|
||||
elif method == 'DELETE':
|
||||
res = requests.delete(full_url, headers=headers)
|
||||
# print(res.status_code, res.text)
|
||||
res: requests.Response = requests.delete(url=full_url, headers=headers)
|
||||
return res.json()
|
||||
|
||||
return await send_by_url(req=req)
|
||||
|
||||
38
modules/manual_leverage.py
Normal file
38
modules/manual_leverage.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(kw_only=False)
|
||||
class Asset_Leverage:
|
||||
exchange: str
|
||||
lh_asset: str
|
||||
rh_asset: str
|
||||
max_leverage: int
|
||||
max_notional: float
|
||||
# max_leverage_notional: list = field(default_factory=list)
|
||||
|
||||
### MANUAL LEVERAGE DATA ###
|
||||
LEVERAGE_BY_EXCH: list[Asset_Leverage] = [
|
||||
Asset_Leverage('ASTER', 'ASTER', 'USDT', 75 , 20_000 ), Asset_Leverage('EXTEND', 'ASTER', 'USD', 25, 400_000 ),
|
||||
Asset_Leverage('ASTER', 'AAVE' , 'USDT', 10 , 115_290), Asset_Leverage('EXTEND', 'AAVE' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', '4' , 'USDT', 50 , 5_000 ), Asset_Leverage('EXTEND', '4' , 'USD', 5 , 100_000 ),
|
||||
Asset_Leverage('ASTER', 'BNB' , 'USDT', 100, 10_000 ), Asset_Leverage('EXTEND', 'BNB' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', 'BTC' , 'USDT', 150, 300_000), Asset_Leverage('EXTEND', 'BTC' , 'USD', 50, 4_000_000),
|
||||
Asset_Leverage('ASTER', 'CHIP' , 'USDT', 50 , 5_000 ), Asset_Leverage('EXTEND', 'CHIP' , 'USD', 5 , 100_000 ),
|
||||
Asset_Leverage('ASTER', 'CLU' , 'USDT', 50 , 10_000 ), Asset_Leverage('EXTEND', 'WTI' , 'USD', 5 , 1_000_000),
|
||||
Asset_Leverage('ASTER', 'DOGE' , 'USDT', 75 , 80_000 ), Asset_Leverage('EXTEND', 'DOGE' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', 'ENA' , 'USDT', 25 , 30_473 ), Asset_Leverage('EXTEND', 'ENA' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', 'ETH' , 'USDT', 150, 300_000), Asset_Leverage('EXTEND', 'ETH' , 'USD', 50, 4_000_000),
|
||||
Asset_Leverage('ASTER', 'HYPE' , 'USDT', 300, 1_000 ), Asset_Leverage('EXTEND', 'HYPE' , 'USD', 50, 1_000_000),
|
||||
Asset_Leverage('ASTER', 'INIT' , 'USDT', 50 , 5_000 ), Asset_Leverage('EXTEND', 'INIT' , 'USD', 5 , 100_000 ),
|
||||
Asset_Leverage('ASTER', 'LIT' , 'USDT', 50 , 2_500 ), Asset_Leverage('EXTEND', 'LIT' , 'USD', 25, 400_000 ),
|
||||
Asset_Leverage('ASTER', 'SOL' , 'USDT', 100, 50_000 ), Asset_Leverage('EXTEND', 'SOL' , 'USD', 50, 1_000_000),
|
||||
Asset_Leverage('ASTER', 'SUI' , 'USDT', 75 , 5_416 ), Asset_Leverage('EXTEND', 'SUI' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', 'TRUMP', 'USDT', 50 , 5_567 ), Asset_Leverage('EXTEND', 'TRUMP', 'USD', 25, 400_000 ),
|
||||
Asset_Leverage('ASTER', 'WLFI' , 'USDT', 25 , 104_869), Asset_Leverage('EXTEND', 'WLFI' , 'USD', 10, 250_000 ),
|
||||
Asset_Leverage('ASTER', 'XAG' , 'USDT', 100, 50_000 ), Asset_Leverage('EXTEND', 'XAG' , 'USD', 10, 1_000_000),
|
||||
Asset_Leverage('ASTER', 'XAU' , 'USDT', 75 , 2_500 ), Asset_Leverage('EXTEND', 'XAU' , 'USD', 25, 2_000_000),
|
||||
Asset_Leverage('ASTER', 'XMR' , 'USDT', 50 , 10_000 ), Asset_Leverage('EXTEND', 'XMR' , 'USD', 25, 400_000 ),
|
||||
Asset_Leverage('ASTER', 'XPT' , 'USDT', 3 , 30_000 ), Asset_Leverage('EXTEND', 'XPT' , 'USD', 5 , 1_000_000),
|
||||
Asset_Leverage('ASTER', 'XRP' , 'USDT', 100, 40_000 ), Asset_Leverage('EXTEND', 'XRP' , 'USD', 50, 500_000 ),
|
||||
Asset_Leverage('ASTER', 'ZEC' , 'USDT', 75 , 6_250 ), Asset_Leverage('EXTEND', 'ZEC' , 'USD', 10, 250_000 ),
|
||||
Asset_Leverage('ASTER', 'ZORA' , 'USDT', 5 , 100_000), Asset_Leverage('EXTEND', 'ZORA' , 'USD', 5 , 100_000 ),
|
||||
]
|
||||
@@ -9,9 +9,11 @@ from pydantic import BaseModel
|
||||
class Algo_Config_Overrides(BaseModel):
|
||||
Allow_Ordering_Aster: bool
|
||||
Allow_Ordering_Extend: bool
|
||||
Allow_Symbol_Change: bool
|
||||
Flatten_Open_Positions: bool
|
||||
Flip_Side_For_Testing: bool
|
||||
|
||||
|
||||
# @dataclass(kw_only=True)
|
||||
class Algo_Config_Config(BaseModel):
|
||||
Loop_Sleep_Sec: int
|
||||
@@ -51,8 +53,8 @@ class Valkey_Stream:
|
||||
none_fill: Any = None
|
||||
|
||||
async def update(self):
|
||||
r = self.client.get(self.channel)
|
||||
self.data = json.loads(r) if r is not None else self.none_fill
|
||||
r: str = self.client.get(name=self.channel) # ty:ignore[invalid-assignment]
|
||||
self.data = json.loads(s=r) if r is not None else self.none_fill
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
@@ -162,40 +164,40 @@ class Perpetual_Exchange:
|
||||
rh_asset: str
|
||||
symbol_asset_separator: str = ''
|
||||
|
||||
async def update(self):
|
||||
await self.Collateral_Updates.update()
|
||||
await self.Order_Updates.update()
|
||||
await self.Position_Updates.update()
|
||||
await self.Funding_Rate.update()
|
||||
# async def update(self):
|
||||
# await self.Collateral_Updates.update()
|
||||
# await self.Order_Updates.update()
|
||||
# await self.Position_Updates.update()
|
||||
# await self.Funding_Rate.update()
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.symbol = f'{self.lh_asset.upper()}{self.symbol_asset_separator}{self.rh_asset.upper()}'
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Aster(Perpetual_Exchange):
|
||||
name: str = 'Aster'
|
||||
lh_asset: str = 'ETH'
|
||||
rh_asset: str = 'USDT'
|
||||
# @dataclass(kw_only=True)
|
||||
# class Aster(Perpetual_Exchange):
|
||||
# name: str = 'Aster'
|
||||
# lh_asset: str = 'ETH'
|
||||
# rh_asset: str = 'USDT'
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
self.Order_Updates = Order_Updates(Valkey=Valkey_Stream(channel = 'fr_aster_user_balances', none_fills = []))
|
||||
self.Collateral_Updates = Collateral(Valkey=Valkey_Stream(channel = 'fr_aster_user_orders', none_fills = []))
|
||||
self.Position_Updates = Open_Positions(Valkey=Valkey_Stream(channel = 'fr_aster_user_positions', none_fills = []))
|
||||
self.Funding_Rate - Funding_Rate(Valkey=Valkey_Stream(channel = 'fund_rate_aster', none_fills = None))
|
||||
# def __post_init__(self):
|
||||
# super().__post_init__()
|
||||
# self.Order_Updates = Order_Updates(Valkey=Valkey_Stream(channel = 'fr_aster_user_balances', none_fills = []))
|
||||
# self.Collateral_Updates = Collateral(Valkey=Valkey_Stream(channel = 'fr_aster_user_orders', none_fills = []))
|
||||
# self.Position_Updates = Open_Positions(Valkey=Valkey_Stream(channel = 'fr_aster_user_positions', none_fills = []))
|
||||
# self.Funding_Rate - Funding_Rate(Valkey=Valkey_Stream(channel = 'fund_rate_aster', none_fills = None))
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Extend(Perpetual_Exchange):
|
||||
name: str = 'Extended'
|
||||
lh_asset: str = 'ETH'
|
||||
rh_asset: str = 'USD'
|
||||
symbol_asset_separator: str = '-'
|
||||
# @dataclass(kw_only=True)
|
||||
# class Extend(Perpetual_Exchange):
|
||||
# name: str = 'Extended'
|
||||
# lh_asset: str = 'ETH'
|
||||
# rh_asset: str = 'USD'
|
||||
# symbol_asset_separator: str = '-'
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
self.Order_Updates = Order_Updates(Valkey=Valkey_Stream(channel = 'fr_aster_user_balances', none_fills = []))
|
||||
self.Collateral_Updates = Collateral(Valkey=Valkey_Stream(channel = 'fr_aster_user_orders', none_fills = []))
|
||||
self.Position_Updates = Open_Positions(Valkey=Valkey_Stream(channel = 'fr_aster_user_positions', none_fills = []))
|
||||
self.Funding_Rate - Funding_Rate(Valkey=Valkey_Stream(channel = 'fund_rate_aster', none_fills = None))
|
||||
# def __post_init__(self):
|
||||
# super().__post_init__()
|
||||
# self.Order_Updates = Order_Updates(Valkey=Valkey_Stream(channel = 'fr_aster_user_balances', none_fills = []))
|
||||
# self.Collateral_Updates = Collateral(Valkey=Valkey_Stream(channel = 'fr_aster_user_orders', none_fills = []))
|
||||
# self.Position_Updates = Open_Positions(Valkey=Valkey_Stream(channel = 'fr_aster_user_positions', none_fills = []))
|
||||
# self.Funding_Rate - Funding_Rate(Valkey=Valkey_Stream(channel = 'fund_rate_aster', none_fills = None))
|
||||
|
||||
@@ -5,7 +5,7 @@ import os
|
||||
|
||||
load_dotenv()
|
||||
|
||||
def upsert_list_of_dicts_by_id(list_of_dicts, new_dict, id='id', seq_check_field: str | None = None):
|
||||
def upsert_list_of_dicts_by_id(list_of_dicts, new_dict, id='id', seq_check_field: str | None = None) -> list[dict]:
|
||||
for index, item in enumerate(list_of_dicts):
|
||||
if item.get(id) == new_dict.get(id):
|
||||
if seq_check_field is not None:
|
||||
@@ -25,4 +25,19 @@ def send_tg_alert(msg: str):
|
||||
url = f'https://api.telegram.org/bot{token}/sendMessage?chat_id={chat_id}'
|
||||
response = requests.post(url, json={'text': str(str(msg)[:250])}, timeout=10)
|
||||
|
||||
return response.json()
|
||||
return response.json()
|
||||
|
||||
def rec_set_dict(orig_dict, new_dict, allow_new_fields: bool = False) -> dict:
|
||||
for k, v in new_dict.items():
|
||||
if isinstance(v, dict):
|
||||
rec_set_dict(orig_dict=orig_dict[k], new_dict=v)
|
||||
else:
|
||||
if allow_new_fields:
|
||||
orig_dict[k] = v
|
||||
else:
|
||||
if orig_dict.get(k, None) is not None:
|
||||
orig_dict[k] = v
|
||||
else:
|
||||
logging.warning(msg=f'rec_set_dict: encountered nonexistent key: "{k}"; skipping')
|
||||
|
||||
return orig_dict
|
||||
Reference in New Issue
Block a user