Skip to content

Commit

Permalink
Greedily attempt rebalancing strategies, increasing likelihood and pr…
Browse files Browse the repository at this point in the history
…ofitability of rebalancing.
  • Loading branch information
dowlandaiello committed Aug 18, 2024
1 parent efbbca6 commit 374b119
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 155 deletions.
108 changes: 50 additions & 58 deletions src/strategies/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,75 +499,67 @@ async def eval_sell_denom(denom: str, sell_denom: str, balance: int) -> None:

logger.info("Rebalancing %d %s", balance, denom)

route_ent_route = await anext(
listen_routes_with_depth_dfs(
ctx.cli_args["hops"],
denom,
sell_denom,
set(),
pools,
auctions,
ctx,
async for route_ent, route in listen_routes_with_depth_dfs(
ctx.cli_args["hops"],
denom,
sell_denom,
set(),
pools,
auctions,
ctx,
):
# For logging
_, execution_plan = await quantities_for_route_profit(
balance, route, route_ent, ctx, seek_profit=False
)
)

if not route_ent_route:
logger.info("No route to rebalance %s; skipping", denom)
# The execution plan was aborted
if len(execution_plan) <= len(route):
ctx.log_route(
route_ent,
"info",
"Insufficient execution planning for rebalancing for %s; skipping",
[denom],
)

return
continue

route_ent, route = route_ent_route
# Check that the execution plan results in a liquidatable quantity
if execution_plan[-1] < ctx.cli_args["rebalance_threshold"]:
ctx.log_route(
route_ent,
"info",
"Not enough funds for rebalancing %s; trying a different execution plan",
[denom],
)

# For logging
_, execution_plan = await quantities_for_route_profit(
balance, route, route_ent, ctx, seek_profit=False
)
continue

# The execution plan was aborted
if len(execution_plan) <= len(route):
ctx.log_route(
route_ent,
"info",
"Insufficient execution planning for rebalancing for %s; skipping",
[denom],
route_ent, "info", "Executing rebalancing plan for %s", [denom]
)

return

# Check that the execution plan results in a liquidatable quantity
if execution_plan[-1] < ctx.cli_args["rebalance_threshold"]:
ctx.log_route(
route_ent,
"info",
"Not enough funds for rebalancing %s; skipping",
[denom],
)
# Execute the plan
route_ent.quantities = execution_plan
ctx.update_route(route_ent)

return
try:
await exec_arb(route_ent, 0, execution_plan, route, ctx)

ctx.log_route(
route_ent, "info", "Executing rebalancing plan for %s", [denom]
)

# Execute the plan
route_ent.quantities = execution_plan
ctx.update_route(route_ent)

try:
await exec_arb(route_ent, 0, execution_plan, route, ctx)
except Exception:
ctx.log_route(
route_ent,
"error",
"Arb failed - rebalancing of %s failed: %s",
[
denom,
traceback.format_exc().replace(
"\n",
f"\n{route_ent.uid}- Arb failed - failed to rebalance funds: ",
),
],
)
break
except Exception:
ctx.log_route(
route_ent,
"error",
"Arb failed - rebalancing of %s failed: %s",
[
denom,
traceback.format_exc().replace(
"\n",
f"\n{route_ent.uid}- Arb failed - failed to rebalance funds: ",
),
],
)

await asyncio.gather(
*[
Expand Down
97 changes: 0 additions & 97 deletions tests/test_strategy_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,100 +105,3 @@ def test_build_atomic_arb() -> None:
collapsed_atomic[0],
LocalWallet.from_mnemonic(TEST_WALLET_MNEMONIC, prefix="neutron"),
)


@pytest.mark.asyncio
async def test_transfer_raw() -> None:
"""
Transfers a tiny amount of USDC to osmosis.
"""

net_config = None

with open("net_conf.json", "r", encoding="utf-8") as nf:
net_config = json.load(nf)

wallet = LocalWallet.from_mnemonic(TEST_WALLET_MNEMONIC, prefix="neutron")

async with aiohttp.ClientSession(
connector=aiohttp.TCPConnector(force_close=True, limit_per_host=1),
timeout=aiohttp.ClientTimeout(total=30),
) as session:
ctx: Ctx[Any] = Ctx(
{
chain_id: [
LedgerClient(
custom_neutron_network_config(endpoint, chain_id=chain_id)
)
for endpoint in endpoints["grpc"]
]
for chain_id, endpoints in net_config.items()
},
net_config,
wallet,
{},
None,
False,
session,
[],
{},
{},
)

denom_infos_on_dest = await denom_info_on_chain(
"neutron-1",
"ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81",
"osmosis-1",
session,
)

if not denom_infos_on_dest:
raise ValueError("Missing denom info for transfer (neutron-1) -> osmosis-1")

ibc_route = await denom_route(
"neutron-1",
"ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81",
"osmosis-1",
denom_infos_on_dest[0].denom,
session,
)

if not ibc_route or len(ibc_route) == 0:
raise ValueError("No route")

src_channel_id = ibc_route[0].channel
sender_addr = str(
Address(wallet.public_key(), prefix=ibc_route[0].from_chain.bech32_prefix)
)
receiver_addr = str(
Address(wallet.public_key(), prefix=ibc_route[0].to_chain.bech32_prefix)
)

memo: Optional[str] = None

for ibc_leg in reversed(ibc_route[1:]):
memo = json.dumps(
{
"forward": {
"receiver": "pfm",
"port": ibc_leg.port,
"channel": ibc_leg.channel,
"timeout": "10m",
"retries": 2,
"next": memo,
}
}
)

await transfer_raw(
"ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81",
ibc_route[0].from_chain.chain_id,
"untrn",
src_channel_id,
ibc_route[0].to_chain.chain_id,
sender_addr,
receiver_addr,
ctx,
1,
memo=memo,
)

0 comments on commit 374b119

Please sign in to comment.