[
  {
    "path": "bitcoin-surge-trading-bot-alpha.py",
    "content": "from datetime import datetime\nfrom itertools import count\nimport time\n\nimport MetaTrader5 as mt5\n\nCRYPTO = 'BTCUSD'\n\n# Price threshold (percentage)\nPRICE_THRESHOLD = 3\n# Stop loss (percentage)\nSTOP_LOSS = 5\n# Take profit (percentage)\nTAKE_PROFIT = 8\n\n# Replace in line 113 to choose between a BUY or SELL order\nBUY = mt5.ORDER_TYPE_BUY\nSELL = mt5.ORDER_TYPE_SELL\nORDER_TYPE = BUY\n\n# connect to the trade account without specifying a password and a server\nmt5.initialize()\n\n# account number in the top left corner of the MT5 terminal window\n# the terminal database password is applied if connection data is set to be remembered\naccount_number = 555\nauthorized = mt5.login(account_number)\n\nif authorized:\n    print(f'connected to account #{account_number}')\nelse:\n    print(f'failed to connect at account #{account_number}, error code: {mt5.last_error()}')\n\n# store the equity of your account\naccount_info = mt5.account_info()\nif account_info is None:\n    raise RuntimeError('Could not load the account equity level.')\nelse:\n    equity = float(account_info[10])\n\n\ndef get_dates():\n    \"\"\"Use dates to define the range of our dataset in the `get_data()`.\"\"\"\n    today = datetime.today()\n    utc_from = datetime(year=today.year, month=today.month, day=today.day - 1)\n    return utc_from, datetime.now()\n\n\ndef get_data():\n    \"\"\"Download one day of 10 minute candles, along with the buy and sell prices for bitcoin.\"\"\"\n    utc_from, utc_to = get_dates()\n    return mt5.copy_rates_range(CRYPTO, mt5.TIMEFRAME_M10, utc_from, utc_to)\n\n\ndef get_current_prices():\n    \"\"\"Return current buy and sell prices.\"\"\"\n    current_buy_price = mt5.symbol_info_tick(CRYPTO)[2]\n    current_sell_price = mt5.symbol_info_tick(CRYPTO)[1]\n    return current_buy_price, current_sell_price\n\n\ndef trade():\n    \"\"\"Determine if we should trade and if so, send requests to MT5.\"\"\"\n    utc_from, utc_to = get_dates()\n    candles = get_data()\n    current_buy_price, current_sell_price = get_current_prices()\n\n    # calculate the % difference between the current price and the close price of the previous candle\n    difference = (candles['close'][-1] - candles['close'][-2]) / candles['close'][-2] * 100\n\n    # used to check if a position has already been placed\n    positions = mt5.positions_get(symbol=CRYPTO)\n    orders = mt5.orders_get(symbol=CRYPTO)\n    symbol_info = mt5.symbol_info(CRYPTO)\n\n    # perform logic check\n    if difference > PRICE_THRESHOLD :\n        print(f'dif 1: {CRYPTO}, {difference}')\n        # Pause for 8 seconds to ensure the increase is sustained\n        time.sleep(8)\n\n        # calculate the difference once again\n        candles = mt5.copy_rates_range(CRYPTO, mt5.TIMEFRAME_M10, utc_from, utc_to)\n        difference = (candles['close'][-1] - candles['close'][-2]) / candles['close'][-2] * 100\n        if difference > PRICE_THRESHOLD:\n            print(f'dif 2: {CRYPTO}, {difference}')\n            price = mt5.symbol_info_tick(CRYPTO).bid\n            print(f'{CRYPTO} is up {str(difference)}% in the last 5 minutes opening BUY position.')\n\n            # prepare the trade request\n            if not mt5.initialize():\n                raise RuntimeError(f'MT5 initialize() failed with error code {mt5.last_error()}')\n\n            # check that there are no open positions or orders\n            if len(positions) == 0 and len(orders) < 1:\n                if symbol_info is None:\n                    print(f'{CRYPTO} not found, can not call order_check()')\n                    mt5.shutdown()\n                    # if the symbol is unavailable in MarketWatch, add it\n                if not symbol_info.visible:\n                    print(f'{CRYPTO} is not visible, trying to switch on')\n                    if not mt5.symbol_select(CRYPTO, True):\n                        print('symbol_select({}}) failed, exit', CRYPTO)\n\n                #this represents 5% Equity. Minimum order is 0.01 BTC. Increase equity share if retcode = 10014\n                lot = float(round(((equity / 20) / current_buy_price), 2))\n                \n                # define stop loss and take profit\n                if ORDER_TYPE == BUY:\n                    sl = price - (price * STOP_LOSS) / 100\n                    tp = price + (price * TAKE_PROFIT) / 100\n                else:\n                    sl = price + (price * STOP_LOSS) / 100\n                    tp = price - (price * TAKE_PROFIT) / 100\n                    \n                request = {\n                    'action': mt5.TRADE_ACTION_DEAL,\n                    'symbol': CRYPTO,\n                    'volume': lot,\n                    'type': ORDER_TYPE,\n                    'price': price,\n                    'sl': sl,\n                    'tp': tp,\n                    'magic': 66,\n                    'comment': 'python-buy',\n                    'type_time': mt5.ORDER_TIME_GTC,\n                    'type_filling': mt5.ORDER_FILLING_IOC,\n                }\n\n                # send a trading request\n                result = mt5.order_send(request)\n\n                # check the execution result\n                print(f'1. order_send(): by {CRYPTO} {lot} lots at {price}')\n\n                if result.retcode != mt5.TRADE_RETCODE_DONE:\n                    print(f'2. order_send failed, retcode={result.retcode}')\n\n                #print the order result - anything else than retcode=10009 is an error in the trading request.\n                print(f'2. order_send done, {result}')\n                print(f'   opened position with POSITION_TICKET={result.order}')\n\n            else:\n                print(f'BUY signal detected, but {CRYPTO} has {len(positions)} active trade')\n\n        else:\n            pass\n\n    else:\n        if orders or positions:\n            print('Buying signal detected but there is already an active trade')\n        else:\n            print(f'difference is only: {str(difference)}% trying again...')\n\n\nif __name__ == '__main__':\n    print('Press Ctrl-C to stop.')\n    for i in count():\n        trade()\n        print(f'Iteration {i}')\n        time.sleep(5)\n"
  },
  {
    "path": "readme.txt",
    "content": "The bot will be trading Bitcoin automatically if the price has increased by more than 3% in the last 10 minutes. \nWe will have a stop loss of 5% and take profit of 8%. \nLater on, you can choose to further optimise your bot and include additional features such as trailing stop loss and close signals – but for now we’ll keep it simple.\n\n**USE CASES**\nUse with a demo account - use on a live account at your own risk\nUse to test different crypto markets\n\n**Prerequisites**\nFollow blog instructions on creating a demo environment.\nAdditional resources needed (modules, software etc.) are also listed on the blog\n\nGo here: https://www.cryptomaton.org/2021/03/14/how-to-code-your-own-crypto-trading-bot-python/\n\n**Considerations**\nThe bot can be adjusted to work with multiple cryptos at once. It currently requires a viable exit strategy.\nIf you test this bot please let me know your results!\nThanks for your interest in this project and good luck!\n\nInterested in colaborating? Get in touch. \n\n\n"
  }
]