Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions elfpy/utils/apeworx_integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def get_wallet_from_trade_history(
raise ValueError(
f"events {balance=} and {on_chain_balance=} disagree by more than {tolerance} wei for {address}"
)
logging.debug(" => calculated balance = on_chain = %s", format_utils.format_float_as_string(balance))
logging.debug(" => calculated balance = on_chain = %s", format_utils.format_numeric_string(balance))
# check if there's an outstanding balance
if balance != 0 or on_chain_balance != 0:
if asset_type == "SHORT":
Expand Down Expand Up @@ -930,7 +930,7 @@ def ape_trade(
return None, None
return get_pool_state(txn_receipt=txn_receipt, hyperdrive_contract=hyperdrive_contract), txn_receipt
except TransactionError as err:
formatted_amount = format_utils.format_float_as_string(amount)
formatted_amount = format_utils.format_numeric_string(amount)
pool_info = hyperdrive_contract.getPoolInfo()
pool_config = hyperdrive_contract.getPoolConfig()
logging.error(
Expand Down Expand Up @@ -1005,8 +1005,8 @@ def attempt_txn(
base_fee = getattr(latest, "base_fee")
logging.debug(
"latest block %s has base_fee %s",
format_utils.format_float_as_string(getattr(latest, "number")),
format_utils.format_float_as_string(base_fee / 1e9, min_digits=3),
format_utils.format_numeric_string(getattr(latest, "number")),
format_utils.format_numeric_string(base_fee / 1e9, min_digits=3),
)
kwargs["max_priority_fee_per_gas"] = int(
agent.provider.priority_fee * (1 + priority_fee_multiple * (attempt - 1))
Expand All @@ -1019,11 +1019,11 @@ def attempt_txn(
# kwargs["gas_price"] = kwargs["max_fee_per_gas"]
formatted_items = []
for key, value in kwargs.items():
value = (
format_utils.format_float_as_string(value / 1e9)
if "fee" in key
else format_utils.format_float_as_string(value)
)
if "fee" in key:
value = format_utils.format_numeric_string(value / 1e9)
elif isinstance(value, (FixedPoint, float)):
value = format_utils.format_numeric_string(value)
# Otherwise, do nothing
formatted_items.append(f"{key}={value}")
logging.debug("txn attempt %s of %s with %s", attempt, mult, ", ".join(formatted_items))
serial_txn: TransactionAPI = contract_txn.serialize_transaction(*args, **kwargs)
Expand Down
10 changes: 8 additions & 2 deletions elfpy/utils/format.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""Formatting utilities to aid in human-readable values."""
from __future__ import annotations # types will be strings by default in 3.11

import logging

import numpy as np
from fixedpointmath import FixedPoint


def format_float_as_string(value: float, precision=3, min_digits=0, debug=False):
def format_numeric_string(value: float | FixedPoint, precision=3, min_digits=0, debug=False):
"""
Format a float to a string with a given precision.
This follows the significant figure behavior, irrespective of the number's size.
Expand All @@ -14,6 +17,9 @@ def format_float_as_string(value: float, precision=3, min_digits=0, debug=False)
log_vars = (value, type(value), precision, min_digits)
logging.error(log_str, *log_vars)

if isinstance(value, FixedPoint):
value = float(value)

if np.isinf(value):
return "inf"
if np.isnan(value):
Expand All @@ -26,7 +32,7 @@ def format_float_as_string(value: float, precision=3, min_digits=0, debug=False)
digits = int(np.floor(np.log10(abs(value)))) + 1
except Exception as err: # pylint: disable=broad-except
if debug:
log_str = "Error in format_float_as_string: value=%s(%s), precision=%s, min_digits=%s, \n error=%s"
log_str = "Error in format_numeric_string: value=%s(%s), precision=%s, min_digits=%s, \n error=%s"
log_vars = (value, type(value), precision, min_digits, err)
logging.error(log_str, *log_vars)
return str(value)
Expand Down
2 changes: 1 addition & 1 deletion elfpy/utils/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def log_hyperdrive_crash_report(
"""Failed to execute %s: %s\n Amount: %s\n Agent: %s\n PoolInfo: %s\n PoolConfig: %s\n""",
trade_type,
error,
format_utils.format_float_as_string(amount),
format_utils.format_numeric_string(amount),
agent_address,
formatted_pool_info,
formatted_pool_config,
Expand Down
20 changes: 9 additions & 11 deletions examples/evm_bots.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from elfpy.bots import BotConfig
from elfpy.bots.bot_info import BotInfo
from elfpy.markets.hyperdrive import HyperdriveMarket, HyperdrivePricingModel
from elfpy.utils.format import format_float_as_string
from elfpy.utils.format import format_numeric_string

ape_logger.set_level(logging.ERROR)

Expand Down Expand Up @@ -174,9 +174,7 @@ def create_agent(

# mint base tokens for the agents
if (need_to_mint := (params["budget"].scaled_value - base_instance.balanceOf(agent.contract.address)) / 1e18) > 0:
logging.info(
" agent_%s needs to mint %s Base", agent.contract.address[:8], format_float_as_string(need_to_mint)
)
logging.info(" agent_%s needs to mint %s Base", agent.contract.address[:8], format_numeric_string(need_to_mint))
if bot_config.devnet:
txn_args = agent.contract.address, int(50_000 * 1e18)
ape_utils.attempt_txn(agent.contract, base_instance.mint, *txn_args)
Expand All @@ -188,9 +186,9 @@ def create_agent(
" agent_%s is a %s with budget=%s Eth=%s Base=%s",
bot.index,
bot.name,
format_float_as_string(params["budget"]),
format_float_as_string(agent.contract.balance / 1e18),
format_float_as_string(base_instance.balanceOf(agent.contract.address) / 1e18),
format_numeric_string(params["budget"]),
format_numeric_string(agent.contract.balance / 1e18),
format_numeric_string(base_instance.balanceOf(agent.contract.address) / 1e18),
)
agent.wallet = ape_utils.get_wallet_from_trade_history(
address=agent.contract.address,
Expand Down Expand Up @@ -257,7 +255,7 @@ def set_up_agents(
start_time_ = now()
if trade_history is None:
trade_history = ape_utils.get_trade_history(hyperdrive_contract=hyperdrive_instance)
logging.debug("Getting on-chain trade info took %s seconds", format_float_as_string(now() - start_time_))
logging.debug("Getting on-chain trade info took %s seconds", format_numeric_string(now() - start_time_))
for bot_name in [name for name in bot_config.scratch["bot_names"] if bot_config.scratch[f"num_{name}"] > 0]:
bot_info = bot_config.scratch[bot_name]
bot_info.name = bot_name
Expand Down Expand Up @@ -333,8 +331,8 @@ def do_trade(
logging.info(
"agent_%s has Eth=%s Base=%s",
agent_contract.address[:8],
format_float_as_string(agent_contract.balance / 1e18),
format_float_as_string(base_instance.balanceOf(agent_contract.address) / 1e18),
format_numeric_string(agent_contract.balance / 1e18),
format_numeric_string(base_instance.balanceOf(agent_contract.address) / 1e18),
)
logging.info("\trade %s", trade.action_type.name)
# execute the trade using key-word arguments
Expand Down Expand Up @@ -370,7 +368,7 @@ def log_and_show_block_info(provider: ape.api.ProjectAPI, trade_streak: int, blo
base_fee = getattr(block, "base_fee") / 1e9
logging.info(
"Block number: %s, Block time: %s, Trades without crashing: %s, base_fee: %s",
format_float_as_string(block_number),
format_numeric_string(block_number),
datetime.fromtimestamp(block_timestamp),
trade_streak,
base_fee,
Expand Down
42 changes: 21 additions & 21 deletions tests/utils/test_format_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,53 @@

import numpy as np

from elfpy.utils.format import format_float_as_string
from elfpy.utils.format import format_numeric_string


class TestFormatFloatAsString:
"""Unit tests for format_float_as_string."""
"""Unit tests for format_numeric_string."""

def test_positive_values(self):
"""Test positive values"""
assert format_float_as_string(123.456, precision=7) == "123.4560"
assert format_float_as_string(123.456, precision=6) == "123.456"
assert format_float_as_string(123.456, precision=5) == "123.46"
assert format_float_as_string(123.456, precision=3) == "123"
assert format_float_as_string(0.12345, precision=3) == "0.123"
assert format_float_as_string(1000000, precision=7) == "1,000,000"
assert format_numeric_string(123.456, precision=7) == "123.4560"
assert format_numeric_string(123.456, precision=6) == "123.456"
assert format_numeric_string(123.456, precision=5) == "123.46"
assert format_numeric_string(123.456, precision=3) == "123"
assert format_numeric_string(0.12345, precision=3) == "0.123"
assert format_numeric_string(1000000, precision=7) == "1,000,000"

def test_negative_values(self):
"""Test negative values"""
assert format_float_as_string(-123.456, precision=6) == "-123.456"
assert format_float_as_string(-0.12345, precision=3) == "-0.123"
assert format_float_as_string(-1000000, precision=7) == "-1,000,000"
assert format_numeric_string(-123.456, precision=6) == "-123.456"
assert format_numeric_string(-0.12345, precision=3) == "-0.123"
assert format_numeric_string(-1000000, precision=7) == "-1,000,000"

def test_values_less_than_one(self):
"""Test values less than 1"""
assert format_float_as_string(0.0000123, precision=7) == "0.0000123"
assert format_float_as_string(0.000001, precision=7) == "0.0000010"
assert format_float_as_string(0.0000001, precision=7) == "0.0000001"
assert format_numeric_string(0.0000123, precision=7) == "0.0000123"
assert format_numeric_string(0.000001, precision=7) == "0.0000010"
assert format_numeric_string(0.0000001, precision=7) == "0.0000001"

def test_large_values(self):
"""Test large values"""
assert format_float_as_string(1e12, precision=13) == "1,000,000,000,000"
assert format_float_as_string(1e9, precision=10) == "1,000,000,000"
assert format_float_as_string(1e6, precision=7) == "1,000,000"
assert format_numeric_string(1e12, precision=13) == "1,000,000,000,000"
assert format_numeric_string(1e9, precision=10) == "1,000,000,000"
assert format_numeric_string(1e6, precision=7) == "1,000,000"

def test_zero_value(self):
"""Test zero value"""
assert format_float_as_string(0) == "0"
assert format_numeric_string(0) == "0"

def test_inf_value(self):
"""Test infinity"""
assert format_float_as_string(np.inf) == "inf"
assert format_numeric_string(np.inf) == "inf"

def test_nan_value(self):
"""Test NaN"""
assert format_float_as_string(np.nan) == "nan"
assert format_numeric_string(np.nan) == "nan"

def test_debug_mode(self, caplog):
"""Test debug mode"""
with caplog.at_level(logging.ERROR):
format_float_as_string(123.456, debug=True)
format_numeric_string(123.456, debug=True)
assert "value: 123.456, type: <class 'float'>, precision: 3, min_digits: 0" in caplog.text