Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test comparable to combinatorial auction filtering #80

Merged
merged 14 commits into from
Nov 10, 2023

Conversation

fhenneke
Copy link
Contributor

We are thinking about implementing combinatorial auctions. This would include filtering out solutions which do not provide more surplus on individual sell token-buy token pairs compared to solutions only including that token pair.

The test in this PR checks if the winning solution would have been filtered out based on this criterion.

One difference to the competition surplus test is that the test in this PR checks token pairs and not orders.

Potentially we want to check more in this test. E.g.

  • Who would have won the auction with the filtering rule?
  • Who would have won the auction with the option to declare multiple winners?
  • What would the benefit in surplus have been?

Todo

  • Fix relative test to compare price improvement and not surplus improvement.

@fhenneke fhenneke requested a review from harisang October 26, 2023 08:29
@fhenneke
Copy link
Contributor Author

I significantly changed the code to really run a simple combinatorial auction.

This gives slightly different information than previously: Before I logged which orders would have provided more surplus on token pairs and would have resulted in filtering the top solution. Now, I log who would have won the combinatorial auction and how much more surplus would have been provided. Both information is useful so I might add the old stuff back. I want to find a cleaner way to do that though. Since the old information is close to some other competition surplus test I went for the code as in the PR.

- aggregate orders on token pairs
- compare winning solution to all solutions with just one order
- computes winners using combinatorial auction
- change in winner implies top solution was filtered out
- logs change in surplus
- removes old test of just comparing the winner to other solutions
- add more debugging info
- show which solutions are filtered and why
- only use objective instead of surplus for single token pair solutions
- make naming consistent: `aggregated_solutions` -> `aggregate_solutions`
- add more test cases
@fhenneke fhenneke force-pushed the combinatorial_filtering branch from e389306 to b10c702 Compare November 2, 2023 17:21


class CombinatorialAuctionSurplusTest(BaseTest):
"""Test how a combinatorial auctions would have settled the auction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plural (auctions) not needed in the comment

- Aggregate surplus on the different directed sell token-buy token pairs for all solutions in
the competition.
- Compute a baseline for surplus on all token pairs from those solutions.
- Filter solutions which to not provide at least as much surplus as the baseline on all token
Copy link
Contributor

@harisang harisang Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "to not" -> do not.

Also, phrase "on all token pairs" could be read as follows: a solver should deal with all token pairs and provide the most surplus in all of them. Maybe add "on all token pairs that the solution touches" ?

"""

solutions = competition_data["solutions"]
solution = competition_data["solutions"][-1]
Copy link
Contributor

@harisang harisang Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename to winning_solution?

It would also help to not confuse things with the for-loop variable in line 60

int(prices[token_pair[0]]),
10**36,
)
elif trade.get_surplus_token() == trade.data.buy_token:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible there is a third case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Should I rewrite as else instead of elif? Or add some error message in case both checks fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote this as if "is sell order": ... else:

)
for solution in solutions
]
aggregate_solution = aggregate_solutions[-1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, a renaming of the variable would help.

surplus_dict[token_pair] = min(
surplus_dict[token_pair], solution["objective"]["total"]
)
# surplus_dict[token_pair] = solution["objective"]["total"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this comment

result: dict[tuple[str, str], tuple[Fraction, int]] = {}
for i, aggregate_solution in enumerate(aggregate_solutions):
if len(aggregate_solution) == 1:
token_pair, surplus = list(aggregate_solution.items())[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the next line are not the easiest to read but they make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments to make it easier to understand. Still a bit messy since I am using (surplus, index) tuples.
A simpler design would be nice.

) -> list[list[int]]:
"""Filter out solutions which do not provide enough surplus.
Only solutions are considered for ranking that supply more surplus than any of the single
aggregate order solutions. The function returns a list of bools where False means the
Copy link
Contributor

@harisang harisang Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment about what the function returns is not accurate.

Also, maybe we could make what the function returns easier to understand?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the comment and added some rational for making it this complicated.
A simpler design would be nice though.

@harisang harisang marked this pull request as ready for review November 9, 2023 11:51
"Combinatorial auction surplus test:",
f"Tx Hash: {competition_data['transactionHash']}",
f"Winning Solver: {solution['solver']}",
f"Winning surplus: {aggregate_solution}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The surplus is a fraction here and so the printing is not easy to read. Would be good to convert this to a decimal in ETH.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I convert this to float now. It looks extremely ugly though. I am a fan of using Fraction in the actual computation though. (I already made a big concession by using ETH and not wei as unit 😜)

@harisang
Copy link
Contributor

harisang commented Nov 9, 2023

Tested locally and seems to be working. Will do one more pass to double-check everything but it looks good!

Added a few minor comments here and there.

Copy link
Contributor

@harisang harisang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some minor comments that would be good to be addressed.

- fixed comments
- renamed variables
- added comments
- simplified buy and sell order cases
- simplified some default value dict access
just experimental since it looks a bit ugly
also removed unnecessary pylint disable
@fhenneke fhenneke requested a review from harisang November 9, 2023 23:43
def run(self, tx_hash: str) -> bool:
"""
Wrapper function for the whole test. Checks if solver competition data is retrievable
and runs EBBO test, else returns True to add to list of unchecked hashes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runs EBBO test..

Maybe fix this.

else returns True...
is this a typo or is this the convention here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed it. The same error is present in some other test. Will fix that later.


# convert surplus to float for logging
winning_aggregate_surplus_float = {
token_pair: float(surplus)
Copy link
Contributor

@harisang harisang Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we maybe reduce the number of decimals to 4? I guess we are not doing it in other tests but it would make things more readable.

Something like round(float_variable,4) should do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a more general function to process those dicts before logging.

@harisang
Copy link
Contributor

Looks good! Added some minor comments, and I guess adding the test in the daemon.py is still missing.

result[solver][token_pair] = aggregate_solutions[solution_index][token_pair]
return result

def convert_fractions_to_floats(self, obj: Any, precision: int = 4) -> Any:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@fhenneke fhenneke requested a review from harisang November 10, 2023 12:04
@harisang
Copy link
Contributor

Things look good. Let's merge and observe!

Can you create a new release btw once this is merged as there 2-3 PRs merged already so a release makes sense.

@fhenneke fhenneke merged commit bcde774 into main Nov 10, 2023
4 checks passed
@fhenneke fhenneke deleted the combinatorial_filtering branch November 10, 2023 13:14
@github-actions github-actions bot locked and limited conversation to collaborators Nov 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants