From 6003eee685d8cb2ff681377d6979408fbaa91117 Mon Sep 17 00:00:00 2001 From: josojo Date: Fri, 27 Sep 2019 05:48:56 +0200 Subject: [PATCH 1/3] some examples --- Optimization-examples/dfusion.py | 99 +++++ Optimization-examples/problem.json | 379 ++++++++++++++++++ Optimization-examples/problem_testcase.json | 57 +++ .../solution_best_disregarded_utility.json | 28 ++ .../solution_expected_best_one.json | 28 ++ ...ion_expected_best_one_with_FT_to_null.json | 28 ++ Optimization-examples/solution_testcase.json | 21 + 7 files changed, 640 insertions(+) create mode 100755 Optimization-examples/dfusion.py create mode 100755 Optimization-examples/problem.json create mode 100644 Optimization-examples/problem_testcase.json create mode 100644 Optimization-examples/solution_best_disregarded_utility.json create mode 100755 Optimization-examples/solution_expected_best_one.json create mode 100644 Optimization-examples/solution_expected_best_one_with_FT_to_null.json create mode 100644 Optimization-examples/solution_testcase.json diff --git a/Optimization-examples/dfusion.py b/Optimization-examples/dfusion.py new file mode 100755 index 0000000..afa0bfa --- /dev/null +++ b/Optimization-examples/dfusion.py @@ -0,0 +1,99 @@ +import json +from collections import defaultdict +from jsonmerge import Merger + +schema = { + "properties": { + "*": { + "mergeStrategy": "append" + } + } + } + +merger = Merger(schema) + + + +def apply_solution(problem_file, solution_file): + + feeConstant = 0.001 + + # sell ... for ... + def getPrice(token1, token2, fee = feeConstant): + return prices[token1] / prices[token2] * (1 - fee) + + def getSellAmount(buyAmount, buyToken, sellToken, fee = feeConstant): + return buyAmount * prices[buyToken] / prices[sellToken] / (1- fee) + + with open(problem_file, 'r') as f: + problem = json.load(f) + + with open(solution_file, 'r') as f: + solution = json.load(f) + + + solution = merger.merge(problem, solution) + + prices = solution["prices"] + orders = solution["orders"] + + print getPrice("S1", "S2") + + delta = defaultdict(int) + counter = 0 + utility = 0 + utility_with_negatives = 0 + utility_from_solution = 0 + for i in orders: + j = orders[i] + if "execBuyAmount" not in j: + j["execBuyAmount"] = 0 + + j["execSellAmount"] = getSellAmount(j["execBuyAmount"], j["buyToken"], j["sellToken"]) + + if j["execBuyAmount"] > 0: + #limit price needs to be below clearing price + assert not j["execBuyAmount"] / j["execSellAmount"] < j["limitRate"][1][0] / j["limitRate"][0][0], j + delta[j["buyToken"]] -= j["execBuyAmount"] + delta[j["sellToken"]] += j["execSellAmount"] + + #(how much token did they got - how much token did they expect) * converted to fee token price + + utility_in_buy_token = j["execBuyAmount"] - j["execSellAmount"] * j["limitRate"][1][0] / j["limitRate"][0][0] + utility += utility_in_buy_token * getPrice(j["buyToken"], "FEE", 0) + utility_with_negatives += utility_in_buy_token * getPrice(j["buyToken"], "FEE", 0) + if j["sellToken"] == 'S1': + utility_for_special_token = utility_in_buy_token * getPrice(j["buyToken"], j["buyToken"], 0) + if "execUtility" in j.keys(): + utility_from_solution += j["execUtility"] + + #the difference between the max utility they could have gotten, vs what they actually have gotten. + # how much token they would have gotten + if getPrice(j["sellToken"], j["buyToken"]) > j["limitRate"][1][0] / j["limitRate"][0][0]: + max_utility = j["maxSellAmount"] * getPrice(j["sellToken"], j["buyToken"]) - j["maxSellAmount"] * j["limitRate"][1][0] / j["limitRate"][0][0] + max_utility_in_fee_token = max_utility * getPrice(j["buyToken"], "FEE", 0) + disregarded_utility = max_utility_in_fee_token - utility_in_buy_token * getPrice(j["buyToken"], "FEE", 0) + utility_with_negatives -= disregarded_utility + + #print i + #print disregarded_utility + + + for token in delta: + if token != "FEE": + assert abs(delta[token]) < 0.02, delta + + + counter += 1 + #print delta + print "Total utility: " + str(utility) + print "Total utility with disregarded util: " + str(utility_with_negatives) + print "Total utility for only S1 token: " + str(utility_for_special_token) + print "" + + +filenames = ['solution_expected_best_one.json', 'solution_best_disregarded_utility.json', 'solution_expected_best_one_with_FT_to_null.json'] + +for i in filenames: + print i + apply_solution("problem.json",i) \ No newline at end of file diff --git a/Optimization-examples/problem.json b/Optimization-examples/problem.json new file mode 100755 index 0000000..d386337 --- /dev/null +++ b/Optimization-examples/problem.json @@ -0,0 +1,379 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order." + }, + "tokens": [ + "FEE", + "S1", + "S2", + "S3", + "S4", + "FT" + ], + "accounts": { + "0x0000": { + "FEE": 10.0 + }, + "0x0001": { + "S1": 1000.0 + }, + "0x0002": { + "S2": 1000.0 + }, + "0x0003": { + "S3": 1000.0 + }, + "0x0004": { + "S4": 1000.0 + }, + "0x1000": { + "S1": 1000.0 + } + }, + "orders": { + "standing_sell_S1_for_S2": { + "sellToken": "S1", + "buyToken": "S2", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S1" + ], + [ + 1001.0, + "S2" + ] + ], + "accountID": "0x0001", + "listIdx": null + }, + "standing_sell_S1_for_S3": { + "sellToken": "S1", + "buyToken": "S3", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S1" + ], + [ + 1001.0, + "S3" + ] + ], + "accountID": "0x0001", + "listIdx": null + }, + "standing_sell_S1_for_S4": { + "sellToken": "S1", + "buyToken": "S4", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S1" + ], + [ + 1001.0, + "S4" + ] + ], + "accountID": "0x0001", + "listIdx": null + }, + "standing_sell_S2_for_S1": { + "sellToken": "S2", + "buyToken": "S1", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S2" + ], + [ + 1001.0, + "S1" + ] + ], + "accountID": "0x0002", + "listIdx": null + }, + "standing_sell_S2_for_S3": { + "sellToken": "S2", + "buyToken": "S3", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S2" + ], + [ + 1001.0, + "S3" + ] + ], + "accountID": "0x0002", + "listIdx": null + }, + "standing_sell_S2_for_S4": { + "sellToken": "S2", + "buyToken": "S4", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S2" + ], + [ + 1001.0, + "S4" + ] + ], + "accountID": "0x0002", + "listIdx": null + }, + "standing_sell_S3_for_S1": { + "sellToken": "S3", + "buyToken": "S1", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S3" + ], + [ + 1001.0, + "S1" + ] + ], + "accountID": "0x0003", + "listIdx": null + }, + "standing_sell_S3_for_S2": { + "sellToken": "S3", + "buyToken": "S2", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S3" + ], + [ + 1001.0, + "S2" + ] + ], + "accountID": "0x0003", + "listIdx": null + }, + "standing_sell_S3_for_S4": { + "sellToken": "S3", + "buyToken": "S4", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S3" + ], + [ + 1001.0, + "S4" + ] + ], + "accountID": "0x0003", + "listIdx": null + }, + "standing_sell_S4_for_S1": { + "sellToken": "S4", + "buyToken": "S1", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S4" + ], + [ + 1001.0, + "S1" + ] + ], + "accountID": "0x0004", + "listIdx": null + }, + "standing_sell_S4_for_S2": { + "sellToken": "S4", + "buyToken": "S2", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S4" + ], + [ + 1001.0, + "S2" + ] + ], + "accountID": "0x0004", + "listIdx": null + }, + "standing_sell_S4_for_S3": { + "sellToken": "S4", + "buyToken": "S3", + "maxSellAmount": 1000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1000.0, + "S4" + ], + [ + 1001.0, + "S3" + ] + ], + "accountID": "0x0004", + "listIdx": null + }, + "standing_sell_FEE_for_S1": { + "sellToken": "FEE", + "buyToken": "S1", + "maxSellAmount": 10.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "FEE" + ], + [ + 1.0, + "S1" + ] + ], + "accountID": "0x0000", + "listIdx": null + }, + "standing_sell_FEE_for_S2": { + "sellToken": "FEE", + "buyToken": "S2", + "maxSellAmount": 10.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "FEE" + ], + [ + 1.0, + "S2" + ] + ], + "accountID": "0x0000", + "listIdx": null + }, + "standing_sell_FEE_for_S3": { + "sellToken": "FEE", + "buyToken": "S3", + "maxSellAmount": 10.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "FEE" + ], + [ + 1.0, + "S3" + ] + ], + "accountID": "0x0000", + "listIdx": null + }, + "standing_sell_FEE_for_S4": { + "sellToken": "FEE", + "buyToken": "S4", + "maxSellAmount": 10.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "FEE" + ], + [ + 1.0, + "S4" + ] + ], + "accountID": "0x0000", + "listIdx": null + }, + "market_sell_S1_for_S2": { + "sellToken": "S1", + "buyToken": "S2", + "maxSellAmount": 10.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "S1" + ], + [ + 0.9, + "S2" + ] + ], + "accountID": "0x1000", + "listIdx": null + }, + "market_sell_FT_for_S2": { + "sellToken": "S1", + "buyToken": "FT", + "maxSellAmount": 100000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "S1" + ], + [ + 0.91, + "S2" + ] + ], + "accountID": "0x1000", + "listIdx": null + }, + "connect_FT_": { + "sellToken": "FT", + "buyToken": "S2", + "maxSellAmount": 100000.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 1.0, + "S1" + ], + [ + 1.0, + "S2" + ] + ], + "accountID": "0x1000", + "listIdx": null + } + } +} \ No newline at end of file diff --git a/Optimization-examples/problem_testcase.json b/Optimization-examples/problem_testcase.json new file mode 100644 index 0000000..ac31d7c --- /dev/null +++ b/Optimization-examples/problem_testcase.json @@ -0,0 +1,57 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order." + }, + "tokens": [ + "FEE", + "S1" + ], + "accounts": { + "0x0000": { + "FEE": 20020.0 + }, + "0x0001": { + "S1": 20020.0 + } + }, + "orders": { + "standing_sell_FEE_for_S1": { + "sellToken": "FEE", + "buyToken": "S1", + "maxSellAmount": 20020.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 20020.0, + "FEE" + ], + [ + 10000.0, + "S1" + ] + ], + "accountID": "0x0001", + "listIdx": null + }, + "standing_sell_S1_for_FEE": { + "sellToken": "S1", + "buyToken": "FEE", + "maxSellAmount": 10010.0, + "maxBuyAmount": null, + "limitRate": [ + [ + 10010.0, + "S1" + ], + [ + 19980.0, + "FEE" + ] + ], + "accountID": "0x0001", + "listIdx": null + } + } +} \ No newline at end of file diff --git a/Optimization-examples/solution_best_disregarded_utility.json b/Optimization-examples/solution_best_disregarded_utility.json new file mode 100644 index 0000000..f0d4d9f --- /dev/null +++ b/Optimization-examples/solution_best_disregarded_utility.json @@ -0,0 +1,28 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order.", + "feeToken": "FEE", + "feePercentage": 0.001 + }, + "prices": { + "FEE": 1.0, + "S1": 0.909, + "S2": 1.001001001, + "S3": 1.0, + "S4": 1.0, + "FT": 1.00000001 + }, + "orders": { + "market_sell_S1_for_S2": { + "execBuyAmount": 9.0702999001 + }, + "standing_sell_FEE_for_S1": { + "execBuyAmount": 0.01999 + }, + "standing_sell_S2_for_S1": { + "execBuyAmount": 9.98001 + } + } +} \ No newline at end of file diff --git a/Optimization-examples/solution_expected_best_one.json b/Optimization-examples/solution_expected_best_one.json new file mode 100755 index 0000000..1138694 --- /dev/null +++ b/Optimization-examples/solution_expected_best_one.json @@ -0,0 +1,28 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order.", + "feeToken": "FEE", + "feePercentage": 0.001 + }, + "prices": { + "FEE": 1.0, + "S1": 0.999, + "S2": 1.001001001, + "S3": 1.0, + "S4": 1.0, + "FT": 1.00000001 + }, + "orders": { + "market_sell_S1_for_S2": { + "execBuyAmount": 9.97002999001 + }, + "standing_sell_FEE_for_S1": { + "execBuyAmount": 0.01999 + }, + "standing_sell_S2_for_S1": { + "execBuyAmount": 9.98001 + } + } +} \ No newline at end of file diff --git a/Optimization-examples/solution_expected_best_one_with_FT_to_null.json b/Optimization-examples/solution_expected_best_one_with_FT_to_null.json new file mode 100644 index 0000000..e330d33 --- /dev/null +++ b/Optimization-examples/solution_expected_best_one_with_FT_to_null.json @@ -0,0 +1,28 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order.", + "feeToken": "FEE", + "feePercentage": 0.001 + }, + "prices": { + "FEE": 1.0, + "S1": 0.999, + "S2": 1.001001001, + "S3": 1.0, + "S4": 1.0, + "FT": 0.00000001 + }, + "orders": { + "market_sell_S1_for_S2": { + "execBuyAmount": 9.97002999001 + }, + "standing_sell_FEE_for_S1": { + "execBuyAmount": 0.01999 + }, + "standing_sell_S2_for_S1": { + "execBuyAmount": 9.98001 + } + } +} \ No newline at end of file diff --git a/Optimization-examples/solution_testcase.json b/Optimization-examples/solution_testcase.json new file mode 100644 index 0000000..3d91f0b --- /dev/null +++ b/Optimization-examples/solution_testcase.json @@ -0,0 +1,21 @@ +{ + "metadata": { + "interfaceVersion": "1.1", + "numberFormat": "float", + "description": "System of 4 stable tokens (+ fee token) with standing orders and a single market order.", + "feeToken": "FEE", + "feePercentage": 0.001 + }, + "prices": { + "FEE": 1.0, + "S1": 2.0 + }, + "orders": { + "standing_sell_FEE_for_S1": { + "execBuyAmount": 10000.0 + }, + "standing_sell_S1_for_FEE": { + "execBuyAmount": 19980.0 + } + } +} \ No newline at end of file From e1e48b504cf1211cb65ee6f2d2bb6aa31715bf9f Mon Sep 17 00:00:00 2001 From: josojo Date: Fri, 27 Sep 2019 06:25:46 +0200 Subject: [PATCH 2/3] minor readme --- Optimization-examples/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Optimization-examples/README.md diff --git a/Optimization-examples/README.md b/Optimization-examples/README.md new file mode 100644 index 0000000..0fffa09 --- /dev/null +++ b/Optimization-examples/README.md @@ -0,0 +1,16 @@ + + +### Optimization Examples for certain problem + +The following scripts calculate certain metrics for proposed solutions of a certain optimization problem. + +#requirements: +``` +pip install jsonmerge +``` + +#test case: +Run +``` +apply_solution("problem_testcase.json",solution_testcase.json) +``` \ No newline at end of file From 3cb455b952f9a5f42361fccb9173f6536a98e239 Mon Sep 17 00:00:00 2001 From: josojo Date: Fri, 27 Sep 2019 06:30:47 +0200 Subject: [PATCH 3/3] some more comments in readme --- Optimization-examples/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Optimization-examples/README.md b/Optimization-examples/README.md index 0fffa09..f1ec435 100644 --- a/Optimization-examples/README.md +++ b/Optimization-examples/README.md @@ -10,7 +10,19 @@ pip install jsonmerge ``` #test case: -Run +Run the following function call ``` apply_solution("problem_testcase.json",solution_testcase.json) -``` \ No newline at end of file +``` +Testcase is currently not working, as rounding is not correct. With: +``` + def getSellAmount(buyAmount, buyToken, sellToken, fee = feeConstant): + return buyAmount * prices[buyToken] / prices[sellToken] // (1- fee) +``` +it works. + + +#Execution +``` +python2 dfusion.py +```