Giter VIP home page Giter VIP logo

gateio-crypto-trading-bot-binance-announcements-new-coins's Introduction

gateio-trading-bot-binance-announcements

This Gateio x Binance cryptocurrency trading bot scans the Binance Announcements page and picks up on new coin listings. It then goes to Gateio and places a buy order on the coin that's due to be listed on Binance. It comes with trailing stop loss, take profit and a test mode.

The idea behind this open source crypto trading algorithm to take advantage of the price spike of new coins as they are being announced for listing on Binance. As Gateio seems to list many of these coins before Binance does, this exchange is a good place to start. It comes with a live and test mode so naturally, use at your own risk.

HOW TO RUN IT

1. Create venv (recommended to use python>=3.8, check with python --version)

python3 -m venv env

2 Activate venv

Linux:
source env/bin/activate

Windows:
env\Scripts\activate.bat

3. Install program requirements

python -m pip install -r requirements.txt

This contains the requirements for the program itself. You may now run the script using python main.py. No additional steps needed for simply running the tool, you may stop here.

4. Install dev requirements

python -m pip install -r dev_requirements.txt

This is necessary make verifying of the code easier and formats the code automatically to match the coding style.

5. Install pre-commit hooks

pre-commit install

This installs the pre-commit git hooks for the project and makes it possible to run the pre-commit script automatically when committing.

6. Run Tests and pre-commit scripts manually

pre-commit checks

To manually run the pre-commit script:

pre-commit run --all-files

Tox

Make sure you enabled the virtual environment. Tox tests the code for multiple environments (3.8, 3.9) and checks code with flake8 and mypy (only on Python Version 3.8). To run Tox:

    tox

PyTest

Make sure you enabled the virtual environment. PyTest runs the unit tests for the code. To run PyTest:

    python -m pytest

Flake8

Make sure you enabled the virtual environment. Flake8 checks the code for errors and warnings. To run Flake8:

    flake8 src

Black

Make sure you enabled the virtual environment. Black formats the code to match the coding style. To run Black:

    black src

 

For a step-by-step guide on how to set it up and configure please see the guide here: Binance new coin trading bot guide

 

The new coins crypto trading bot explained in more detail.
See the video linked below for an explanation and rationale behind the bot.

binance new coin listings bot

Want to talk trading bots? Join the discord https://discord.gg/Ga56KXUUNn

gateio-crypto-trading-bot-binance-announcements-new-coins's People

Contributors

andreademasi avatar androidoatmeal avatar busyuqboy avatar circle3451 avatar cryptmjt avatar cyberpunkmetalhead avatar dominicfrei avatar flumi3 avatar hebelhuber avatar iamtodor avatar jrjy3 avatar kazyka avatar linus045 avatar mikeczabator avatar paludgus avatar prastiwari avatar shoestar avatar talha2299 avatar triasmus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gateio-crypto-trading-bot-binance-announcements-new-coins's Issues

get_last_price crashes program when Binance announces a coin that isnt available on gate.io

DAR was announced on Binance, it isnt available as a DAR_USDT trade pair and therefore returns an error which crashes the program. My solution was to add a try/except block to the request and then make it so if get_latest_price returns none if the response is an error instead of price and then telling the main function not to buy it if price=None. I also added a new json file of 'not listed' to check against so it is not trying to buy the unlisted coin every time its picked up by the scraper.

API exception when a new announcement is detected but the coin is not listed on on gate.io

It seems that this exception is not handled. Shouldn't it try in a few minutes/hours again if the coin is not listed?

New annoucement detected: LAZIO
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/gate_api/api_client.py", line 190, in __call_api
    response_data = self.request(
  File "/usr/local/lib/python3.8/dist-packages/gate_api/api_client.py", line 447, in request
    return self.rest_client.GET(
  File "/usr/local/lib/python3.8/dist-packages/gate_api/rest.py", line 237, in GET
    return self.request(
  File "/usr/local/lib/python3.8/dist-packages/gate_api/rest.py", line 232, in request
    raise ApiException(http_resp=r)
gate_api.exceptions.ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 19 Oct 2021 09:28:30 GMT', 'Content-Type': 'application/json', 'Content-Length': '63', 'Connection': 'keep-alive', 'Server': 'openresty', 'X-Request-Id': '[66c99e50-81227577]'})
HTTP response body: {"label":"INVALID_CURRENCY","message":"Invalid currency LAZIO"}```

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

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 kekkokk@62e9799

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:

JASMY detected but couldn't buy it

Hey,

Got that in the logs:

2021-11-22 09:00:24,197 INFO: New coin detected: JASMY
2021-11-22 09:00:24,198 INFO: File does not exist, creating file
2021-11-22 09:00:24,198 INFO: Checking for coin announcements every 3 seconds (in a separate thread)
2021-11-22 09:00:24,198 INFO: New announcement detected: JASMY
2021-11-22 09:00:25,197 INFO: LATEST TRADE: JASMY_USDT | id=2192886784 | create_time=22-11-21 08:00:17.315000 | side=sell | amount=663.812 | price=0.223892
2021-11-22 09:00:25,198 INFO: starting buy place_order with : announcement_coin='JASMY' | globals.pairing='USDT' | volume=15 | amount=66.99658764046951 x price='0.223892' | side = buy | status='test_partial_fill_order'
2021-11-22 09:00:25,198 ERROR: 
2021-11-22 09:00:25,209 INFO: No coins announced, or coin has already been bought/sold. Checking more frequently in case TP and SL need updating

After that I got thousand lines with "No coins announced..."

Do you think it's because the order couldn't be filled?

TypeError: 'Order' object is not subscriptable

I'm getting a TypeError from the 'Order' object wich is returned by Gate.io Api.

Traceback (most recent call last):
File "E:/Entwicklung/binanceListingTradingbot/main.py", line 63, in main
stored_price = float(order[coin]['price'])
TypeError: 'Order' object is not subscriptable

Two issues: Multiple buy orders and Multiple session support

Overview

  1. Multiple orders

There is an edge case issue where two orders trying to opperate buy/sells at the same time will create an invalid order. This will be an issue if a second announcement is made while the first announcement has completed and turned into an active order (in order.json).

The second order will create the invalid order issue only when it comes back as cancelled status. This is the edge case. If the order comes back closed the operation isn't impacted. This is due to the order dictionary being "cleared" (all orders) instead of removing just the key (coin) that needs to be re-purchased.

The issue is known by the following log output:
Order is initialized but not ready. Continuing.

  1. Multiple session support

The session.json file is used to help with partially filled/multiple orders per coin and to help sum the total fees for all orders produced. This is critical for the sale order to be able to sell 100% of the amount that the bot purchased.

There is an initialization of the session variable that is killing the historical/saved values. This can cause an active order to not be able to sell correctly due to the summed fees being wiped.

These two issues were introduced by code introduced by PR #62

New source to track new coinlistings

image

I am here learning and searching... I found that Binance has a voting section to elect next project/token to be listed.
So, this may be a new source for new coins to buy??

MOVR announcement analysis

Just for reference:

My bot picked up MOVR at 2021-8-11 2.59.45

This is consistent with the timestamp on binance.com:
image

In terms of trading activity the wave had already started.

image

coin_sl and frequency never used

When the scripts load the order from the file and assigns all the variables, coin_sl is never used. Instead it uses the sl variable from config. is this correct?

Also frequency is never used.

Why QUANTITY as only trading option.

Is there a reason one can only set QUANTITY to say how much the bot should buy. As it is different for any coin, you not really have control over your balance.

I would propose to implement an option like TRADE_SUM and calculate the QUANTITY from it (QUANTITY = price / TRADE_SUM). If this is a wanted future, I would volunteer to implement it.

get_all_currencies thread stops working after some internet connection issues

After the following output, the get_all_currencies thread is stopped and does not work anymore. The thread is not throwing any exceptions. At the moment, I have no idea to fix this.

2021-10-25 02:57:10,947 INFO: Getting the list of supported currencies from gate io
2021-10-25 02:57:15,966 WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb5b921a8>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /api/v4/spot/currencies
2021-10-25 02:57:20,984 WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb5675a48>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /api/v4/spot/currencies
2021-10-25 02:57:31,004 WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb5675b98>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /api/v4/spot/currencies

Error running script

I get this error when running script from main.py
image

I am on Windows 10 running Python through Visual Studio Code.
I configured auth.yml file and config.yml file, all correctly.
I also installed all requirements.
I am not a programmer, so excuse me if this is a newbie error. :D

I still see check announcement message happening every 1 minute

I still see the below, I thought the recent YouTube video (https://www.youtube.com/watch?v=4gul6AqAoEo) mentioned that the announcement check time is now reduced to milliseconds.

No coins announced, or coin has already been bought/sold. Checking more frequently in case TP and SL need updating. You can comment me out, I live on line 176 in main.py
No coins announced, or coin has already been bought/sold. Checking more frequently in case TP and SL need updating. You can comment me out, I live on line 176 in main.py
Checking for coin announcements every 1 minute (in a separate thread)

new_listing.json non created on first run?

Hi there! It seems that new_listing.json is not created at the first execution of the script, despise https://www.binance.com/bapi/composite/v1/public/cms/article/catalog/list/query?catalogId=48&pageNo=1&pageSize=15 showing some "good" lines (e.g.

{ "id":69844, "code":"abccb898c2144bfda3647031b2a60bc7", "title":"Binance Will List SuperRare (RARE)", "body":null, "type":null, "catalogId":null, "catalogName":null, "publishDate":null },

or
{ "id":70224, "code":"7e2ab0778e4b409d857dedcb2d4da175", "title":"Introducing the Lazio Fan Token (LAZIO) Token Sale on Binance Launchpad!", "body":null, "type":null, "catalogId":null, "catalogName":null, "publishDate":null }

Thread search_and_update stops without any error.

I fell that the search_and_update thread sometimes just stops and throws no error, and the application runs without it. Anyone else observed this?
If so I would propose to invest some time in improving the different threads needed to have the bot running stable. In case I find some time, I can do that, or assist with that.

Gate API returns incorrect filled price in order response / incorrect PNL / incorrect volume purchase

The bot is using incorrect price values (possibly) from the response of Gate.io spot orders API payload.
Not sure what we can do about this. It's simply wrong info. The price returned doesn't even match what they show on their website for your trade order history.

Real Example:
I had the bot purchase a new listing coin on gate.io called ZLK.
The purchase went through and I had an order closed (and filled 100%). The order id is 97094620091. It's real. it's in the books.
But...
The bot recorded the response to the spot order with a price of 7.
The gateio website shows a filled price of 6.10.
The bot determined it bought a volume of 49.9999998 (config set to 50) at an amount of 7.14285714 at a price of 7.
The gateio website shows a volume of 43.571428554 at an amount of 7.14285714 at a price of 6.10.
Interesting, huh?
If I GET the order by id (GET /spot/orders/{order_id}), it shows an price of 7. Even a request by order id returns the wrong price amount. How can this be, Gateio? How can your website have a different price than your orders endpoint?

The outcome of the bot says I lost -12%. But it was using an incorrect price. I actually lost less than 1% (it was $0.90 USDT).
2021-11-25 11:00:21,708 INFO: Sold ZLK with -0.9 profit | -12.857% PNL

  • Gate.io website trade history:
    image

  • Session data from the buy
    image

  • API GET to orders/[id]
    image

I'm not sure there is anything we can do about this. It's a gate.io issue really.

Error from live CHESS detection

I got this error when CHESS was listed. It placed the buy order but then failed:

I had print(order) so heres its output and the error

New annoucement detected: CHESS
'Order' object does not support item assignment
{'CHESS': {'account': 'spot',
 'amount': '1.56384392',
 'auto_borrow': None,
 'auto_repay': None,
 'create_time': '1634871636',
 'create_time_ms': 1634871636858,
 'currency_pair': 'CHESS_USDT',
 'fee': '0',
 'fee_currency': 'CHESS',
 'fill_price': '0',
 'filled_total': '0',
 'gt_discount': False,
 'gt_fee': '0',
 'iceberg': '0',
 'id': '231244324',
 'left': '1.32112213',
 'point_fee': '0',
 'price': '6.3945',
 'rebated_fee': '0',
 'rebated_fee_currency': 'USDT',
 'side': 'buy',
 'status': 'open',
 'text': 'apiv4',
 'time_in_force': 'gtc',
 'type': 'limit',
 'update_time': '1634871636',
 'update_time_ms': 1634871636858}}

Traceback (most recent call last):
  File "main.py", line 195, in <module>
    main()
  File "main.py", line 67, in main
    stored_price = float(order[coin]['price'])
TypeError: 'Order' object is not subscriptable

AttributeError: module 'yaml' has no attribute 'FullLoader'

I have followed your guide from the website to get this script running but received the following traceback error when running main.py:

Traceback (most recent call last):
File "/Users/username/gateio-crypto-trading-bot-binance-announcements-new-coins/main.py", line 1, in
from trade_client import *
File "/Users/username/gateio-crypto-trading-bot-binance-announcements-new-coins/trade_client.py", line 4, in
client = load_gateio_creds('auth/auth.yml')
File "/Users/username/gateio-crypto-trading-bot-binance-announcements-new-coins/auth/gateio_auth.py", line 7, in load_gateio_creds
auth = yaml.load(file, Loader=yaml.FullLoader)
AttributeError: module 'yaml' has no attribute 'FullLoader'

The following python version was used:
Python version: Python 3.10.0 (v3.10.0:b494f5935c, Oct 4 2021, 14:59:20) on a Mac

Any hint for me?

Thank you in advance!

order removed from orders.json in test or failure.

print(f"sold {coin} with {(float(last_price) - stored_price) / float(stored_price)*100}% PNL")

print(f"sold {coin} with {(float(last_price) - stored_price) / float(stored_price)*100}% PNL")

# remove order from json file
order.pop(coin)
store_order('order.json', order)

these lines should only be called if test_mode=False and place_order on line 101 are successful.

I can follow up with a PR as I dig in more.

line in scrapper

I am rusty in pyhton but I think this line

31 uppers = None

is redundant.
pls check

Config Parameters

Has anyone altered the config Parameters for tp SL Tsl ttp? If so, any Suggestions that worked Out for you so far? It seems the bot wont sell If Tsl is anything Other than 0...

Also Tried the latest Iteration... Syntax Error File fstring Line 1... Cant Seem to find it...

Santax iusses

Tested the old bot a few weeks ago
Trying to run this one but having this iusses
Running on rpi4

python3 main.py
File "", line 1
(last_price=)
^
SyntaxError: invalid syntax

coin_sl isntead of sl

In Line 111 it has to be coin_sl instead of sl, or am i wrong?

elif float(last_price) < stored_price + (
stored_price * sl / 100) or float(last_price) > stored_price + (
stored_price * coin_tp / 100) and not enable_tsl:

Feedback

I let my robot run this night in my computer, but the results were not good. As you can see.
2021-10-22 09-16-08
2021-10-22 09-15-07

The bot bought at the max price. :/

order_status='cancelled'

I'm using the last version of place_order (trade_client.py) with the parameter time_in_force='ioc'. I would like to understand why it always fails before than buy or sell, getting a order_status='cancelled'. Could I avoid this?

powr

[BUG] Not working stop loss...

Hello.

@CyberPunkMetalHead

I sold it manually because I saw that the stop loss was not working at all

My config.yml:

---
  TRADE_OPTIONS:
    # In your pairing coin
    QUANTITY: 5
    # BTCUSDT will be bought for example
    PAIRING: USDT
    TEST: False
    # In %
    SL: -3
    TP: 60
    ENABLE_TSL: True
    TSL: -4
    TTP: 20
  LOGGING:
    # Logging levels used in this program are ERROR, INFO, and DEBUG
    LOG_LEVEL: INFO
    LOG_FILE: bot.log

2021-11-04 10:04:14,384 INFO: last_price='242.061'
2021-11-04 10:04:14,384 INFO: stored_price + (stored_price*sl /100)=242.5
2021-11-04 10:04:14,384 INFO: starting sell place_order with :BNX | USDT | 295.31442 | side=sell 242.061
2021-11-04 10:04:14,680 ERROR: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Date': 'Thu, 04 Nov 2021 07:04:14 GMT', 'Content-Type': 'application/json', 'Content-Length': '61', 'Connection': 'keep-alive', 'Server': 'openresty', 'X-Request-Id': '[48530729-1567413425]'})
HTTP response body: {"label":"BALANCE_NOT_ENOUGH","message":"Not enough balance"}

2021-11-04 10:04:14,681 ERROR: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Date': 'Thu, 04 Nov 2021 07:04:14 GMT', 'Content-Type': 'application/json', 'Content-Length': '61', 'Connection': 'keep-alive', 'Server': 'openresty', 'X-Request-Id': '[48530729-1567413425]'})
HTTP response body: {"label":"BALANCE_NOT_ENOUGH","message":"Not enough balance"}

Logs say uppers=None?

Pretty recently my raspberry started to spit out uppers=None

What does this mean? Has the bot some issue I am not aware of?

Exception in thread

Exception in thread Thread-1:
Traceback (most recent call last):
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 699, in urlopen
httplib_response = self._make_request(
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 445, in _make_request
six.raise_from(e, None)
File “”, line 3, in raise_from
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 440, in _make_request
httplib_response = conn.getresponse()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 1371, in getresponse
response.begin()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 319, in begin
version, status, reason = self._read_status()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 288, in _read_status
raise RemoteDisconnected(“Remote end closed connection without”
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/local/lib/python3.9/site-packages/requests/adapters.py”, line 439, in send
resp = conn.urlopen(
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 755, in urlopen
retries = retries.increment(
File “/usr/local/lib/python3.9/site-packages/urllib3/util/retry.py”, line 532, in increment
raise six.reraise(type(error), error, _stacktrace)
File “/usr/local/lib/python3.9/site-packages/urllib3/packages/six.py”, line 769, in reraise
raise value.with_traceback(tb)
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 699, in urlopen
httplib_response = self._make_request(
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 445, in _make_request
six.raise_from(e, None)
File “”, line 3, in raise_from
File “/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py”, line 440, in _make_request
httplib_response = conn.getresponse()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 1371, in getresponse
response.begin()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 319, in begin
version, status, reason = self._read_status()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py”, line 288, in _read_status
raise RemoteDisconnected(“Remote end closed connection without”
urllib3.exceptions.ProtocolError: (‘Connection aborted.’, RemoteDisconnected(‘Remote end closed connection without response’))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py”, line 973, in _bootstrap_inner
self.run()
File “/usr/local/Cellar/[email protected]/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py”, line 910, in run
self._target(self._args, self._kwargs)
File “/Users/
/Documents/gateio-crypto-trading-bot-binance-announcements-new-coins-master/new_listings_scraper.py”, line 55, in search_and_update
latest_coin = get_last_coin()
File “/Users/
***/Documents/gateio-crypto-trading-bot-binance-announcements-new-coins-master/new_listings_scraper.py”, line 13, in get_last_coin
latest_announcement = requests.get(“https://www.binance.com/bapi/composite/v1/public/cms/article/catalog/list/query?catalogId=48&pageNo=1&pageSize=15”)
File “/usr/local/lib/python3.9/site-packages/requests/api.py”, line 76, in get
return request(‘get’, url, params=params, **kwargs)
File “/usr/local/lib/python3.9/site-packages/requests/api.py”, line 61, in request
return session.request(method=method, url=url, **kwargs)
File “/usr/local/lib/python3.9/site-packages/requests/sessions.py”, line 542, in request
resp = self.send(prep, **send_kwargs)
File “/usr/local/lib/python3.9/site-packages/requests/sessions.py”, line 655, in send
r = adapter.send(request, **kwargs)
File “/usr/local/lib/python3.9/site-packages/requests/adapters.py”, line 498, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: (‘Connection aborted.’, RemoteDisconnected(‘Remote end closed connection without response’))

Wrong amount on sell

order = Order(amount=str(float(amount)/float(last_price)), price=last_price, side=side, currency_pair=f'{base}_{quote}')

this can work for a buy order, but dividing the amount by the price while selling is wrong (If I understood correctly?)

example error code on sell:
{"label":"INVALID_PARAM_VALUE","message":"Your order size 0.00799004248012527 is too small. The minimum is 1 USDT"}

JASMY announcement detected, but late or delayed!!

The announcement published on Binance at (07:59 AM) (UTC)
The announcement detected via program ( 2021-11-22 08:00:08,348 INFO: New coin detected: JASMY) (UTC)

reviewing the chart on gate.io
JASMY price on the minute 59 opened 0.15
JASMY price on the minute 59 closed 0.21

I think there is another source others can detect announcements on time,
thanks for CyberPunkMetalHead for the great program and hope he can solve this issue.

Binance "Adds"

Hey,
I really liked how the bot works and it's really amazing but I think that you could make it even more profitable by including:
"(Binance Adds) XXX/BUSD and XXX/USDT Trading Pairs" announcement
Whenever that adds announcement is including "/USDT" option. It usually has the same spike a little bit lower spike than new listing of course but still profitable. Just an idea you could take into consideration.
And I really wanted to thank you for sharing this bot as an open source, really appreciate it!

Configurable Order Type

Problem:
The bot created an order, but it was not executed because the price was already higher. T
herefore I think the possibility to set the order type via configuration would be great.
So i can change type from limit to market.....

Not buying / not spotting new listings

The bot does not seem to be buying anything / spotting newly listed coins.
In previous versions it did buy, but couldnt sell due to 'not enough balance' errors.

There isn't anything to be seen in the logs.

Does anyone have a fix for this problem?

Syntax Error

I've been working to get this running, but I keep encountering the same error regardless of adjustments made. When executing python3 main.py it gives the following result:

File "<fstring>", line 1 (last_price=) ^ SyntaxError: invalid syntax

Python has been updated to 3.9.5, and the requirements have been installed. Any advice or solution? Thank you.

What have I done... 401 error

Been testing and running fine now this must of done something I guess please help did I miss something on resetting it up

2021-11-10 01:26:07,408 ERROR: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 09 Nov 2021 12:26:07 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Server': 'openresty'})
HTTP response body: {"label":"INVALID_KEY","message":"Invalid key provided"}

Listing with multiple coins not working

Last listing:
"Binance Will List Amp (AMP) and PlayDapp (PLA)"

Didn't work because the method get_last_coin() from new_listings_scraper.py only gets a new coin if there is just one on the listing title. Check the if statements at the end of get_last_coin() method:

def get_last_coin():
    """
     Returns new Symbol when appropriate
    """
    latest_announcement = get_announcement()

    found_coin = re.findall('\(([^)]+)', latest_announcement)

    uppers = None

    if 'Will List' not in latest_announcement or found_coin[0] == globals.latest_listing or \
            found_coin[0] in previously_found_coins:
        return None
    else:
        if len(found_coin) == 1:
            uppers = found_coin[0]
            previously_found_coins.add(uppers)
            logger.info('New coin detected: ' + uppers)
        if len(found_coin) != 1:
            uppers = None
    print(f'{uppers=}')
    return uppers

If we want to get all coins from that same listing message, I would suggest using this method, that will grab the first coin the first time the listing message is passed, the second coin the second time... etc:

def get_last_coin():
    """
     Returns new Symbol when appropriate
    """

    latest_announcement = get_announcement()

    found_coins = re.findall('\(([^)]+)', latest_announcement)

    # My method for supporting multi-coin announcements
    if 'Will List' not in latest_announcement or len(found_coins) < 1:
        return None
    else:
        for coin in found_coins:
            if coin != globals.latest_listing and coin not in previously_found_coins:
                previously_found_coins.add(coin)
                logger.info('New coin detected: ' + coin)
                print(f'{coin=}')
                return coin
        return None

If you just want to grab the first coin and ignore the second one cause it might cause problems with buying/selling orders (I haven't read the trading code so much) : the method can easily be modified like this:

def get_last_coin():
    """
     Returns new Symbol when appropriate
    """

    latest_announcement = get_announcement()

    found_coins = re.findall('\(([^)]+)', latest_announcement)

    # My method for supporting multi-coin announcements
    if 'Will List' not in latest_announcement or len(found_coins) < 1:
        return None
    else:
        coin = found_coins[0]
        if coin != globals.latest_listing and coin not in previously_found_coins:
            previously_found_coins.add(coin)
            logger.info('New coin detected: ' + coin)
            print(f'{coin=}')
            return coin
        return None

Hope it helps!

KeyError: 'LOGGING' after recent git pull

Hi

After having the bot run for about a month or two I decided to do a git pull two days ago.
Since then I'm not able to start it anymore, it gives me the following lines:

user@computer:~/gateio-crypto-trading-bot-binance-announcements-new-coins$ python3.9 main.py Traceback (most recent call last): File "/home/user/gateio-crypto-trading-bot-binance-announcements-new-coins/main.py", line 1, in <module> from trade_client import * File "/home/user/gateio-crypto-trading-bot-binance-announcements-new-coins/trade_client.py", line 1, in <module> from logger import logger File "/home/user/gateio-crypto-trading-bot-binance-announcements-new-coins/logger.py", line 15, in <module> log_level = config['LOGGING']['LOG_LEVEL'] KeyError: 'LOGGING'

I already tried to recheck for requirements, but everything seems to be in order.
I also deleted the folder and cloned the code again, but the same error appears.
Is there anything I'm missing?
Any help/pointer appreciated

API check

Is there any error handling (or warnings) id the API is wrong ?

Handling of partially filled orders. "Not Enough balance" errors on sell.

https://github.com/CyberPunkMetalHead/gateio-crypto-trading-bot-binance-announcements-new-coins/blob/master/main.py#L223

At line 223, we assume that the order has been filled. We write to the order.json file the full amount in this assumption.
At this point, the order may be in a status of open, cancelled, filled or closed

One change I have made is:

  1. to change the order create to use the time_in_force=ioc flag. Immediate or cancel. This makes my order automatically cancel if any or none is filled. The status is 'cancelled'. I don't ever want to leave an 'open' status order.

Here is my definition of my place_order method. Notice the ioc provision.

def place_order(base,quote, amount, side, last_price):
    """
    Args:
    'DOT', 'USDT', 50, 'buy', 400
    """
    try:
        order = Order(amount=str(float(amount)/float(last_price)), price=last_price, side=side, currency_pair=f'{base}_{quote}', time_in_force='ioc')
        order = spot_api.create_order(order)
        t = order
        logger.info(f"PLACE ORDER: {t.side} | {t.id} | {t.account} | {t.type} | {t.currency_pair} | {t.status} | amount={t.amount} | price={t.price} | left={t.left} | filled_total={t.filled_total} | fill_price={t.fill_price}")
    except Exception as e:
        logger.error(e)
        raise

    else:
        return order

The second and important change I made is to:

  1. Update the buy amount in the order.json file to be accurate to what your order came back with.

At line 223, I have changed the code to this

else:
                        if test_mode:
                            order_status = order[announcement_coin]['status']
                        else:
                            order_status = order[announcement_coin]['_status']

                        message = f'Order created on {announcement_coin} at a price of {price} each.  {order_status=}'
                        logger.info(message)
                        

                        if order_status == 'filled' or order_status == "closed":
                            if test_mode and float(order[announcement_coin]['_left']) > 0 and float(order[announcement_coin]['_amount']) > float(order[announcement_coin]['_left']):
                                # you can only sell what you have. Minus fees.  Look for unfulfilled
                                newAmount = float(order[announcement_coin]['_amount']) - float(order[announcement_coin]['_left']) - float(order[announcement_coin]['_fee'])
                                order[announcement_coin]['volume'] = newAmount
                            else:
                                store_order('order_fulfilled.json', order)

                                # you can only sell what you have. Minus fees.  Look for unfulfilled
                                newAmount = float(order[announcement_coin]['_amount']) - float(order[announcement_coin]['_left']) - float(order[announcement_coin]['_fee'])
                                order[announcement_coin]['_amount'] = newAmount

                            store_order('order.json', order)
                            
                            if not test_mode and enable_sms:
                                try:
                                    send_sms_message(message)
                                except Exception:
                                    pass
                        elif order_status == 'open' or order_status == 'cancelled':
                            if not test_mode and order_status == 'open':
                                # cancel orders and try again in the next iteration
                                cancel_open_order(order[announcement_coin]['_id'], announcement_coin, pairing)
                                logger.info(f"Cancelled order {order[announcement_coin]['_id']} .  Waiting for status of 'filled/closed' for {announcement_coin}")
                            
                            order.clear()  # reset for next iteration
                            

You must deflate the order by the fee amount too to make sure you get a successful sell order filled.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.