bug fixes
This commit is contained in:
76
main.py
76
main.py
@@ -38,6 +38,7 @@ LOG_FILEPATH: str = os.getenv("LOGS_PATH") + '/Fund_Rate_Algo.log'
|
||||
|
||||
### Algo Config ###
|
||||
ALGO_CONFIG: structs.Algo_Config = None
|
||||
MIN_TIME_TO_FUNDING: int
|
||||
|
||||
### CONSTANTS ###
|
||||
ASTER = structs.Perpetual_Exchange(
|
||||
@@ -64,6 +65,12 @@ EXTEND_AVAIL_COLLATERAL = 0
|
||||
ASTER_NOTIONAL_POSITION = 0
|
||||
EXTEND_NOTIONAL_POSITION = 0
|
||||
|
||||
ASTER_NOTIONAL_OBJ: dict | None = None
|
||||
EXTEND_NOTIONAL_OBJ: dict | None = None
|
||||
|
||||
ASTER_UNREALIZED_PNL = 0
|
||||
EXTEND_UNREALIZED_PNL = 0
|
||||
|
||||
ASTER_OPEN_ORDERS = []
|
||||
EXTEND_OPEN_ORDERS = []
|
||||
|
||||
@@ -111,9 +118,13 @@ async def get_aster_collateral():
|
||||
ASTER_AVAIL_COLLATERAL = float([d for d in r if d.get('asset')==ASTER.rh_asset][0].get('availableBalance'))
|
||||
|
||||
async def get_aster_notional_position(resp: dict | None = None):
|
||||
global ASTER_NOTIONAL_OBJ
|
||||
global ASTER_NOTIONAL_POSITION
|
||||
global ASTER_UNREALIZED_PNL
|
||||
global ASTER_MULT
|
||||
|
||||
previous_notional_obj = ASTER_NOTIONAL_OBJ
|
||||
|
||||
if not resp:
|
||||
fut_acct_positionRisk = {
|
||||
"url": "/fapi/v3/positionRisk",
|
||||
@@ -123,29 +134,38 @@ async def get_aster_notional_position(resp: dict | None = None):
|
||||
}
|
||||
}
|
||||
resp = await aster_auth.post_authenticated_url(fut_acct_positionRisk)
|
||||
d = [x for x in resp if x.get('symbol', None) == ASTER.symbol][0]
|
||||
d['timestamp_arrival'] = round(datetime.now().timestamp()*1000)
|
||||
else:
|
||||
d = [x for x in resp if x.get('symbol', None) == ASTER.symbol][0]
|
||||
|
||||
if previous_notional_obj is not None:
|
||||
if previous_notional_obj['timestamp_arrival'] > d['timestamp_arrival']:
|
||||
# logging.info(f'ASTER NOTIONAL: prev timestamp ({pd.to_datetime(previous_notional_obj['timestamp_arrival'], unit='ms')}) > new timestamp ({pd.to_datetime(d['timestamp_arrival'], unit='ms')}); skipping')
|
||||
return
|
||||
|
||||
d = [x for x in resp if x.get('symbol', None) == ASTER.symbol][0]
|
||||
ASTER_NOTIONAL_OBJ = d
|
||||
|
||||
if len(d) < 1:
|
||||
logging.info(f'BAD NOTIONAL - ASTER CHANGE: Empty d: {d}; resp: {resp}')
|
||||
await kill_algo()
|
||||
|
||||
aster_unrealized_pnl = float(d['unrealized_pnl']) if d.get('unrealized_pnl') is not None else float(d['unRealizedProfit'])
|
||||
ASTER_UNREALIZED_PNL = float(d['unrealized_pnl']) if d.get('unrealized_pnl') is not None else float(d['unRealizedProfit'])
|
||||
|
||||
if d.get('notional') is not None:
|
||||
notional = float(d['notional'])
|
||||
ASTER_NOTIONAL_POSITION = float(d['notional']) - ASTER_UNREALIZED_PNL
|
||||
else:
|
||||
notional = float(d['position_amount'])*float(d['entry_price'])
|
||||
ASTER_NOTIONAL_POSITION = float(d['position_amount'])*float(d['entry_price'])
|
||||
|
||||
previous_notional_position = ASTER_NOTIONAL_POSITION
|
||||
ASTER_NOTIONAL_POSITION = notional - aster_unrealized_pnl
|
||||
if not resp:
|
||||
ASTER_MULT = float(d['leverage'])
|
||||
if abs(ASTER_NOTIONAL_POSITION) > ALGO_CONFIG.Max_Target_Notional*1.01:
|
||||
logging.info(f'BAD NOTIONAL - ASTER CHANGE: {ASTER_NOTIONAL_POSITION}; UR PNL: {aster_unrealized_pnl}; MULT: {ASTER_MULT}; d: {d}; resp: {resp}')
|
||||
# if not resp: # this can never evaluate
|
||||
# ASTER_MULT = float(d['leverage'])
|
||||
# if abs(ASTER_NOTIONAL_POSITION) > ALGO_CONFIG.Max_Target_Notional*1.01:
|
||||
if abs(ASTER_NOTIONAL_POSITION) > ALGO_CONFIG.Max_Target_Notional*2.01:
|
||||
logging.info(f'BAD NOTIONAL - ASTER CHANGE: {previous_notional_position} -> {ASTER_NOTIONAL_POSITION}; UR PNL: {ASTER_UNREALIZED_PNL}; MULT: {ASTER_MULT}; d: {d}; resp: {resp}')
|
||||
await kill_algo()
|
||||
if ASTER_NOTIONAL_POSITION != previous_notional_position:
|
||||
logging.info(f'ASTER NOTIONAL CHANGE: {previous_notional_position} -> {ASTER_NOTIONAL_POSITION:.2f}; UR PNL: {aster_unrealized_pnl:.2f}; MULT: {ASTER_MULT:.0f}; resp: {bool(resp)}')
|
||||
# if ASTER_NOTIONAL_POSITION != previous_notional_position:
|
||||
logging.info(f'ASTER NOTIONAL CHANGE: {previous_notional_position} -> {ASTER_NOTIONAL_POSITION:.2f}; UR PNL: {ASTER_UNREALIZED_PNL:.2f}; MULT: {ASTER_MULT:.0f}; resp: {bool(resp)}')
|
||||
|
||||
async def get_extend_collateral():
|
||||
global EXTEND_AVAIL_COLLATERAL
|
||||
@@ -155,6 +175,7 @@ async def get_extend_collateral():
|
||||
|
||||
async def get_extend_notional(resp: dict | None = None):
|
||||
global EXTEND_NOTIONAL_POSITION
|
||||
global EXTEND_UNREALIZED_PNL
|
||||
global EXTEND_MULT
|
||||
|
||||
if not resp:
|
||||
@@ -166,7 +187,7 @@ async def get_extend_notional(resp: dict | None = None):
|
||||
logging.info('get_extend_notional - No Positions')
|
||||
else:
|
||||
pos_dict = pos_dict[0]
|
||||
unrealized_pnl = pos_dict.get('unrealised_pnl', 0)
|
||||
EXTEND_UNREALIZED_PNL = pos_dict.get('unrealised_pnl', 0)
|
||||
previous_notional_position = EXTEND_NOTIONAL_POSITION
|
||||
position_side = pos_dict['side'] # LONG or SHORT
|
||||
notional_pos_abs = abs(float(pos_dict['value']))
|
||||
@@ -177,10 +198,13 @@ async def get_extend_notional(resp: dict | None = None):
|
||||
else:
|
||||
logging.info(f'EXTEND BAD SIDE ON POSITION UPDATE: {pos_dict}')
|
||||
|
||||
EXTEND_NOTIONAL_POSITION = notional_pos_sided - float(unrealized_pnl)
|
||||
EXTEND_NOTIONAL_POSITION = notional_pos_sided - float(EXTEND_UNREALIZED_PNL)
|
||||
EXTEND_MULT = pos_dict.get('leverage', EXTEND_MULT)
|
||||
if abs(EXTEND_NOTIONAL_POSITION) > ALGO_CONFIG.Max_Target_Notional*2.01:
|
||||
logging.info(f'BAD NOTIONAL - EXTEND CHANGE: {previous_notional_position} -> {EXTEND_NOTIONAL_POSITION}; UR PNL: {EXTEND_UNREALIZED_PNL}; MULT: {EXTEND_MULT}; d: {pos_dict}; resp: {resp}')
|
||||
await kill_algo()
|
||||
if EXTEND_NOTIONAL_POSITION != previous_notional_position:
|
||||
logging.info(f'EXTEND NOTIONAL CHANGE: {previous_notional_position} -> {EXTEND_NOTIONAL_POSITION:.2f}; UR PNL: {unrealized_pnl:.2f}; MULT: {EXTEND_MULT:.0f}; resp: {bool(resp)}')
|
||||
logging.info(f'EXTEND NOTIONAL CHANGE: {previous_notional_position} -> {EXTEND_NOTIONAL_POSITION:.2f}; UR PNL: {EXTEND_UNREALIZED_PNL:.2f}; MULT: {EXTEND_MULT:.0f}; resp: {bool(resp)}')
|
||||
|
||||
### EXCHANGE INFO ###
|
||||
async def get_aster_exch_info():
|
||||
@@ -226,9 +250,11 @@ async def kill_algo():
|
||||
logging.info('ALGO KILL FLAG ACTIVATED; CANCELLING OPEN ORDERS AND SHUTTING DOWN')
|
||||
raise ValueError('KILL FLAG ACTIVATED')
|
||||
|
||||
|
||||
### ALGO LOOP ###
|
||||
async def run_algo():
|
||||
global ALGO_CONFIG
|
||||
global MIN_TIME_TO_FUNDING
|
||||
global ASTER_OPEN_ORDERS
|
||||
global EXTEND_OPEN_ORDERS
|
||||
|
||||
@@ -288,13 +314,15 @@ async def run_algo():
|
||||
now_ms = round(datetime.now().timestamp()*1000)
|
||||
time_to_funding_ms = min([ASTER_FUND_RATE_TIME, EXTEND_FUND_RATE_TIME]) - now_ms
|
||||
if ( time_to_funding_ms > MIN_TIME_TO_FUNDING ) and (not ASTER_OPEN_ORDERS) and (not EXTEND_OPEN_ORDERS):
|
||||
print(f'Outside action window (minutes) and no active order (sleeping for 5 sec): {pd.to_datetime(time_to_funding_ms, unit='ms').minute} > {pd.to_datetime(MIN_TIME_TO_FUNDING, unit='ms').minute}')
|
||||
logging.info(f'Outside action window (minutes) and no active order (sleeping for 5 sec): {pd.to_datetime(time_to_funding_ms, unit='ms').minute} > {pd.to_datetime(MIN_TIME_TO_FUNDING, unit='ms').minute}')
|
||||
time.sleep(5)
|
||||
continue
|
||||
|
||||
if len(ASTER_WS_POS_UPDATES) > 0:
|
||||
# await get_aster_notional_position()
|
||||
await get_aster_notional_position(resp=ASTER_WS_POS_UPDATES)
|
||||
###### *** returned 0 notional even though had a position, need to handle and safety check to not order above max notional.
|
||||
##### NEED TO UPDATE SO IT TAKES THE LATEST MSG, ie drop the WS msg if its older than the exisiting one from the API.
|
||||
|
||||
if len(EXTEND_WS_POS_UPDATES) > 0:
|
||||
await get_extend_notional(resp=EXTEND_WS_POS_UPDATES)
|
||||
@@ -304,7 +332,7 @@ async def run_algo():
|
||||
if ASTER_WS_ORDER_UPDATES is not None:
|
||||
for idx, o in enumerate(ASTER_OPEN_ORDERS):
|
||||
order_id = o.get('order_id') if o.get('order_id') is not None else o['orderId']
|
||||
order_orig_status = o['status'] ### Got a keyerror on this
|
||||
order_orig_status = o.get('status') if o.get('status') is not None else o['order_status']
|
||||
order_update = [ou for ou in ASTER_WS_ORDER_UPDATES if ou.get('order_id', None) == order_id]
|
||||
|
||||
if len(order_update) > 0:
|
||||
@@ -411,8 +439,8 @@ async def run_algo():
|
||||
EXTEND_TOB_PX = float(EXTENDED_TICKER_DICT['best_bid_px'])
|
||||
|
||||
|
||||
ASTER_TGT_TAIL = ASTER_TGT_NOTIONAL - ASTER_NOTIONAL_POSITION
|
||||
EXTEND_TGT_TAIL = EXTEND_TGT_NOTIONAL - EXTEND_NOTIONAL_POSITION
|
||||
ASTER_TGT_TAIL = ASTER_TGT_NOTIONAL - ( float(ASTER_NOTIONAL_POSITION) + float(ASTER_UNREALIZED_PNL) )
|
||||
EXTEND_TGT_TAIL = EXTEND_TGT_NOTIONAL - ( float(EXTEND_NOTIONAL_POSITION) + float(EXTEND_UNREALIZED_PNL) )
|
||||
|
||||
ASTER_TGT_TAIL_BASE_QTY = Decimal(str(float(ASTER_TGT_TAIL) / float(ASTER_TOB_PX))).quantize(Decimal(str(0.001)), rounding=ROUND_DOWN)
|
||||
EXTEND_TGT_TAIL_BASE_QTY = Decimal(str(float(EXTEND_TGT_TAIL) / float(EXTEND_TOB_PX))).quantize(Decimal(str(0.001)), rounding=ROUND_DOWN)
|
||||
@@ -426,9 +454,10 @@ async def run_algo():
|
||||
OUT: print | logging.info = logging.info if use_logging else print
|
||||
|
||||
OUT(f'''
|
||||
LOOP SLEEP (SEC): {ALGO_CONFIG.Loop_Sleep_Sec}
|
||||
FLIP SIDES FOR TESTING?: {ALGO_CONFIG.Flip_Side_For_Testing}
|
||||
{pd.to_datetime(ASTER_FUND_RATE_TIME, unit='ms')} ({(pd.to_datetime(ASTER_FUND_RATE_TIME, unit='ms')-datetime.now()):}) | {pd.to_datetime(EXTEND_FUND_RATE_TIME, unit='ms')} ({(pd.to_datetime(EXTEND_FUND_RATE_TIME, unit='ms')-datetime.now()):})
|
||||
ASTER: {ASTER_FUND_RATE:.6%} [{ASTER_FUND_RATE*10_000:.2f}bps] [{ASTER_FUND_RATE*1_000_000:.0f}pips] | EXTEND: {EXTEND_FUND_RATE:.6%} [{EXTEND_FUND_RATE*10_000:.2f}bps] [{EXTEND_FUND_RATE*1_000_000:.0f}pips]
|
||||
ASTER: {ASTER_FUND_RATE:.6%} [{ASTER_FUND_RATE*10_000:.2f}bps] [{ASTER_FUND_RATE*1_000_000:.0f}pips] | EXTEND: {EXTEND_FUND_RATE:.6%} [{EXTEND_FUND_RATE*10_000:.2f}bps] [{EXTEND_FUND_RATE*1_000_000:.0f}pips]
|
||||
ASTER: {'LONG PAYS SHORT' if ASTER_FUND_RATE > 0 else 'SHORT PAYS LONG'} | EXTEND: {'LONG PAYS SHORT' if EXTEND_FUND_RATE > 0 else 'SHORT PAYS LONG'}
|
||||
ASTER: [ Available Collateral: {ASTER_AVAIL_COLLATERAL:.4f} ] | EXTEND: [ Available Collateral: {EXTEND_AVAIL_COLLATERAL:.4f} ]
|
||||
ASTER: [ Notional Position $ : {ASTER_NOTIONAL_POSITION:.4f} ] | EXTEND: [ Notional Position $ : {EXTEND_NOTIONAL_POSITION:.4f} ]
|
||||
@@ -440,7 +469,7 @@ async def run_algo():
|
||||
TGT NOTIONAL: $ {ALGO_CONFIG.Max_Target_Notional if not Flags.NET_FUNDING_IS_ZERO else 0.00}
|
||||
|
||||
ASTER: {ASTER_NOTIONAL_POSITION:.4f} -> {ASTER_TGT_NOTIONAL:.2f} [ Remain: {ASTER_TGT_TAIL:.4f} ] | EXTEND: {EXTEND_NOTIONAL_POSITION:.4f} -> {EXTEND_TGT_NOTIONAL:.2f} [ Remain: {EXTEND_TGT_TAIL:.4f} ]
|
||||
ASTER: {ASTER_TGT_NOTIONAL:.4f} - {ASTER_NOTIONAL_POSITION:.4f} = Tail: {ASTER_TGT_TAIL:4f} | EXTEND: {EXTEND_TGT_NOTIONAL:.4f} - {EXTEND_NOTIONAL_POSITION:.4f} = Tail: {EXTEND_TGT_TAIL:4f}
|
||||
ASTER: {ASTER_TGT_NOTIONAL:.2f} - {ASTER_NOTIONAL_POSITION:.2f} + {ASTER_UNREALIZED_PNL:.2f} = {ASTER_TGT_TAIL:2f} | EXTEND: {EXTEND_TGT_NOTIONAL:.2f} - {EXTEND_NOTIONAL_POSITION:.2f} + {EXTEND_UNREALIZED_PNL:.2f} = {EXTEND_TGT_TAIL:2f}
|
||||
ASTER: {ASTER_TGT_TAIL_BASE_QTY:.4f} > {MAX_MIN_ORDER_QTY:.4f} min [ Order: {ASTER_TGT_TAIL_ORDERABLE} ] | EXTEND: {EXTEND_TGT_TAIL_BASE_QTY:.4f} > {MAX_MIN_ORDER_QTY:.4f} min [ Order: {EXTEND_TGT_TAIL_ORDERABLE} ]
|
||||
|
||||
--- ASTER OPEN ORDERS ---
|
||||
@@ -449,8 +478,10 @@ async def run_algo():
|
||||
--- EXTEND OPEN ORDERS ---
|
||||
{EXTEND_OPEN_ORDERS}
|
||||
''')
|
||||
if ALGO_CONFIG.Log_Summary_Each_Loop:
|
||||
print_summary(use_logging=True)
|
||||
if ALGO_CONFIG.Print_Summary_Each_Loop:
|
||||
print_summary()
|
||||
print_summary(use_logging=False)
|
||||
# print_summary()
|
||||
|
||||
### ROUTES ###
|
||||
@@ -510,6 +541,7 @@ async def run_algo():
|
||||
order_resp = await aster_auth.post_authenticated_url(post_order)
|
||||
if order_resp.get('orderId', None) is not None:
|
||||
order_resp['original_price'] = price
|
||||
order_resp['order_status'] = order_resp['status']
|
||||
ASTER_OPEN_ORDERS.append(order_resp)
|
||||
utils.send_tg_alert(f'FR_ALGO - ASTER Order. Start_$: {ASTER_NOTIONAL_POSITION:.2f}; Value: {float(ASTER_TGT_TAIL_BASE_QTY)*float(price):.2f}; Price: {float(price):.2f}')
|
||||
logging.info(f'ASTER ORDER PLACED SUCCESS: {order_resp}')
|
||||
@@ -594,7 +626,7 @@ async def run_algo():
|
||||
logging.info('EXTEND HAS NO TAIL BUT OPEN ORDERS - CANCELLING OPEN ORDERS')
|
||||
await extend_cancel_all_orders()
|
||||
|
||||
print(f'__________ End ___________ (Algo Engine ms: {(time.time() - loop_start)*1000})')
|
||||
# print(f'__________ End ___________ (Algo Engine ms: {(time.time() - loop_start)*1000}); Sleeping for sec: {ALGO_CONFIG.Loop_Sleep_Sec}')
|
||||
|
||||
time.sleep(ALGO_CONFIG.Loop_Sleep_Sec)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user