From d35cd73eb491bec514476e0f41b4475c48ce8d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danilo=20Arau=CC=81jo=20Silva?= Date: Fri, 11 Aug 2023 13:22:47 +0200 Subject: [PATCH] Inclusion of the Kujira connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 784a0c8ecd9aafb993ec8b031327b2a644f392b2 Author: Danilo Araújo Silva Date: Wed Aug 9 17:18:28 2023 +0200 Updating start method to also start the network, if needed. commit ae64a9e4f4cfbebaec8dbf96b403ed4cff9ef256 Author: Danilo Araújo Silva Date: Wed Aug 9 16:13:15 2023 +0200 Removing changes to add the parent reference abd to do not dispatch a async task when asking if the connector is ready. commit d4202eb6d79be9a79b1b5ea39ea854d32f0c2199 Author: Danilo Araújo Silva Date: Wed Aug 9 15:55:34 2023 +0200 Updating the code to add support to market orders and updating the enum to remove non-supported orders. commit 09704951bd797604e2f3d86b2608821c87954125 Author: Danilo Araújo Silva Date: Wed Aug 9 14:58:07 2023 +0200 Changing the imports to use the full path. commit 080c8e4e42f695392f789f9c4a069b1ac08adc07 Author: Danilo Araújo Silva Date: Sat Aug 5 00:35:51 2023 +0200 Updating gateway_clob_spot.py and gateway_clob_api_data_source_base.py commit 4430a523e8c4f393c853d33e12b93b7d0d885cf5 Author: Danilo Araújo Silva Date: Fri Aug 4 23:25:03 2023 +0200 Updating gateway_clob_spot.py and gateway_clob_api_data_source_base.py commit a3937c8170195ea4f90e46e055dbf6aceb7bfab7 Author: Danilo Araújo Silva Date: Fri Aug 4 17:50:11 2023 +0200 Updating kujira api data source implementation. Changing base files to a new approach. commit 5350be60f89781ddac48032b4f85d4380d05e6b8 Author: Darley Araújo Silva Date: Thu Aug 3 18:12:31 2023 -0300 Returning True for '_execute_order_cancel_and_process_update' method to update the order status in the 'in flight order' if the order is not found. commit 24bbda196a256a2d45b1b597fa4fa446cd2a3e11 Author: Álvaro E. F. Mota Date: Thu Aug 3 17:11:26 2023 -0300 Updating order status after exception commit 2753ce9194fdecde8c07f0440035705278675bea Author: Darley Araújo Silva Date: Thu Aug 3 16:51:28 2023 -0300 Adding error handling for 'cancelOrder' method if the order is not found. commit cb8bf53df62e90a7886fc1e68e8b15e7d1aade35 Author: Álvaro E. F. Mota Date: Fri Jul 28 21:01:29 2023 -0300 updating cancel_order commit 114a7e413a2181c138e80e275b236cb7d9b21cce Author: Danilo Araújo Silva Date: Sat Jul 29 00:37:04 2023 +0300 Updating cancel_order method. commit 176cc60c776dfdbc931494f14fe061eb67243d9d Author: Álvaro E. F. Mota Date: Fri Jul 28 18:28:16 2023 -0300 updating cancel_order commit 9bf654bc55972a7ba189bd54906b7fb66e372a54 Author: Álvaro E. F. Mota Date: Fri Jul 28 17:35:22 2023 -0300 improving cancel_order command commit a846c58cc82a76435c5aa3c19bf759d515506a7e Author: Danilo Araújo Silva Date: Fri Jul 28 23:13:51 2023 +0300 Updating gateway_clob_spot.py so we can configure a customized timeout when cancelling all orders. commit ec232cc312a881e5fbf29ee599641493f7774a50 Author: Danilo Araújo Silva Date: Fri Jul 28 17:17:13 2023 +0300 Fixing override. commit 5357535aa911de0b8a90c55352e63dfe03e18c11 Author: Danilo Araújo Silva Date: Fri Jul 28 17:10:41 2023 +0300 Updating kujira_constants.py commit 84d304be0afbf858ddcb6ed34a4272a645cdb7a5 Author: Danilo Araújo Silva Date: Fri Jul 28 16:58:44 2023 +0300 Updating kujira_api_data_source.py commit 507063c17d531e5c54f2bb40b62cec499441af9f Author: Danilo Araújo Silva Date: Fri Jul 28 16:02:21 2023 +0300 Updating kujira_api_data_source.py commit 968bd6f551636a01df07bdd3604a7f440332ca3e Author: Danilo Araújo Silva Date: Fri Jul 28 13:07:23 2023 +0300 Updating kujira_api_data_source.py and related files. commit 1db00f11881630ea2bbc710031e614f908bfb37a Author: Álvaro E. F. Mota Date: Thu Jul 27 18:33:39 2023 -0300 Fixed bug with stop command right after order placed commit 6cf72b111818d9885a24dce9df54ca5cf43f9573 Author: Danilo Araújo Silva Date: Fri Jul 28 00:17:35 2023 +0300 Updating gateway_clob_spot.py commit 258b693f81dae1314ad23534b541ffa7df6a83ee Author: Danilo Araújo Silva Date: Thu Jul 27 23:56:28 2023 +0300 Reverting changes from gateway_clob_spot.py commit 01296b18ed4eeeaffc6d4c45e513b88e3f584730 Author: Danilo Araújo Silva Date: Thu Jul 27 23:51:31 2023 +0300 Updating kujira data source files. commit 6827feac784900e025134fd15519827204561dac Author: Danilo Araújo Silva Date: Thu Jul 27 23:47:21 2023 +0300 Updating gateway_clob_spot.py commit f6e85b4f792ced8aad1e5dec21fd6789988c93d4 Author: Danilo Araújo Silva Date: Thu Jul 27 23:36:50 2023 +0300 Updating gateway_clob_spot.py commit a1b5bce4dce7faebc075c939e02e9ca31c3a43ef Author: Danilo Araújo Silva Date: Thu Jul 27 23:20:08 2023 +0300 Updating gateway_clob_spot.py commit cb3afa6692bb00f7324323beb3c02f11ca3b3b3e Author: Danilo Araújo Silva Date: Thu Jul 27 23:13:24 2023 +0300 Updating gateway_clob_spot.py commit 02e944e34ea5b096e353812321427e2afb3fbfef Author: Danilo Araújo Silva Date: Thu Jul 27 22:34:07 2023 +0300 Updating gateway_clob_spot.py commit 308e78435f7bcd9c14cabfec372460b363f47415 Author: Danilo Araújo Silva Date: Thu Jul 27 21:17:09 2023 +0300 Updating kujira_api_data_source.py commit 4ae16b99aa14105143d3ee83c1fe4924a0078882 Author: Danilo Araújo Silva Date: Thu Jul 27 21:02:28 2023 +0300 Updating kujira_api_data_source.py commit d7dd734bb66eccb21e09983b9af78497b2145bc5 Author: Danilo Araújo Silva Date: Thu Jul 27 20:57:40 2023 +0300 Updating _update_order_status method. commit b34fd2731da0b127d93054153a82b8f146a331a4 Author: Danilo Araújo Silva Date: Thu Jul 27 20:54:29 2023 +0300 Updating _update_order_status method. commit 3e840cd21a3b00b8e7ea4ee7a56f804935fb48a7 Author: Álvaro E. F. Mota Date: Thu Jul 27 14:03:01 2023 -0300 Updated get_order_status_update and cancel order commit 96690cc02eb2c1894bb409847714e64985d56edc Author: Danilo Araújo Silva Date: Thu Jul 27 19:39:12 2023 +0300 Updating log levels. commit 6b724ec30e9ae277fa43658b4d5b364f6bb9bf94 Author: Danilo Araújo Silva Date: Wed Jul 26 16:54:40 2023 +0300 Reverting changes. commit a80b7b7ed7be61813ff95e005f74f9592658dfc2 Author: Danilo Araújo Silva Date: Wed Jul 26 00:04:58 2023 +0300 Updating and improving kujira_api_data_source.py. commit dd00a7265d7dbc28ab7ddf652064100d0f062e8a Author: Danilo Araújo Silva Date: Tue Jul 25 23:47:03 2023 +0300 Updating and improving kujira_api_data_source.py. commit 28e5934a94e8e7412fc1646331d2f4499134e387 Author: Álvaro E. F. Mota Date: Tue Jul 25 16:33:13 2023 -0300 Fixed async lock commit 6fb2b79276d6c86008b82373445a8e077701be6c Author: Danilo Araújo Silva Date: Tue Jul 25 22:25:50 2023 +0300 Small changes. commit 6fb806b90ee4f71e40177c2d2536b1e3b3ab878e Author: Danilo Araújo Silva Date: Tue Jul 25 22:24:28 2023 +0300 Updating and improving kujira_api_data_source.py. commit ac0ca8e1df77333a0d7b416c704db126ea40efc5 Author: Danilo Araújo Silva Date: Tue Jul 25 22:21:37 2023 +0300 Updating and improving kujira_api_data_source.py. commit 51a6a808d81b60ce3b36ca653cadb1dc86cbb43e Author: Danilo Araújo Silva Date: Tue Jul 25 22:13:40 2023 +0300 Updating and improving kujira_api_data_source.py. commit acb7fbe337cd799e41d1649541985488cbc7e208 Author: Álvaro E. F. Mota Date: Tue Jul 25 14:31:17 2023 -0300 Resolved a bug commit 62c0229fef0fd7c6581dc86ad9a19b14dc299a50 Author: Álvaro E. F. Mota Date: Tue Jul 25 13:45:09 2023 -0300 Fixed a bug on update_order_status commit 56ba4e9ea60d20144e532cdc269bee3163ddbb2a Author: Danilo Araújo Silva Date: Tue Jul 25 00:28:28 2023 +0300 Adding a decorator for easy retry with timeout and adding the decorator the main functions. commit f6a915e5dd285d813b7bf6b3828c556ad8aadcee Author: Danilo Araújo Silva Date: Mon Jul 24 19:14:45 2023 +0300 Changing the base of the class, implementing abstract methods, and fixing issues regarding the orderbook handling. commit ab2f72803904690652922b558b1fe9e0a15deff4 Author: Danilo Araújo Silva Date: Mon Jul 24 19:13:20 2023 +0300 Adding a new mechanism to start the network if the ready is called but not start process has been dispatched before (this is specially important to fix the problem with the stop/start commands). commit 0bcb67254db3fe6386f7fdb0da57a9aaffb655a1 Author: Danilo Araújo Silva Date: Mon Jul 24 19:12:18 2023 +0300 Increasing the timeout to wait for the orders cancellation. commit 6f6f5adf32c8657b8b842797d9e789b86ca72907 Author: Darley Araújo Silva Date: Sat Jul 22 02:07:07 2023 -0300 Fixing event_tag. commit c94e6b6023d15f7e87b3291d7ab69d7ef9183a2a Author: Darley Araújo Silva Date: Sat Jul 22 01:29:55 2023 -0300 Testing orders status update. commit 9171186f086d0894a0142e94fc7e3c7ba48764f5 Author: Álvaro E. F. Mota Date: Wed Jul 19 17:39:25 2023 -0300 Fixed the filled order counter commit 28a2d4d533019d7ff1fdd75195e3d92b91ab0ad3 Author: Darley Araújo Silva Date: Wed Jul 19 16:22:47 2023 -0300 Improving '_update_markets' method. commit 1438bc5eacfec97d04f8057345cd00625b8bab9a Author: Darley Araújo Silva Date: Wed Jul 19 15:22:39 2023 -0300 Reverting commit 70bfd514a99d9d2b0450320348c11a4b6cd63caa commit 9f8dbfc516e4793532bf0ab4db01e37ca218b548 Author: Darley Araújo Silva Date: Wed Jul 19 14:48:28 2023 -0300 Fixing the bug that caused the _markets property not to receive the list of all markets correctly. commit 1b8cf77017ee8be41ea0aa628eed3a75ba497170 Author: Darley Araújo Silva Date: Wed Jul 19 13:39:46 2023 -0300 Reverting commit 253439abc5cabf8a6e2677b196fb99a0949363a2 commit 1c2941ef16e4d944ce39295ebd79309a7fdf78aa Author: Darley Araújo Silva Date: Tue Jul 18 20:24:18 2023 -0300 Solving start and stop commands behaviors issues. commit 70c26505e648922a3820a8b4c7299769fcc1a238 Author: Álvaro E. F. Mota Date: Mon Jul 17 13:59:37 2023 -0300 Fixed buy and sell filled order counter commit 919fcd17516441ea0f63a85254d3a79a72805d48 Author: Danilo Araújo Silva Date: Mon Jul 17 18:04:02 2023 +0300 Updating kujira_api_data_source.py to remove cancel all method. commit 956655871e0d29ae5f2450239971328194cf472f Author: Danilo Araújo Silva Date: Mon Jul 17 16:29:49 2023 +0300 Disabling method to cancel all orders at once. commit 1015f18af72add4f5a10a12049f84d38e91422d6 Author: Darley Araújo Silva Date: Sat Jul 15 01:21:54 2023 -0300 Fixing trade history so that the correct number of filled orders is shown. commit 8d5b321763ff43725dce8cb35551cc0d9c67a08c Author: Álvaro E. F. Mota Date: Fri Jul 14 18:25:04 2023 -0300 Fixed cancel_order commit 905d11cd6ebd9db2ffd69d8ddbecaa7c42c363c2 Author: Álvaro E. F. Mota Date: Fri Jul 14 18:10:38 2023 -0300 Fixed cancel_order commit 1dbfc31e223d9c10dcf803d4853e6a1d9bd72a1e Author: Álvaro E. F. Mota Date: Wed Jul 12 16:47:13 2023 -0300 Fixed cancell_all_orders function commit 54b0591085cb4259ee7096e8b5a47155b102e626 Author: Danilo Araújo Silva Date: Wed Jul 12 15:16:53 2023 +0300 Reverting changes. commit 151fa1410e23b68afaa741d44f504b4c57d6b4d5 Author: Danilo Araújo Silva Date: Wed Jul 12 01:08:00 2023 +0300 Cleaning code. commit 796613e0ad6a4be19bf7ef7c1dba9ab66b7f7dd7 Author: Danilo Araújo Silva Date: Wed Jul 12 00:57:43 2023 +0300 Reverting changes. commit 9f4ee55464aa505a20fad32260fc23304fa73c54 Author: Danilo Araújo Silva Date: Wed Jul 12 00:18:40 2023 +0300 Updating test_gateway_http_client_clob.py tests. commit cdd3438bbf52f138c6d6988e241440b6589ca871 Author: Danilo Araújo Silva Date: Tue Jul 11 21:35:41 2023 +0300 Updating kujira_api_data_source.py. commit 4bef4e01d984da30144c19b3604641532b0d2d0b Author: Danilo Araújo Silva Date: Tue Jul 11 20:53:23 2023 +0300 Updating kujira_api_data_source.py. commit c9229f0c3ff21944a0929b7b6878fdc7b98be99e Author: Danilo Araújo Silva Date: Tue Jul 11 19:49:15 2023 +0300 Updating kujira_api_data_source.py. commit 1e394c9beaac9c39146125dddd4c1b529a0f8b39 Author: Danilo Araújo Silva Date: Tue Jul 11 19:12:37 2023 +0300 Updating kujira_api_data_source.py. commit c99224497152b0812465bd2000f8466514af79ce Author: Danilo Araújo Silva Date: Tue Jul 11 18:28:51 2023 +0300 Updating kujira_api_data_source.py. commit 58c35b6c2149e188d170609a3f06a026c0af0e2a Author: Danilo Araújo Silva Date: Tue Jul 11 17:47:21 2023 +0300 Updating kujira_api_data_source.py commit 9f1c1767c47ffe3ff9222fa33ab71d3c3494df4d Author: Darley Araújo Silva Date: Tue Jul 11 01:54:25 2023 -0300 Initial changes to using clob endpoints. commit c0dae46dd3769bea3bde2cb8304d9e224cb7eeb8 Author: Danilo Araújo Silva Date: Tue Jul 11 00:20:00 2023 +0300 Updating kujira_api_data_source.py. commit cd7fc634aa3db5293b28f9876d3550747b1d71a2 Author: Danilo Araújo Silva Date: Mon Jul 10 22:34:57 2023 +0300 Removing some kujira code and files. commit 52af60e606a44cca40258c3864c11cb623edd6fb Author: Danilo Araújo Silva Date: Fri Jul 7 18:41:28 2023 +0300 Updating kujira url references. commit 82ced0877d03a4201b551f61f498fd119cc3678f Author: Danilo Araújo Silva Date: Fri Jul 7 17:42:18 2023 +0300 Improving tests to conform the new changes. commit 7fd4d21e9fd8d2d5a42256c7ab2a087401bf9f6b Author: Danilo Araújo Silva Date: Fri Jul 7 17:20:48 2023 +0300 Cleaning types and removing unused injective types. commit 3ee8232ef4d33a244961fa86a294b4c566f2871c Author: Danilo Araújo Silva Date: Fri Jul 7 17:20:25 2023 +0300 Readding needed constant. commit 97e06719d5d956a38a35545c332bbe8c48a0ac51 Author: Danilo Araújo Silva Date: Fri Jul 7 17:10:40 2023 +0300 Cleaning constants. commit 4d861952c7f757dfdb9725027539befb27f58415 Author: Danilo Araújo Silva Date: Fri Jul 7 17:08:30 2023 +0300 Cleaning helpers. commit a814e4dd29717fcecce2fd897e0f0aaee43c42cd Author: Danilo Araújo Silva Date: Fri Jul 7 17:04:35 2023 +0300 Updating gateway_http_client.py and related files. commit 33a08df18206a84879f20004eb3ef1a02c42af87 Author: Darley Araújo Silva Date: Thu Jul 6 22:58:44 2023 -0300 Changes required due to the change made to gateway_http_client where the methods used to communicate with the Gateway were removed. commit 7148a9b03c56c9215f9c2b48c8215442cf87f10d Author: Darley Araújo Silva Date: Thu Jul 6 22:55:47 2023 -0300 Fixing some route paths at Route enum. commit d69088b6f7bb792d1f58ecc830ed1480aa624dd7 Author: Danilo Araújo Silva Date: Fri Jul 7 00:58:31 2023 +0300 Updating the gateway_http_client.py and related files. commit 0e49e44a5ae7ca3035f130a8d0b27d842e829721 Author: Danilo Araújo Silva Date: Fri Jul 7 00:54:20 2023 +0300 Updating the gateway_http_client.py and related files. commit bb11d19bddce7b5c46a38e1f5f572be6b1ac0bcd Author: Danilo Araújo Silva Date: Fri Jul 7 00:30:35 2023 +0300 Updating the gateway_http_client.py commit d5dba5f6c7038b1a67db315997d214e2d05baad8 Author: Danilo Araújo Silva Date: Thu Jul 6 20:17:34 2023 +0300 Updating Kujira routes on gateway_http_client.py. commit 6d290fbd70b07835dd44ba074e300795ab643309 Author: Darley Araújo Silva Date: Thu Jul 6 01:28:53 2023 -0300 Reverting removal of the 'clob_example.py' file. commit efe6c2f005bfa40c8266fcea80ec45a91b25ac3e Author: Darley Araújo Silva Date: Mon Jul 3 18:40:39 2023 -0300 Removing non-fundamental changes from core files. commit db288fbaf38107790f97bae342119f35653e10df Author: Danilo Araújo Silva Date: Fri Jun 30 14:30:18 2023 +0300 Fixing kujira pmm scripts. commit 0044233e731e79c0a589fe8b39b038f96ada3239 Author: Álvaro E. F. Mota Date: Thu Jun 29 18:01:03 2023 -0300 Resolving some todos commit b2380cd4481bebaefd268535a48d60e363402e13 Author: Álvaro E. F. Mota Date: Thu Jun 29 16:54:40 2023 -0300 Fixed the kujira_pmm_example commit 53427027f9577edb5c77a49d018c421b4d92742c Author: Danilo Araújo Silva Date: Wed Jun 28 00:21:51 2023 +0300 Updating some error messages. commit 69188bfbc0f10306ca3696bf18b40719efae7635 Author: Álvaro E. F. Mota Date: Mon Jun 26 15:20:12 2023 -0300 Removed some commented code and unused files commit 006454aeb5de18899e3b0e90e05da0a0a5c28974 Author: Álvaro E. F. Mota Date: Fri Jun 23 16:06:02 2023 -0300 Making a carefully revision commit a7b04480e0a609cbd18857422e57adfc2140e8ef Author: Danilo Araújo Silva Date: Fri Jun 23 12:35:43 2023 +0300 Removing unsed file. commit cabad1ed17397cb153500151c61f945d2749828a Author: Danilo Araújo Silva Date: Fri Jun 23 12:14:14 2023 +0300 Removing the quickstart guide from the client. commit 09b73b5d595a74bac13d024cdc887a4239ab84f5 Author: Danilo Araújo Silva Date: Thu Jun 22 22:07:33 2023 +0300 Reverting to original code. commit 7ec08e64f03fc44ae3e92b38187f8fcd8073f06e Author: Darley Araújo Silva Date: Wed Jun 21 19:24:05 2023 -0300 Returning an OrderUpdate even when there is no update. commit 9a95846d10251e46263768ffc0a4c02b0552150c Author: Danilo Araújo Silva Date: Thu Jun 22 00:11:22 2023 +0300 Improving and fixing the cancel order method. commit 1335c6c664dd03b560ef80bcaa200418d8984360 Author: Danilo Araújo Silva Date: Thu Jun 22 00:11:01 2023 +0300 Updating the statement to avoid problems when the order update object does not exist. commit b4a3a516886125bfd987e9092a1f6d1bb4648646 Author: Darley Araújo Silva Date: Wed Jun 21 16:43:50 2023 -0300 Skipping cancelled orders... commit 0d4836de99a918b55df1ffd253e391dc1973997c Author: Álvaro E. F. Mota Date: Tue Jun 20 17:20:05 2023 -0300 Small fixes commit 80949b398f76aa9734c0ebc688a5d23ef641d0ab Author: Álvaro E. F. Mota Date: Tue Jun 20 13:47:04 2023 -0300 Removed cancel_all_orders from kujira data source start commit 8b3d17c38f49c96df8db405183a355e56ecbb35c Author: Darley Araújo Silva Date: Tue Jun 20 12:41:20 2023 -0300 Working at Client unittests commit cae0ec0d639b41c717553028fecfc3d04004c9b2 Author: Darley Araújo Silva Date: Mon Jun 19 18:04:23 2023 -0300 Working at Client unittests (wip) commit de608ef5deba8f022348b7320b6b242d07fc98ea Author: Darley Araújo Silva Date: Mon Jun 19 16:04:19 2023 -0300 Working at Client unittests (wip) commit bf2214f1bb15d8005ec8ddd9e4f0083d71f370c6 Author: Danilo Araújo Silva Date: Fri Jun 16 00:14:56 2023 +0300 Updating readme.md from the quickstart guide. commit 639babaf5d8c253a22ccce37ae434400a8ed7a19 Author: Danilo Araújo Silva Date: Wed Jun 14 19:50:12 2023 +0300 Updating the tokens ids. commit 24d924291d548db8a823fe73da39902958ca646e Author: Álvaro E. F. Mota Date: Mon Jun 12 18:15:20 2023 -0300 Fixing the cancell order test (Work in progress) commit 620b3607a6c03705b94981c82ebc1e3fb016ff05 Author: Álvaro E. F. Mota Date: Mon Jun 12 16:59:38 2023 -0300 Created test_clob_place_order commit a64b4b486936a6a391a1b507fa9ad0ffeb1197ac Author: Álvaro E. F. Mota Date: Mon Jun 12 16:53:27 2023 -0300 Created test_clob_cancel_order commit 24aa5dc818673d353bf576d2e992d5052b3f6a21 Author: Álvaro E. F. Mota Date: Mon Jun 12 15:06:44 2023 -0300 Small fix commit 0f669061efa2d39a75a133c87f456aa3caf5bae5 Author: Danilo Araújo Silva Date: Tue Jun 13 19:45:54 2023 +0300 Adding a kujira_pmm_strategy_example.yml for the PMM strategy. commit 138f9153d5d0a57f5672d3d4962abfa747bc750c Author: Danilo Araújo Silva Date: Tue Jun 13 19:43:37 2023 +0300 Updating quickstart .gitignore commit f41a8b8c769705eaa98660c823d14ce20f0725fd Author: Danilo Araújo Silva Date: Thu Jun 8 18:57:13 2023 +0300 Updating quickstart guide files. commit 831ca70c7cb4a0b8cb485131d52e11d03da6ebf2 Author: Danilo Araújo Silva Date: Thu Jun 8 18:00:57 2023 +0300 Updating quickstart guide files. commit 2ccfc08d74e4a280bf9f9ebc544ab00a8313667f Author: Danilo Araújo Silva Date: Thu Jun 8 16:56:12 2023 +0300 Updating quickstart guide files. commit 75636d65cec3323cac9537ac8ad87e8630d37b2e Author: Danilo Araújo Silva Date: Thu Jun 8 16:54:31 2023 +0300 Updating quickstart guide files. commit cedcb845c0b15009d21111420d223ce426dbc469 Author: Danilo Araújo Silva Date: Thu Jun 8 16:48:24 2023 +0300 Updating quickstart guide files. commit 0d1698396bc902b62d215a4e87dfe83fd91bf29f Author: Danilo Araújo Silva Date: Thu Jun 8 16:43:21 2023 +0300 Updating quickstart guide files. commit c08f1759ab1b6577a59f327742f764df8e5ea093 Author: Danilo Araújo Silva Date: Thu Jun 8 16:28:11 2023 +0300 Updating quickstart guide files. commit bbb11653e6f8485224ffecb6d6d393b7d6c3009e Author: Danilo Araújo Silva Date: Thu Jun 8 16:25:42 2023 +0300 Updating quickstart guide files. commit 88d0014e59f84d11dec1243c8763ab1fc3db4e97 Author: Danilo Araújo Silva Date: Thu Jun 8 16:03:10 2023 +0300 Updating quickstart guide files. commit 3775d459bb051d67cf0b11d524772a469edd0389 Author: Danilo Araújo Silva Date: Thu Jun 8 15:48:41 2023 +0300 Updating Dockerfiles. commit b9199d059a2780dd56fb54193d2134de271a0d09 Author: Danilo Araújo Silva Date: Thu Jun 8 13:16:24 2023 +0300 Updating Dockerfiles. commit 77ac03bfad58d31fe38c8f8ae551f14e79f33dce Author: Danilo Araújo Silva Date: Thu Jun 8 13:14:17 2023 +0300 Updating Dockerfiles. commit 4a825564c53914d7f76edc2f37f8aef79c47b25e Author: Danilo Araújo Silva Date: Thu Jun 8 12:45:01 2023 +0300 Updating Dockerfiles. commit 870e24e0543417ad0169e173475c67d5dcea54fa Author: Danilo Araújo Silva Date: Thu Jun 8 11:30:45 2023 +0300 Improving Dockerfiles. commit d5897d756b85ec0541d13e6e78c9252177c1d340 Author: Danilo Araújo Silva Date: Thu Jun 8 00:24:45 2023 +0300 Updating Dockerfiles. commit 250e77443c6a8026220382c6febb8e88baa8f98b Author: Danilo Araújo Silva Date: Thu Jun 8 00:24:26 2023 +0300 Updating Dockerfiles. commit 528023df826537195b55a4d783a581e9d3da56ce Author: Danilo Araújo Silva Date: Thu Jun 8 00:23:23 2023 +0300 Updating Dockerfiles. commit dc0dc84c51fde7689a2d568473d0c47bb3dad45f Author: Danilo Araújo Silva Date: Wed Jun 7 23:35:22 2023 +0300 Updating chmod. commit 7d57239b13403c73d037d1e04d240cb1f967ade7 Author: Danilo Araújo Silva Date: Wed Jun 7 23:32:26 2023 +0300 Updating Dockerfiles. commit 9b2c9e22122d1e76d4bc102a1fb98ae186f826f0 Author: Danilo Araújo Silva Date: Wed Jun 7 23:09:58 2023 +0300 Updating Dockerfile. commit 0904fee07242fbd16377811fc15d0981ce35c8bd Author: Danilo Araújo Silva Date: Wed Jun 7 23:00:58 2023 +0300 Improving docker scripts. commit 4c398d89cd5d3a478f7e181e776ac86d4f1a606b Author: Danilo Araújo Silva Date: Wed Jun 7 23:00:43 2023 +0300 Improving docker scripts. commit 3a7edd1256b437c020015e2b2bcdb33a7b45461d Author: Danilo Araújo Silva Date: Wed Jun 7 00:01:21 2023 +0300 Adding docker scripts folder. commit 8cc4128394774bcfc93bd29ac49e4cfc05f624c9 Author: Álvaro E. F. Mota Date: Mon May 22 14:28:36 2023 -0300 Removed kujira_api_data_source_tester commit 5e511aea9f7df7874177e5da444ec039cfd4e1a5 Author: Danilo Araújo Silva Date: Mon May 22 19:11:09 2023 +0200 Updating kujira_pmm_example.py commit ce07f81966bdf8b398afeb7d5ba26c0b42a50398 Author: Danilo Araújo Silva Date: Fri May 19 17:28:53 2023 +0200 Fixing todos. commit c0db6f3036be89518742d0b6b80228c8fd126fb8 Author: Danilo Araújo Silva Date: Thu May 18 19:37:51 2023 +0200 Improving Kujira Gateway and Client implementation. commit 4b76bc1b3379094954a54c9978a23349f848bc45 Author: Danilo Araújo Silva Date: Thu May 18 19:00:39 2023 +0200 Improving and fixing KujiraDEX implementation. commit 3ec6bac6a8a5ebd365a314b8eb839c292b0ad94a Author: Danilo Araújo Silva Date: Thu May 18 18:35:59 2023 +0200 Improving and fixing KujiraDEX implementation. commit a057546bad060c2035cb96c46376d3c3b4547ebd Author: Danilo Araújo Silva Date: Thu May 18 18:14:02 2023 +0200 Improving and fixing KujiraDEX implementation. commit e985822f887d451937a97cb5b52b6373cf7d8423 Author: Álvaro E. F. Mota Date: Thu May 18 13:10:01 2023 -0300 Fixing an small bug commit 73cc241c3b4ebd06c9f8f326a9400ed7169c2f67 Author: Danilo Araújo Silva Date: Thu May 18 17:47:56 2023 +0200 Improving and fixing KujiraDEX implementation. commit 6e4f0da9084dccf888b87bb6322f47cec56e44a4 Author: Danilo Araújo Silva Date: Thu May 18 17:24:48 2023 +0200 Improving and fixing KujiraDEX implementation. commit 0655987939d5b29beb8ac29cd46ef4f91a23f155 Author: Álvaro E. F. Mota Date: Thu May 18 12:13:23 2023 -0300 Added logs for all functions int the Kujira api data source commit 2b5ed051c9a42f91a21c5d7ce943e715ded7f38d Author: Danilo Araújo Silva Date: Thu May 18 17:14:31 2023 +0200 Improving and fixing KujiraDEX implementation. commit 6282ad7dbf59ff91aa9670d26b6c48b36dd980d4 Author: Álvaro E. F. Mota Date: Thu May 18 11:26:32 2023 -0300 Added request and response log function commit 883157345aa0eb4e4f169cde4b98858c3fe2cf5b Author: Danilo Araújo Silva Date: Thu May 18 01:38:39 2023 +0200 Improving and fixing KujiraDEX implementation. commit 9d2704087cefe5ffac91cac5260f28da3de186da Author: Danilo Araújo Silva Date: Thu May 18 01:06:21 2023 +0200 Improving and fixing KujiraDEX implementation. commit ab978c84c159c6e972e440b3bfb801c1c940d7a8 Author: Danilo Araújo Silva Date: Thu May 18 00:20:20 2023 +0200 Improving and fixing KujiraDEX implementation. commit f20aa2d50eebfe5b43c60313ea72965ca67c2379 Author: Danilo Araújo Silva Date: Wed May 17 19:16:33 2023 +0200 Improving kujira_api_data_source.py. commit f16dce03207ddc7a8799067165d3e07a8b09c4b8 Author: Danilo Araújo Silva Date: Wed May 17 18:46:39 2023 +0200 Fixing kujira_api_data_source.py. commit c5c1f6773b96a787e2c71ea315bcd668d8c7300e Author: Danilo Araújo Silva Date: Wed May 17 18:46:09 2023 +0200 Fixing kujira_api_data_source.py. commit e716c6eaa0f58b2f98044728ded4260248f6b0e9 Author: Danilo Araújo Silva Date: Wed May 17 18:20:08 2023 +0200 Fixing KujiraDEX. commit 539adcd463dd38e80480e6d2b604b9169a1c867c Author: Danilo Araújo Silva Date: Wed May 17 17:55:05 2023 +0200 Fixing KujiraDEX. commit 2b45220bc445af6a5962e5cc7c0a70c39942b94f Author: Danilo Araújo Silva Date: Wed May 17 17:41:41 2023 +0200 Fixing KujiraDEX. commit 8eb66ff7ce0353bb5f7272f95da1a0d3e00952ad Author: Danilo Araújo Silva Date: Wed May 17 15:44:36 2023 +0200 Renaming and removing non needed files. commit ade82ecb2742be1987957286c4eaa8bddd089595 Author: Danilo Araújo Silva Date: Wed May 17 00:24:02 2023 +0200 Adding the remaining methods of the kujira_api_data_source_2.py. commit 131dd1dbe415f5f26bbbaa91b1287da0a18d93ea Author: Álvaro E. F. Mota Date: Tue May 16 16:05:44 2023 -0300 Updated environments, added nest_asyncio and dotmap commit 95de27df9f0dc259419e9c90fd4c44a2c2dfd38e Author: Danilo Araújo Silva Date: Tue May 16 22:55:57 2023 +0200 Implementing the kujira_api_data_source_2.py methods. WIP. commit 6106a7845fff4c59dd9a5b5d4b31e1e746ec7b69 Author: Álvaro E. F. Mota Date: Tue May 16 13:03:48 2023 -0300 Fixed get all filled order commit 8dd47c331c25f3c5df95eedca915d0d3d7095006 Author: Danilo Araújo Silva Date: Tue May 16 18:39:37 2023 +0200 Kujira Client improvements. commit 931a11807c2fccab711a5082e17b062b48d5c2bf Author: Danilo Araújo Silva Date: Tue May 16 16:04:21 2023 +0200 Kujira Client improvements. commit f67921916dfdef285dee1280d294a866094814fe Author: Darley Araújo Silva Date: Sun May 14 14:41:34 2023 -0300 Changing the balances order of magnitude. commit 6fe50ddad762800763e9ebe8bc369c33b1a781ff Author: Álvaro E. F. Mota Date: Fri May 12 18:58:54 2023 -0300 Fixing place order commit 49884ec066416e895d3e614c4c8153f78e1f4964 Author: Danilo Araújo Silva Date: Sat May 13 00:26:33 2023 +0200 Kujira Client improvements. commit 63bc31792a9b99724ccdf91e0c63c2fd213d39dd Author: Danilo Araújo Silva Date: Fri May 12 21:53:16 2023 +0200 Kujira Client improvements. commit a3bbbab8d609351149d7a9b3e88494952d9814e7 Author: Danilo Araújo Silva Date: Fri May 12 17:46:44 2023 +0200 Working with the kujira_api_data_source.py. commit b8b206a068a3387456101b5c30ae5e143173ecaf Author: Danilo Araújo Silva Date: Fri May 12 17:29:29 2023 +0200 Fixing generate_hash function. commit bda34312ef23c525453f91b392fb8cd057d725ba Author: Danilo Araújo Silva Date: Fri May 12 16:55:59 2023 +0200 Fixing kujira_api_data_source.py commit 355e39a65ca4846359816ec058cb4f1354987c62 Author: Álvaro E. F. Mota Date: Fri May 12 11:53:36 2023 -0300 Added generate_hash function commit 71e3d0fb43f8507a7bda48a03007fff05bc24b78 Author: Danilo Araújo Silva Date: Fri May 12 16:09:36 2023 +0200 Fixing kujira_api_data_source.py commit 17481276a2c8c69d0ab359ad42a379008cea348e Author: Danilo Araújo Silva Date: Fri May 12 15:45:24 2023 +0200 Fixing kujira_api_data_source_tester.py script. commit da35eb3daecda9276ff8fae45b24e42bd4192d55 Author: Darley Araújo Silva Date: Thu May 11 20:57:16 2023 -0300 Fixing get_account_balances (wip) commit 6cdbe3acf07d84ef330c70a3aef1e46b4ab0fe0a Author: Darley Araújo Silva Date: Thu May 11 19:37:23 2023 -0300 Implementing check_network_status method at kujira_api_data_source_2 commit d11f2a0927a1903ff8dd60d32604bcc3294a7357 Author: Darley Araújo Silva Date: Thu May 11 19:18:20 2023 -0300 Implementing get_account_balances method at kujira_api_data_source_2 commit 40eb703530d21d9392cb155c516c934766a96655 Author: Darley Araújo Silva Date: Thu May 11 19:10:46 2023 -0300 Implementing cancel_order method at kujira_api_data_source_2 commit ef9e64736cbb38914bbba137100d4b1668ea1215 Author: Darley Araújo Silva Date: Thu May 11 18:53:49 2023 -0300 Creating of kujira_api_data_source_2 commit 02f4cf96ab7e44cee782c3b44628484e5ad66a13 Author: Danilo Araújo Silva Date: Thu May 11 23:40:10 2023 +0200 Temporary approach for the kujira_api_data_source.py commit 27823b53d703c555c25226eaf4103d4d03dd2088 Author: Danilo Araújo Silva Date: Thu May 11 21:15:24 2023 +0200 Updating the kujira_api_data_source.py commit 5dc7187a2c312142788e5557c0954f3b18362b00 Author: Danilo Araújo Silva Date: Thu May 11 20:42:18 2023 +0200 Updating the kujira_api_data_source.py commit c2eb7a5033ecfee4e924ac894ac83b19609a93cb Author: Danilo Araújo Silva Date: Thu May 11 20:06:11 2023 +0200 Updating kujira/kujira_api_data_source.py commit fbadc1c5cbfb8cc38903fa17482c07a3943c3587 Author: Danilo Araújo Silva Date: Thu May 11 19:14:45 2023 +0200 Adding new Kujira routes compatible with the Injective implementation. commit def953d20209c6f45284051418162954bda6233f Author: Danilo Araújo Silva Date: Thu May 11 18:59:50 2023 +0200 Disabling some injective specific code. commit cb59791ff81eb5d53fb0bc3d68f44f65ccb9a101 Author: Darley Araújo Silva Date: Thu May 11 13:44:30 2023 -0300 Changing the method that was called by kujira_api_data_source.py commit a4676115f674acee97694073f2016cf720501158 Author: Danilo Araújo Silva Date: Thu May 11 16:10:48 2023 +0200 WIP. commit b71c71e88703bf67f99ed76ae7de4225fd21b5fa Author: Danilo Araújo Silva Date: Thu May 11 15:46:52 2023 +0200 Adding a kujira_api_data_source_tester.py tester script. commit e192b1e271f49e563ba7adbabfc30019224fbd57 Author: Danilo Araújo Silva Date: Thu May 11 15:15:38 2023 +0200 Updating Kujira implementation. commit 88ee2341ae60349c4b062b45036781b14e82131f Author: Danilo Araújo Silva Date: Thu May 11 15:06:22 2023 +0200 Updating the kujira_api_data_source.py commit 3b0c29b5915acbf3b784be4cf515680fdb83dd95 Author: Danilo Araújo Silva Date: Thu May 11 14:09:12 2023 +0200 Updating Kujira client implementation. commit 3fa83206164d5c2037c52c53a2fcf94df054e4b4 Author: Álvaro E. F. Mota Date: Thu May 4 12:44:52 2023 -0300 Fixed "RuntimeError: This event loop is already running in python" with nest_asyncio package commit 3a7fc6ae29b247a12fe308f8cbc0a478c08d8aab Author: Danilo Araújo Silva Date: Wed May 3 22:24:02 2023 +0200 Updating kujira_pmm_example.py to reflect new changes from the Gateway API. commit dcb30630b3526aa32df0cc5ea37d4092bc0e3265 Author: Danilo Araújo Silva Date: Fri Apr 28 18:11:07 2023 +0000 First stable version of the kujira_pmm_example.py script. commit 90063d650efe9914d54592ca42351aba09374946 Author: Danilo Araújo Silva Date: Fri Apr 28 13:16:47 2023 +0000 First stable version of the kujira_pmm_example.py script. commit 93d0080fb3ec766da6344fdc57a7dc0b2bce1a73 Author: Danilo Araújo Silva Date: Fri Apr 28 12:03:03 2023 +0000 First stable version of the kujira_pmm_example.py script. commit 2bb459d069c2f2d2a9e2fd9344028206ecb403bb Author: Danilo Araújo Silva Date: Fri Apr 28 11:23:39 2023 +0000 Improving Kujira PMM script. commit 7a18c609b8230a13064cc689443ec50361a237a6 Author: Danilo Araújo Silva Date: Thu Apr 27 23:51:22 2023 +0000 Fixing and improving kujira_pmm_example.py script. commit d2f35628830ed6cede53bb9a4d2dd6cd8313f0cf Author: Danilo Araújo Silva Date: Thu Apr 27 23:36:51 2023 +0000 Fixing and improving kujira_pmm_example.py script. commit b42693044fe11c600e15363aa88de58cab7819a4 Author: Danilo Araújo Silva Date: Wed Apr 26 18:05:38 2023 +0000 Adding more kujira types and working with the kujira pmm script. commit ef79c32e51ba9d1a0fc5ae0e395ad25d398c3e28 Author: Danilo Araújo Silva Date: Wed Apr 26 14:19:07 2023 +0000 Improving Kujira PMM script and other related changes to support that. commit 3711f0622aff36aefac6ed0754cd113365633f44 Author: Danilo Araújo Silva Date: Tue Apr 25 19:00:34 2023 +0000 Fixing gateway_http_client.py commit 4238d37d3ed968494195449543c1c125314f82b8 Author: Danilo Araújo Silva Date: Tue Apr 25 18:49:57 2023 +0000 Improving and fixing kujira_pmm_example.py commit afd66404e8f74e1e99307651df3b641b0dbe9629 Author: Danilo Araújo Silva Date: Tue Apr 25 18:48:10 2023 +0000 Updating the gateway_http_client.py commit e48061cf2293d1edbd0805dd7e49120bbd91c00c Author: Danilo Araújo Silva Date: Tue Apr 25 18:43:20 2023 +0000 Changing the start_command.py and script_strategy_base.py so the scripts can use async initialization and tick methods, among some other improvements. Fixing and improving the gateway_http_client.py and kujira_pmm_example.py commit 822292978dddd8feb9d0f8de5b03704cf943aba0 Author: Danilo Araújo Silva Date: Tue Apr 25 16:13:43 2023 +0000 Updating Kujira implementation. commit aff16f2611895cd2f6c991a711a2dbed12938217 Author: Danilo Araújo Silva Date: Fri Apr 21 14:33:52 2023 +0000 Improving kujira pmm script and the order_candidate class. commit 4620751d20a531f9f5150af196627f9cc25e5571 Author: Danilo Araújo Silva Date: Thu Apr 20 16:38:20 2023 +0000 Updating kujira_types.py. commit 4743a2730f0b92a84b42845369f724869b728d65 Author: Danilo Araújo Silva Date: Wed Apr 19 23:56:29 2023 +0000 Improving kujira_pmm_example.py script. Modifying kujira_types.py. commit fe95586768681ddfada2c89b8e38f786e46da62d Author: Danilo Araújo Silva Date: Wed Apr 19 20:10:42 2023 +0000 Doing changes regarding the creation of the Kujira PMM Script. commit 4fbfcc05f6ef78b72cbda97280321327b1e78995 Author: Danilo Araújo Silva Date: Tue Apr 18 23:54:28 2023 +0000 Working with the Kujira connector. WIP. commit 012f82416ea70086eb847c92d478e5890d7f6b39 Author: Danilo Araújo Silva Date: Wed Apr 12 22:28:47 2023 +0200 Adding kujira routes commit 29f60201e736dc4066622ff3bb25c95b4b4ca4da Author: Danilo Araújo Silva Date: Wed Apr 5 23:42:12 2023 +0200 Adding Kujira client files to integrate it as a new datasource for CLOB_SPOT. commit a723e528e6d1fb0b91f6d3ebc7d8bf4525c10863 Author: Danilo Araújo Silva Date: Fri Mar 17 23:13:28 2023 +0000 Adding some content (simliar to Injective) for the Kujira data source. commit f978b683adff6a78f4f3a7c26f124425a92657b1 Author: Danilo Araújo Silva Date: Thu Mar 16 21:53:27 2023 +0000 Improving kujira_api_data_source.py. commit 7a817f0b09003486ba38bb7da29a9909e89bfebc Author: Danilo Araújo Silva Date: Thu Mar 16 17:02:00 2023 +0000 Adding main files for the Kujira data source. commit ef187a61a8e7c0b740bf8d3fcffd43f398651459 Author: Danilo Araújo Silva Date: Fri Mar 3 20:13:15 2023 +0000 Updating .gitignore. --- hummingbot/connector/connector_status.py | 1 + .../data_sources/clob_api_data_source_base.py | 5 + .../clob_spot/data_sources/kujira/__init__.py | 0 .../kujira/kujira_api_data_source.py | 992 ++++++++++++++++++ .../data_sources/kujira/kujira_constants.py | 17 + .../data_sources/kujira/kujira_helpers.py | 65 ++ .../data_sources/kujira/kujira_types.py | 132 +++ .../gateway/clob_spot/gateway_clob_spot.py | 31 +- hummingbot/core/utils/gateway_config_utils.py | 3 +- setup/environment.yml | 2 + test/hummingbot/client/test_settings.py | 45 + 11 files changed, 1289 insertions(+), 4 deletions(-) create mode 100644 hummingbot/connector/gateway/clob_spot/data_sources/kujira/__init__.py create mode 100644 hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_api_data_source.py create mode 100644 hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_constants.py create mode 100644 hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_helpers.py create mode 100644 hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_types.py diff --git a/hummingbot/connector/connector_status.py b/hummingbot/connector/connector_status.py index 110d1b86ce..71035e6176 100644 --- a/hummingbot/connector/connector_status.py +++ b/hummingbot/connector/connector_status.py @@ -62,6 +62,7 @@ 'vertex': 'bronze', 'vertex_testnet': 'bronze', 'injective_v2': 'bronze', + 'kujira': 'bronze', } warning_messages = { diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/clob_api_data_source_base.py b/hummingbot/connector/gateway/clob_spot/data_sources/clob_api_data_source_base.py index 385337cdc8..61069082c4 100644 --- a/hummingbot/connector/gateway/clob_spot/data_sources/clob_api_data_source_base.py +++ b/hummingbot/connector/gateway/clob_spot/data_sources/clob_api_data_source_base.py @@ -44,6 +44,7 @@ def __init__( self._forwarders_map: Dict[Tuple[Enum, Callable], EventForwarder] = {} self._gateway_order_tracker: Optional[GatewayOrderTracker] = None self._markets_info: Dict[str, Any] = {} + self.cancel_all_orders_timeout = None @property @abstractmethod @@ -223,3 +224,7 @@ def add_listener(self, event_tag: Enum, listener: EventListener): def remove_listener(self, event_tag: Enum, listener: EventListener): self._publisher.remove_listener(event_tag=event_tag, listener=listener) + + @property + def is_cancel_request_in_exchange_synchronous(self) -> bool: + return False diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/kujira/__init__.py b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_api_data_source.py b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_api_data_source.py new file mode 100644 index 0000000000..6998c1f5b6 --- /dev/null +++ b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_api_data_source.py @@ -0,0 +1,992 @@ +import asyncio +import copy +from asyncio import Task +from enum import Enum +from time import time +from typing import Any, Dict, List, Optional, Tuple + +import jsonpickle +from _decimal import Decimal +from dotmap import DotMap + +from hummingbot.client.config.config_helpers import ClientConfigAdapter +from hummingbot.connector.gateway.clob_spot.data_sources.gateway_clob_api_data_source_base import ( + GatewayCLOBAPIDataSourceBase, +) +from hummingbot.connector.gateway.clob_spot.data_sources.kujira.kujira_constants import ( + CONNECTOR, + DELAY_BETWEEN_RETRIES, + KUJIRA_NATIVE_TOKEN, + MARKETS_UPDATE_INTERVAL, + NUMBER_OF_RETRIES, + TIMEOUT, + UPDATE_ORDER_STATUS_INTERVAL, +) +from hummingbot.connector.gateway.clob_spot.data_sources.kujira.kujira_helpers import ( + AsyncLock, + automatic_retry_with_timeout, + convert_market_name_to_hb_trading_pair, + generate_hash, +) +from hummingbot.connector.gateway.clob_spot.data_sources.kujira.kujira_types import OrderStatus as KujiraOrderStatus +from hummingbot.connector.gateway.common_types import CancelOrderResult, PlaceOrderResult +from hummingbot.connector.gateway.gateway_in_flight_order import GatewayInFlightOrder +from hummingbot.connector.trading_rule import TradingRule +from hummingbot.core.data_type import in_flight_order +from hummingbot.core.data_type.common import OrderType +from hummingbot.core.data_type.in_flight_order import OrderState, OrderUpdate, TradeUpdate +from hummingbot.core.data_type.order_book_message import OrderBookMessage, OrderBookMessageType +from hummingbot.core.data_type.trade_fee import MakerTakerExchangeFeeRates, TokenAmount, TradeFeeBase, TradeFeeSchema +from hummingbot.core.event.events import AccountEvent, MarketEvent, OrderBookDataSourceEvent, OrderCancelledEvent +from hummingbot.core.gateway.gateway_http_client import GatewayHttpClient +from hummingbot.core.network_iterator import NetworkStatus +from hummingbot.core.utils.async_utils import safe_ensure_future, safe_gather + + +class KujiraAPIDataSource(GatewayCLOBAPIDataSourceBase): + + def __init__( + self, + trading_pairs: List[str], + connector_spec: Dict[str, Any], + client_config_map: ClientConfigAdapter, + ): + super().__init__( + trading_pairs=trading_pairs, + connector_spec=connector_spec, + client_config_map=client_config_map + ) + + self._chain = connector_spec["chain"] + self._network = connector_spec["network"] + self._connector = CONNECTOR + self._owner_address = connector_spec["wallet_address"] + self._payer_address = self._owner_address + + self._trading_pair = None + if self._trading_pairs: + self._trading_pair = self._trading_pairs[0] + + self._markets = None + self._market = None + + self._user_balances = None + + self._tasks = DotMap({ + "update_order_status_loop": None + }, _dynamic=False) + + self._locks = DotMap({ + "place_order": AsyncLock(), + "place_orders": AsyncLock(), + "cancel_order": AsyncLock(), + "cancel_orders": AsyncLock(), + "settle_market_funds": AsyncLock(), + "settle_markets_funds": AsyncLock(), + "settle_all_markets_funds": AsyncLock(), + "all_active_orders": AsyncLock(), + }, _dynamic=False) + + self._gateway = GatewayHttpClient.get_instance(self._client_config) + + self._all_active_orders = None + + self._snapshots_min_update_interval = 30 + self._snapshots_max_update_interval = 60 + self.cancel_all_orders_timeout = TIMEOUT + + @property + def connector_name(self) -> str: + return CONNECTOR + + @property + def real_time_balance_update(self) -> bool: + return False + + @property + def events_are_streamed(self) -> bool: + return False + + @staticmethod + def supported_stream_events() -> List[Enum]: + return [ + MarketEvent.TradeUpdate, + MarketEvent.OrderUpdate, + MarketEvent.OrderFilled, + AccountEvent.BalanceEvent, + OrderBookDataSourceEvent.TRADE_EVENT, + OrderBookDataSourceEvent.DIFF_EVENT, + OrderBookDataSourceEvent.SNAPSHOT_EVENT, + ] + + def get_supported_order_types(self) -> List[OrderType]: + return [OrderType.LIMIT, OrderType.MARKET] + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def start(self): + self.logger().setLevel("INFO") + self.logger().debug("start: start") + + await super().start() + + self._tasks.update_order_status_loop = self._tasks.update_order_status_loop \ + or safe_ensure_future( + coro=self._update_all_active_orders() + ) + + self.logger().debug("start: end") + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def stop(self): + self.logger().debug("stop: start") + + await super().stop() + + self._tasks.update_order_status_loop and self._tasks.update_order_status_loop.cancel() + self._tasks.update_order_status_loop = None + + self.logger().debug("stop: end") + + async def place_order(self, order: GatewayInFlightOrder, **kwargs) -> Tuple[Optional[str], Optional[Dict[str, Any]]]: + self.logger().debug("place_order: start") + + self._check_markets_initialized() or await self._update_markets() + + async with self._locks.place_order: + try: + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + "trading_pair": self._trading_pair, + "address": self._owner_address, + "trade_type": order.trade_type, + "order_type": order.order_type, + "price": order.price, + "size": order.amount, + "client_order_id": order.client_order_id, + } + + self.logger().debug(f"""clob_place_order request:\n "{self._dump(request)}".""") + + response = await self._gateway_clob_place_order(request) + + self.logger().debug(f"""clob_place_order response:\n "{self._dump(response)}".""") + + transaction_hash = response["txHash"] + + order.exchange_order_id = response["id"] + + order.current_state = OrderState.CREATED + + self.logger().info( + f"""Order "{order.client_order_id}" / "{order.exchange_order_id}" successfully placed. Transaction hash: "{transaction_hash}".""" + ) + except Exception as exception: + self.logger().info( + f"""Placement of order "{order.client_order_id}" failed.""" + ) + + raise exception + + if transaction_hash in (None, ""): + raise Exception( + f"""Placement of order "{order.client_order_id}" failed. Invalid transaction hash: "{transaction_hash}".""" + ) + + misc_updates = DotMap({ + "creation_transaction_hash": transaction_hash, + }, _dynamic=False) + + self.logger().debug("place_order: end") + + await self._update_order_status() + + return order.exchange_order_id, misc_updates + + async def batch_order_create(self, orders_to_create: List[GatewayInFlightOrder]) -> List[PlaceOrderResult]: + self.logger().debug("batch_order_create: start") + + self._check_markets_initialized() or await self._update_markets() + + candidate_orders = [in_flight_order] + client_ids = [] + for order_to_create in orders_to_create: + order_to_create.client_order_id = generate_hash(order_to_create) + client_ids.append(order_to_create.client_order_id) + + candidate_order = in_flight_order.InFlightOrder( + amount=order_to_create.amount, + client_order_id=order_to_create.client_order_id, + creation_timestamp=0, + order_type=order_to_create.order_type, + trade_type=order_to_create.trade_type, + trading_pair=self._trading_pair, + ) + candidate_orders.append(candidate_order) + + async with self._locks.place_orders: + try: + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + "address": self._owner_address, + "orders_to_create": candidate_orders, + "orders_to_cancel": [], + } + + self.logger().debug(f"""clob_batch_order_modify request:\n "{self._dump(request)}".""") + + response = await self._gateway_clob_batch_order_modify(request) + + self.logger().debug(f"""clob_batch_order_modify response:\n "{self._dump(response)}".""") + + transaction_hash = response["txHash"] + + self.logger().info( + f"""Orders "{client_ids}" successfully placed. Transaction hash: {transaction_hash}.""" + ) + except Exception as exception: + self.logger().info( + f"""Placement of orders "{client_ids}" failed.""" + ) + + raise exception + + if transaction_hash in (None, ""): + raise RuntimeError( + f"""Placement of orders "{client_ids}" failed. Invalid transaction hash: "{transaction_hash}".""" + ) + + place_order_results = [] + for order_to_create, exchange_order_id in zip(orders_to_create, response["ids"]): + order_to_create.exchange_order_id = None + + place_order_results.append(PlaceOrderResult( + update_timestamp=time(), + client_order_id=order_to_create.client_order_id, + exchange_order_id=exchange_order_id, + trading_pair=order_to_create.trading_pair, + misc_updates={ + "creation_transaction_hash": transaction_hash, + }, + exception=None, + )) + + self.logger().debug("batch_order_create: end") + + return place_order_results + + async def cancel_order(self, order: GatewayInFlightOrder) -> Tuple[bool, Optional[Dict[str, Any]]]: + active_order = self._gateway_order_tracker.active_orders.get(order.client_order_id) + + if active_order.exchange_order_id is None: + await self._update_order_status() + active_order = self._gateway_order_tracker.active_orders.get(order.client_order_id) + + fillable = self._gateway_order_tracker.all_fillable_orders_by_exchange_order_id.get( + active_order.exchange_order_id + ) + + if fillable and ( + active_order + ) and ( + active_order.current_state != OrderState.CANCELED + ) and ( + active_order.current_state != OrderState.FILLED + ) and ( + active_order.exchange_order_id + ): + self.logger().debug("cancel_order: start") + + self._check_markets_initialized() or await self._update_markets() + + await order.get_exchange_order_id() + + transaction_hash = None + + async with self._locks.cancel_order: + try: + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + "trading_pair": order.trading_pair, + "address": self._owner_address, + "exchange_order_id": order.exchange_order_id, + } + + self.logger().debug(f"""clob_cancel_order request:\n "{self._dump(request)}".""") + + response = await self._gateway_clob_cancel_order(request) + + self.logger().debug(f"""clob_cancel_order response:\n "{self._dump(response)}".""") + + transaction_hash = response["txHash"] + + if transaction_hash in ("", None): + return False, DotMap({}, _dynamic=False) + + self.logger().info( + f"""Order "{order.client_order_id}" / "{order.exchange_order_id}" successfully cancelled. Transaction hash: "{transaction_hash}".""" + ) + except Exception as exception: + # await self.gateway_order_tracker.process_order_not_found(order.client_order_id) + if f"""Order "{order.exchange_order_id}" not found on markets""" in str(exception.args): + # order_update = self.get_order_status_update(order) + # self.gateway_order_tracker.process_order_update(order_update) + + self.logger().info( + f"""Order "{order.exchange_order_id}" not found on markets""" + ) + + return True, DotMap({}, _dynamic=False) + + elif 'No orders with the specified information exist' in str(exception.args): + self.logger().info( + f"""Order "{order.client_order_id}" / "{order.exchange_order_id}" already cancelled.""" + ) + + transaction_hash = "0000000000000000000000000000000000000000000000000000000000000000" # noqa: mock + else: + self.logger().info( + f"""Cancellation of order "{order.client_order_id}" / "{order.exchange_order_id}" failed.""" + ) + + raise exception + + misc_updates = DotMap({ + "cancelation_transaction_hash": transaction_hash, + }, _dynamic=False) + + self.logger().debug("cancel_order: end") + + order.cancel_tx_hash = transaction_hash + + await self._update_order_status() + + return True, misc_updates + + return False, DotMap({}, _dynamic=False) + + async def batch_order_cancel(self, orders_to_cancel: List[GatewayInFlightOrder]) -> List[CancelOrderResult]: + self.logger().debug("batch_order_cancel: start") + + self._check_markets_initialized() or await self._update_markets() + + client_ids = [order.client_order_id for order in orders_to_cancel] + + in_flight_orders_to_cancel = [ + self._gateway_order_tracker.fetch_tracked_order(client_order_id=order.client_order_id) + for order in orders_to_cancel + ] + exchange_order_ids_to_cancel = await safe_gather( + *[order.get_exchange_order_id() for order in in_flight_orders_to_cancel], + return_exceptions=True, + ) + found_orders_to_cancel = [ + order + for order, result in zip(orders_to_cancel, exchange_order_ids_to_cancel) + if not isinstance(result, asyncio.TimeoutError) + ] + + ids = [order.exchange_order_id for order in found_orders_to_cancel] + + async with self._locks.cancel_orders: + try: + + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + "address": self._owner_address, + "orders_to_create": [], + "orders_to_cancel": found_orders_to_cancel, + } + + self.logger().debug(f"""clob_batch_order_moodify request:\n "{self._dump(request)}".""") + + response = await self._gateway_clob_batch_order_modify(request) + + self.logger().debug(f"""clob_batch_order_modify response:\n "{self._dump(response)}".""") + + transaction_hash = response["txHash"] + + self.logger().info( + f"""Orders "{client_ids}" / "{ids}" successfully cancelled. Transaction hash(es): "{transaction_hash}".""" + ) + except Exception as exception: + self.logger().info( + f"""Cancellation of orders "{client_ids}" / "{ids}" failed.""" + ) + + raise exception + + if transaction_hash in (None, ""): + raise RuntimeError( + f"""Cancellation of orders "{client_ids}" / "{ids}" failed. Invalid transaction hash: "{transaction_hash}".""" + ) + + cancel_order_results = [] + for order_to_cancel in orders_to_cancel: + cancel_order_results.append(CancelOrderResult( + client_order_id=order_to_cancel.client_order_id, + trading_pair=order_to_cancel.trading_pair, + misc_updates={ + "cancelation_transaction_hash": transaction_hash + }, + exception=None, + )) + + self.logger().debug("batch_order_cancel: end") + + return cancel_order_results + + async def get_last_traded_price(self, trading_pair: str) -> Decimal: + self.logger().debug("get_last_traded_price: start") + + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + "trading_pair": self._trading_pair, + } + + self.logger().debug(f"""get_clob_ticker request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_clob_ticker(request) + + self.logger().debug(f"""get_clob_ticker response:\n "{self._dump(response)}".""") + + ticker = DotMap(response, _dynamic=False).markets[self._trading_pair] + + ticker_price = Decimal(ticker.price) + + self.logger().debug("get_last_traded_price: end") + + return ticker_price + + async def get_order_book_snapshot(self, trading_pair: str) -> OrderBookMessage: + self.logger().debug("get_order_book_snapshot: start") + + request = { + "trading_pair": self._trading_pair, + "connector": self._connector, + "chain": self._chain, + "network": self._network, + } + + self.logger().debug(f"""get_clob_orderbook_snapshot request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_clob_orderbook_snapshot(request) + + self.logger().debug(f"""get_clob_orderbook_snapshot response:\n "{self._dump(response)}".""") + + order_book = DotMap(response, _dynamic=False) + + price_scale = 1 + size_scale = 1 + + timestamp = time() + + bids = [] + asks = [] + for bid in order_book.buys: + bids.append((Decimal(bid.price) * price_scale, Decimal(bid.quantity) * size_scale)) + + for ask in order_book.sells: + asks.append((Decimal(ask.price) * price_scale, Decimal(ask.quantity) * size_scale)) + + snapshot = OrderBookMessage( + message_type=OrderBookMessageType.SNAPSHOT, + content={ + "trading_pair": trading_pair, + "update_id": timestamp, + "bids": bids, + "asks": asks, + }, + timestamp=timestamp + ) + + self.logger().debug("get_order_book_snapshot: end") + + return snapshot + + async def get_account_balances(self) -> Dict[str, Dict[str, Decimal]]: + self.logger().debug("get_account_balances: start") + + request = { + "chain": self._chain, + "network": self._network, + "address": self._owner_address, + "connector": self._connector, + } + + if self._trading_pair: + request["token_symbols"] = [self._trading_pair.split("-")[0], self._trading_pair.split("-")[1], KUJIRA_NATIVE_TOKEN] + else: + request["token_symbols"] = [] + + # self.logger().debug(f"""get_balances request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_balances(request) + + self.logger().debug(f"""get_balances response:\n "{self._dump(response)}".""") + + balances = DotMap(response, _dynamic=False).balances + + hb_balances = {} + for token, balance in balances.items(): + hb_balances[token] = DotMap({}, _dynamic=False) + hb_balances[token]["total_balance"] = balance + hb_balances[token]["available_balance"] = balance + + # self.logger().debug("get_account_balances: end") + + return hb_balances + + async def get_order_status_update(self, in_flight_order: GatewayInFlightOrder) -> OrderUpdate: + active_order = self.gateway_order_tracker.active_orders.get(in_flight_order.client_order_id) + + if active_order: + self.logger().debug("get_order_status_update: start") + + if active_order.current_state != OrderState.CANCELED: + await in_flight_order.get_exchange_order_id() + + request = { + "trading_pair": self._trading_pair, + "chain": self._chain, + "network": self._network, + "connector": self._connector, + "address": self._owner_address, + "exchange_order_id": in_flight_order.exchange_order_id, + } + + self.logger().debug(f"""get_clob_order_status_updates request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_clob_order_status_updates(request) + + self.logger().debug(f"""get_clob_order_status_updates response:\n "{self._dump(response)}".""") + + order_response = DotMap(response, _dynamic=False)["orders"] + order_update: OrderUpdate + if order_response: + order = order_response[0] + if order: + order_status = KujiraOrderStatus.to_hummingbot(KujiraOrderStatus.from_name(order.state)) + else: + order_status = in_flight_order.current_state + + open_update = OrderUpdate( + trading_pair=in_flight_order.trading_pair, + update_timestamp=time(), + new_state=order_status, + client_order_id=in_flight_order.client_order_id, + exchange_order_id=in_flight_order.exchange_order_id, + misc_updates={ + "creation_transaction_hash": in_flight_order.creation_transaction_hash, + "cancelation_transaction_hash": in_flight_order.cancel_tx_hash, + }, + ) + + order_update = open_update + else: + canceled_update = OrderUpdate( + trading_pair=in_flight_order.trading_pair, + update_timestamp=time(), + new_state=OrderState.CANCELED, + client_order_id=in_flight_order.client_order_id, + exchange_order_id=in_flight_order.exchange_order_id, + misc_updates={ + "creation_transaction_hash": in_flight_order.creation_transaction_hash, + "cancelation_transaction_hash": in_flight_order.cancel_tx_hash, + }, + ) + + order_update = canceled_update + + self.logger().debug("get_order_status_update: end") + return order_update + + no_update = OrderUpdate( + trading_pair=in_flight_order.trading_pair, + update_timestamp=time(), + new_state=in_flight_order.current_state, + client_order_id=in_flight_order.client_order_id, + exchange_order_id=in_flight_order.exchange_order_id, + misc_updates={ + "creation_transaction_hash": in_flight_order.creation_transaction_hash, + "cancelation_transaction_hash": in_flight_order.cancel_tx_hash, + }, + ) + self.logger().debug("get_order_status_update: end") + return no_update + + async def get_all_order_fills(self, in_flight_order: GatewayInFlightOrder) -> List[TradeUpdate]: + if in_flight_order.exchange_order_id: + + active_order = self.gateway_order_tracker.active_orders.get(in_flight_order.client_order_id) + + if active_order: + if active_order.current_state != OrderState.CANCELED: + self.logger().debug("get_all_order_fills: start") + + trade_update = None + + request = { + "trading_pair": self._trading_pair, + "chain": self._chain, + "network": self._network, + "connector": self._connector, + "address": self._owner_address, + "exchange_order_id": in_flight_order.exchange_order_id, + } + + self.logger().debug(f"""get_clob_order_status_updates request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_clob_order_status_updates(request) + + self.logger().debug(f"""get_clob_order_status_updates response:\n "{self._dump(response)}".""") + + orders = DotMap(response, _dynamic=False)["orders"] + + order = None + if len(orders): + order = orders[0] + + if order is not None: + order_status = KujiraOrderStatus.to_hummingbot(KujiraOrderStatus.from_name(order.state)) + else: + order_status = in_flight_order.current_state + + if order and order_status == OrderState.FILLED: + timestamp = time() + trade_id = str(timestamp) + + trade_update = TradeUpdate( + trade_id=trade_id, + client_order_id=in_flight_order.client_order_id, + exchange_order_id=in_flight_order.exchange_order_id, + trading_pair=in_flight_order.trading_pair, + fill_timestamp=timestamp, + fill_price=in_flight_order.price, + fill_base_amount=in_flight_order.amount, + fill_quote_amount=in_flight_order.price * in_flight_order.amount, + fee=TradeFeeBase.new_spot_fee( + fee_schema=TradeFeeSchema(), + trade_type=in_flight_order.trade_type, + flat_fees=[TokenAmount( + amount=Decimal(self._market.fees.taker), + token=self._market.quoteToken.symbol + )] + ), + ) + + self.logger().debug("get_all_order_fills: end") + + if trade_update: + return [trade_update] + + return [] + + def _get_trading_pair_from_market_info(self, market_info: Dict[str, Any]) -> str: + return market_info["hb_trading_pair"] + + def _get_exchange_base_quote_tokens_from_market_info(self, market_info: Dict[str, Any]) -> Tuple[str, str]: + base = market_info["baseToken"]["symbol"] + quote = market_info["quoteToken"]["symbol"] + + return base, quote + + def _get_last_trade_price_from_ticker_data(self, ticker_data: List[Dict[str, Any]]) -> Decimal: + raise NotImplementedError + + def is_order_not_found_during_status_update_error(self, status_update_exception: Exception) -> bool: + self.logger().debug("is_order_not_found_during_status_update_error: start") + + output = str(status_update_exception).startswith("No update found for order") + + self.logger().debug("is_order_not_found_during_status_update_error: end") + + return output + + def is_order_not_found_during_cancelation_error(self, cancelation_exception: Exception) -> bool: + self.logger().debug("is_order_not_found_during_cancelation_error: start") + + output = False + + self.logger().debug("is_order_not_found_during_cancelation_error: end") + + return output + + async def check_network_status(self) -> NetworkStatus: + # self.logger().debug("check_network_status: start") + + try: + await self._gateway_ping_gateway() + + output = NetworkStatus.CONNECTED + except asyncio.CancelledError: + raise + except Exception as exception: + self.logger().error(exception) + + output = NetworkStatus.NOT_CONNECTED + + # self.logger().debug("check_network_status: end") + + return output + + @property + def is_cancel_request_in_exchange_synchronous(self) -> bool: + self.logger().debug("is_cancel_request_in_exchange_synchronous: start") + + output = True + + self.logger().debug("is_cancel_request_in_exchange_synchronous: end") + + return output + + def _check_markets_initialized(self) -> bool: + # self.logger().debug("_check_markets_initialized: start") + + output = self._markets is not None and bool(self._markets) + + # self.logger().debug("_check_markets_initialized: end") + + return output + + async def _update_markets(self): + self.logger().debug("_update_markets: start") + + request = { + "connector": self._connector, + "chain": self._chain, + "network": self._network, + } + + if self._trading_pair: + request["trading_pair"] = self._trading_pair + + self.logger().debug(f"""get_clob_markets request:\n "{self._dump(request)}".""") + + response = await self._gateway_get_clob_markets(request) + + self.logger().debug(f"""get_clob_markets response:\n "{self._dump(response)}".""") + + if 'trading_pair' in request or self._trading_pair: + markets = DotMap(response, _dynamic=False).markets + self._markets = markets[request['trading_pair']] + self._market = self._markets + self._markets_info.clear() + self._market["hb_trading_pair"] = convert_market_name_to_hb_trading_pair(self._market.name) + self._markets_info[self._market["hb_trading_pair"]] = self._market + else: + self._markets = DotMap(response, _dynamic=False).markets + + self._markets_info.clear() + for market in self._markets.values(): + market["hb_trading_pair"] = convert_market_name_to_hb_trading_pair(market.name) + self._markets_info[market["hb_trading_pair"]] = market + + self.logger().debug("_update_markets: end") + + return self._markets + + def _parse_trading_rule(self, trading_pair: str, market_info: Any) -> TradingRule: + self.logger().debug("_parse_trading_rule: start") + + trading_rule = TradingRule( + trading_pair=trading_pair, + min_order_size=Decimal(market_info.minimumOrderSize), + min_price_increment=Decimal(market_info.minimumPriceIncrement), + min_base_amount_increment=Decimal(market_info.minimumBaseAmountIncrement), + min_quote_amount_increment=Decimal(market_info.minimumQuoteAmountIncrement), + ) + + self.logger().debug("_parse_trading_rule: end") + + return trading_rule + + def _get_exchange_trading_pair_from_market_info(self, market_info: Any) -> str: + self.logger().debug("_get_exchange_trading_pair_from_market_info: start") + + output = market_info.id + + self.logger().debug("_get_exchange_trading_pair_from_market_info: end") + + return output + + def _get_maker_taker_exchange_fee_rates_from_market_info(self, market_info: Any) -> MakerTakerExchangeFeeRates: + self.logger().debug("_get_maker_taker_exchange_fee_rates_from_market_info: start") + + fee_scaler = Decimal("1") - Decimal(market_info.fees.serviceProvider) + maker_fee = Decimal(market_info.fees.maker) * fee_scaler + taker_fee = Decimal(market_info.fees.taker) * fee_scaler + + output = MakerTakerExchangeFeeRates( + maker=maker_fee, + taker=taker_fee, + maker_flat_fees=[], + taker_flat_fees=[] + ) + + self.logger().debug("_get_maker_taker_exchange_fee_rates_from_market_info: end") + + return output + + async def _update_markets_loop(self): + self.logger().debug("_update_markets_loop: start") + + while True: + self.logger().debug("_update_markets_loop: start loop") + + await self._update_markets() + await asyncio.sleep(MARKETS_UPDATE_INTERVAL) + + self.logger().debug("_update_markets_loop: end loop") + + async def _check_if_order_failed_based_on_transaction( + self, + transaction: Any, + order: GatewayInFlightOrder + ) -> bool: + order_id = await order.get_exchange_order_id() + + return order_id.lower() not in transaction.data.lower() + + @staticmethod + def _dump(target: Any): + try: + return jsonpickle.encode(target, unpicklable=True, indent=2) + except (Exception,): + return target + + @staticmethod + def _create_task(target: Any) -> Task: + return asyncio.ensure_future(target) + + @staticmethod + def _create_event_loop(): + return asyncio.get_event_loop() + + def _create_and_run_task(self, target: Any): + event_loop = self._create_event_loop() + task = self._create_task(target) + if not event_loop.is_running(): + event_loop.run_until_complete(task) + + async def _update_order_status(self): + async with self._locks.all_active_orders: + self._all_active_orders = ( + self._gateway_order_tracker.active_orders if self._gateway_order_tracker else {} + ) + + orders = copy.copy(self._all_active_orders).values() + + for order in orders: + request = { + "trading_pair": self._trading_pair, + "chain": self._chain, + "network": self._network, + "connector": self._connector, + "address": self._owner_address, + "exchange_order_id": order.exchange_order_id, + } + + response = await self._gateway_get_clob_order_status_updates(request) + + try: + if response["orders"] is not None and len(response['orders']) and response["orders"][0] is not None and response["orders"][0]["state"] != order.current_state: + updated_order = response["orders"][0] + + message = { + "trading_pair": self._trading_pair, + "update_timestamp": + updated_order["updatedAt"] if len(updated_order["updatedAt"]) else time(), + "new_state": updated_order["state"], + } + + if updated_order["state"] in { + OrderState.PENDING_CREATE, + OrderState.OPEN, + OrderState.PARTIALLY_FILLED, + OrderState.PENDING_CANCEL, + }: + + self._publisher.trigger_event(event_tag=MarketEvent.OrderUpdate, message=message) + + elif updated_order["state"] == OrderState.FILLED.name: + + message = { + "timestamp": + updated_order["updatedAt"] if len(updated_order["updatedAt"]) else time(), + "order_id": order.client_order_id, + "trading_pair": self._trading_pair, + "trade_type": order.trade_type, + "order_type": order.order_type, + "price": order.price, + "amount": order.amount, + "trade_fee": '', + "exchange_trade_id": "", + "exchange_order_id": order.exchange_order_id, + } + + self._publisher.trigger_event(event_tag=MarketEvent.OrderFilled, message=message) + + elif updated_order["state"] == OrderState.CANCELED.name: + + message = { + "timestamp": + updated_order["updatedAt"] if len(updated_order["updatedAt"]) else time(), + "order_id": order.client_order_id, + "exchange_order_id": order.exchange_order_id, + } + + self._publisher.trigger_event(event_tag=OrderCancelledEvent, message=message) + + except Exception: + raise self.logger().exception(Exception) + + async def _update_all_active_orders(self): + while True: + await self._update_order_status() + await asyncio.sleep(UPDATE_ORDER_STATUS_INTERVAL) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_ping_gateway(self, request): + return await self._gateway.ping_gateway() + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_get_clob_markets(self, request): + return await self._gateway.get_clob_markets(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_get_clob_orderbook_snapshot(self, request): + return await self._gateway.get_clob_orderbook_snapshot(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_get_clob_ticker(self, request): + return await self._gateway.get_clob_ticker(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_get_balances(self, request): + return await self._gateway.get_balances(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_clob_place_order(self, request): + return await self._gateway.clob_place_order(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_clob_cancel_order(self, request): + return await self._gateway.clob_cancel_order(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_clob_batch_order_modify(self, request): + return await self._gateway.clob_batch_order_modify(**request) + + @automatic_retry_with_timeout(retries=NUMBER_OF_RETRIES, delay=DELAY_BETWEEN_RETRIES, timeout=TIMEOUT) + async def _gateway_get_clob_order_status_updates(self, request): + return await self._gateway.get_clob_order_status_updates(**request) diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_constants.py b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_constants.py new file mode 100644 index 0000000000..d7372da29c --- /dev/null +++ b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_constants.py @@ -0,0 +1,17 @@ +from dotmap import DotMap + +KUJIRA_NATIVE_TOKEN = DotMap({ + "id": "ukuji", + "name": "Kuji", + "symbol": "KUJI", + "decimals": "6", +}, _dynamic=False) + +CONNECTOR = "kujira" + +MARKETS_UPDATE_INTERVAL = 8 * 60 * 60 +UPDATE_ORDER_STATUS_INTERVAL = 1 + +NUMBER_OF_RETRIES = 3 +DELAY_BETWEEN_RETRIES = 3 +TIMEOUT = 60 diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_helpers.py b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_helpers.py new file mode 100644 index 0000000000..21942f4d4f --- /dev/null +++ b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_helpers.py @@ -0,0 +1,65 @@ +import asyncio +import hashlib +import traceback +from datetime import datetime +from typing import Any, List + +import jsonpickle + + +def generate_hash(input: Any) -> str: + return generate_hashes([input])[0] + + +def generate_hashes(inputs: List[Any]) -> List[str]: + hashes = [] + salt = datetime.now() + + for input in inputs: + serialized = jsonpickle.encode(input, unpicklable=True) + hasher = hashlib.md5() + target = f"{salt}{serialized}".encode("utf-8") + hasher.update(target) + hash = hasher.hexdigest() + + hashes.append(hash) + + return hashes + + +def convert_hb_trading_pair_to_market_name(trading_pair: str) -> str: + return trading_pair.replace("-", "/") + + +def convert_market_name_to_hb_trading_pair(market_name: str) -> str: + return market_name.replace("/", "-") + + +def automatic_retry_with_timeout(retries=1, delay=0, timeout=None): + def decorator(func): + async def wrapper(*args, **kwargs): + errors = [] + for i in range(retries): + try: + result = await asyncio.wait_for(func(*args, **kwargs), timeout=timeout) + return result + except Exception as e: + tb_str = traceback.format_exception(type(e), value=e, tb=e.__traceback__) + errors.append(''.join(tb_str)) + await asyncio.sleep(delay) + error_message = f"Function failed after {retries} attempts. Here are the errors:\n" + "\n".join(errors) + raise Exception(error_message) + return wrapper + return decorator + + +class AsyncLock: + def __init__(self): + self._lock = asyncio.Lock() + + async def __aenter__(self): + await self._lock.acquire() + return self + + async def __aexit__(self, exc_type, exc_value, traceback): + self._lock.release() diff --git a/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_types.py b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_types.py new file mode 100644 index 0000000000..4469acb6b7 --- /dev/null +++ b/hummingbot/connector/gateway/clob_spot/data_sources/kujira/kujira_types.py @@ -0,0 +1,132 @@ +from enum import Enum + +from hummingbot.core.data_type.common import OrderType as HummingBotOrderType, TradeType as HummingBotOrderSide +from hummingbot.core.data_type.in_flight_order import OrderState as HummingBotOrderStatus + + +class OrderStatus(Enum): + OPEN = "OPEN", + CANCELLED = "CANCELLED", + PARTIALLY_FILLED = "PARTIALLY_FILLED", + FILLED = "FILLED", + CREATION_PENDING = "CREATION_PENDING", + CANCELLATION_PENDING = "CANCELLATION_PENDING", + UNKNOWN = "UNKNOWN" + + @staticmethod + def from_name(name: str): + if name == "OPEN": + return OrderStatus.OPEN + elif name == "CANCELLED": + return OrderStatus.CANCELLED + elif name == "PARTIALLY_FILLED": + return OrderStatus.PARTIALLY_FILLED + elif name == "FILLED": + return OrderStatus.FILLED + elif name == "CREATION_PENDING": + return OrderStatus.CREATION_PENDING + elif name == "CANCELLATION_PENDING": + return OrderStatus.CANCELLATION_PENDING + else: + raise ValueError(f"Unknown order status: {name}") + + @staticmethod + def from_hummingbot(target: HummingBotOrderStatus): + if target == HummingBotOrderStatus.PENDING_CREATE: + return OrderStatus.CREATION_PENDING + elif target == HummingBotOrderStatus.OPEN: + return OrderStatus.OPEN + elif target == HummingBotOrderStatus.PENDING_CANCEL: + return OrderStatus.CANCELLATION_PENDING + elif target == HummingBotOrderStatus.CANCELED: + return OrderStatus.CANCELLED + elif target == HummingBotOrderStatus.PARTIALLY_FILLED: + return OrderStatus.PARTIALLY_FILLED + elif target == HummingBotOrderStatus.FILLED: + return OrderStatus.FILLED + else: + raise ValueError(f"Unknown order status: {target}") + + @staticmethod + def to_hummingbot(self): + if self == OrderStatus.OPEN: + return HummingBotOrderStatus.OPEN + elif self == OrderStatus.CANCELLED: + return HummingBotOrderStatus.CANCELED + elif self == OrderStatus.PARTIALLY_FILLED: + return HummingBotOrderStatus.PARTIALLY_FILLED + elif self == OrderStatus.FILLED: + return HummingBotOrderStatus.FILLED + elif self == OrderStatus.CREATION_PENDING: + return HummingBotOrderStatus.PENDING_CREATE + elif self == OrderStatus.CANCELLATION_PENDING: + return HummingBotOrderStatus.PENDING_CANCEL + else: + raise ValueError(f"Unknown order status: {self}") + + +class OrderType(Enum): + MARKET = 'MARKET', + LIMIT = 'LIMIT', + + @staticmethod + def from_name(name: str): + if name == "MARKET": + return OrderType.MARKET + elif name == "LIMIT": + return OrderType.LIMIT + else: + raise ValueError(f"Unknown order type: {name}") + + @staticmethod + def from_hummingbot(target: HummingBotOrderType): + if target == HummingBotOrderType.LIMIT: + return OrderType.LIMIT + else: + raise ValueError(f'Unrecognized order type "{target}".') + + @staticmethod + def to_hummingbot(self): + if self == OrderType.LIMIT: + return HummingBotOrderType.LIMIT + else: + raise ValueError(f'Unrecognized order type "{self}".') + + +class OrderSide(Enum): + BUY = 'BUY', + SELL = 'SELL', + + @staticmethod + def from_name(name: str): + if name == "BUY": + return OrderSide.BUY + elif name == "SELL": + return OrderSide.SELL + else: + raise ValueError(f"Unknown order side: {name}") + + @staticmethod + def from_hummingbot(target: HummingBotOrderSide): + if target == HummingBotOrderSide.BUY: + return OrderSide.BUY + elif target == HummingBotOrderSide.SELL: + return OrderSide.SELL + else: + raise ValueError(f'Unrecognized order side "{target}".') + + def to_hummingbot(self): + if self == OrderSide.BUY: + return HummingBotOrderSide.BUY + elif self == OrderSide.SELL: + return HummingBotOrderSide.SELL + else: + raise ValueError(f'Unrecognized order side "{self}".') + + +class TickerSource(Enum): + ORDER_BOOK_SAP = "orderBookSimpleAveragePrice", + ORDER_BOOK_WAP = "orderBookWeightedAveragePrice", + ORDER_BOOK_VWAP = "orderBookVolumeWeightedAveragePrice", + LAST_FILLED_ORDER = "lastFilledOrder", + NOMICS = "nomics", diff --git a/hummingbot/connector/gateway/clob_spot/gateway_clob_spot.py b/hummingbot/connector/gateway/clob_spot/gateway_clob_spot.py index 74f7cac85d..06510d928e 100644 --- a/hummingbot/connector/gateway/clob_spot/gateway_clob_spot.py +++ b/hummingbot/connector/gateway/clob_spot/gateway_clob_spot.py @@ -70,6 +70,8 @@ def __init__( self._add_forwarders() + self.has_started = False + super().__init__(client_config_map) @property @@ -121,7 +123,7 @@ def trading_pairs(self) -> List[str]: @property def is_cancel_request_in_exchange_synchronous(self) -> bool: - return False + return self._api_data_source.is_cancel_request_in_exchange_synchronous @property def is_trading_required(self) -> bool: @@ -152,13 +154,29 @@ def status_dict(self) -> Dict[str, bool]: sd["api_data_source_initialized"] = self._api_data_source.ready return sd + def start(self, *args, **kwargs): + super().start(**kwargs) + safe_ensure_future(self.start_network()) + safe_ensure_future(self._api_data_source.start()) + + def stop(self, *args, **kwargs): + super().stop(**kwargs) + safe_ensure_future(self._api_data_source.stop()) + async def start_network(self): - await self._api_data_source.start() - await super().start_network() + if not self.has_started: + await self._api_data_source.start() + await super().start_network() + self.has_started = True async def stop_network(self): await super().stop_network() await self._api_data_source.stop() + self.has_started = False + + @property + def ready(self) -> bool: + return super().ready def supported_order_types(self) -> List[OrderType]: return self._api_data_source.get_supported_order_types() @@ -719,3 +737,10 @@ def _get_poll_interval(self, timestamp: float) -> float: else self.LONG_POLL_INTERVAL ) return poll_interval + + async def cancel_all(self, timeout_seconds: float) -> List[CancellationResult]: + timeout = self._api_data_source.cancel_all_orders_timeout \ + if self._api_data_source.cancel_all_orders_timeout is not None \ + else timeout_seconds + + return await super().cancel_all(timeout) diff --git a/hummingbot/core/utils/gateway_config_utils.py b/hummingbot/core/utils/gateway_config_utils.py index d5a566fd05..3104c9189f 100644 --- a/hummingbot/core/utils/gateway_config_utils.py +++ b/hummingbot/core/utils/gateway_config_utils.py @@ -14,7 +14,8 @@ "cronos": "CRO", "near": "NEAR", "injective": "INJ", - "xdc": "XDC" + "xdc": "XDC", + "kujira": "KUJI" } SUPPORTED_CHAINS = set(native_tokens.keys()) diff --git a/setup/environment.yml b/setup/environment.yml index e9463ad839..ca9b230575 100644 --- a/setup/environment.yml +++ b/setup/environment.yml @@ -44,10 +44,12 @@ dependencies: - diff-cover==5.1.2 - docker==5.0.3 - eip712-structs==1.1.0 + - dotmap==1.3.30 - ethsnarks-loopring==0.1.5 - flake8==3.7.9 - importlib-metadata==0.23 - injective-py==0.7.* + - jsonpickle==3.0.1 - mypy-extensions==0.4.3 - pandas_ta==0.3.14b - pre-commit==2.18.1 diff --git a/test/hummingbot/client/test_settings.py b/test/hummingbot/client/test_settings.py index 535fdef3de..85c03439b5 100644 --- a/test/hummingbot/client/test_settings.py +++ b/test/hummingbot/client/test_settings.py @@ -8,6 +8,7 @@ from hummingbot.connector.gateway.clob_spot.data_sources.injective.injective_api_data_source import ( InjectiveAPIDataSource, ) +from hummingbot.connector.gateway.clob_spot.data_sources.kujira.kujira_api_data_source import KujiraAPIDataSource from hummingbot.core.data_type.trade_fee import TradeFeeSchema @@ -150,3 +151,47 @@ def test_conn_init_parameters_for_gateway_injective_connector( self.assertIsInstance(api_data_source, InjectiveAPIDataSource) self.assertEqual(expected_params_without_api_data_source, params) + + @patch("hummingbot.client.settings.GatewayConnectionSetting.get_connector_spec_from_market_name") + def test_conn_init_parameters_for_gateway_kujira_connector( + self, get_connector_spec_from_market_name_mock: MagicMock + ): + get_connector_spec_from_market_name_mock.return_value = { + "connector": "kujira", + "chain": "kujira", + "network": "mainnet", + "trading_type": "CLOB_SPOT", + "wallet_address": "0xA86b66F4e7DC45a943D71a11c7DDddE341246682", # noqa: mock + "additional_spenders": [], + } + conn_settings = ConnectorSetting( + name="kujira_kujira_mainnet", + type=ConnectorType.CLOB_SPOT, + example_pair="KUJI-DEMO", + centralised=True, + use_ethereum_wallet=False, + trade_fee_schema=TradeFeeSchema(), + config_keys=None, + is_sub_domain=False, + parent_name=None, + domain_parameter=None, + use_eth_gas_lookup=False, + ) + + expected_params_without_api_data_source = { + "connector_name": "kujira", + "chain": "kujira", + "network": "mainnet", + "address": "0xA86b66F4e7DC45a943D71a11c7DDddE341246682", # noqa: mock + "trading_pairs": [], + "trading_required": False, + "client_config_map": None, + } + params = conn_settings.conn_init_parameters() + + self.assertIn("api_data_source", params) + + api_data_source = params.pop("api_data_source") + + self.assertIsInstance(api_data_source, KujiraAPIDataSource) + self.assertEqual(expected_params_without_api_data_source, params)