Bid Bot Bot

in #utopian8 years ago (edited)

You know @yabapmatt bot tracker?
Quite a good tool for calculating when to bid by hand.
Here is a simple script, how to automate the bidding itself:

Requirements:

python with steem,pymongo installed
DB with our postings and bidbots:

bid_bots: id (int)|username (varchar)|amount_mSBD (int)|vote_delta (int)|vote_pct (int)
bid_posts: id (int)|s_posted_id (int)|bid_bots_id (int)|bid_time (int)
s_posted: id (int)|link (varchar)
steempy with user in wallet
This script can run via crontab every x minutes, so you will not miss any bots
The list of bots for the `bid_bots` table you can get from here:
`http://www.steembottracker.com/`
# Script
```python
from pymongo import MongoClient
import datetime
import time
import os
#time and date is always a weird thing, I did need this one here
from dateutil import parser
from steem import Steem
from steem.account import Account
from steem.commit import Commit
from steem.post import Post
#Debug output or not
DEBUG = False 
if DEBUG:
    print(time.strftime("%a, %d %b %Y %H:%M:%S +0000",time.localtime()),flush=True) 
    
#Cheers to SteemData!
con = MongoClient(host='mongo1.steemdata.com',username='steemit',password='steemit',port=27017)
con = MongoClient('mongodb://steemit:[email protected]:27017/SteemData')
db = con.SteemData
#This is your local DB with postings, bidbots, etc
import MySQLdb as mdb
host = 'host'
user = 'user'
pw = 'pw'
thisdb = 'DBname'
conn = mdb.connect(host, user, pw, thisdb)
cursor = conn.cursor()
# your steem user, threshold, to not let this bot run your account dry
username = 'isnochys'
help_thr = 1.5 #SBD
#SteemData is not always on time..
blocks_behind = 50
def getdict_query(query):   
    colname = [ d[0] for d in query.description ]
    result_list = [ dict(zip(colname, r)) for r in query.fetchall() ]
    return result_list
# I usually choose the fastest steem node, but you will not need it for this bot..yet
s = Steem()
account = Account(username,s)
balance = account.balances
sbd = balance['available']['SBD']
# is there enough SBD on our account?
if sbd > help_thr:
    # let's get the bots we can afford
    # amount I store as MilliSBD, mSBD
    cursor.execute("SELECT * FROM bid_bots WHERE amount_mSBD <= %s",[sbd*100,])
    bbl = getdict_query(cursor)
    # we need this to calculate the bots click value
    rwl = s.get_reward_fund('post')
    rc = int(rwl['recent_claims'])
    rb = float(rwl['reward_balance'].split(' ')[0])
    # Check if SteemData is even online or how far back it is
    import requests
    link = "https://api.steemdata.com/health"
    d={}
    try:
        f = requests.get(link)
        d=f.json()
    except:
        d['diff']=blocks_behind*2
    # Looping through available bots
    for bb in bbl:
        bot =''
        no_mssql = False
        # Let's calculate the bots click worth:
        if d['diff'] < blocks_behind:
            #this is ugly, but it worked fastest for me
            for ob in db.Accounts.find({'name':bb['username']}):
                bot = ob
            mvs = bot['vesting_shares']['amount']+bot['received_vesting_shares']['amount']-bot['delegated_vesting_shares']['amount']
            last_vote = parser.parse(str(bot['last_vote_time'])+' UTC')
        else:
            maccount = Account(bb['username'],s)
            last_vote = parser.parse(maccount['last_vote_time']+' UTC')
            mvs = float(maccount['vesting_shares'].split(' ')[0])+float(maccount['received_vesting_shares'].split(' ')[0])-float(maccount['delegated_vesting_shares'].split(' ')[0])
        mvs1 = mvs * 20000
        # Not all bots vote with 100%
        # Nettybot for example did only vote with 25% at some time# and other bots waited also so long for their vote
        # this is kind of a rating for that bot.
        click = (mvs1 * rb / rc)*0.75*bb['vote_pct']/100
        
        # Don't judge.. time and date .. it never worked out in any other way for me..
        now = parser.parse(str(datetime.datetime.utcnow())+' UTC')
        #When did the bot last vote?
        #We want to bid within the last minutes
        if datetime.timedelta(minutes=bb['vote_delta']) >now-last_vote >= datetime.timedelta(minutes=(bb['vote_delta']-5)):# or now-last_vote > datetime.timedelta(minutes=160):
            total_bid =0
            # Sum all transfered money since last vote, plus a little further, 3 minutes, to get the long voting trail transfers
            if d['diff'] < blocks_behind:
                for tr in db.Operations.find({'type':'transfer','amount.asset':'SBD','timestamp':{"$gte":last_vote-datetime.timedelta(minutes=3)},'to':bb['username']}):
                    total_bid += tr['amount']['amount']
            else:
                #Steem Data is not available. Dang!
                #SteemSQL to the rescue!
                import pymssql
                try:
                    server = 'sql.steemsql.com'
                    user = 'steemit'
                    password = 'steemit'
                    msconn = pymssql.connect(server, user, password, "DBSteem")
                    mscursor = msconn.cursor(as_dict=True)
                    mscursor.execute("SELECT * FROM TxTransfers WHERE type=%s AND [to]=%s AND [timestamp]>%s ORDER BY ID DESC",('transfer',bb['username'],last_vote))
                    ret = mscursor.fetchall()
                    for re in ret:
                        total_bid += float(re['amount'])
                except:
                    no_mssql = True
            
            if no_mssql:
                # What? SteemSQL is also not available?
                # Dammit, we do it live!
                ac = Account(bb['username'],s)
                lvt = last_vote
                hrs = ac.history_reverse(filter_by='transfer')
                allt = 0.0
                for x in hrs:
                    mytime = parser.parse(x['timestamp']+' UTC')
                    if mytime<lvt:
                        break
                    if x['to'] == bb['username']:
                        tr = float(x['amount'].split(' ')[0])
                        allt += tr
                total_bid = allt
            if DEBUG:
                print(bb['username'],(total_bid+(bb['amount_mSBD']/1000))/click )
                
            # we want following number as low as possibe.
            # What number?
            # value of 1 means, you will get in return exactly as much as you put in there.
            # 0.5: caching, double the amount, 2 for the price of 1
            # for me, 0.6 worked out best, as it could still buffer some later bids from other users and not being to low, so I would maybe miss an opportunity
            # but you have to see for yourself, what is best
            vdb = 0.6
            vdb_late = 0.66
            if (total_bid+(bb['amount_mSBD']/1000))/click <vdb or (total_bid+(bb['amount_mSBD']/1000))/click <vdb_late and  datetime.timedelta(minutes=3) >now-last_vote:
                # Search in our DB for postings, this bid bot has not yet voted on
                cursor.execute("SELECT * FROM s_posted WHERE id NOT IN (SELECT s_posted_id FROM bid_posts WHERE bb_id = %s) ORDER BY id DESC LIMIT 1",[bb['id'],])
                spostl = getdict_query(cursor)
                if spostl:
                    spost = spostl[0]
                    if DEBUG:
                        print('vote!')
                        print(total_bid/click,':',click*0.1/(total_bid+0.1))
                        print(bb['username'],last_vote,click,total_bid)
                    
                    amount = bb['amount_mSBD']
                    memo = spost['link']
                    try:
                        c = Commit(s)
                        #remember, we stored this amount as mSBD
                        amountbb=amount/1000.0
                        os.environ["UNLOCK"] = 'yourwalletpw'
                        # this is where the magic happens:
                        returncode = c.transfer(to=bb['username'], amount=amountbb, asset='SBD', memo=memo, account=username)
                        if DEBUG:
                            print(returncode)
                    except:
                        pass #Or catch your exception, whatever you prefer)
                    finally:        
                        # we made the bid, so let's save that,  even if it wasn't successfull, we do not want to waste money on it
                        cursor.execute("INSERT INTO bid_posts (s_posted_id, bb_id, bid_time) VALUES(%s,%s,%s)",[spost['id'],bb['id'],int(time.time())])
                        conn.commit()
                        
**MACK-BOT. SIT! GOOD BOY!**

Sort:  

Can't get this so run on my codeanywhere.com python server, with the necessary imports installed... Could you write a guide on how to run this. In exchange for SBD?

I will look into that.

How good is your python?
Is the database connected? Filled?
Maybe I will write another version, a bit toned down.

My python is semi-basic. Another version would be great...

Congratulations! - As you follow @fisheggs bot your post has randomly been selected for an upvote.
call @originalworks

@minnowpond has voted on behalf of @minnowpond.
If you would like to recieve upvotes from minnowponds team on all your posts, simply FOLLOW @minnowpond.

            To receive an BiggerUpvote send 0.5 SBD to @minnowpond with your posts url as the memo
            To receive an BiggerUpvote and a reSteem send 1.25SBD to @minnowpond with your posts url as the memo
            To receive an upvote send 0.25 SBD to @minnowpond with your posts url as the memo
            To receive an reSteem send 0.75 SBD to @minnowpond with your posts url as the memo
            To receive an upvote and a reSteem send 1.00SBD to @minnowpond with your posts url as the memo

Congratulations! This post has been randomly Resteemed! To join the ResteemSupport network and be entered into the lottery please upvote this post and see the following rules.

Coin Marketplace

STEEM 0.13
TRX 0.35
JST 0.033
BTC 125179.41
ETH 4677.79
SBD 0.79