Witness Feed Publishing with Automatic SBD/USD Peg

in steem •  8 years ago  (edited)

A simple witness feed publishing with SBD/USD peg

I have been working on the markets module for steemtools v1.1 (which is going to be released later this week), and I have finished a sample witness feed publishing script earlier today.

@dantheman has made a case for SBD/USD $1 peg, which would improve the confidence in SBD, as well as increase its usefulness in trade.

I have modified the witness feed publishing script to allow for easy toggling between supporting the peg vs. reporting the regular implied price.

Without further ado, lets look into the code:

import time

from steemtools.experimental import Transactions
from steemtools.markets import Markets
from steemtools.node import Node

settings = {
    "sleep_time_seconds": 60,
    "minimum_spread_pct": 1.0,
    "sbd_usd_peg": True,
}
witness = "furion"
wif = "<PRIVATE ACTIVE KEY HERE>"

if __name__ == '__main__':
    steem = Node().default()
    markets = Markets()

    def get_last_published_price():
        my_info = steem.rpc.get_witness_by_account(witness)
        price = 0
        if float(my_info["sbd_exchange_rate"]["quote"].split()[0]) != 0:
            price = float(my_info["sbd_exchange_rate"]["base"].split()[0]) / float(
                my_info["sbd_exchange_rate"]["quote"].split()[0])
        return price

    while True:
        print("\n" + time.ctime())
        last_price = get_last_published_price()
        print("Published STEEM/USD price is: " + format(last_price, ".3f"))

        current_price = markets.steem_usd_implied()
        print("Implied STEEM/USD price is: %.3f" % current_price)
        if settings['sbd_usd_peg']:
            current_price *= markets.sbd_usd_implied()
            print("Pegged STEEM/USD price is: %.3f" % current_price)

        # if price diverged for more than our defined %, update the feed
        spread = abs(markets.calc_spread(last_price, current_price))
        print("Spread Between Prices: %.3f%%" % spread)
        if spread > settings['minimum_spread_pct']:
            tx = Transactions().witness_feed_publish(current_price, witness, wif, sim_mode=False)
            # print(tx)
            print("Updated the witness price feed.")

        time.sleep(settings['sleep_time_seconds'])

The above script will check the price every minute, and update it, if the price deviates from our published price by more than 1%.

We can change the the refresh interval, percent tolerance as well as toggle the SBD/USD peg by manipulating the settings:

settings = {
    "sleep_time_seconds": 60,  # refresh interval in seconds
    "minimum_spread_pct": 1.0, # 1% spread tolerance
    "sbd_usd_peg": True,       # support 1 SBD == 1 USD peg
}

Sample Output:

# Sample Output:
Mon Sep 19 12:26:20 2016
Tue Sep 20 01:07:22 2016
Published STEEM/USD price is: 0.462
Implied STEEM/USD price is: 0.491
Pegged STEEM/USD price is: 0.462
Spread Between Prices: 0.058%

Tue Sep 20 01:08:23 2016
Published STEEM/USD price is: 0.462
Implied STEEM/USD price is: 0.484
Pegged STEEM/USD price is: 0.455
Spread Between Prices: 1.569%
Updated the witness price feed.

Tue Sep 20 01:09:25 2016
Published STEEM/USD price is: 0.455
Implied STEEM/USD price is: 0.484
Pegged STEEM/USD price is: 0.455
Spread Between Prices: 0.023%

Sources:
> Feed Publishing Script Source
> Markets Implementation Source
> Transactions Implementation Source

How are the prices calculated?

BTC/USD:
Bitcoin price is a VWAP (volume weighted average price) of the prices from the following exchanges:

  • Bitstamp
  • Coinbase
  • Bitfinex
  • OKCoin
  • BTC-E

The exchanges with more volume have higher weight in determining the price.

STEEM, SBD:
STEEM and SBD are based on median prices from STEEM/BTC and STEEM/SBD pairs on:

  • Poloniex
  • Bittrex

Support for decentralized platforms (ie. Bitshares) is coming soon.

How does the peg work?

This is where the magic happens. Lets break it down.

from steemtools.markets import Markets

m = Markets()

m.steem_usd_implied()
#> 0.490638718898

m.steem_sbd_implied()
#> 0.522381648604

m.sbd_usd_implied()
#> 0.939234217376

.
steem_usd_implied() gives us the USD value of STEEM, according to the STEEM/BTC trades happening on 3rd party exchanges such as Poloniex and Bittrex.
We calculate it using this formula:

STEEM_USD = STEEM_BTC * BTC_USD

.
steem_sbd_implied() gives us the SBD value of STEEM, according to the relationship between STEEM/BTC and SBD/BTC trading pairs on 3rd party exchanges.
We calculate it using this formula:

STEEM_SBD = STEEM_BTC / SBD_BTC

.
sbd_usd_implied() give us the implied USD value of SBD, according to the SBD/BTC and BTC/USD trading pairs on 3rd party exchanges.
We calculate it using this formula:

SBD_USD = SBD_BTC * BTC_USD

Applying the $1 SBD = $1 USD Peg
To apply the peg, we simply multiply the STEEM/USD price with the implied SBD/USD price.

current_price = markets.steem_usd_implied()
if settings['sbd_usd_peg']:
    current_price *= markets.sbd_usd_implied()

This way, our pegged price will aim to correct the deviation of SBD/USD from the desired peg by manipulating the price of SBD/STEEM downwards if the SBD/USD is below $1, and by manipulating the price of SBD/STEEM upwards, if the SBD/USD is trading above $1.

Further considerations

You might want to modify the way the script operates. For instance, if you would like to reduce the responsiveness of the script to the recent price changes, you may want to take the average of the last X prices like so:

# add a list of recent prices outside of while True loop
recent_prices = []

# add our most recent price to the list
recent_prices.append(current_price)

# take the average of last 10 recent prices
average_price = numpy.mean(recent_prices[-10:])

I also highly recommend you do your due diligence and familiarize yourself with the experimental and markets modules of steemtools before proceeding.

Installation

This script depends on steemtools, which is a high level library built on top of @xeroc's Piston stack.

To install steemtools, simply run:

pip install -U steemtools

First, you need to provide a wif.wif (private active key). You can do this via environment variables, or a safe extraction from encrypted Piston wallet, see get_active_key_from_piston_wallet here).

Then you can run the script:

python witness_node.py

Enjoy :)


@furion is now a witness #83. Thank you for voting.


Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

The automatic peg feature is a bad idea. Dan does not recommend this, nor do I. That is just not how the pegging mechanism in Steem is supposed to work. Witnesses can bias their feed in help align the market toward the SBD=USD target, but it should be based on a broader understanding of market conditions, not just SBD/USD price itself.

I would suggest disabling it by default at a minimum, if not removing it.

I don't want to be involved in political side of things.

The intent of this post is to showcase how easy it is to build a powerful witness script on top of steemtools, as well as how to enable automatic pegging.

I hope it will be a useful resource to witnesses.

Showcases are certainly fine, but people who are not programmers are going to download your script and use it. Applying a default configuration that it configured in a manner that is contrary to the design of the system is irresponsible.

If top witnesses were so incompetent they couldn't change a setting from True to False based on their preferences, then the system IS broken.

The script can't be run without adding a mechanism for wif, which was intentionally left out for simplicity sake. The settings list is right there, and it has 3 settings.

  ·  8 years ago (edited)

I mostly wasn't referring to top witnesses, but to the many backups with varying technical skills (the system, by design, allows literally anyone to become a witness even via self voting). Their feed votes still count, albeit to a much lesser extent. It is a reasonable point that the script won't run at all without editing. I wasn't aware of that and negates my criticism to a large extent.

Just voted for you!

Thank you :)

thank you for explaining !

Thank you for a look behind the curtain to see how it all works! :)

  ·  8 years ago (edited)

thank you

I would like to ask two questions.

The first thing is as follows. Do you consider that BTCUSD benchmark calculated based on index ( Bitstamp , Coinbase , Bitfinex , OKCoin , BTC-E ) seems a bit inaccurate once those exchanges only covers 1.2% of global traded volume of bitcoin?


https://steemit.com/bitcoin/@airmike/global-market-overview-btc-sep-16-2016-quiz-included

The second thing . Are you going to change SMD/USD if some of the different exchanges will list SMD and STEEM and traded volume will be higher than traded volume on Bitfinex and Bittrex?

thank you

Volume on zero-fee exchanges is not trustworthy and for data to have any real legitimacy, they must be excluded. If there isn't sham trading on those exchanges why don't they charge 0.01% fees? It would be a goldmine.

The btc_usd_ticker() uses OkCoin.com price. The .com version does charge regular trading fees. None of the Chinese exchanges with questionable volume are used as a source of price feeds.

Just small additional comment. BTCC as a main critic of printing volume has 222k BTC in last 24 hours. (Okcoin 868k and Huobi 747k) . This explains everything. Even you have slowest messaging and no printing algorithm you can outperform rest of the world only by location.

I agree that volume on the zero-fees exchanges is not accurate. In the other hand I can assure you that any of the Chinese exchange do greater volume than rest of the world together.

I explained this volume issue in this post.
https://steemit.com/bitcoin/@airmike/bobby-lee-may-be-wrong-btc-curiosity-series

Long story short. " printing of the volume " is a way how the exchanges protects themselves against HFT predatory algorithms (order-flow algorithms and front running algorithms). This situations are rare. The situations happens only when LPs pulling their orders from the orderbook very quickly in high volatility. This mechanism of printing is only temporary protection (definitely not 24/7). When volatility is low most of the volume is accurate. Printing is not needed.

There is lot of mystery on the Reddit and other discussions about this issue. Most of the people do not trade high volume so they don't know whats going on there. BTCC is only one exchange which haven't been using this type of protection, yet. They use different type of protection. " they do it by slowing of the messaging" you can not get confirmation of your trade in scale of milliseconds. There is plenty of solutions how to solve this problem but important thing is that we shouldn't ignore 98% of traded volume around the globe and calculate index from ridiculously small exchanges (one of them is at bankruptcy already).