algo logic 1
This commit is contained in:
6839
aster.ipynb
6839
aster.ipynb
File diff suppressed because it is too large
Load Diff
63
main.py
63
main.py
@@ -9,7 +9,7 @@ from dataclasses import asdict, dataclass
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import AsyncContextManager
|
from typing import AsyncContextManager
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from decimal import Decimal, ROUND_DOWN
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import requests
|
import requests
|
||||||
@@ -48,19 +48,27 @@ ASTER_MIN_ORDER_QTY = 0.001
|
|||||||
EXTEND_MIN_ORDER_QTY = 0.01
|
EXTEND_MIN_ORDER_QTY = 0.01
|
||||||
|
|
||||||
ASTER_AVAIL_COLLATERAL = 0
|
ASTER_AVAIL_COLLATERAL = 0
|
||||||
ASTER_NOTIONAL_POSITION = 0
|
|
||||||
EXTEND_AVAIL_COLLATERAL = 0
|
EXTEND_AVAIL_COLLATERAL = 0
|
||||||
EXTEND_NOTIONAL_POSITION = 0
|
|
||||||
|
|
||||||
ASTER_OPEN_POSITIONS = []
|
ASTER_NOTIONAL_POSITION = 0
|
||||||
EXTEND_OPEN_POSITIONS = []
|
EXTEND_NOTIONAL_POSITION = 0
|
||||||
|
|
||||||
ASTER_OPEN_ORDERS = []
|
ASTER_OPEN_ORDERS = []
|
||||||
EXTEND_OPEN_ORDERS = []
|
EXTEND_OPEN_ORDERS = []
|
||||||
|
|
||||||
|
# ASTER_OPEN_POSITIONS = []
|
||||||
|
# EXTEND_OPEN_POSITIONS = []
|
||||||
|
|
||||||
### FLAGS ###
|
### FLAGS ###
|
||||||
LIQUIDATE_POS_AND_KILL_ALGO_FLAG: bool = False
|
LIQUIDATE_POS_AND_KILL_ALGO_FLAG: bool = False
|
||||||
|
NET_FUNDING_IS_ZERO: bool = False
|
||||||
|
|
||||||
|
### UTILS ###
|
||||||
|
def round_decimal_down(value, decimal_places):
|
||||||
|
# Construct precision string like '0.01' for 2 places
|
||||||
|
fmt = f'0.{"0" * decimal_places}' if decimal_places > 0 else '0'
|
||||||
|
precision = Decimal(fmt)
|
||||||
|
return Decimal(str(value)).quantize(precision, rounding=ROUND_DOWN)
|
||||||
|
|
||||||
### OPEN ORDERS ###
|
### OPEN ORDERS ###
|
||||||
async def get_aster_open_orders():
|
async def get_aster_open_orders():
|
||||||
@@ -146,6 +154,11 @@ async def get_extend_exch_info():
|
|||||||
EXTEND_MIN_ORDER_QTY = float(r['ETH-USD'].trading_config.min_order_size)
|
EXTEND_MIN_ORDER_QTY = float(r['ETH-USD'].trading_config.min_order_size)
|
||||||
|
|
||||||
|
|
||||||
|
### CANCEL ORDERS ###
|
||||||
|
async def aster_cancel_all_orders():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ROUTES ###
|
### ROUTES ###
|
||||||
async def aster_remainder_route():
|
async def aster_remainder_route():
|
||||||
# Check open orders...cancel replace or new order?
|
# Check open orders...cancel replace or new order?
|
||||||
@@ -186,7 +199,10 @@ async def run_algo():
|
|||||||
ASTER_PAYOUT_DIRECTION_STR = 'LONG PAYS SHORT' if ASTER_FUND_RATE > 0 else 'SHORT PAYS LONG'
|
ASTER_PAYOUT_DIRECTION_STR = 'LONG PAYS SHORT' if ASTER_FUND_RATE > 0 else 'SHORT PAYS LONG'
|
||||||
EXTEND_PAYOUT_DIRECTION_STR = 'LONG PAYS SHORT' if EXTEND_FUND_RATE > 0 else 'SHORT PAYS LONG'
|
EXTEND_PAYOUT_DIRECTION_STR = 'LONG PAYS SHORT' if EXTEND_FUND_RATE > 0 else 'SHORT PAYS LONG'
|
||||||
|
|
||||||
FUNDINGS_AT_SAME_TIME_NEXT_HR = ( (ASTER_FUND_RATE_TIME < 60*60*1000) and (EXTEND_FUND_RATE < 60*60*1000) )
|
min_between_fundings = round((abs(ASTER_FUND_RATE_TIME - EXTEND_FUND_RATE_TIME) / 1000 / 60))
|
||||||
|
FUNDINGS_AT_SAME_TIME_NEXT_HR = min_between_fundings < 5
|
||||||
|
# FUNDINGS_AT_SAME_TIME_NEXT_HR = ( (ASTER_FUND_RATE_TIME < 60*60*1000) and (EXTEND_FUND_RATE < 60*60*1000) )
|
||||||
|
|
||||||
|
|
||||||
if ( abs(ASTER_FUND_RATE) > abs(EXTEND_FUND_RATE) ) and FUNDINGS_AT_SAME_TIME_NEXT_HR:
|
if ( abs(ASTER_FUND_RATE) > abs(EXTEND_FUND_RATE) ) and FUNDINGS_AT_SAME_TIME_NEXT_HR:
|
||||||
ALPHA_EXCH = 'ASTER'
|
ALPHA_EXCH = 'ASTER'
|
||||||
@@ -210,19 +226,36 @@ async def run_algo():
|
|||||||
return EXTEND_FUND_RATE
|
return EXTEND_FUND_RATE
|
||||||
|
|
||||||
NEXT_NET_FUNDING_RATE = calc_next_net_fund_rate(FUNDINGS_AT_SAME_TIME_NEXT_HR)
|
NEXT_NET_FUNDING_RATE = calc_next_net_fund_rate(FUNDINGS_AT_SAME_TIME_NEXT_HR)
|
||||||
|
NET_FUNDING_IS_ZERO = NEXT_NET_FUNDING_RATE == 0.00
|
||||||
|
|
||||||
if ALPHA_EXCH == 'EXTEND':
|
if ALPHA_EXCH == 'EXTEND':
|
||||||
ASTER_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL*-1
|
ASTER_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL*-1
|
||||||
EXTEND_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL
|
EXTEND_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL
|
||||||
|
if ALPHA_CARRY_SIDE == 'BUY':
|
||||||
|
ASTER_TOB_PX = float(ASTER_TICKER_DICT['best_ask_px'])
|
||||||
|
EXTEND_TOB_PX = float(EXTENDED_TICKER_DICT['best_bid_px'])
|
||||||
|
else:
|
||||||
|
ASTER_TOB_PX = float(ASTER_TICKER_DICT['best_bid_px'])
|
||||||
|
EXTEND_TOB_PX = float(EXTENDED_TICKER_DICT['best_ask_px'])
|
||||||
else:
|
else:
|
||||||
ASTER_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL
|
ASTER_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL
|
||||||
EXTEND_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL*-1
|
EXTEND_TGT_NOTIONAL = ALPHA_TGT_NOTIONAL*-1
|
||||||
|
if ALPHA_CARRY_SIDE == 'BUY':
|
||||||
|
ASTER_TOB_PX = float(ASTER_TICKER_DICT['best_bid_px'])
|
||||||
|
EXTEND_TOB_PX = float(EXTENDED_TICKER_DICT['best_ask_px'])
|
||||||
|
else:
|
||||||
|
ASTER_TOB_PX = float(ASTER_TICKER_DICT['best_ask_px'])
|
||||||
|
EXTEND_TOB_PX = float(EXTENDED_TICKER_DICT['best_bid_px'])
|
||||||
|
|
||||||
|
|
||||||
ASTER_TGT_TAIL = ASTER_TGT_NOTIONAL - ASTER_NOTIONAL_POSITION
|
ASTER_TGT_TAIL = ASTER_TGT_NOTIONAL - ASTER_NOTIONAL_POSITION
|
||||||
EXTEND_TGT_TAIL = EXTEND_TGT_NOTIONAL - EXTEND_NOTIONAL_POSITION
|
EXTEND_TGT_TAIL = EXTEND_TGT_NOTIONAL - EXTEND_NOTIONAL_POSITION
|
||||||
|
|
||||||
ASTER_TGT_TAIL_ORDERABLE = abs(ASTER_TGT_TAIL) >= ASTER_MIN_ORDER_QTY
|
ASTER_TGT_TAIL_BASE_QTY = Decimal(str(ASTER_TGT_TAIL / ASTER_TOB_PX)).quantize(Decimal(str(0.001)), rounding=ROUND_DOWN)
|
||||||
EXTEND_TGT_TAIL_ORDERABLE = abs(EXTEND_TGT_TAIL) >= EXTEND_MIN_ORDER_QTY
|
EXTEND_TGT_TAIL_BASE_QTY = Decimal(str(EXTEND_TGT_TAIL / EXTEND_TOB_PX)).quantize(Decimal(str(0.001)), rounding=ROUND_DOWN)
|
||||||
|
|
||||||
|
ASTER_TGT_TAIL_ORDERABLE = abs(ASTER_TGT_TAIL_BASE_QTY) >= ASTER_MIN_ORDER_QTY
|
||||||
|
EXTEND_TGT_TAIL_ORDERABLE = abs(EXTEND_TGT_TAIL_BASE_QTY) >= EXTEND_MIN_ORDER_QTY
|
||||||
|
|
||||||
print(f'''
|
print(f'''
|
||||||
{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()):})
|
{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()):})
|
||||||
@@ -231,14 +264,14 @@ async def run_algo():
|
|||||||
ASTER: [ Available Collateral: {ASTER_AVAIL_COLLATERAL:.4f} ] | EXTEND: [ Available Collateral: {EXTEND_AVAIL_COLLATERAL:.4f} ]
|
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} ]
|
ASTER: [ Notional Position $ : {ASTER_NOTIONAL_POSITION:.4f} ] | EXTEND: [ Notional Position $ : {EXTEND_NOTIONAL_POSITION:.4f} ]
|
||||||
|
|
||||||
SAME TIME? : {FUNDINGS_AT_SAME_TIME_NEXT_HR}
|
SAME TIME? : {FUNDINGS_AT_SAME_TIME_NEXT_HR} [ Minutes Between Fundings: {min_between_fundings} ]
|
||||||
NET FUNDING : {NEXT_NET_FUNDING_RATE:.6%} [{NEXT_NET_FUNDING_RATE*10_000:.2f}bps] [{NEXT_NET_FUNDING_RATE*1_000_000:.0f}pips]
|
NET FUNDING : {NEXT_NET_FUNDING_RATE:.6%} [{NEXT_NET_FUNDING_RATE*10_000:.2f}bps] [{NEXT_NET_FUNDING_RATE*1_000_000:.0f}pips]; Is Zero?: {NET_FUNDING_IS_ZERO}
|
||||||
ALPHA SIDE : {ALPHA_EXCH} [{ALPHA_CARRY_SIDE}]
|
ALPHA SIDE : {ALPHA_EXCH} [{ALPHA_CARRY_SIDE}]
|
||||||
|
|
||||||
TGT NOTIONAL: $ {MAX_TARGET_NOTIONAL}
|
TGT NOTIONAL: $ {MAX_TARGET_NOTIONAL}
|
||||||
|
|
||||||
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} ]
|
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} ]
|
||||||
ASTER: {ASTER_TGT_TAIL:.4f} > {ASTER_MIN_ORDER_QTY:.4f} min [ Order: {ASTER_TGT_TAIL_ORDERABLE} ] | EXTEND: {EXTEND_TGT_TAIL:.4f} > {EXTEND_MIN_ORDER_QTY:.4f} min [ Order: {EXTEND_TGT_TAIL_ORDERABLE} ]
|
ASTER: {ASTER_TGT_TAIL_BASE_QTY:.4f} > {ASTER_MIN_ORDER_QTY:.4f} min [ Order: {ASTER_TGT_TAIL_ORDERABLE} ] | EXTEND: {EXTEND_TGT_TAIL_BASE_QTY:.4f} > {EXTEND_MIN_ORDER_QTY:.4f} min [ Order: {EXTEND_TGT_TAIL_ORDERABLE} ]
|
||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
@@ -250,13 +283,19 @@ async def run_algo():
|
|||||||
|
|
||||||
|
|
||||||
### ROUTES ###
|
### ROUTES ###
|
||||||
|
if NET_FUNDING_IS_ZERO:
|
||||||
|
logging.info('NET FUNDING = 0.00; Cancelling Open Order and Flattening Open Positions; Wait Until Non-Zero.')
|
||||||
|
### ZERO NET FUNDING - CXL OPEN ORDERS, CLOSE POSITIONS, and WAIT
|
||||||
|
else:
|
||||||
if ASTER_TGT_TAIL_ORDERABLE:
|
if ASTER_TGT_TAIL_ORDERABLE:
|
||||||
await aster_remainder_route()
|
await aster_remainder_route()
|
||||||
|
elif not(ASTER_TGT_TAIL_ORDERABLE) and ASTER_OPEN_ORDERS:
|
||||||
|
logging.info('ASTER HAS NO TAIL BUT OPEN ORDERS - CANCELLING OPEN ORDERS')
|
||||||
|
|
||||||
|
pass
|
||||||
if EXTEND_TGT_TAIL_ORDERABLE:
|
if EXTEND_TGT_TAIL_ORDERABLE:
|
||||||
await extend_remainder_route()
|
await extend_remainder_route()
|
||||||
|
|
||||||
|
|
||||||
print(f'__________ End ___________ (Algo Engine ms: {(time.time() - loop_start)*1000})')
|
print(f'__________ End ___________ (Algo Engine ms: {(time.time() - loop_start)*1000})')
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user