Can now specify a different 'hedging' interval in the marketmaker.
This commit is contained in:
parent
1967a63cc6
commit
0be350a134
|
@ -38,8 +38,10 @@ parser.add_argument("--existing-order-tolerance", type=Decimal, default=Decimal(
|
|||
help="tolerance in price and quantity when matching existing orders or cancelling/replacing")
|
||||
parser.add_argument("--redeem-threshold", type=Decimal,
|
||||
help="threshold above which liquidity incentives will be automatically moved to the account (default: no moving)")
|
||||
parser.add_argument("--pulse-interval", type=int, default=10,
|
||||
parser.add_argument("--pulse-interval", type=float, default=10.0,
|
||||
help="number of seconds between each 'pulse' of the market maker")
|
||||
parser.add_argument("--hedging-pulse-interval", type=float,
|
||||
help="number of seconds between each 'pulse' of the hedger (if hedging configured) - defaults to the --pulse-interval value if not specified")
|
||||
parser.add_argument("--hedging-market", type=str, help="spot market symbol to use for hedging (e.g. ETH/USDC)")
|
||||
parser.add_argument("--hedging-max-price-slippage-factor", type=Decimal, default=Decimal("0.05"),
|
||||
help="the maximum value the IOC hedging order price can slip by when hedging (default is 0.05 for 5%%)")
|
||||
|
@ -164,7 +166,7 @@ mango.InstrumentValue.report([asset for asset in account.net_values if asset is
|
|||
manager.open()
|
||||
|
||||
|
||||
def pulse_action(_: int) -> None:
|
||||
def combined_pulse_action(_: int) -> None:
|
||||
try:
|
||||
context.client.require_data_from_fresh_slot()
|
||||
model_state: mango.ModelState = model_state_builder.build(context)
|
||||
|
@ -174,14 +176,50 @@ def pulse_action(_: int) -> None:
|
|||
logging.error(f"Pulse action failed: {traceback.format_exc()}")
|
||||
|
||||
|
||||
pulse_disposable = rx.interval(args.pulse_interval).pipe(
|
||||
def marketmaking_pulse_action(_: int) -> None:
|
||||
try:
|
||||
context.client.require_data_from_fresh_slot()
|
||||
model_state: mango.ModelState = model_state_builder.build(context)
|
||||
market_maker.pulse(context, model_state)
|
||||
except Exception:
|
||||
logging.error(f"Pulse action failed: {traceback.format_exc()}")
|
||||
|
||||
|
||||
def hedging_pulse_action(_: int) -> None:
|
||||
try:
|
||||
model_state: mango.ModelState = model_state_builder.build(context)
|
||||
hedger.pulse(context, model_state)
|
||||
except Exception:
|
||||
logging.error(f"Pulse action failed: {traceback.format_exc()}")
|
||||
|
||||
|
||||
hedging_pulse_interval: float = args.hedging_pulse_interval or args.pulse_interval
|
||||
separate_hedge_pulse = False
|
||||
if isinstance(hedger, mango.hedging.NullHedger):
|
||||
logging.info(f"Using a pulse action with an interval of {args.pulse_interval} seconds.")
|
||||
pulse_action = marketmaking_pulse_action
|
||||
elif hedging_pulse_interval == args.pulse_interval:
|
||||
logging.info(f"Using a combined pulse action with an interval of {args.pulse_interval} seconds.")
|
||||
pulse_action = combined_pulse_action
|
||||
else:
|
||||
logging.info(
|
||||
f"Using separate pulse actions with a marketmaking interval of {args.pulse_interval} seconds and a hedging interval of {hedging_pulse_interval} seconds.")
|
||||
pulse_action = marketmaking_pulse_action
|
||||
hedging_pulse_disposable = rx.interval(hedging_pulse_interval).pipe(
|
||||
rx.operators.observe_on(context.create_thread_pool_scheduler()),
|
||||
rx.operators.start_with(-1),
|
||||
rx.operators.catch(mango.observable_pipeline_error_reporter),
|
||||
rx.operators.retry()
|
||||
).subscribe(mango.create_backpressure_skipping_observer(on_next=hedging_pulse_action, on_error=mango.log_subscription_error))
|
||||
disposer.add_disposable(hedging_pulse_disposable)
|
||||
|
||||
marketmaking_pulse_disposable = rx.interval(args.pulse_interval).pipe(
|
||||
rx.operators.observe_on(context.create_thread_pool_scheduler()),
|
||||
rx.operators.start_with(-1),
|
||||
rx.operators.catch(mango.observable_pipeline_error_reporter),
|
||||
rx.operators.retry()
|
||||
).subscribe(
|
||||
on_next=pulse_action)
|
||||
disposer.add_disposable(pulse_disposable)
|
||||
).subscribe(mango.create_backpressure_skipping_observer(on_next=pulse_action, on_error=mango.log_subscription_error))
|
||||
disposer.add_disposable(marketmaking_pulse_disposable)
|
||||
|
||||
# Wait - don't exit. Exiting will be handled by signals/interrupts.
|
||||
waiter = threading.Event()
|
||||
|
|
|
@ -56,21 +56,31 @@ class PerpToSpotHedger(Hedger):
|
|||
|
||||
def pulse(self, context: mango.Context, model_state: mango.ModelState) -> None:
|
||||
try:
|
||||
# Latency can be important here so fetch fresh Account data in one gulp.
|
||||
fresh_data: typing.Sequence[mango.AccountInfo] = mango.AccountInfo.load_multiple(
|
||||
context, [model_state.group.address, model_state.group.cache, model_state.account.address])
|
||||
fresh_group: mango.Group = mango.Group.parse_with_context(context, fresh_data[0])
|
||||
fresh_cache: mango.Cache = mango.Cache.parse(fresh_data[1])
|
||||
fresh_account: mango.Account = mango.Account.parse(fresh_data[2], fresh_group, fresh_cache)
|
||||
perp_account: typing.Optional[mango.PerpAccount] = fresh_account.perp_accounts_by_index[self.market_index]
|
||||
perp_account: typing.Optional[mango.PerpAccount] = model_state.account.perp_accounts_by_index[self.market_index]
|
||||
if perp_account is None:
|
||||
raise Exception(
|
||||
f"Could not find perp account at index {self.market_index} in account {fresh_account.address}.")
|
||||
f"Could not find perp account at index {self.market_index} in account {model_state.account.address}.")
|
||||
|
||||
basket_token: typing.Optional[mango.AccountSlot] = fresh_account.slots_by_index[self.market_index]
|
||||
basket_token: typing.Optional[mango.AccountSlot] = model_state.account.slots_by_index[self.market_index]
|
||||
if basket_token is None:
|
||||
raise Exception(
|
||||
f"Could not find basket token at index {self.market_index} in account {fresh_account.address}.")
|
||||
f"Could not find basket token at index {self.market_index} in account {model_state.account.address}.")
|
||||
|
||||
# # Latency can be important here so fetch fresh Account data in one gulp.
|
||||
# fresh_data: typing.Sequence[mango.AccountInfo] = mango.AccountInfo.load_multiple(
|
||||
# context, [model_state.group.address, model_state.group.cache, model_state.account.address])
|
||||
# fresh_group: mango.Group = mango.Group.parse_with_context(context, fresh_data[0])
|
||||
# fresh_cache: mango.Cache = mango.Cache.parse(fresh_data[1])
|
||||
# fresh_account: mango.Account = mango.Account.parse(fresh_data[2], fresh_group, fresh_cache)
|
||||
# perp_account: typing.Optional[mango.PerpAccount] = fresh_account.perp_accounts_by_index[self.market_index]
|
||||
# if perp_account is None:
|
||||
# raise Exception(
|
||||
# f"Could not find perp account at index {self.market_index} in account {fresh_account.address}.")
|
||||
|
||||
# basket_token: typing.Optional[mango.AccountSlot] = fresh_account.slots_by_index[self.market_index]
|
||||
# if basket_token is None:
|
||||
# raise Exception(
|
||||
# f"Could not find basket token at index {self.market_index} in account {fresh_account.address}.")
|
||||
|
||||
token_balance: mango.InstrumentValue = basket_token.net_value
|
||||
perp_position: mango.InstrumentValue = perp_account.base_token_value
|
||||
|
|
Loading…
Reference in New Issue