Much appreciated for this tutorial on the rental system. I have a basic understanding of the API since I've used it to collect data and stats for Excel, but wanted to go for a Python approach with it.
I've made a few modifications to the code that I think some would find useful.
First of, the API caller URL is at the moment of writing https://cache-api.splinterlands.com/
.
Rewriting Market Update Prices
The rental system has updated the API call for updating the market prices for rentals.
Changes here are
- Rewriting the MarketUpdatePrice class in the MarketHiveTransactions.py file
- Changing custom_json to
sm_update_rental_price
- Change how we append to the update_prices, now use the market_id instead.
def update_prices(orders: List[Tuple[str, float]], auth_user:str):
items: MarketUpdatePrice = MarketUpdatePrice(orders)
data = items.__dict__
hive.custom_json("sm_update_rental_price", json_data=data,
required_auths=[auth_user])
class MarketUpdatePrice:
items: List[List[any]]
def __init__(self, orders: List[Tuple[str, float]]):
if orders:
self.items = []
for order in orders:
self.items.append([order[0], order[1]])
prices_for_update.append((card["market_id"], max(0.1, new_price)))
Get the best BCX price for your cards XP
I changed the way the calc_price_per_bcx function selects the best entry.
The issue, as some has noted here in comments, is that some low cards can have a terrible price match compared to higher cards as they are usually dumped on the market.
Instead, here we make sure we only use cards with equal or higher XP to match with. We also filter out any of our own entries, as we want to know the best other price to match with. If we would not do this, and our own price is the best, we would match against that one.
Changes here are
- Get the card data from collection Dict.
- Match only with equal or higher XP
- Match only if we are not the seller
def calc_price_per_bcx(uid: str, collection, card_details, settings, auth_user:str):
result = get_rentals_by_uid(uid, collection)
card = collection[uid]
price_per_bcx = []
for entry in result:
if entry["xp"] >= card["xp"] and entry["seller"] != auth_user:
per_bcx = float(entry["buy_price"]) / calc_bcx(entry["card_detail_id"],
entry["edition"],
entry["gold"],
entry["xp"],
card_details,
settings)
price_per_bcx.append(per_bcx)
price_per_bcx.sort(key=lambda x: x, reverse=False)
return price_per_bcx[0]
I have also made a few other modifications as I created a seperate file for Splinterlands API functions. This is why a few of the function classes have more items than the original code.
Hey @sc-steemit,
judging by your username you've been around for some time ;). Thanks for pointing the changes out.
When did they change the base API url ? Didn't catch that change at all.
Whats up with sm_update_rental_price ? Is it a new operation type ? Any advantage ?
Edit: filtering the prices by level is a good idea. although you could also look into the for_rent_grouped endpoint. saves a LOT of api calls. It's a bit delayed, but i haven't noticed a large difference in rental revenue between the two.
True, been around for a while, when steemit was the main platform :)
I like automation and Python, and loved your detailed info on how you made it work, helped me out a lot.
I can't recall why exactly, but I guess it's all about optimization. It's the API url that peakmonsters use, and has been working well since a few months ago. Can't find it in the official changelog though.
sm_update_rental_price is documented here. Not sure when it was implemented, but I guess it was with the new rental system came to place? The advantage is that you don't have to send more than one transaction with all the updates, instead of cancelling and publishing. Also, I don't think the transaction type used in the OP is working any more.
I considered making a call for the API for_rent_grouped, but as you can't call for a specific card ID you have to pull the entire list for all ten market levels. May save some though, as per card data is pretty much as well. You just have to keep track on if your current listprice is the same so you don't underbid yourself.