Getting the book in order
Python and Hive
A few months ago I started programming in Python and directly dived into programming for hive. Luckily @holger80 once write the hiveengine library for Python. Thank you very much.
And a few weeks ago I started with the quest: How to access the token market data?
The former mentioned library brings with it a Market and Token class to do your bidding in that case.
Getting the book
One of the most interesting and important data is the current order book to a token. Hiveengine lib is pretty simple to use for that:
That is all it takes to get the first 5 lines of each side. The result looks as follows:
I find it quite interesting that we can discover the account corresponding to an order this way. That information is normally hidden by tribaldex or the hive-engine market sites.
On the other hand I notice those are not the top orders. They are the oldest orders.
Replacing the limit=5 by limit=100 confirms my concerns, we are getting the orders sorted by their date of creation.
The most interesting orders are usually the highest bids and lowest asks. To get these orders we need to load the entire book and resort it. Very inefficient in time and traffic just to get the top 10 lines of each side, if the book contains hundreds or even thousands of orders.
Digg into that code
So I take a deeper look into the code. What do the functions get_buy_book() and get_sell_book() actually do?
Ok, looks simple enough. First of all I notice there is no parameter that allows for a different kind of sorting. That's a bummer. My next thought is: It is simply passing along the request to the find() method of an api object. So what does that do?
At this point I feel like Alice falling down the rabbit hole. Yet another pass along. This time to an rpc object. After some more digging I find a hint of what's happening in the Api class:
At this point I am very very happy and glad @holger80 put all this together for us.
Getting more information
Some more perusing reveals that all the calls are just packed into a query that is sent to api.hive-engine.com and then the result is given back. After a long back and forth fight with google I decide to take another approach and venture into the hive engine discord server.
I don't even have to ask, the search function in the developer channel brings me to the documentation site in which I find this:
Aha! So there is a choice of index. And now the rpc call (see screenshot above) makes sense with the index variable. Sadly this parameter is skipped on its way up to the Token class and therefore not used.
While I'm there (in the discord developer channel) I start searching for a few keywords and stumble upon this entry:
Eureka! Thank you very much @foxon, you just saved my day.
There is a way to select the index, determine the sorting order and limit the results. Now this just needs to get implemented into the Token class.
Implementing the solution
I do not want to mess with the original code. So I chose the path of inheritance and override the get methods:
Since the original methods simply passed along the parameters to api.find() which in turn called rpc.find I now call the rpc.find() method directly and put in all the parameters I need for the sorting I want. Looking at @foxon's example I gather I simply have to fill in the index parameter and also append the descending True/False information. The json builder used in the rpc object will put it all together into a nice call to the hive-engine api and give us the result as we know it (also in json).
If you find this useful and want to use it yourself, here is the code in text form:
from hiveengine.tokenobject import Token
class TBToken(Token):
def get_buy_book(self, limit=100, offset=0):
"""Returns the buy book"""
result = self.api.rpc.find({"contract": "market", "table": "buyBook", "query": {"symbol": self.symbol},"limit": limit, "offset": offset, "indexes": [{"index":"priceDec", "descending":True}]}, endpoint = "contracts")
return result
def get_sell_book(self, limit=100, offset=0):
"""Returns the sell book"""
result = self.api.rpc.find({"contract": "market", "table": "sellBook", "query": {"symbol": self.symbol}, "limit": limit, "offset": offset, "indexes": {"index":"priceDec", "descending":False}]}, endpoint = "contracts")
return result
So now I use the TBToken class instead of the Token class and my get_buy_book() and get_sell_book() calls return in proper order (starting with the highest bid and lowest ask).
Finally
Running the new code, we get the following result for the first five lines:
Looking good, we get the buy book with highest bid first and sell book with lowest ask first. And we don't waste traffic and time loading and sorting the complete book first. Most times we are only interested in the first few lines of these books anyway, right?
While this is a hot patch for my own personal programming needs, I think the overall library would benefit from including these sorting options into their code. That is why I tagged the respective accounts in this post, in the hope they read this and grant my humble request.
That's all Folks
Thank you for coming along in this journey. Did you learn something new? Did I make a terrible mistake? Do you like my solution? Let me know so I can learn. Thank you. 😊
I hope you had as much fun coming along as I had being on this trip.
Edit: Screenshot and paragraph presenting the result of the modified code inserted.
Python seems too hard for me. Congrats on what you have accomplished. I haven't programmed since back in college over 20 years ago. It was C++ and I wasn't that good at it. I'd like to learn Python, but I can' think of a practical use for it.
Thank you.
Ah, I have (had) a huge gap in my programming experience as well. Started with PASCAL back then, ventured through C/C++ PHP and all that stuff and after over a decade of pause I picked up Python now.
Give it a try, pretty simply especially if you have background. There's a lib for almost anything in there.
To quote xkcd:
Source
:) that is funny. I know I should give it a try. Like I said though, I can't think of anything practical to apply it to. I think that is the biggest hiccup for me. If I had a problem I wanted to solve, it might make it easier.
If you ever do and write a post about it, I cannot wait to read it.
Will be interesting to know what problem finally brought you to it. 😊
Don't hold your breath! School is starting soon, so my time is going to be monopolized by that I think!
Hi, I'm sloth, I'm full of great ideas with no practical knowledge of putting them into effect, so, if you'd like some problems I can give you a list! Come buzz with us at sloth.buzz.
Let's make Hive great again!
Good to know, thanks!
I keep meaning to use Hive as a guinea pig, I learnt python in lockdown then did nothing with it 🤣
For example you could use it to automatically create your Saturday Saver's club diagrams and tables. I bet there is a library to write into excel tables. 😉
Oh now that is a good idea!
Do something!! dooooo something!!!
Come make something cool for the sloths :D
Congratulations @hannes-stoffel! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)
Your next target is to reach 5000 upvotes.
Your next target is to reach 4000 replies.
You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!
Check out our last posts:
Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!
Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).
You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.
Congratulations @hannes-stoffel! You received a personal badge!
Wait until the end of Power Up Day to find out the size of your Power-Bee.
May the Hive Power be with you!
You can view your badges on your board and compare yourself to others in the Ranking
Check out our last posts: