├── .docker ├── freqtrade-ui │ └── Dockerfile └── freqtrade │ └── Dockerfile ├── .gitignore ├── .stubs ├── configs │ └── private │ │ ├── api.json │ │ ├── exchange.json │ │ ├── main.json │ │ ├── pairs.json │ │ ├── protections.json │ │ ├── strategies │ │ └── example.json │ │ └── telegram.json └── instances │ └── stub.sh ├── .tmp └── .gitkeep ├── README.md ├── b ├── configs └── components │ ├── backtest.json │ ├── exchanges │ ├── binance.json │ ├── binance │ │ ├── blacklist.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ ├── pairlist.dynamic.busd.json │ │ └── pairlist.dynamic.usdt.json │ ├── bybit │ │ ├── blacklist.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ └── pairlist.dynamic.usdt.json │ ├── gateio.json │ ├── gateio │ │ ├── blacklist.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ └── pairlist.dynamic.usdt.json │ ├── huobi │ │ ├── blacklist.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ └── pairlist.dynamic.usdt.json │ ├── kucoin.json │ ├── kucoin │ │ ├── kucoin.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ └── pairlist.dynamic.usdt.json │ └── okx │ │ ├── blacklist.json │ │ ├── main.json │ │ ├── pairlist.dynamic.btc.json │ │ └── pairlist.dynamic.usdt.json │ └── settings │ ├── do-not-run-at-start.json │ └── enable-force-buy.json ├── hyperopts └── .gitkeep ├── instances └── .gitkeep └── strategies ├── .gitkeep └── Example.py /.docker/freqtrade-ui/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19.4.0-alpine as ui-builder 2 | 3 | ENV NODE_OPTIONS --openssl-legacy-provider 4 | 5 | RUN mkdir /app 6 | 7 | WORKDIR /app 8 | 9 | # ENV PATH /usr/src/app/node_modules/.bin:$PATH 10 | 11 | RUN wget --quiet https://github.com/freqtrade/frequi/archive/refs/tags/0.6.3.tar.gz -O /tmp/ui.tar.gz \ 12 | && tar xf /tmp/ui.tar.gz -C /app --strip 1 \ 13 | && rm /tmp/ui.tar.gz 14 | 15 | RUN apk add --update --no-cache python3 g++ make \ 16 | && yarn \ 17 | && apk del python3 g++ make 18 | 19 | RUN yarn build 20 | 21 | FROM nginx:1.21.4-alpine 22 | COPY --from=ui-builder /app/dist /etc/nginx/html 23 | COPY --from=ui-builder /app/nginx.conf /etc/nginx/nginx.conf 24 | EXPOSE 80 25 | CMD ["nginx"] 26 | -------------------------------------------------------------------------------- /.docker/freqtrade/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM freqtradeorg/freqtrade:stable 2 | 3 | RUN pip install --upgrade pip 4 | 5 | RUN pip install -U -r requirements-plot.txt 6 | RUN pip install technical 7 | RUN pip install ta 8 | RUN pip install finta 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .tmp/* 2 | configs/private 3 | instances/* 4 | strategies/* 5 | !strategies/Example.py 6 | hyperopts/* 7 | -------------------------------------------------------------------------------- /.stubs/configs/private/api.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_server": { 3 | "jwt_secret_key": "xxx", 4 | "username": "xxx", 5 | "password": "xxx", 6 | "CORS_origins": [ 7 | "http://localhost" 8 | ], 9 | "enabled": true, 10 | "listen_ip_address": "0.0.0.0", 11 | "listen_port": 8080, 12 | "verbosity": "error" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.stubs/configs/private/exchange.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "key": "xxx", 4 | "secret": "xxx" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.stubs/configs/private/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "max_open_trades": 4, 3 | "stake_currency": "USDT", 4 | "stake_amount" : "unlimited", 5 | "amend_last_stake_amount ": true, 6 | "tradable_balance_ratio": 0.99, 7 | "fiat_display_currency": "USD", 8 | "dry_run": true, 9 | "dry_run_wallet": 100, 10 | "cancel_open_orders_on_exit": false, 11 | "ignore_buying_expired_candle_after" : 90, 12 | "unfilledtimeout": { 13 | "buy": 30, 14 | "sell": 10, 15 | "unit": "seconds" 16 | }, 17 | "order_types": { 18 | "buy": "market", 19 | "sell": "market", 20 | "forcesell": "market", 21 | "emergencysell": "market", 22 | "trailing_stop_loss": "market", 23 | "stoploss": "market", 24 | "stoploss_on_exchange": false, 25 | "stoploss_on_exchange_interval": 60 26 | }, 27 | "bid_strategy": { 28 | "price_side": "ask", 29 | "ask_last_balance": 0.0, 30 | "use_order_book": false, 31 | "order_book_top": 1, 32 | "check_depth_of_market": { 33 | "enabled": false, 34 | "bids_to_ask_delta": 1 35 | } 36 | }, 37 | "ask_strategy": { 38 | "price_side": "bid", 39 | "use_order_book": false, 40 | "order_book_min": 1, 41 | "order_book_max": 1 42 | }, 43 | "edge": { 44 | "enabled": false, 45 | "process_throttle_secs": 3600, 46 | "calculate_since_number_of_days": 7, 47 | "allowed_risk": 0.01, 48 | "stoploss_range_min": -0.01, 49 | "stoploss_range_max": -0.1, 50 | "stoploss_range_step": -0.01, 51 | "minimum_winrate": 0.60, 52 | "minimum_expectancy": 0.10, 53 | "min_trade_number": 10, 54 | "max_trade_duration_minute": 1440, 55 | "remove_pumps": false 56 | }, 57 | "initial_state": "running", 58 | "forcebuy_enable": false, 59 | "internals": { 60 | "process_throttle_secs": 2 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.stubs/configs/private/pairs.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume" 7 | }, 8 | { 9 | "method": "AgeFilter", 10 | "min_days_listed": 30 11 | }, 12 | { 13 | "method": "VolatilityFilter", 14 | "lookback_days": 3, 15 | "min_volatility": 0.02, 16 | "refresh_period": 1800 17 | }, 18 | { 19 | "method": "VolumePairList", 20 | "number_assets": 80, 21 | "sort_key": "quoteVolume" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.stubs/configs/private/protections.json: -------------------------------------------------------------------------------- 1 | { 2 | "protections": [ 3 | { 4 | "method": "StoplossGuard", 5 | "lookback_period_candles": 24, 6 | "trade_limit": 4, 7 | "stop_duration_candles": 4, 8 | "only_per_pair": false 9 | }, 10 | { 11 | "method": "CooldownPeriod", 12 | "stop_duration_candles": 2 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.stubs/configs/private/strategies/example.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /.stubs/configs/private/telegram.json: -------------------------------------------------------------------------------- 1 | { 2 | "telegram": { 3 | "enabled": true, 4 | "token": "xxx", 5 | "chat_id": "xxx", 6 | "notification_settings": { 7 | "status": "silent", 8 | "warning": "on", 9 | "startup": "off", 10 | "buy": "silent", 11 | "sell": { 12 | "roi": "silent", 13 | "emergency_sell": "on", 14 | "force_sell": "on", 15 | "sell_signal": "silent", 16 | "trailing_stop_loss": "on", 17 | "stop_loss": "on", 18 | "stoploss_on_exchange": "on", 19 | "custom_sell": "silent" 20 | }, 21 | "buy_cancel": "silent", 22 | "sell_cancel": "on", 23 | "buy_fill": "off", 24 | "sell_fill": "off", 25 | "protection_trigger": "off", 26 | "protection_trigger_global": "on" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.stubs/instances/stub.sh: -------------------------------------------------------------------------------- 1 | FT_DRY_RUN="true" 2 | FT_INSTANCE_NAME="" 3 | FT_STRATEGY="Example" # .......... Change with your wanted Strategy (must be into ./strategies folder, just give the name) 4 | FT_API_SERVER_PORT="12345" # ......... Choose a unique and free port for each instance, and use http(s)://: from UI to connect to 5 | FT_DRY_RUN_WALLET="500" # ............ Used for dry-run mode and backtesting 6 | 7 | # Add some configuration files 8 | 9 | FT_INSTANCE_CONFIGS=( 10 | /configs/private/main.json 11 | /configs/private/pairs.json 12 | # /configs/private/protections.json 13 | /configs/components/exchanges/binance/main.json # adapt to yours from `/configs/components/exchanges` 14 | /configs/components/exchanges/binance/blacklist.json # adapt to yours from `/configs/components/exchanges` 15 | /configs/components/exchanges/binance/pairlist.dynamic.busd.json # adapt to yours from `/configs/components/exchanges` 16 | /configs/private/exchange.json 17 | # /configs/private/api.json 18 | # /configs/private/telegram.json 19 | # /configs/private/strategies/example.json # put your strategies configs into `/configs/private/strategies` 20 | # /configs/components/settings/do-not-run-at-start.json 21 | # /configs/components/settings/enable-force-buy.json 22 | ) 23 | 24 | # Add some configuration files for backesting 25 | 26 | FT_INSTANCE_CONFIGS_BACKTESTING=( 27 | /configs/components/backtest.json 28 | ) 29 | -------------------------------------------------------------------------------- /.tmp/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ph3nol/FT-Trading-Bot/0cf50a2a3d182505ae5510ff80fe1f1cf71fae63/.tmp/.gitkeep -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cryptocurrencies Trading Bot - Freqtrade Manager 2 | 3 | This automated Trading Bot is based on the amazing [Freqtrade](https://www.freqtrade.io/en/latest/) one. 4 | It allows you to manage many Freqtrade fully Dockerized instances and UI with ease. 5 | 6 | ## Features 7 | 8 | * **Fast & easy deploy** 🚀 9 | * Generate a new ready instance with 1 command line only 10 | * Unlimited instances configurations from 1 file 11 | * Many available public strategies, grabbed from multiple sources (Github, Discord, etc.) 12 | * Many more is coming! 13 | 14 | ## DISCLAIMER 15 | 16 | Do not risk money which you are afraid to lose. **USE THIS APPLICATION AT YOUR OWN RISK.** THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY ABOUT YOUR TRADING RESULTS. 17 | 18 | ## Installation 19 | 20 | ### Requirements 21 | 22 | * A cryptocurrency exchange account, like [Binance](https://www.binance.com/fr/register?ref=69525434) or [Kucoin](https://www.kucoin.com/ucenter/signup?rcode=rJ4U44Y) 23 | * [Docker](https://www.docker.com/) #CaptainObvious 24 | 25 | ### Get this Trading Bot 26 | 27 | ``` 28 | mkdir fq-trading-bot && cd fq-trading-bot 29 | git clone https://github.com/Ph3nol/FT-Trading-Bot.git . 30 | ./b install 31 | ``` 32 | 33 | ### Configure & Customize 34 | 35 | * Adapt basic private generated files into `./configs/private` — **of course you can add yours!** 36 | * Use or add your best strategies into `./strategies` — **first official ones are into official/ dedicated directory!** 37 | * Use or add your hyperopts into `./hyperopts` 38 | 39 | ### Create and configure your first instance 40 | 41 | Suppose you want to create an instance named `unicorn01`. 42 | 43 | ``` 44 | ./b i unicorn01 create 45 | ``` 46 | 47 | * Configure your instance parameters from `./instances/unicorn01.sh` 48 | 49 | ## Usage 50 | 51 | Just use `./b` from your Trading Bot directory. 52 | 53 | ## Backtesting 54 | 55 | ``` 56 | ./b instance unicorn data 10 # Download 10 days of data for `unicorn` instance 57 | ./b instance unicorn backtesting # Let's backtest! 58 | ``` 59 | 60 | ## Start common UI 61 | 62 | ``` 63 | ./b ui start 64 | ./b ui start 8888 # if you want 8888 as HTTP port 65 | ``` 66 | 67 | ## Thanks 68 | 69 | ![Thanks](https://media.giphy.com/media/PoImMjCPa8QaiBWJd0/giphy.gif) 70 | 71 | You want to support this project? 72 | You are using this project and you want to contribute? 73 | Feeling generous? 74 | 75 | * **BTC** -> `1MksZdEXqFwqNhEiPT5sLhgWijuCH42r9c` 76 | * **ETH** (ERC20) -> `0x3167ddc7a6b47a0af1ce5270e067a70b997fd313` 77 | * **BSC - Binance Smart Chain** (BEP20) -> `0x3167ddc7a6b47a0af1ce5270e067a70b997fd313` 78 | * **Solana** (SOL) -> `DsftXATN6aQe5ppjByzQyJAQ2fJkZcN9UDF8HDiUY7iH` 79 | * **TRX** (TRC20) -> `TVurVvbyXDzqTKhVXj1eq3U2T8UfVD4KsD` 80 | 81 | ## Development 82 | 83 | ![Development](https://media.giphy.com/media/fQZX2aoRC1Tqw/giphy.gif) 84 | 85 | ### (Re)Build reference Docker images 86 | 87 | ``` 88 | docker buildx build --no-cache --push --platform linux/amd64 \ 89 | --file .docker/freqtrade/Dockerfile \ 90 | --tag ph3nol/ft-trading-bot:latest . 91 | 92 | docker buildx build --no-cache --push --platform linux/amd64 \ 93 | --file .docker/freqtrade-ui/Dockerfile \ 94 | --tag ph3nol/ft-trading-bot-ui:latest . 95 | ``` 96 | -------------------------------------------------------------------------------- /b: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASE_CONFIGS_DIRECTORY="${PWD}/configs" 4 | BASE_INSTANCES_DIRECTORY="${PWD}/instances" 5 | BASE_TMP_DIRECTORY="${PWD}/.tmp" 6 | if [ ! -d "${BASE_CONFIGS_DIRECTORY}" ] || [ ! -d "${BASE_INSTANCES_DIRECTORY}" ]; then 7 | echo "🔴 [ERROR] You are not into a Freqtrade Trading instances directory" 8 | exit 1 9 | fi 10 | 11 | prepare() { 12 | DOCKER_FREQTRADE_IMAGE="ph3nol/ft-trading-bot:latest" 13 | DOCKER_FREQTRADE_UI_IMAGE="ph3nol/ft-trading-bot-ui:latest" 14 | DOCKER_CONTAINER_BASE_PREFIX="ft-trading-bots" 15 | DOCKER_NETWORK="${DOCKER_CONTAINER_BASE_PREFIX}-network" 16 | 17 | DOCKER_BUILD="docker build" 18 | DOCKER_RUN="docker run --rm -it" 19 | DOCKER_RUN_WITH_RESTART="docker run -d --restart=always -it" 20 | DOCKER_KILL="docker kill" 21 | DOCKER_RM="docker rm" 22 | DOCKER_LOGS="docker logs" 23 | 24 | if [[ `uname -m` == 'arm64' ]]; then 25 | DOCKER_BUILD="${DOCKER_BUILD} --platform linux/amd64" 26 | DOCKER_RUN="${DOCKER_RUN} --platform linux/amd64" 27 | DOCKER_RUN_WITH_RESTART="${DOCKER_RUN_WITH_RESTART} --platform linux/amd64" 28 | fi 29 | 30 | docker network create ${DOCKER_NETWORK} > /dev/null 2>&1 31 | 32 | CONFIGS_PRIVATE_DIRECTORY="${BASE_CONFIGS_DIRECTORY}/private" 33 | if [ ! -d "${CONFIGS_PRIVATE_DIRECTORY}" ]; then mkdir ${CONFIGS_PRIVATE_DIRECTORY}; fi 34 | if [[ "$(ls ${CONFIGS_PRIVATE_DIRECTORY} | wc -l)" -eq "0" ]]; then 35 | cp -r ${PWD}/.stubs/configs/private/* ${CONFIGS_PRIVATE_DIRECTORY}/ 36 | fi 37 | } 38 | 39 | instance_create() { 40 | if [ -d "${INSTANCE_DIRECTORY}" ] || [ -f "${INSTANCE_CONFIG_FILE}" ]; then 41 | echo "🔴 [ERROR] ${INSTANCE} instance already exists" 42 | exit 1 43 | fi 44 | 45 | echo "Creating..." 46 | 47 | cp ${PWD}/.stubs/instances/stub.sh ${INSTANCE_CONFIG_FILE} 48 | echo "$(sed "2s/.*/FT_INSTANCE_NAME=\""${INSTANCE}"\"/" ${INSTANCE_CONFIG_FILE})" > ${INSTANCE_CONFIG_FILE} 49 | 50 | mkdir -p ${INSTANCE_DIRECTORY} ${INSTANCE_DIRECTORY}/user_data 51 | touch ${INSTANCE_CONFIG_FILE} \ 52 | ${INSTANCE_DIRECTORY}/tradesv3.sqlite \ 53 | ${INSTANCE_DIRECTORY}/tradesv3.dryrun.sqlite 54 | chmod -R 777 ${INSTANCE_DIRECTORY} 55 | } 56 | 57 | instance_remove() { 58 | if [ ! -d "${INSTANCE_DIRECTORY}" ]; then 59 | echo "🔴 [ERROR] ${INSTANCE} instance does not exist" 60 | exit 1 61 | fi 62 | 63 | echo "Removing..." 64 | rm -rf ${INSTANCE_DIRECTORY} ${INSTANCE_CONFIG_FILE} 65 | } 66 | 67 | instance_init() { 68 | TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE_NAME="${INSTANCE}.config.exchange.pairs.json" 69 | TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE="${BASE_TMP_DIRECTORY}/${TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE_NAME}" 70 | 71 | if [ ! -d "${INSTANCE_DIRECTORY}" ] || [ ! -f "${INSTANCE_CONFIG_FILE}" ]; then 72 | instance_create 73 | fi 74 | 75 | . ${INSTANCE_CONFIG_FILE} 76 | 77 | FT_CONFIGS_ARGS="" 78 | for CONFIG_FILE in "${FT_INSTANCE_CONFIGS[@]}"; do FT_CONFIGS_ARGS+="--config ${CONFIG_FILE} "; done 79 | 80 | VOLUMES=( 81 | "/etc/localtime:/etc/localtime:ro" 82 | "${BASE_CONFIGS_DIRECTORY}:/configs:ro" 83 | "${BASE_TMP_DIRECTORY}:/.tmp:ro" 84 | "${INSTANCE_DIRECTORY}/tradesv3.sqlite:/freqtrade/tradesv3.sqlite:rw" 85 | "${INSTANCE_DIRECTORY}/tradesv3.dryrun.sqlite:/freqtrade/tradesv3.dryrun.sqlite:rw" 86 | "${INSTANCE_DIRECTORY}/user_data:/freqtrade/user_data:rw" 87 | "${PWD}/strategies:/freqtrade/user_data/strategies:rw" 88 | ) 89 | VOLUMES_ARGS="" 90 | for VOLUME in "${VOLUMES[@]}"; do VOLUMES_ARGS+="-v ${VOLUME} "; done 91 | 92 | ENVS=( 93 | "FREQTRADE__BOT_NAME=${FT_INSTANCE_NAME}" 94 | "FREQTRADE__DRY_RUN=${FT_DRY_RUN}" 95 | "FREQTRADE__DRY_RUN_WALLET=${FT_DRY_RUN_WALLET}" 96 | ) 97 | ENVS_ARGS="" 98 | for ENV in "${ENVS[@]}"; do ENVS_ARGS+="-e ${ENV} "; done 99 | 100 | DOCKER_CONTAINER_BASE_NAME="${DOCKER_CONTAINER_BASE_PREFIX}-${INSTANCE}" 101 | DOCKER_CONTAINER_NAME="${DOCKER_CONTAINER_BASE_NAME}-${ACTION}" 102 | } 103 | 104 | instance_update_backtesting_pairlists() { 105 | echo "Updating backtesting pairlists..." 106 | 107 | PAIRS_LIST=$( 108 | ${DOCKER_RUN} --name ${DOCKER_CONTAINER_NAME}-update-backtesting-pairslist --network ${DOCKER_NETWORK} \ 109 | ${VOLUMES_ARGS} ${ENVS_ARGS} \ 110 | ${DOCKER_FREQTRADE_IMAGE} test-pairlist ${FT_CONFIGS_ARGS} --print-json 111 | ) 112 | 113 | PAIRS_LIST=${PAIRS_LIST##*$'\n'} 114 | 115 | cat << EOF > ${TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE} 116 | { 117 | "exchange": { 118 | "pair_whitelist": ${PAIRS_LIST} 119 | } 120 | } 121 | EOF 122 | } 123 | 124 | instance_stop() { 125 | echo "Stopping..." 126 | 127 | ${DOCKER_KILL} "${DOCKER_CONTAINER_BASE_NAME}-data-update-backtesting-pairslist" > /dev/null 2>&1 128 | ${DOCKER_RM} "${DOCKER_CONTAINER_BASE_NAME}-data-update-backtesting-pairslist" > /dev/null 2>&1 129 | ${DOCKER_KILL} "${DOCKER_CONTAINER_BASE_NAME}-pairs" > /dev/null 2>&1 130 | ${DOCKER_RM} "${DOCKER_CONTAINER_BASE_NAME}-pairs" > /dev/null 2>&1 131 | ${DOCKER_KILL} "${DOCKER_CONTAINER_BASE_NAME}-trade" > /dev/null 2>&1 132 | ${DOCKER_RM} "${DOCKER_CONTAINER_BASE_NAME}-trade" > /dev/null 2>&1 133 | ${DOCKER_KILL} "${DOCKER_CONTAINER_BASE_NAME}-data" > /dev/null 2>&1 134 | ${DOCKER_RM} "${DOCKER_CONTAINER_BASE_NAME}-data" > /dev/null 2>&1 135 | ${DOCKER_KILL} "${DOCKER_CONTAINER_BASE_NAME}-backtesting" > /dev/null 2>&1 136 | ${DOCKER_RM} "${DOCKER_CONTAINER_BASE_NAME}-backtesting" > /dev/null 2>&1 137 | } 138 | 139 | instance_logs() { 140 | echo "Tailing instance logs..." 141 | 142 | ${DOCKER_LOGS} -f ${DOCKER_CONTAINER_NAME} 143 | } 144 | 145 | instance_init_backtesting() { 146 | for CONFIG_BACKTEST_FILE in "${FT_INSTANCE_CONFIGS_BACKTESTING[@]}"; do FT_CONFIGS_ARGS+="--config ${CONFIG_BACKTEST_FILE} "; done 147 | 148 | if [ -f "${TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE}" ]; then 149 | FT_CONFIGS_ARGS+="--config /.tmp/${TMP_CONFIG_EXCHANGE_PAIRSLIST_FILE_NAME} " 150 | fi 151 | } 152 | 153 | instance_display_informations() { 154 | echo "" 155 | 156 | if [[ ${FT_DRY_RUN} = "true" ]]; then 157 | DISPLAYED_MODE="😴 [DRY-RUN]" 158 | else 159 | DISPLAYED_MODE="🚀 [LIVE]" 160 | fi 161 | 162 | echo "${DISPLAYED_MODE} ${FT_INSTANCE_NAME} @ Port ${FT_API_SERVER_PORT}" 163 | echo " • Strategy .................. ${FT_STRATEGY}" 164 | echo " • Port ...................... ${FT_API_SERVER_PORT}" 165 | if [[ ${FT_DRY_RUN} -eq "true" ]]; then 166 | echo " • Dry-run Wallet ............ ${FT_DRY_RUN_WALLET}" 167 | fi 168 | } 169 | 170 | display_help() { 171 | echo "🚀 Trading Bot command usage:" 172 | echo "" 173 | echo " ./`basename ${0}` instance create ...................... Create/Init an instance" 174 | echo " ./`basename ${0}` instance trade ....................... Trade" 175 | echo " ./`basename ${0}` instance pairs ............... List available exchange pairs" 176 | echo " ./`basename ${0}` instance configs-pairs ....... Set TMP pairs, from configs" 177 | echo " ./`basename ${0}` instance data ........... Download data for backtests" 178 | echo " ./`basename ${0}` instance backtesting ..... Run backtest ( format: 20211102)" 179 | echo " ./`basename ${0}` instance reset ....................... Reset instance data" 180 | echo " ./`basename ${0}` instance remove ...................... Remove instance" 181 | echo " ./`basename ${0}` instance logs ........................ Tail running instance Freqtrade logs" 182 | echo "" 183 | echo " ./`basename ${0}` ui start ............................................. Start UI" 184 | echo " ./`basename ${0}` ui stop .............................................. Stop UI" 185 | echo "" 186 | echo " 👉 Note that you can use './`basename ${0}` i <...>' as an alias for './`basename ${0}` instance <...>'" 187 | } 188 | 189 | handle_instance() { 190 | case ${ACTION} in 191 | create) 192 | instance_create 193 | exit 0 194 | ;; 195 | remove) 196 | instance_remove 197 | exit 0 198 | ;; 199 | reset) 200 | instance_remove && instance_create 201 | exit 0 202 | ;; 203 | pairs) 204 | instance_init 205 | 206 | echo "🚥 Loading pairs..." 207 | ${DOCKER_RUN} --name ${DOCKER_CONTAINER_NAME} --network ${DOCKER_NETWORK} \ 208 | ${VOLUMES_ARGS} ${ENVS_ARGS} \ 209 | ${DOCKER_FREQTRADE_IMAGE} list-pairs ${FT_CONFIGS_ARGS} --quote ${ACTION_ARGS[0]} --print-json 210 | exit 0 211 | ;; 212 | configs-pairs) 213 | instance_init 214 | instance_update_backtesting_pairlists 215 | exit 0 216 | ;; 217 | trade) 218 | instance_init 219 | instance_stop > /dev/null 2>&1 220 | 221 | echo "🚥 Trading..." 222 | ${DOCKER_RUN_WITH_RESTART} --name ${DOCKER_CONTAINER_NAME} --network ${DOCKER_NETWORK} \ 223 | ${VOLUMES_ARGS} ${ENVS_ARGS} -p ${FT_API_SERVER_PORT}:8080 \ 224 | ${DOCKER_FREQTRADE_IMAGE} trade --strategy ${FT_STRATEGY} ${FT_CONFIGS_ARGS} \ 225 | > /dev/null 2>&1 226 | instance_display_informations 227 | exit 0 228 | ;; 229 | data) 230 | instance_init 231 | instance_update_backtesting_pairlists 232 | instance_init_backtesting 233 | 234 | echo "🚥 Downloading data..." 235 | 236 | if [ ! "${ACTION_ARGS[1]}" = "" ]; then 237 | ${DOCKER_RUN} --name ${DOCKER_CONTAINER_NAME} --network ${DOCKER_NETWORK} \ 238 | ${VOLUMES_ARGS} ${ENVS_ARGS} \ 239 | ${DOCKER_FREQTRADE_IMAGE} download-data ${FT_CONFIGS_ARGS} --days ${ACTION_ARGS[0]} -t {1m,5m,15m,1h,4h,12h,1d} \ 240 | --pairs ${ACTION_ARGS[1]} 241 | else 242 | ${DOCKER_RUN} --name ${DOCKER_CONTAINER_NAME} --network ${DOCKER_NETWORK} \ 243 | ${VOLUMES_ARGS} ${ENVS_ARGS} \ 244 | ${DOCKER_FREQTRADE_IMAGE} download-data ${FT_CONFIGS_ARGS} --days ${ACTION_ARGS[0]} -t {1m,5m,15m,1h,4h,12h,1d} \ 245 | --erase 246 | fi 247 | exit 0 248 | ;; 249 | backtesting) 250 | instance_init && instance_init_backtesting 251 | 252 | echo "🚥 Backtesting..." 253 | FT_BACKTEST_TIMERANGE_ARG="" 254 | if [ ! -z ${ACTION_ARGS[0]} ]; then 255 | FT_BACKTEST_TIMERANGE_ARG="--timerange ${ACTION_ARGS[0]}" 256 | fi 257 | ${DOCKER_RUN} --name ${DOCKER_CONTAINER_NAME} --network ${DOCKER_NETWORK} \ 258 | ${VOLUMES_ARGS} ${ENVS_ARGS} \ 259 | ${DOCKER_FREQTRADE_IMAGE} backtesting --enable-protections --strategy ${FT_STRATEGY} ${FT_CONFIGS_ARGS} ${FT_BACKTEST_TIMERANGE_ARG} 260 | exit 0 261 | ;; 262 | stop) 263 | instance_init && instance_stop 264 | exit 0 265 | ;; 266 | logs) 267 | instance_init && instance_logs 268 | exit 0 269 | ;; 270 | *) 271 | display_help 272 | exit 1 273 | ;; 274 | esac 275 | } 276 | 277 | ui_init() { 278 | VOLUMES=( 279 | "/etc/localtime:/etc/localtime:ro" 280 | ) 281 | VOLUMES_ARGS="" 282 | 283 | ENVS_ARGS="" 284 | 285 | DOCKER_CONTAINER_BASE_NAME="${DOCKER_CONTAINER_BASE_PREFIX}-${INSTANCE}" 286 | DOCKER_CONTAINER_NAME="${DOCKER_CONTAINER_BASE_NAME}-ui" 287 | 288 | UI_PUBLIC_PORT="${ACTION_ARGS[0]:-22222}" 289 | } 290 | 291 | ui_start() { 292 | echo "🚥 Starting..." 293 | 294 | ${DOCKER_RUN_WITH_RESTART} --name ${DOCKER_CONTAINER_NAME} \ 295 | ${VOLUMES_ARGS} ${ENVS_ARGS} -p ${UI_PUBLIC_PORT}:80 \ 296 | ${DOCKER_FREQTRADE_UI_IMAGE} \ 297 | > /dev/null 2>&1 298 | 299 | echo "Note: UI is available from http(s)://:${UI_PUBLIC_PORT}" 300 | } 301 | 302 | ui_stop() { 303 | echo "🚥 Stopping..." 304 | 305 | ${DOCKER_KILL} ${DOCKER_CONTAINER_NAME} > /dev/null 2>&1 306 | ${DOCKER_RM} ${DOCKER_CONTAINER_NAME} > /dev/null 2>&1 307 | } 308 | 309 | handle_ui() { 310 | case ${ACTION} in 311 | start) 312 | ui_init && ui_start 313 | exit 0 314 | ;; 315 | stop) 316 | ui_init && ui_stop 317 | exit 0 318 | ;; 319 | *) 320 | display_help 321 | exit 1 322 | ;; 323 | esac 324 | } 325 | 326 | handle_list() { 327 | INSTANCES=$(docker ps --no-trunc -f "name=${DOCKER_CONTAINER_BASE_PREFIX}" | sed "1 d") 328 | # @todo To be continued 329 | } 330 | 331 | handle_init_install_upgrade() { 332 | echo "🚥 Initializing/Installing/Upgrading..." 333 | echo "--- Be patient, it could take from some seconds to some minutes! ---" 334 | echo "" 335 | echo " > Downloading Freqtrade Docker image..." 336 | docker pull --quiet ${DOCKER_FREQTRADE_IMAGE} > /dev/null 2>&1 337 | echo " > Downloading Freqtrade UI Docker image..." 338 | docker pull --quiet ${DOCKER_FREQTRADE_UI_IMAGE} > /dev/null 2>&1 339 | echo " > Downloading first official Freqtrade strategies and hyperopts..." 340 | rm -rf .tmp/freqtrade-strategies && \ 341 | git clone --quiet https://github.com/freqtrade/freqtrade-strategies.git .tmp/freqtrade-strategies \ 342 | && mkdir -p strategies/official \ 343 | && cp -r .tmp/freqtrade-strategies/user_data/strategies/* strategies/official/ \ 344 | && mkdir -p hyperopts/official \ 345 | && cp -r .tmp/freqtrade-strategies/user_data/hyperopts/* hyperopts/official/ \ 346 | && rm -rf .tmp/freqtrade-strategies 347 | 348 | echo "" 349 | echo "✅ Ready to use!" 350 | echo "" 351 | display_help 352 | } 353 | 354 | prepare 355 | 356 | COMMAND="${1}" 357 | 358 | case ${COMMAND} in 359 | init | install | upgrade) 360 | handle_init_install_upgrade 361 | exit 0 362 | ;; 363 | list) 364 | handle_list 365 | exit 0 366 | ;; 367 | i | instance) 368 | INSTANCE="${2}" 369 | ACTION="${3}" 370 | ACTION_ARGS=(${@:4}) 371 | if [ -z "${INSTANCE}" ] || [ -z "${ACTION}" ]; then 372 | display_help 373 | exit 1 374 | fi 375 | 376 | INSTANCE_DIRECTORY="${BASE_INSTANCES_DIRECTORY}/${INSTANCE}" 377 | INSTANCE_CONFIG_FILE="${BASE_INSTANCES_DIRECTORY}/${INSTANCE}.sh" 378 | 379 | handle_instance 380 | exit 0 381 | ;; 382 | ui) 383 | ACTION="${2}" 384 | ACTION_ARGS=(${@:3}) 385 | if [ -z "${ACTION}" ]; then 386 | display_help 387 | exit 1 388 | fi 389 | 390 | handle_ui 391 | exit 0 392 | ;; 393 | help) 394 | display_help 395 | exit 0 396 | ;; 397 | *) 398 | display_help 399 | exit 1 400 | ;; 401 | esac 402 | -------------------------------------------------------------------------------- /configs/components/backtest.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "StaticPairList" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "binance", 4 | "ccxt_config": { 5 | "enableRateLimit": true 6 | }, 7 | "ccxt_async_config": { 8 | "enableRateLimit": true, 9 | "rateLimit": 0 10 | }, 11 | "pair_blacklist": [ 12 | // Exchange 13 | "(BNB)/.*", 14 | // Leverage 15 | ".*(_PREMIUM|BEAR|BULL|DOWN|HALF|HEDGE|UP|[1235][SL])/.*", 16 | // Fiat 17 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 18 | // Stable 19 | "(BUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDP|USDT|VAI)/.*", 20 | // FAN 21 | "(ACM|AFA|ALA|ALL|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LAZIO|LEG|LOCK-1|NAVI|NMR|NOV|OG|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange 5 | "(BNB)/.*", 6 | // Leverage 7 | ".*(_PREMIUM|BEAR|BULL|HALF|HEDGE|UP|DOWN|[1235][SL])/.*", 8 | // Fiat 9 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 10 | // Stable 11 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USTC|AUSD)/.*", 12 | // FAN 13 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CHZ|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*", 14 | // Others 15 | "(1EARTH|ILA|BOBA|CTXC|CWAR|HBAR|NMR|OMG|ONG|ARDR|DMTR|MLS|TORN|ANC|LUNA|BTS|QKC|COS|ACA|FTT|SRM|YFII|SNM|BNX|WAVES|MIR)/.*" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "binance" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.01 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance/pairlist.dynamic.busd.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/binance/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/bybit/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange Tokens 5 | // Leverage tokens 6 | ".*(5L|5S)/.*", 7 | // Fiat 8 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 9 | // Stable tokens 10 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USTC|AUSD)/.*", 11 | // FAN Tokens 12 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*", 13 | // Other Coins 14 | "(1EARTH|ILA|MEM|AMPL|BOBA|CWAR|OMG|XYM|POLX|CARR|SKEY|KLV|KRL|DMTR|MLS|XCN|FTT|SRM|WAVES)/.*" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /configs/components/exchanges/bybit/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "bybit" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/bybit/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.01 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/bybit/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/gateio.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "gateio", 4 | "ccxt_config": { 5 | "enableRateLimit": true 6 | }, 7 | "ccxt_async_config": { 8 | "enableRateLimit": true, 9 | "rateLimit": 0 10 | }, 11 | "pair_blacklist": [ 12 | // Exchange Tokens 13 | "GT/.*", 14 | // Leverage tokens 15 | ".*(3|3L|3S|5L|5S)/.*", 16 | // Fiat 17 | "(AUD|EUR|GBP|CHF|CAD|JPY)/.*", 18 | // Stable tokens 19 | "(BUSD|USDT|TUSD|USDC|CUSDT|DAI|USDN|CUSD)/.*", 20 | // FAN Tokens 21 | "(ACM|AFA|ALA|ALL|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|OG|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /configs/components/exchanges/gateio/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange Tokens 5 | "(GT|POINT)/.*", 6 | // Leverage tokens 7 | ".*(3L|3S|5L|5S)/.*", 8 | // Fiat 9 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 10 | // Stable tokens 11 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USDD|USDJ|USTC|AUSD)/.*", 12 | // FAN Tokens 13 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO|ARG)/.*", 14 | // Other Coins 15 | "(AMPL|1EARTH|ILA|BOBA|CWAR|MEM|AMPL|OMG|XYM|CARR|SGB|SKEY|KLV|KOK|DMTR|CPOOL|KRL|MLS|SB|CEL|WWY|PTS|TORN|BANK|SYLO|VR|DOME|ANC|LUNA|REDTOKEN|COS|NFTY|EPK|ZBC|AZY|ZCX|PLATO|ACA|XCN|FTT|SRM|BVT|SWP|YFII|XWG|PIAS|KICKS|TIME|BNX|WEMIX|WAVES|MIR|FCON)/.*" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /configs/components/exchanges/gateio/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "gateio" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/gateio/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 28}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.01 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/gateio/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/huobi/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange Tokens 5 | "HT/.*", 6 | // Leverage tokens 7 | ".*(5L|5S)/.*", 8 | // Fiat 9 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 10 | // Stable tokens 11 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USDD|USDJ|USTC|AUSD)/.*", 12 | // FAN Tokens 13 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO|ARG)/.*", 14 | // Other Coins 15 | "(1EARTH|ILA|MEM|AMPL|BOBA|CWAR|OMG|XYM|POLX|CARR|SKEY|KLV|KRL|DMTR|MLS|CEL|WWY|VR|ANC|LUNA|ZBC|ZCX|PLATO|ACA|XCN|FTT|SRM|YFII|WEMIX|WAVES|MIR)/.*" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /configs/components/exchanges/huobi/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "huobi" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/huobi/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "SpreadFilter", 12 | "max_spread_ratio": 0.0075 13 | }, 14 | { 15 | "method": "PriceFilter", 16 | "low_price_ratio": 0.01 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/huobi/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/kucoin.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "kucoin", 4 | "ccxt_config": { 5 | "enableRateLimit": true 6 | }, 7 | "ccxt_async_config": { 8 | "enableRateLimit": true, 9 | "rateLimit": 0 10 | }, 11 | "pair_blacklist": [ 12 | // Exchange 13 | "(BNB)/.*", 14 | // Leverage 15 | ".*(_PREMIUM|BEAR|BULL|DOWN|HALF|HEDGE|UP|[1235][SL])/.*", 16 | // Fiat 17 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 18 | // Stable 19 | "(BUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDP|USDT|VAI)/.*", 20 | // FAN 21 | "(ACM|AFA|ALA|ALL|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LAZIO|LEG|LOCK-1|NAVI|NMR|NOV|OG|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /configs/components/exchanges/kucoin/kucoin.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange Tokens 5 | "KCS/.*", 6 | // Leverage tokens 7 | ".*(3L|3S|5L|5S)/.*", 8 | // Fiat 9 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 10 | // Stable tokens 11 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USDD|USDJ|USTC|AUSD)/.*", 12 | // FAN Tokens 13 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO)/.*", 14 | // Other Coins 15 | "(1EARTH|ILA|MEM|AMPL|BOBA|CWAR|OMG|XYM|POLX|CARR|SKEY|KLV|KRL|KOK|DMTR|CHMB|CPOOL|MLS|RBS|SRBS|SYLO|VR|KARA|ANC|LUNA|SRBP|PSL|AI|QKC|EPK|BAX|UQC|ZBC|ZCX|PLATO|HISAND33|HIODBS|ACA|HIENS4|XCN|MC|HIENS3|FTT|HIDOODLES|HIMAYC|HIBAYC|SRM|PRMX|SWP|XWG|HIOD|HISQUIGGLE|HIMEEBITS|PIAS|KICKS|HIPUNKS|HIFIDENZA|HIGAZERS|TIME|BNX|WEMIX|WAVES|MIR|FCON)/.*" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /configs/components/exchanges/kucoin/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "kucoin" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/kucoin/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.01 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/kucoin/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/okx/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "pair_blacklist": [ 4 | // Exchange Tokens 5 | "OKB/.*", 6 | // Leverage tokens 7 | ".*(3L|3S|5L|5S)/.*", 8 | // Fiat 9 | "(AUD|BRZ|CAD|CHF|EUR|GBP|HKD|IDRT|JPY|NGN|RUB|SGD|TRY|UAH|USD|ZAR)/.*", 10 | // Stable tokens 11 | "(BUSD|CUSD|CUSDT|DAI|PAXG|SUSD|TUSD|USDC|USDN|USDP|USDT|VAI|UST|USTC|AUSD)/.*", 12 | // FAN Tokens 13 | "(ACM|AFA|ALA|ALL|ALPINE|APL|ASR|ATM|BAR|CAI|CITY|FOR|GAL|GOZ|IBFK|JUV|LEG|LOCK-1|NAVI|NMR|NOV|PFL|PORTO|PSG|ROUSH|STV|TH|TRA|UCH|UFC|YBO|ARG)/.*", 14 | // Other Coins 15 | "(1EARTH|ILA|MEM|AMPL|BOBA|CWAR|OMG|XYM|POLX|CARR|SKEY|KLV|KRL|DMTR|MLS|CEL|TORN|DOME|ANC|LUNA|ZBC|AZY|ACA|FTT|SRM|YFII|WEMIX|WAVES|MIR)/.*" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /configs/components/exchanges/okx/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "exchange": { 3 | "name": "okx" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /configs/components/exchanges/okx/pairlist.dynamic.btc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.01 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 60, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/exchanges/okx/pairlist.dynamic.usdt.json: -------------------------------------------------------------------------------- 1 | { 2 | "pairlists": [ 3 | { 4 | "method": "VolumePairList", 5 | "number_assets": 100, 6 | "sort_key": "quoteVolume", 7 | "refresh_period": 1800 8 | }, 9 | {"method": "AgeFilter", "min_days_listed": 30}, 10 | { 11 | "method": "PriceFilter", 12 | "low_price_ratio": 0.003 13 | }, 14 | { 15 | "method": "SpreadFilter", 16 | "max_spread_ratio": 0.0075 17 | }, 18 | { 19 | "method": "RangeStabilityFilter", 20 | "lookback_days": 3, 21 | "min_rate_of_change": 0.03, 22 | "refresh_period": 1800 23 | }, 24 | { 25 | "method": "VolatilityFilter", 26 | "lookback_days": 3, 27 | "min_volatility": 0.01, 28 | "max_volatility": 0.75, 29 | "refresh_period": 43200 30 | }, 31 | { 32 | "method": "VolumePairList", 33 | "number_assets": 65, 34 | "sort_key": "quoteVolume" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /configs/components/settings/do-not-run-at-start.json: -------------------------------------------------------------------------------- 1 | { 2 | "initial_state": "stopped" 3 | } 4 | -------------------------------------------------------------------------------- /configs/components/settings/enable-force-buy.json: -------------------------------------------------------------------------------- 1 | { 2 | "forcebuy_enable": true 3 | } 4 | -------------------------------------------------------------------------------- /hyperopts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ph3nol/FT-Trading-Bot/0cf50a2a3d182505ae5510ff80fe1f1cf71fae63/hyperopts/.gitkeep -------------------------------------------------------------------------------- /instances/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ph3nol/FT-Trading-Bot/0cf50a2a3d182505ae5510ff80fe1f1cf71fae63/instances/.gitkeep -------------------------------------------------------------------------------- /strategies/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ph3nol/FT-Trading-Bot/0cf50a2a3d182505ae5510ff80fe1f1cf71fae63/strategies/.gitkeep -------------------------------------------------------------------------------- /strategies/Example.py: -------------------------------------------------------------------------------- 1 | """ 2 | Just for example. 3 | Based on BreakEven strategy (https://github.com/freqtrade/freqtrade-strategies/blob/main/user_data/strategies/BreakEven.py). 4 | """ 5 | 6 | # --- Do not remove these libs --- 7 | from freqtrade.strategy import IStrategy 8 | from pandas import DataFrame 9 | 10 | # -------------------------------- 11 | 12 | class Example(IStrategy): 13 | """ 14 | author@: lenik 15 | 16 | Sometimes I want to close the bot ASAP, but not have the positions floating around. 17 | 18 | I can "/stopbuy" and wait for the positions to get closed by the bot rules, which is 19 | waiting for some profit, etc -- this usually takes too long... 20 | 21 | What I would prefer is to close everything that is over 0% profit to avoid the losses. 22 | 23 | Here's a simple strategy with empty buy/sell signals and "minimal_roi = { 0 : 0 }" that 24 | sells everything already at profit and wait until the positions at loss will come to break 25 | even point (or the small profit you provide in ROI table). 26 | 27 | You may restart the bot with the new strategy as a command-line parameter. 28 | 29 | Another way would be to specify the original strategy in the config file, then change to 30 | this one and simply "/reload_config" from the Telegram bot. 31 | 32 | """ 33 | 34 | INTERFACE_VERSION: int = 3 35 | # This attribute will be overridden if the config file contains "minimal_roi" 36 | minimal_roi = { 37 | "0": 0.01, # at least 1% at first 38 | "10": 0 # after 10min, everything goes 39 | } 40 | 41 | # This is more radical version that sells everything above the profit level 42 | # minimal_roi = { 43 | # "0": 0 44 | # } 45 | 46 | # And this is basically "/forcesell all", that sells no matter what profit 47 | # minimal_roi = { 48 | # "0": -1 49 | # } 50 | 51 | # Optimal stoploss designed for the strategy 52 | stoploss = -0.05 53 | 54 | # Optimal timeframe for the strategy 55 | timeframe = '5m' 56 | 57 | # don't generate any buy or sell signals, everything is handled by ROI and stop_loss 58 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 59 | return dataframe 60 | 61 | def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 62 | dataframe.loc[ 63 | ( 64 | ), 65 | 'enter_long'] = 0 66 | return dataframe 67 | 68 | def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 69 | dataframe.loc[ 70 | ( 71 | ), 72 | 'exit_long'] = 0 73 | return dataframe 74 | --------------------------------------------------------------------------------