trading-bot-simulator / bot.py
bot.py
Raw
import krakenex
import json
import time
import datetime
import calendar


def get_crypto_data(pair, since):
    return api.query_public('OHLC', data = {'pair': pair, 'since': since})['result'][pair]


"""
            A rudimentary trading algorithm.
            
            Not recommended. Change your strategy for actual trading.
"""
def analyze(pair, since):
    data = get_crypto_data(pair[0]+pair[1], since)

    lowest = 0
    highest = 0

    for prices in data:
        balance = get_fake_balance()  # Replace with get_balance() for real trades
        last_trade = get_last_trade(pair[0]+pair[1])
        last_trade_price = float(last_trade["price"])

        open_ = float(prices[0])
        high_ = float(prices[1])
        low_ = float(prices[2])
        close_ = float(prices[3])

        did_sell = False

        """
            Issues:
                -> If price goes down right after a sell, bot might buy again immediately.
                -> Trading fees not considered here.
        """

        try:
            balance[pair[0]]
            # If reqd currency pair exists, check sell
            # Set up a stop-loss
            # Change margins and don't forget to add trading fee
            selling_point_win = last_trade_price * 1.005    ##
            selling_point_loss = last_trade_price * 0.995   ##

            # Selling at win:
            if open_ >= selling_point_win or close_ >= selling_point_win:
                # Sell at profit
                did_sell = True
                fake_sell(pair, close_, last_trade)
                
            elif open_ <= selling_point_loss or close_ <= selling_point_loss:
                # Sell at loss
                did_sell = True
                fake_sell(pair, close_, last_trade)

        except:
            pass

        # Logic for buy:
        if not did_sell and float(balance["USD.HOLD"]) > 0:
            if low_ < lowest or low_ == 0:
                lowest = low_
            if high_ > highest:
                highest = high_
            
            ##  Change this ratio for real trades.
            price_to_buy = 1.0005

            if highest/lowest >= price_to_buy and low_ <= lowest:
                available_money = balance["USD.HOLD"]
                # Buy
                fake_buy(pair, available_money, close_, last_trade)



"""
    Rename funcions and call statements for real trades.

    *----------------------------------------------------------------------------------*
    
    -> For real trades: Use Kraken API to send a buy/sell order:
       
        api.query_private(
            "AddOrder", {
                "pair": pair,
                "type": "buy"/"sell"
                .
                .
                ...
            }
        )           

    -> For fake trades, reflect a hypothetical buy/sell order in
         balance.json and tradeshistory.json: 
            1. S
            2. Update tradeshistory.json file to 
    
    *----------------------------------------------------------------------------------*
"""

##
#   @param:
#       was_sold (Boolean): True if fake_sell() executed, False if fake_buy() executed
def fake_update_balance(pair, dollar_amount, close_, was_sold):
    balance = get_fake_balance()
    prev_balance = float(balance["USD.HOLD"])
    new_balance = 0

    if was_sold:
        new_balance = prev_balance + float(dollar_amount)
        # Selling all currency for simulation. Edit to change strategy.
        del balance[pair[0]]
    else:
        new_balance = prev_balance - float(dollar_amount)
        # Adding the new pair to the balance sheet
        balance[pair[0]] = str(float(dollar_amount) / close_)
    
    balance["USD.HOLD"] = str(new_balance)

    # Updating changes to balance.json
    with open("balance.json", "w") as f:
        json.dump(balance, f, indent=4)



def fake_buy(pair, dollar_amount, close_, last_trade):
    trades_history = get_fake_trades_history()
    last_trade["price"] = str(close_)
    last_trade["type"] = "buy"
    last_trade["cost"] = dollar_amount
    last_trade["time"] = datetime.datetime.now().timestamp()
    last_trade["vol"] = str(float(dollar_amount) / close_)  # volume
    
    trades_history["result"]["trades"][str(datetime.datetime.now().timestamp())] = last_trade
    
    with open("tradeshistory.json", "w") as f:
        json.dump(trades_history, f, indent=4)
        fake_update_balance(pair, dollar_amount, close_, False)


def fake_sell(pair, close_, last_trade):
    trades_history = get_fake_trades_history()
    last_trade["price"] = str(close_)
    last_trade["type"] = "sell"
    last_trade["cost"] = str(float(last_trade["vol"]) * close_)
    last_trade["time"] = datetime.datetime.now().timestamp()

    trades_history["result"]["trades"][str(datetime.datetime.now().timestamp())] = last_trade
    
    with open("tradeshistory.json", "w") as f:
        json.dump(trades_history, f, indent=4)
        fake_update_balance(pair, float(last_trade["cost"]), close_, True)




"""Get REAL balance from Kraken's API (NOT SIMULATION)"""
def get_balance():
    return api.query_private('Balance')


"""Get fake balance from fake-balance sheet used in paper trading """
def get_fake_balance():
    with open("balance.json", "r") as f:
        return json.load(f)


def get_last_trade(pair):
    trades_history = get_fake_trades_history()["result"]["trades"]  # Replace with get_trades_history() for real trades
    last_trade = {}

    for trade in trades_history:
        trade = trades_history[trade]
        if trade["pair"] == pair and trade["type"] == "buy":
            last_trade = trade
    
    return last_trade


def get_fake_trades_history():
    with open("tradeshistory.json", "r") as f:
        return json.load(f)



def get_trades_history():
    start_date = datetime.datetime(2021, 7, 4)
    end_date = datetime.datetime.today()
  
    return api.query_private("TradesHistory", req(start_date, end_date, 1))['result']['trades']


def date_nix(str_date):
    return calendar.timegm(str_date.timetuple())


def req(start, end, ofs):
    req_data = {
        "type": "all",
        "trades": "true",
        "start": str(date_nix(start)),
        "end": str(date_nix(end)),
        "ofs": str(ofs)
    }


if __name__ == "__main__":
    api = krakenex.API()
    api.load_key('kraken.key')
    pair = ("XETH", "ZUSD")
    since = str(int(time.time() - 3600))

    analyze(pair, since)