Introducing BSC Predict Starter Bot

Published: 2021-12-12

Introducing the official BSC Predict Starter Bot


I get a lot of questions about strategies and creating a bot. I try to answer as many as I can but what people really need is a solid foundation from which to start.


So I'm proud to announce the official BSC Predict Starter Bot written in Python.


The bot lets you get started with just a few lines of code. It comes with two sample bots: SimpleBot and TrendingBot.


SimpleBot simply copies the last winner. For instance if the upcoming round is epoch 100, it checks to see the winner of epoch 98 (99 is still live) and bets that.


TrendingBot looks at the last 5 Oracle updates and only bets if there have been 5 bulls or bears in a row, in which case it takes the last value.


I didn't include these because they're good strategies (they're terrible), but to show off how to implement your own. So let's dive into it.

Security


NEVER GIVE ANYONE YOUR PRIVATE KEY
If someone or some service asks you for your private key for whatever reason, its a scam. If someone has your key they can (and will) take all your money and there's nothing you can do about it. Don't blindly download random code online and update your private key anywhere. This repo is no exception.



Obviously the app needs your private key to trade. This is updated in .env as described in the project's readme.


The only place the .env file is read is main.py where its passed to BaseBot and stored as self.secret_key. There its passed to two functions both in contracts/predict.py, claim and make_bet



You should search the code for another reference to either the .env file or self.private_key in the BaseBot file.



The other scam is swapping out prediction contracts. I can create a contract with the same ABI (interface) and just have that take your money. So it's important to know what contract you're calling.



All the contract stuff is in the contracts folder and prediction contract is in contract/prediction.py. There you'll see a reference to config.py which has the prediction contract address:


prediction_contract = "0x18B2A687610328590Bc8F2e5fEdDe3b582A49cdA"


Make sure its the contract you know and love.


Even with all that, you should create a new account, transfer a small amount of money you'd be okay with getting scammed out of, and try the bot out.

Quick Start


  • Setup your virtual environment python3 -m venv venv && source venv/bin/activate && pip install -r requirements


  • Copy over .env.sample to .env and update it with your account and secret key


  • See strategies/SimpleBot.py for a simple "follow" strategy that copies over the last available winner. Edit the logic


  • Run the bot python main.py --strategy SimpleBot --size 0.001


  • Press CTRL+C to cancel


Implementing a bot


To implement a bot, you can simply create a file in /strategies folder. There you can create a class called Bot that inherits from BaseBot.


The only function you need to implement is get_bet, which receives an upcoming round. The object has historical round data (self.history) as well as historical oracle data (self.oracle_history).


Take a look at SimpleBot, which bets the last winner:


  def get_bet(self, upcoming: Round) -> Optional[Bet]:
    # This function returns either a Bet or None based on the upcoming round.
    # If it returns a Bet, then that bet will be made
    # upcoming is the upcoming round that you're betting on

    # bet in the last 30 seconds
    timestamp = time.time()
    if upcoming.lockTimestamp - timestamp > 30:
      return None
    
    # you also have access to `self.history` which is the entire history of the games
    # At any time, there is an upcoming round that you can bet on, a `live` round that has not yet closed and the history  
    # here we filter on completed rounds or rounds that closed
    completed = [r for r in self.history if r.oracleCalled]

    if len(completed) > 0:
      last_winner = completed[-1]
      if last_winner.winner:
        return Bet(direction=last_winner.winner, amount_eth=self.bet_size_eth, epoch=upcoming.epoch)

self.history is a List of Rounds a dataclass with the following properties:


class Round:
  epoch: int
  startTimestamp: int
  lockTimestamp: int
  closeTimestamp: int
  lockPrice: float
  closePrice: float
  lockOracleId: str
  closeOracleId: str
  totalAmount: float
  bullAmount: float
  bearAmount: float
  rewardBaseCalAmount: float
  rewardAmount: int
  oracleCalled: bool

You also have access to the historical Oracle data, which TrendingBot uses. Here's the code for trending bot:


class Bot(BaseBot):
  def get_bet(self, upcoming: Round) -> Optional[Bet]:
    timestamp = time.time()
    if upcoming.lockTimestamp - timestamp > 30:
      return None
    
    # Look at the last 5 oracle values
    # NOTE: Oracle is the "current" price. Oracles get updated more frequently than rounds.
    last_oracles = self.oracle_history[-5:]

    # assume both bullish and bearish
    # bullish means every oracle print is greater than the prior (e.g. [500, 500.1, 500.2, 500.3, 500.4])
    # bearish means every oracle print is lower than the prior
    bullish = True
    bearish = True
    
    prior = last_oracles[0]
    for o in last_oracles[1:]:
      # oracle is lower than the prior, so not bullish
      if o.answer < prior:
        bullish = False
      # oracle is greater than the prior, so not bearish
      elif o.answer > prior:
        bearish = False
      prior = o

    if bullish:
      # if last 5 value are trending up, bet BULL
      return Bet(direction=Direction.BULL, amount_eth=self.bet_size_eth, epoch=upcoming.epoch)
    elif bearish:
      # if last 5 value are trending down, bet BEAR
      return Bet(direction=Direction.BEAR, amount_eth=self.bet_size_eth, epoch=upcoming.epoch)

This strategy uses self.oracle_history which is just a list of Oracle values. The Oracle dataclass is as follows:


@dataclass
class Oracle:
  roundId: int
  answer: float
  startedAt: int
  updatedAt: int
  answeredInRound: int

You can change the code to only consider the last 3 oracles values, or require a more stringent test, or flip the direction, or something else entirely. Again, I haven't tested any of these strategies and they're just used for demonstration purposes.


Best of luck and bet responsibly!