CyberPunkMetalHead / gateio-crypto-trading-bot-binance-announcements-new-coins

This is a crypto trading bot that scans the Binance Annoucements page for new coins, and places trades on Gateio
MIT License
1.21k stars 303 forks source link

Using 24h high to decide whether to buy in on a new announcement. #57

Closed fievelbud closed 2 years ago

fievelbud commented 2 years ago

Note I have never coded in python, used github or git before this bot, so if you see mistakes or ways to improve, comment below.

I've been working on an idea to not buy an announcement coin if it has already "peaked"

I think a good idea would be to pull the 24 high, then add a config option to choose how much higher the 24h high has to be above than the current price in % to not buy the coin.

i.e. you run the bot and it detects and announcement for xyz that has already "peaked", let's say at 100 and you have a 24h % set at 5% then if the current price of the coin is 95, the bot won't buy it.

since this is a customizable number, you get to choose what you believe a big enough price difference is to skip buying. The 24h high pull runs before the current price pull so the price is less likely to be below the 24h price due to a delay in data pull.

I've added the changes and it appears to work. I tested it by adding a coin to new_listings.json to trick the bot into wanting to order it. Tested using RGT as an example, which has spiked already to 62.76 and landed on ~47 atm which is about a 35% difference. When the 24H setting in config was 30%, it did not buy the coin.

Suggestions were made, changes happened. Here is what I have ended up with. Not sure how to highlight the changes in here, if anyone knows how, let me know and I'll edit this.

Note I have implemented the code from https://github.com/kekkokk/gateio-crypto-trading-bot-binance-announcements-new-coins/commit/62e9799fb6cee170dde4e825422614144b3c34e0

config change Added 24H option

 TRADE_OPTIONS:
    # In your pairing coin
    # DO NOT DISABLE TSL!!!! YOUR BOT WILL NOT SELL
    QUANTITY: 15
    # BTCUSDT will be bought for example
    PAIRING: USDT
    TEST: True
    # In %
    SL: -3
    TP: 2
    24H: 2
    ENABLE_TSL: True
    TSL: -4
    TTP: 2
  LOGGING:
    # Logging levels used in this program are ERROR, INFO, and DEBUG
    LOG_LEVEL: INFO
    LOG_FILE: bot.log

trade_client.py change Changed get_last_price to get_coin_info and adjusted to keep all info returned.

def get_coin_info(base,quote):
    """
    Args:
    'DOT', 'USDT'
    """
    tickers = spot_api.list_tickers(currency_pair=f'{base}_{quote}')
    return tickers[0]

main.py changes Mostly changes to reflect using new get_coin_info method and addition of the 24h high check to not buy.

                logger.debug(f'Data for sell: {coin=} | {stored_price=} | {coin_tp=} | {coin_sl=} | {volume=} | {symbol=} ')

                logger.info(f'get_coin_info existing coin: {coin}')
                coin_info = get_coin_info(symbol, pairing)

                logger.info("Finished get_coin_info")
                logger.info(f'{coin_info.last=}')
                logger.info(f'{stored_price + (stored_price*sl /100)=}')

                # update stop loss and take profit values if threshold is reached
                if float(coin_info.last) > stored_price + (
                        stored_price * coin_tp / 100) and enable_tsl:
                    # increase as absolute value for TP
                    new_tp = float(coin_info.last) + (float(coin_info.last) * ttp / 100)
                    # convert back into % difference from when the coin was bought
                    new_tp = float((new_tp - stored_price) / stored_price * 100)

                    # same deal as above, only applied to trailing SL
                    new_sl = float(coin_info.last) + (float(coin_info.last)*tsl / 100)
                    new_sl = float((new_sl - stored_price) / stored_price * 100)

                    # new values to be added to the json file
                    order[coin]['tp'] = new_tp
                    order[coin]['sl'] = new_sl
                    store_order('order.json', order)

                    logger.info(f'Updated TP: {round(new_tp, 3)} and SL:'
                                 f' {round(new_sl, 3)}')

                # close trade if tsl is reached or trail option is not enabled
                elif float(coin_info.last) < stored_price + (
                        stored_price * coin_sl / 100) or float(coin_info.last) > stored_price + (
                        stored_price * coin_tp / 100) and not enable_tsl:
                    try:
                        # sell for real if test mode is set to false
                        if not test_mode:
                            logger.info(f'starting sell place_order with :{symbol} | {pairing} | {float(volume)*float(coin_info.last)} | side=sell {coin_info.last}')
                            sell = place_order(symbol, pairing, float(volume)*float(coin_info.last), 'sell', coin_info.last)
                            logger.info("Finish sell place_order")
                        logger.info(f'sold {coin} with {(float(coin_info.last) - stored_price) / float(stored_price)*100}% PNL')

                        # remove order from json file
                        order.pop(coin)
                        store_order('order.json', order)
                        logger.debug('Order saved in order.json')

                    except Exception as e:
                        logger.error(e)

                    # store sold trades data
                    else:
                        if not test_mode:
                            sold_coins[coin] = sell
                            sold_coins[coin] = sell.__dict__
                            sold_coins[coin].pop("local_vars_configuration")

                            store_order('sold.json', sold_coins)
                            logger.info('Order saved in sold.json')
                        else:
                            sold_coins[coin] = {
                                'symbol': coin,
                                'price': coin_info.last,
                                'volume': volume,
                                'time': datetime.timestamp(datetime.now()),
                                'profit': float(coin_info.last) - stored_price,
                                'relative_profit_%': round((float(
                                    coin_info.last) - stored_price) / stored_price * 100, 3),
                                'id': 'test-order',
                                'text': 'test-order',
                                'create_time': datetime.timestamp(datetime.now()),
                                'update_time': datetime.timestamp(datetime.now()),
                                'currency_pair': f'{symbol}_{pairing}',
                                'status': 'closed',
                                'type': 'limit',
                                'account': 'spot',
                                'side': 'sell',
                                'iceberg': '0'}
                            logger.info('Sold coins:' + str(sold_coins[coin]))

                            store_order('sold.json', sold_coins)

        # the buy block and logic pass
        # announcement_coin = load_order('new_listing.json')
        if os.path.isfile('new_listing.json'):
            announcement_coin = load_order('new_listing.json')
        else:
            announcement_coin = False

        global supported_currencies

        if announcement_coin not in order and announcement_coin not in sold_coins and announcement_coin not in old_coins:
            if announcement_coin == False:
                logger.info( 'No coins announced, or coin has already been bought/sold.')
            if announcement_coin:
                logger.info(f'New announcement detected: {announcement_coin}')
            if supported_currencies:
                if announcement_coin in supported_currencies:
                    logger.debug("Starting get_coin_info")
                    coin_info = get_coin_info(announcement_coin, pairing)

                    logger.debug('24h High: ' + coin_info.high_24h)
                    logger.debug('Coin price: ' + coin_info.last)
                    logger.debug('Finished get_coin_info')

                    try:
                        # Run a test trade if true
                        if config['TRADE_OPTIONS']['TEST']:
                            if float(coin_info.high_24h) > float(coin_info.last) + (float(coin_info.last) * float(ath) / 100):
                                logger.info(f'24h High is {ath}% greater than price, coin not traded')
                            else:
                                order[announcement_coin] = {
                                    'symbol': announcement_coin,
                                    'price': price,
                                    'volume': qty,
                                    'time': datetime.timestamp(datetime.now()),
                                    'tp': tp,
                                    'sl': sl,
                                    'id': 'test-order',
                                    'text': 'test-order',
                                    'create_time': datetime.timestamp(datetime.now()),
                                    'update_time': datetime.timestamp(datetime.now()),
                                    'currency_pair': f'{announcement_coin}_{pairing}',
                                    'status': 'filled',
                                    'type': 'limit',
                                    'account': 'spot',
                                    'side': 'buy',
                                    'iceberg': '0'
                                }
                                logger.info('PLACING TEST ORDER')
                                logger.debug(order[announcement_coin])
                        # place a live order if False
                        else:
                            if float(coin_info.high_24h) > float(coin_info.last) + (float(coin_info.last) * float(ath) / 100):
                                logger.info(f'24h High is {ath}% greater than price, coin not traded')
                            else:
                                logger.info(f'starting buy place_order with : {announcement_coin=} | {pairing=} | {qty=} | side = buy | {price=}')
                                order[announcement_coin] = place_order(announcement_coin, pairing, qty,'buy', price)
                                order[announcement_coin] = order[announcement_coin].__dict__
                                order[announcement_coin].pop("local_vars_configuration")
                                order[announcement_coin]['tp'] = tp
                                order[announcement_coin]['sl'] = sl
                                logger.info('Finished buy place_order')

                    except Exception as e:
                        logger.error(e)

                    else:
                        if float(coin_info.high_24h) > float(coin_info.last) + (float(coin_info.last) * float(ath) / 100):
                            logger.info('No order status to report')
                        else:
                            if test_mode: