Home Creators Posts Import Register Favorites Logout
haven't archived this post yet. have a subscription? use the importer!

Downloads

  • MacheteV8b_Fixed.py

Missing 1 file, as this post has not yet been imported.

Content

In this post I will provide you the fixed MacheteV8b strategy file for the Docker version 2024.1

However ALL CREDITS GO TO YOU AS A COMMUNITY! 

Special credits go to Frederic Auricombe, Nikos, Nacho Villamil and all other Patrons that helped fix this error! For background information about the solution and more fixes of other strategies, please go to the comments section of the 1.000.000 Dollar Algo Strategy Post. 

One warning though and that is that the algo has been changed and thus can cause  different results than the original file. So please check this before making any definitive conclusions! 

The way I fixed this problem on my test laptop is as follows:

Create the Docker compose and Docker custom file. My examples are below and they work on my Linux Mint laptop:

> cat docker-compose.yml

---
version: '3'
services:
  freqtrade:
    image: freqtrade_custom
    build:
      context: .
      dockerfile: "./Dockerfile.custom"
    restart: unless-stopped
    container_name: freqtrade
    volumes:
      - "./user_data:/freqtrade/user_data"
    ports:
      - "127.0.0.1:8080:8080"
    command: >
      trade
      --logfile /freqtrade/user_data/logs/freqtrade.log
      --db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
      --config /freqtrade/user_data/config.json
      --strategy SampleStrategy


> cat Dockerfile.custom 

FROM freqtradeorg/freqtrade:stable 
RUN pip install --user ta finta

Next you can download the Docker image and build it with the additional TA libraries.

> docker-compose run --rm freqtrade --version
Building freqtrade
Step 1/2 : FROM freqtradeorg/freqtrade:stable
stable: Pulling from freqtradeorg/freqtrade
2f44b7a888fa: Pull complete
3f00b3697662: Pull complete
9f2fc8d8f9bd: Pull complete
4ea8b799d366: Pull complete
d7d8cad868ee: Pull complete
d425f42ce5ea: Pull complete
4f4fb700ef54: Pull complete
591a93cb0262: Pull complete
214ff5b36efe: Pull complete
ff2d48e52088: Pull complete
62265a5880a3: Pull complete
Digest: sha256:03af37c14248dfca3f526f89f9b670f9b178847f5d32aa6c8e9386e5a23c0d88
Status: Downloaded newer image for freqtradeorg/freqtrade:stable
 ---> 753e49c5dd3a
Step 2/2 : RUN pip install --user ta finta
 ---> Running in f3396cd2be72
Collecting ta
  Downloading ta-0.11.0.tar.gz (25 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting finta
  Downloading finta-1.3-py3-none-any.whl (29 kB)
Requirement already satisfied: numpy in /home/ftuser/.local/lib/python3.11/site-packages (from ta) (1.26.3)
Requirement already satisfied: pandas in /home/ftuser/.local/lib/python3.11/site-packages (from ta) (2.1.4)
Requirement already satisfied: python-dateutil>=2.8.2 in /home/ftuser/.local/lib/python3.11/site-packages (from pandas->ta) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /home/ftuser/.local/lib/python3.11/site-packages (from pandas->ta) (2023.4)
Requirement already satisfied: tzdata>=2022.1 in /home/ftuser/.local/lib/python3.11/site-packages (from pandas->ta) (2023.4)
Requirement already satisfied: six>=1.5 in /home/ftuser/.local/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas->ta) (1.16.0)
Building wheels for collected packages: ta
  Building wheel for ta (setup.py): started
  Building wheel for ta (setup.py): finished with status 'done'
  Created wheel for ta: filename=ta-0.11.0-py3-none-any.whl size=29413 sha256=5d929963c0c014f21d0a865a3a173c73caaa2c38a54b08543c33aafc1af860e0
  Stored in directory: /home/ftuser/.cache/pip/wheels/a1/d7/29/7781cc5eb9a3659d032d7d15bdd0f49d07d2b24fec29f44bc4
Successfully built ta
Installing collected packages: ta, finta
Successfully installed finta-1.3 ta-0.11.0

[notice] A new release of pip is available: 23.2.1 -> 24.0
[notice] To update, run: pip install --upgrade pip
 ---> Removed intermediate container f3396cd2be72
 ---> f6d8d187ea51

Successfully built f6d8d187ea51
Successfully tagged freqtrade_custom:latest
WARNING: Image for service freqtrade was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating ft_userdata_freqtrade_run ... done
freqtrade 2024.1

I recreated this Docker container in a directory that already contained all the configurations so I do not have to create these. I now can just run the freqtrade code.


> docker-compose run --rm freqtrade list-strategies
Creating ft_userdata_freqtrade_run ... done
2024-02-11 15:57:54,943 - freqtrade - INFO - freqtrade 2024.1
2024-02-11 15:57:54,943 - freqtrade.configuration.load_config - INFO - Using config: user_data/config.json ...
2024-02-11 15:57:54,945 - freqtrade.loggers - INFO - Verbosity set to 0
2024-02-11 15:57:54,968 - freqtrade.configuration.configuration - INFO - Using user-data directory: /freqtrade/user_data ...
2024-02-11 15:57:54,968 - freqtrade.configuration.configuration - INFO - Using data directory: /freqtrade/user_data/data/binance ...
2024-02-11 15:57:54,970 - freqtrade.exchange.check_exchange - INFO - Checking exchange...
2024-02-11 15:57:54,984 - freqtrade.exchange.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team.
2024-02-11 15:57:54,984 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration.
2024-02-11 15:57:54,984 - freqtrade.configuration.config_validation - INFO - Validating configuration ...
Add {
"method": "AgeFilter",
"min_days_listed": 30
},
 to your pairlists in config (Under StaticPairList)
+----------------+--------------------+----------+----------------+--------------+---------------+
|           name |           location |   status |   hyperoptable |   buy-Params |   sell-Params |
|----------------+--------------------+----------+----------------+--------------+---------------|
|        GodStra |         GodStra.py |       OK |             No |            0 |             0 |
|     MacheteV8b_Fixed |      MacheteV8b_Fixed.py |       OK |            Yes |           17 |            12 |
| SampleStrategy | sample_strategy.py |       OK |            Yes |            2 |             2 |
+----------------+--------------------+----------+----------------+--------------+---------------+

Next download the data to that information is most recent:

> docker-compose run --rm freqtrade download-data --config user_data/config.json  --days 712 -t 12h 1h 5m
Creating ft_userdata_freqtrade_run ... done
2024-02-11 16:28:19,739 - freqtrade - INFO - freqtrade 2024.1
2024-02-11 16:28:19,739 - freqtrade.configuration.load_config - INFO - Using config: user_data/config.json ...
2024-02-11 16:28:19,740 - freqtrade.loggers - INFO - Verbosity set to 0
2024-02-11 16:28:19,762 - freqtrade.configuration.configuration - INFO - Using user-data directory: /freqtrade/user_data ...
2024-02-11 16:28:19,763 - freqtrade.configuration.configuration - INFO - Using data directory: /freqtrade/user_data/data/binance ...
2024-02-11 16:28:19,763 - freqtrade.configuration.configuration - INFO - timeframes --timeframes: ['12h', '1h', '5m']
2024-02-11 16:28:19,763 - freqtrade.configuration.configuration - INFO - Detected --days: 712
2024-02-11 16:28:19,764 - freqtrade.exchange.check_exchange - INFO - Checking exchange...
2024-02-11 16:28:19,778 - freqtrade.exchange.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team.
2024-02-11 16:28:19,778 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration.
2024-02-11 16:28:19,778 - freqtrade.configuration.config_validation - INFO - Validating configuration ...
2024-02-11 16:28:19,783 - freqtrade.exchange.exchange - INFO - Instance is running with dry_run enabled
2024-02-11 16:28:19,783 - freqtrade.exchange.exchange - INFO - Using CCXT 4.2.25
2024-02-11 16:28:19,810 - freqtrade.exchange.exchange - INFO - Using Exchange "Binance"
2024-02-11 16:28:19,810 - freqtrade.resolvers.exchange_resolver - INFO - Using resolved exchange 'Binance'...
2024-02-11 16:28:19,810 - freqtrade.exchange.exchange - INFO - Markets were not loaded. Loading them now..
2024-02-11 16:28:26,908 - freqtrade.data.history.history_utils - INFO - About to download pairs: ['BTC/USDT', 'HBAR/USDT', 'GALA/USDT'], intervals: ['12h', '1h', '5m'] to /freqtrade/user_data/data/binance
2024-02-11 16:28:26,949 - freqtrade.data.history.history_utils - INFO - (1/3) - Download history data for "BTC/USDT", 12h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:27,791 - freqtrade.exchange.exchange - INFO - Downloaded data for BTC/USDT with length 1426.
2024-02-11 16:28:27,809 - freqtrade.data.history.history_utils - INFO - (1/3) - Download history data for "BTC/USDT", 1h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:29,632 - freqtrade.exchange.exchange - INFO - Downloaded data for BTC/USDT with length 17105.
2024-02-11 16:28:29,730 - freqtrade.data.history.history_utils - INFO - (1/3) - Download history data for "BTC/USDT", 5m, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:36,849 - freqtrade.exchange.exchange - INFO - Downloaded data for BTC/USDT with length 205254.
2024-02-11 16:28:37,368 - freqtrade.data.history.history_utils - INFO - (2/3) - Download history data for "HBAR/USDT", 12h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:39,763 - freqtrade.exchange.exchange - INFO - Downloaded data for HBAR/USDT with length 1426.
2024-02-11 16:28:39,777 - freqtrade.data.history.history_utils - INFO - (2/3) - Download history data for "HBAR/USDT", 1h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:41,392 - freqtrade.exchange.exchange - INFO - Downloaded data for HBAR/USDT with length 17105.
2024-02-11 16:28:41,488 - freqtrade.data.history.history_utils - INFO - (2/3) - Download history data for "HBAR/USDT", 5m, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:48,512 - freqtrade.exchange.exchange - INFO - Downloaded data for HBAR/USDT with length 205254.
2024-02-11 16:28:48,957 - freqtrade.data.history.history_utils - INFO - (3/3) - Download history data for "GALA/USDT", 12h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:49,804 - freqtrade.exchange.exchange - INFO - Downloaded data for GALA/USDT with length 1426.
2024-02-11 16:28:49,817 - freqtrade.data.history.history_utils - INFO - (3/3) - Download history data for "GALA/USDT", 1h, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:52,050 - freqtrade.exchange.exchange - INFO - Downloaded data for GALA/USDT with length 17105.
2024-02-11 16:28:52,146 - freqtrade.data.history.history_utils - INFO - (3/3) - Download history data for "GALA/USDT", 5m, spot and store in /freqtrade/user_data/data/binance. From 2022-03-01T00:00:00 to now
2024-02-11 16:28:59,761 - freqtrade.exchange.exchange - INFO - Downloaded data for GALA/USDT with length 205254.

Then check the data to see if its all there:


> docker-compose run --rm freqtrade list-data
Creating ft_userdata_freqtrade_run ... done
2024-02-11 16:31:01,282 - freqtrade - INFO - freqtrade 2024.1
2024-02-11 16:31:01,282 - freqtrade.configuration.load_config - INFO - Using config: user_data/config.json ...
2024-02-11 16:31:01,284 - freqtrade.loggers - INFO - Verbosity set to 0
2024-02-11 16:31:01,306 - freqtrade.configuration.configuration - INFO - Using user-data directory: /freqtrade/user_data ...
2024-02-11 16:31:01,306 - freqtrade.configuration.configuration - INFO - Using data directory: /freqtrade/user_data/data/binance ...
2024-02-11 16:31:01,308 - freqtrade.exchange.check_exchange - INFO - Checking exchange...
2024-02-11 16:31:01,322 - freqtrade.exchange.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team.
2024-02-11 16:31:01,322 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration.
2024-02-11 16:31:01,322 - freqtrade.configuration.config_validation - INFO - Validating configuration ...
Found 10 pair / timeframe combinations.
+-----------+------------------+--------+
|      Pair |        Timeframe |   Type |
|-----------+------------------+--------|
|  BTC/USDT | 5m, 15m, 1h, 12h |   spot |
| GALA/USDT |      5m, 1h, 12h |   spot |
| HBAR/USDT |      5m, 1h, 12h |   spot |
+-----------+------------------+--------+


Now I can start backtesting with the adjused strategy file:


>  docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy MacheteV8b_Fixed
Creating ft_userdata_freqtrade_run ... done
2024-02-11 16:39:02,367 - freqtrade - INFO - freqtrade 2024.1
2024-02-11 16:39:02,380 - freqtrade.configuration.load_config - INFO - Using config: user_data/config.json ...
2024-02-11 16:39:02,381 - freqtrade.loggers - INFO - Verbosity set to 0
2024-02-11 16:39:02,382 - freqtrade.configuration.configuration - INFO - Using max_open_trades: 3 ...
2024-02-11 16:39:02,405 - freqtrade.configuration.configuration - INFO - Using user-data directory: /freqtrade/user_data ...
2024-02-11 16:39:02,405 - freqtrade.configuration.configuration - INFO - Using data directory: /freqtrade/user_data/data/binance ...
2024-02-11 16:39:02,406 - freqtrade.configuration.configuration - INFO - Parameter --cache=day detected ...
2024-02-11 16:39:02,407 - freqtrade.exchange.check_exchange - INFO - Checking exchange...
2024-02-11 16:39:02,421 - freqtrade.exchange.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team.
2024-02-11 16:39:02,421 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration.
2024-02-11 16:39:02,421 - freqtrade.configuration.config_validation - INFO - Validating configuration ...
2024-02-11 16:39:02,427 - freqtrade.commands.optimize_commands - INFO - Starting freqtrade in Backtesting mode
2024-02-11 16:39:02,427 - freqtrade.exchange.exchange - INFO - Instance is running with dry_run enabled
2024-02-11 16:39:02,427 - freqtrade.exchange.exchange - INFO - Using CCXT 4.2.25
2024-02-11 16:39:02,451 - freqtrade.exchange.exchange - INFO - Using Exchange "Binance"
2024-02-11 16:39:09,463 - freqtrade.resolvers.exchange_resolver - INFO - Using resolved exchange 'Binance'...
Add {
"method": "AgeFilter",
"min_days_listed": 30
},
 to your pairlists in config (Under StaticPairList)
2024-02-11 16:39:09,510 - freqtrade.resolvers.iresolver - INFO - Using resolved strategy MacheteV8b_Fixed from '/freqtrade/user_data/strategies/MacheteV8b_Fixed.py'...
2024-02-11 16:39:09,510 - freqtrade.strategy.hyper - INFO - Found no parameter file.
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_currency' with value in config file: USDT.
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_amount' with value in config file: unlimited.
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'unfilledtimeout' with value in config file: {'entry': 10, 'exit': 10, 'exit_timeout_count': 0, 'unit': 'minutes'}.
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'max_open_trades' with value in config file: 3.
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using minimal_roi: {'0': 0.279, '92': 0.109, '245': 0.059, '561': 0}
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using timeframe: 15m
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stoploss: -0.1
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop: False
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop_positive_offset: 0.0
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_only_offset_is_reached: False
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_custom_stoploss: True
2024-02-11 16:39:09,511 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using process_only_new_candles: False
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_types: {'entry': 'limit', 'exit': 'limit', 'stoploss': 'market', 'stoploss_on_exchange': False}
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_time_in_force: {'entry': 'GTC', 'exit': 'GTC'}
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_currency: USDT
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_amount: unlimited
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using protections: []
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using startup_candle_count: 500
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using unfilledtimeout: {'entry': 10, 'exit': 10, 'exit_timeout_count': 0, 'unit': 'minutes'}
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_exit_signal: True
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using exit_profit_only: False
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_roi_if_entry_signal: False
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using exit_profit_offset: 0.0
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using disable_dataframe_checks: False
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_buying_expired_candle_after: 0
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using position_adjustment_enable: False
2024-02-11 16:39:09,512 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using max_entry_position_adjustment: -1
2024-02-11 16:39:09,513 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using max_open_trades: 3
2024-02-11 16:39:09,513 - freqtrade.configuration.config_validation - INFO - Validating configuration ...
2024-02-11 16:39:09,521 - freqtrade.resolvers.iresolver - INFO - Using resolved pairlist StaticPairList from '/freqtrade/freqtrade/plugins/pairlist/StaticPairList.py'...
2024-02-11 16:39:09,549 - freqtrade.data.history.history_utils - INFO - Using indicator startup period: 500 ...
2024-02-11 16:39:09,626 - freqtrade.data.history.idatahandler - WARNING - No history for HBAR/USDT, spot, 15m found. Use `freqtrade download-data` to download the data
2024-02-11 16:39:09,627 - freqtrade.data.history.idatahandler - WARNING - No history for GALA/USDT, spot, 15m found. Use `freqtrade download-data` to download the data
2024-02-11 16:39:09,628 - freqtrade.optimize.backtesting - INFO - Loading data from 2023-01-25 00:00:00 up to 2024-01-25 19:00:00 (365 days).
2024-02-11 16:39:09,628 - freqtrade.configuration.timerange - WARNING - Moving start-date by 500 candles to account for startup time.
2024-02-11 16:39:09,628 - freqtrade.optimize.backtesting - INFO - Dataload complete. Calculating indicators
2024-02-11 16:39:09,629 - freqtrade.optimize.backtesting - WARNING - Backtest result caching disabled due to use of open-ended timerange.
2024-02-11 16:39:09,629 - freqtrade.optimize.backtesting - INFO - Running backtesting for Strategy MacheteV8b_Fixed
2024-02-11 16:39:09,629 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_adx_momentum = False
2024-02-11 16:39:09,629 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_adx_smas = True
2024-02-11 16:39:09,629 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_asdts_rockwelltrading = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_averages_strategy = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_awesome_macd = True
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_fisher_hull = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_gettin_moist = True
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_hlhb = True
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_macd_strategy = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_macd_strategy_crossed = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_pmax = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_quickie = True
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_scalp = True
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_simple = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_strategy001 = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_technical_example_strategy = False
2024-02-11 16:39:09,630 - freqtrade.strategy.hyper - INFO - Strategy Parameter: buy_should_use_get_buy_signal_tema_rsi_strategy = False
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_bail_how = roc
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_bail_roc = -0.032
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_bail_time = 1108
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_bb_trailing_input = bb_lowerband_neutral_inf
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_threshold = -0.036
2024-02-11 16:39:09,631 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_trailing_max_stoploss = 0.054
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_trailing_only_offset_is_reached = 0.06
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: cstp_trailing_stop_profit_devider = 2
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: droi_pullback = True
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: droi_pullback_amount = 0.005
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: droi_pullback_respect_table = False
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - Strategy Parameter: droi_trend_type = any
2024-02-11 16:39:09,632 - freqtrade.strategy.hyper - INFO - No params for protection found, using default values.
2024-02-11 16:39:26,082 - freqtrade.data.dataprovider - INFO - Loading data for BTC/USDT 1h from unbounded to unbounded
2024-02-11 16:39:26,262 - freqtrade.optimize.backtesting - INFO - Backtesting with data from 2023-01-30 05:00:00 up to 2024-01-25 19:00:00 (360 days).
2024-02-11 16:39:31,427 - freqtrade.misc - INFO - dumping json to "/freqtrade/user_data/backtest_results/backtest-result-2024-02-11_16-39-31.meta.json"
2024-02-11 16:39:31,428 - freqtrade.misc - INFO - dumping json to "/freqtrade/user_data/backtest_results/backtest-result-2024-02-11_16-39-31.json"
2024-02-11 16:39:31,436 - freqtrade.misc - INFO - dumping json to "/freqtrade/user_data/backtest_results/.last_result.json"
Result for strategy MacheteV8b_Fixed
=========================================================== BACKTESTING REPORT ===========================================================
|     Pair |   Entries |   Avg Profit % |   Cum Profit % |   Tot Profit USDT |   Tot Profit % |   Avg Duration |   Win  Draw  Loss  Win% |
|----------+-----------+----------------+----------------+-------------------+----------------+----------------+-------------------------|
| BTC/USDT |       134 |          -0.04 |          -5.09 |           -18.032 |          -1.80 |        6:59:00 |    68     8    58  50.7 |
|    TOTAL |       134 |          -0.04 |          -5.09 |           -18.032 |          -1.80 |        6:59:00 |    68     8    58  50.7 |
======================================================= LEFT OPEN TRADES REPORT ========================================================
|   Pair |   Entries |   Avg Profit % |   Cum Profit % |   Tot Profit USDT |   Tot Profit % |   Avg Duration |   Win  Draw  Loss  Win% |
|--------+-----------+----------------+----------------+-------------------+----------------+----------------+-------------------------|
|  TOTAL |         0 |           0.00 |           0.00 |             0.000 |           0.00 |           0:00 |     0     0     0     0 |
=========================================================== ENTER TAG STATS ===========================================================
|   TAG |   Entries |   Avg Profit % |   Cum Profit % |   Tot Profit USDT |   Tot Profit % |   Avg Duration |   Win  Draw  Loss  Win% |
|-------+-----------+----------------+----------------+-------------------+----------------+----------------+-------------------------|
| OTHER |       134 |          -0.04 |          -5.09 |           -18.032 |          -1.80 |        6:59:00 |    68     8    58  50.7 |
| TOTAL |       134 |          -0.04 |          -5.09 |           -18.032 |          -1.80 |        6:59:00 |    68     8    58  50.7 |
======================================================= EXIT REASON STATS ========================================================
|        Exit Reason |   Exits |   Win  Draws  Loss  Win% |   Avg Profit % |   Cum Profit % |   Tot Profit USDT |   Tot Profit % |
|--------------------+---------+--------------------------+----------------+----------------+-------------------+----------------|
|                roi |      75 |     67     8     0   100 |           0.76 |          57.2  |           183.622 |          57.2  |
| trailing_stop_loss |      57 |      1     0    56   1.8 |          -1.02 |         -57.86 |          -186.928 |         -57.86 |
|        exit_signal |       2 |      0     0     2     0 |          -2.21 |          -4.43 |           -14.725 |          -4.43 |
================== SUMMARY METRICS ==================
| Metric                      | Value               |
|-----------------------------+---------------------|
| Backtesting from            | 2023-01-30 05:00:00 |
| Backtesting to              | 2024-01-25 19:00:00 |
| Max open trades             | 1                   |
|                             |                     |
| Total/Daily Avg Trades      | 134 / 0.37          |
| Starting balance            | 1000 USDT           |
| Final balance               | 981.968 USDT        |
| Absolute profit             | -18.032 USDT        |
| Total profit %              | -1.80%              |
| CAGR %                      | -1.83%              |
| Sortino                     | -0.36               |
| Sharpe                      | -0.21               |
| Calmar                      | -1.37               |
| Profit factor               | 0.92                |
| Expectancy (Ratio)          | -0.13 (-0.10)       |
| Trades per day              | 0.37                |
| Avg. daily profit %         | -0.01%              |
| Avg. stake amount           | 322.004 USDT        |
| Total trade volume          | 43148.597 USDT      |
|                             |                     |
| Best Pair                   | BTC/USDT -5.09%     |
| Worst Pair                  | BTC/USDT -5.09%     |
| Best trade                  | BTC/USDT 4.70%      |
| Worst trade                 | BTC/USDT -3.72%     |
| Best day                    | 23.156 USDT         |
| Worst day                   | -11.917 USDT        |
| Days win/draw/lose          | 29 / 251 / 48       |
| Avg. Duration Winners       | 5:36:00             |
| Avg. Duration Loser         | 7:37:00             |
| Max Consecutive Wins / Loss | 8 / 9               |
| Rejected Entry signals      | 0                   |
| Entry/Exit Timeouts         | 0 / 0               |
|                             |                     |
| Min balance                 | 939.328 USDT        |
| Max balance                 | 1010.059 USDT       |
| Max % of account underwater | 7.00%               |
| Absolute Drawdown (Account) | 7.00%               |
| Absolute Drawdown           | 70.731 USDT         |
| Drawdown high               | 10.059 USDT         |
| Drawdown low                | -60.672 USDT        |
| Drawdown Start              | 2023-03-19 20:15:00 |
| Drawdown End                | 2023-09-21 01:15:00 |
| Market change               | 75.95%              |
=====================================================

Backtested 2023-01-30 05:00:00 -> 2024-01-25 19:00:00 | Max open trades : 1
=========================================================================== STRATEGY SUMMARY ==========================================================================
|         Strategy |   Entries |   Avg Profit % |   Cum Profit % |   Tot Profit USDT |   Tot Profit % |   Avg Duration |   Win  Draw  Loss  Win% |           Drawdown |
|------------------+-----------+----------------+----------------+-------------------+----------------+----------------+-------------------------+--------------------|
| MacheteV8b_Fixed |       134 |          -0.04 |          -5.09 |           -18.032 |          -1.80 |        6:59:00 |    68     8    58  50.7 | 70.731 USDT  7.00% |
=======================================================================================================================================================================

For more details, please look at the detail tables above







Comments

Kha Trương Ngọc

Does anyone else encounter the same error as I do when performing a dry run or hyperopt on this fixed file? MacheteV8b_Fixed.py", line 590, in custom_stoploss bb_trailing = self.custom_trade_info[trade.pair][self.cstp_bb_trailing_input.value].loc[current_time][self.cstp_bb_trailing_input.value] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ KeyError: 'bb_lowerband_trend' MacheteV8b_Fixed.py", line 590, in custom_stoploss bb_trailing = self.custom_trade_info[trade.pair][self.cstp_bb_trailing_input.value].loc[current_time][self.cstp_bb_trailing_input.value] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ KeyError: 'bb_lowerband_neutral'

Kha Trương Ngọc

I have no issues with backtesting, but when I try dry run or hyperopt, I encounter the errors I mentioned earlier. I can't remember the specific parameters I added for hyperopt, but dry run consistently displays these errors. Initially, I thought it was due to some errors in my modified file, but I realized that the errors were present in your original file.

Michael

Great job guys! thanks much for fixing it!

Yaşar

also I got this error for all the coins that the bot bought.: 2024-02-23 21:30:57,267 - freqtrade.strategy.strategy_wrapper - ERROR - Unexpected error LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low' calling > Traceback (most recent call last): File "/home/ubuntu/freqtrade/freqtrade/strategy/strategy_wrapper.py", line 27, in wrapper return f(*args, **kwargs) File "/home/ubuntu/freqtrade/freqtrade/strategy/interface.py", line 873, in _analyze_ticker_internal dataframe = self.analyze_ticker(dataframe, metadata) File "/home/ubuntu/freqtrade/freqtrade/strategy/interface.py", line 851, in analyze_ticker dataframe = self.advise_indicators(dataframe, metadata) File "/home/ubuntu/freqtrade/freqtrade/strategy/interface.py", line 1378, in advise_indicators return self.populate_indicators(dataframe, metadata) File "/home/ubuntu/freqtrade/user_data/strategies/MacheteV8b_Fixed.py", line 144, in populate_indicators self.custom_trade_info[metadata['pair']] = self.populate_trades(metadata['pair']) File "/home/ubuntu/freqtrade/user_data/strategies/MacheteV8b_Fixed.py", line 547, in populate_trades active_trade[0].adjust_min_max_rates(current_rate) TypeError: LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low'

Juul

I have the same error, can't seem to solve it either

Frederic Collard

Hello community, I tried this on in dryrun and strange enough, it gives the exact same error as with the "lookahead-analysis" option. ``` 2024-03-12 14:07:06,728 - freqtrade.strategy.strategy_wrapper - ERROR - Unexpected error 'sroc_inf' calling > Traceback (most recent call last): File "/freqtrade/freqtrade/strategy/strategy_wrapper.py", line 27, in wrapper return f(*args, **kwargs) ^^^^^^^^^^^^^^^^^^ File "/freqtrade/user_data/strategies/MacheteV8b_Fixed.py", line 433, in custom_stoploss sroc = dataframe['sroc_inf'].iat[-1] ~~~~~~~~~^^^^^^^^^^^^ File "/home/ftuser/.local/lib/python3.11/site-packages/pandas/core/frame.py", line 3893, in __getitem__ indexer = self.columns.get_loc(key) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ftuser/.local/lib/python3.11/site-packages/pandas/core/indexes/range.py", line 418, in get_loc raise KeyError(key) KeyError: 'sroc_inf' 2024-03-12 14:07:06,730 - freqtrade.commands.trade_commands - ERROR - 'rmi-up-trend_inf' 2024-03-12 14:07:06,730 - freqtrade.commands.trade_commands - ERROR - Fatal exception! Traceback (most recent call last): File "/freqtrade/freqtrade/commands/trade_commands.py", line 25, in start_trading worker.run() File "/freqtrade/freqtrade/worker.py", line 75, in run state = self._worker(old_state=state) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/worker.py", line 116, in _worker self._throttle(func=self._process_running, throttle_secs=self._throttle_secs, File "/freqtrade/freqtrade/worker.py", line 147, in _throttle result = func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/worker.py", line 180, in _process_running self.freqtrade.process() File "/freqtrade/freqtrade/freqtradebot.py", line 239, in process self.exit_positions(trades) File "/freqtrade/freqtrade/freqtradebot.py", line 1097, in exit_positions if not trade.has_open_orders and trade.is_open and self.handle_trade(trade): ^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/freqtradebot.py", line 1138, in handle_trade if self._check_and_execute_exit(trade, exit_rate, enter, exit_, exit_tag): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/freqtradebot.py", line 1149, in _check_and_execute_exit exits: List[ExitCheckTuple] = self.strategy.should_exit( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/strategy/interface.py", line 1153, in should_exit and self.min_roi_reached(trade=trade, current_profit=current_profit_best, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/user_data/strategies/MacheteV8b_Fixed.py", line 504, in min_roi_reached _, roi = self.min_roi_reached_dynamic(trade, current_profit, current_time, trade_dur) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/user_data/strategies/MacheteV8b_Fixed.py", line 466, in min_roi_reached_dynamic rmi_trend = dataframe['rmi-up-trend_inf'].iat[-1] ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^ File "/home/ftuser/.local/lib/python3.11/site-packages/pandas/core/frame.py", line 3893, in __getitem__ indexer = self.columns.get_loc(key) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ftuser/.local/lib/python3.11/site-packages/pandas/core/indexes/range.py", line 418, in get_loc raise KeyError(key) KeyError: 'rmi-up-trend_inf' 2024-03-12 14:07:06,732 - freqtrade.commands.trade_commands - INFO - worker found ... calling exit 2024-03-12 14:07:06,732 - freqtrade.rpc.rpc_manager - INFO - Sending rpc message: {'type': status, 'status': 'process died'} ``` This seems related to usage of `dataframe['sroc_inf'].iat[-1]` and `rmi-up-trend_inf`. I'm not a python pandas expert but when looking at the doc, I see noting about using `.iat[-1]` (negative number) for the iat method on a pandas dataframe. Generaly this is used by giving 2 positive integers as parameters. The fact that this gives the same error in dryrun as in lookahead-bias mode shows that the code should be fixed. Did you experience the same or a similar error ? Did you test lookahead-bias as well ? Is it worth investigating further on this one ?

Anthony Cuthbertson

Hi, I had some of the errors others have mentioned. Biggest issue being if you stopped and restarted the docker the strategy would crash when trying to handle already open trades. I'm not a coder just mixed and matched a couple of different versions to get a working file. Backtesting and dry run results so far the same as the "fixed" version. from typing import Dict, List, Optional, Tuple from datetime import datetime, timedelta from cachetools import TTLCache from pandas import DataFrame, Series import numpy as np ## Indicator libs import talib.abstract as ta from finta import TA as fta import technical.indicators as ftt from technical.indicators import hull_moving_average from technical.indicators import PMAX, dema from technical.indicators import cmf ## FT stuffs from freqtrade.strategy import IStrategy, merge_informative_pair, stoploss_from_open, IntParameter, DecimalParameter, CategoricalParameter import freqtrade.vendor.qtpylib.indicators as qtpylib from freqtrade.exchange import timeframe_to_minutes from freqtrade.persistence import Trade from skopt.space import Dimension """ NOTE: docker-compose run --rm freqtrade hyperopt -c user_data/config-backtesting.json --strategy IchimokuHaulingV8a --hyperopt-loss SortinoHyperOptLossDaily --spaces roi buy sell --timerange=1624940400-1630447200 -j 4 -e 1000 """ class MacheteV8b_Fixed2(IStrategy): # Buy hyperspace params: buy_params = { "buy_should_use_get_buy_signal_quickie": True, #0/0/0 "buy_should_use_get_buy_signal_scalp": True, #2/0/0 "buy_should_use_get_buy_signal_adx_smas": True, #18/0/2 "buy_should_use_get_buy_signal_awesome_macd": True, #3/0/1 "buy_should_use_get_buy_signal_gettin_moist": True, #6/0/0 "buy_should_use_get_buy_signal_hlhb": True, #3/0/1 "buy_should_use_get_buy_signal_adx_momentum": False, #32/1/3 "buy_should_use_get_buy_signal_asdts_rockwelltrading": False, #24/0/3 "buy_should_use_get_buy_signal_averages_strategy": False, #2/0/2 "buy_should_use_get_buy_signal_fisher_hull": False, #7/0/4 "buy_should_use_get_buy_signal_macd_strategy": False, #2/0/0 "buy_should_use_get_buy_signal_macd_strategy_crossed": False, #0/0/0 "buy_should_use_get_buy_signal_pmax": False, #2/0/0 "buy_should_use_get_buy_signal_simple": False, #23/0/2 "buy_should_use_get_buy_signal_strategy001": False, #0/0/0 "buy_should_use_get_buy_signal_technical_example_strategy": False, #36/0/7 "buy_should_use_get_buy_signal_tema_rsi_strategy": False, #0/0/0 } # Sell hyperspace params: sell_params = { "cstp_bail_how": "roc", "cstp_bail_roc": -0.032, "cstp_bail_time": 1108, "cstp_bb_trailing_input": "bb_lowerband_neutral_inf", "cstp_threshold": -0.036, "cstp_trailing_max_stoploss": 0.054, "cstp_trailing_only_offset_is_reached": 0.06, "cstp_trailing_stop_profit_devider": 2, "droi_pullback": True, "droi_pullback_amount": 0.005, "droi_pullback_respect_table": False, "droi_trend_type": "any", } # ROI table: minimal_roi = { "0": 0.279, "92": 0.109, "245": 0.059, "561": 0 } # Stoploss: stoploss = -0.1#-0.046 # Trailing stop: trailing_stop = False #trailing_stop_positive = 0.0247 #trailing_stop_positive_offset = 0.0248 #trailing_only_offset_is_reached = True use_custom_stoploss = True # buy signal buy_should_use_get_buy_signal_awesome_macd = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_awesome_macd'], space='buy', optimize=True) buy_should_use_get_buy_signal_adx_momentum = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_adx_momentum'], space='buy', optimize=True) buy_should_use_get_buy_signal_adx_smas = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_adx_smas'], space='buy', optimize=True) buy_should_use_get_buy_signal_asdts_rockwelltrading = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_asdts_rockwelltrading'], space='buy', optimize=True) buy_should_use_get_buy_signal_averages_strategy = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_averages_strategy'], space='buy', optimize=True) buy_should_use_get_buy_signal_fisher_hull = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_fisher_hull'], space='buy', optimize=True) buy_should_use_get_buy_signal_gettin_moist = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_gettin_moist'], space='buy', optimize=True) buy_should_use_get_buy_signal_hlhb = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_hlhb'], space='buy', optimize=True) buy_should_use_get_buy_signal_macd_strategy_crossed = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_macd_strategy_crossed'], space='buy', optimize=True) buy_should_use_get_buy_signal_macd_strategy = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_macd_strategy'], space='buy', optimize=True) buy_should_use_get_buy_signal_pmax = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_pmax'], space='buy', optimize=True) buy_should_use_get_buy_signal_quickie = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_quickie'], space='buy', optimize=True) buy_should_use_get_buy_signal_scalp = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_scalp'], space='buy', optimize=True) buy_should_use_get_buy_signal_simple = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_simple'], space='buy', optimize=True) buy_should_use_get_buy_signal_strategy001 = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_strategy001'], space='buy', optimize=True) buy_should_use_get_buy_signal_technical_example_strategy = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_technical_example_strategy'], space='buy', optimize=True) buy_should_use_get_buy_signal_tema_rsi_strategy = CategoricalParameter([True, False], default=buy_params['buy_should_use_get_buy_signal_tema_rsi_strategy'], space='buy', optimize=True) # Dynamic ROI droi_trend_type = CategoricalParameter(['rmi', 'ssl', 'candle', 'any'], default=sell_params['droi_trend_type'], space='sell', optimize=True) droi_pullback = CategoricalParameter([True, False], default=sell_params['droi_pullback'], space='sell', optimize=True) droi_pullback_amount = DecimalParameter(0.005, 0.02, default=sell_params['droi_pullback_amount'], space='sell') droi_pullback_respect_table = CategoricalParameter([True, False], default=sell_params['droi_pullback_respect_table'], space='sell', optimize=True) # Custom Stoploss cstp_threshold = DecimalParameter(-0.05, 0, default=sell_params['cstp_threshold'], space='sell') cstp_bail_how = CategoricalParameter(['roc', 'time', 'any'], default=sell_params['cstp_bail_how'], space='sell', optimize=True) cstp_bail_roc = DecimalParameter(-0.05, -0.01, default=sell_params['cstp_bail_roc'], space='sell') cstp_bail_time = IntParameter(720, 1440, default=sell_params['cstp_bail_time'], space='sell') cstp_trailing_only_offset_is_reached = DecimalParameter(0.01, 0.06, default=sell_params['cstp_trailing_only_offset_is_reached'], space='sell') cstp_trailing_stop_profit_devider = IntParameter(2, 4, default=sell_params['cstp_trailing_stop_profit_devider'], space='sell') cstp_trailing_max_stoploss = DecimalParameter(0.02, 0.08, default=sell_params['cstp_trailing_max_stoploss'], space='sell') cstp_bb_trailing_input = CategoricalParameter(['bb_lowerband_trend', 'bb_lowerband_trend_inf', 'bb_lowerband_neutral', 'bb_lowerband_neutral_inf', 'bb_upperband_neutral_inf'], default=sell_params['cstp_bb_trailing_input'], space='sell', optimize=True) # nested hyperopt class class HyperOpt: # defining as dummy, so that no error is thrown about missing # sell indicator space when hyperopting for all spaces @staticmethod def indicator_space() -> List[Dimension]: return [] custom_trade_info = {} custom_current_price_cache: TTLCache = TTLCache(maxsize=100, ttl=300) # 5 minutes # run "populate_indicators" only for new candle process_only_new_candles = False # Experimental settings (configuration will overide these if set) use_sell_signal = True sell_profit_only = False ignore_roi_if_buy_signal = False startup_candle_count = 500#149 use_dynamic_roi = True timeframe = '15m' informative_timeframe = '1h' # Optional order type mapping order_types = { 'entry': 'limit', 'exit': 'limit', 'stoploss': 'market', 'stoploss_on_exchange': False } plot_config = { 'main_plot': { 'chikou_span_inf': {'color': 'green'}, 'tenkan_sen_inf': {'color': 'blue'}, 'kijun_sen_inf': {'color': 'red'}, 'senkou_a_inf': { 'color': 'green', 'fill_to': 'senkou_b', 'fill_label': 'Kumo', 'fill_color': 'rgba(51, 255, 117, 0.2)', }, 'senkou_b_inf': {'color': 'red'}, 'leading_senkou_span_a_inf': {'color': 'green'}, 'leading_senkou_span_b_inf': {'color': 'red'}, 'sslUp_inf': {'color': 'green'}, 'sslDown_inf': {'color': 'red'} }, 'subplots': { 'summary': { 'cloud_green_inf': {}, 'cloud_red_inf': {}, 'future_green_inf': {}, 'chikou_high_inf': {}, 'go_long_inf': {} } } } def informative_pairs(self): pairs = self.dp.current_whitelist() informative_pairs = [(pair, self.informative_timeframe) for pair in pairs] return informative_pairs # # Processing indicators # def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: self.custom_trade_info[metadata['pair']] = self.populate_trades(metadata['pair']) if not self.dp: return dataframe dataframe = self.get_buy_signal_indicators(dataframe, metadata) informative_tmp = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.informative_timeframe) informative = self.get_market_condition_indicators(informative_tmp.copy(), metadata) informative = self.get_custom_stoploss_indicators(informative, metadata) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.informative_timeframe, ffill=True) dataframe.rename(columns=lambda s: s.replace("_{}".format(self.informative_timeframe), "_inf"), inplace=True) # Slam some indicators into the trade_info dict so we can dynamic roi and custom stoploss in backtest if self.dp.runmode.value in ('backtest', 'hyperopt'): self.custom_trade_info[metadata['pair']]['roc_inf'] = dataframe[['date', 'roc_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['atr_inf'] = dataframe[['date', 'atr_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['sroc_inf'] = dataframe[['date', 'sroc_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['ssl-dir_inf'] = dataframe[['date', 'ssl-dir_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['rmi-up-trend_inf'] = dataframe[['date', 'rmi-up-trend_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['candle-up-trend_inf'] = dataframe[['date', 'candle-up-trend_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['bb_lowerband_trend_inf'] = dataframe[['date', 'bb_lowerband_trend_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['bb_lowerband_trend_inf'] = dataframe[['date', 'bb_lowerband_trend_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['bb_lowerband_neutral_inf'] = dataframe[['date', 'bb_lowerband_neutral_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['bb_lowerband_neutral_inf'] = dataframe[['date', 'bb_lowerband_neutral_inf']].copy().set_index('date') self.custom_trade_info[metadata['pair']]['bb_upperband_neutral_inf'] = dataframe[['date', 'bb_upperband_neutral_inf']].copy().set_index('date') return dataframe def get_buy_signal_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # get_buy_signal_awesome_macd dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] dataframe['macdhist'] = macd['macdhist'] # get_buy_signal_adx_momentum #dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=25) dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=25) dataframe['sar'] = ta.SAR(dataframe) dataframe['mom'] = ta.MOM(dataframe, timeperiod=14) # get_buy_signal_adx_smas #dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) dataframe['short'] = ta.SMA(dataframe, timeperiod=3) dataframe['long'] = ta.SMA(dataframe, timeperiod=6) # get_buy_signal_asdts_rockwelltrading #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] # get_buy_signal_averages_strategy dataframe['maShort'] = ta.EMA(dataframe, timeperiod=8) dataframe['maMedium'] = ta.EMA(dataframe, timeperiod=21) # get_buy_signal_fisher_hull dataframe['hma'] = hull_moving_average(dataframe, 14, 'close') dataframe['cci'] = ta.CCI(dataframe, timeperiod=14) dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) rsi = 0.1 * (dataframe['rsi'] - 50) dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) # get_buy_signal_gettin_moist dataframe['color'] = dataframe['close'] > dataframe['open'] #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] dataframe['rsi_7'] = ta.RSI(dataframe, timeperiod=7) dataframe['roc_6'] = ta.ROC(dataframe, timeperiod=6) dataframe['primed'] = np.where(dataframe['color'].rolling(3).sum() == 3,1,0) dataframe['in-the-mood'] = dataframe['rsi_7'] > dataframe['rsi_7'].rolling(12).mean() dataframe['moist'] = qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']) dataframe['throbbing'] = dataframe['roc_6'] > dataframe['roc_6'].rolling(12).mean() dataframe['ready-to-go'] = np.where(dataframe['close'] > dataframe['open'].rolling(12).mean(), 1,0) # get_buy_signal_hlhb dataframe['hl2'] = (dataframe["close"] + dataframe["open"]) / 2 dataframe['rsi_10'] = ta.RSI(dataframe, timeperiod=10, price='hl2') dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) #dataframe['adx'] = ta.ADX(dataframe) # get_buy_signal_macd_strategy_crossed #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] #dataframe['cci'] = ta.CCI(dataframe) # get_buy_signal_macd_strategy #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] #dataframe['cci'] = ta.CCI(dataframe) # get_buy_signal_pmax dataframe['DEMA'] = dema(dataframe, period=10) dataframe = PMAX(dataframe, period=10, multiplier=3, length=10, MAtype=2, src=2) # get_buy_signal_quickie #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) dataframe['sma_200'] = ta.SMA(dataframe, timeperiod=200) dataframe['sma_50'] = ta.SMA(dataframe, timeperiod=200) #dataframe['adx'] = ta.ADX(dataframe) bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) dataframe['bb_lowerband'] = bollinger['lower'] dataframe['bb_middleband'] = bollinger['mid'] dataframe['bb_upperband'] = bollinger['upper'] # get_buy_signal_scalp dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) dataframe['fastd'] = stoch_fast['fastd'] dataframe['fastk'] = stoch_fast['fastk'] #dataframe['adx'] = ta.ADX(dataframe) # get_buy_signal_simple #macd = ta.MACD(dataframe) #dataframe['macd'] = macd['macd'] #dataframe['macdsignal'] = macd['macdsignal'] #dataframe['macdhist'] = macd['macdhist'] #dataframe['rsi_7'] = ta.RSI(dataframe, timeperiod=7) #bollinger = qtpylib.bollinger_bands(dataframe['close'], window=12, stds=2) #dataframe['bb_lowerband'] = bollinger['lower'] #dataframe['bb_upperband'] = bollinger['upper'] #dataframe['bb_middleband'] = bollinger['mid'] # get_buy_signal_strategy001 dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20) dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) heikinashi = qtpylib.heikinashi(dataframe) dataframe['ha_open'] = heikinashi['open'] dataframe['ha_close'] = heikinashi['close'] # get_buy_signal_technical_example_strategy dataframe['cmf'] = cmf(dataframe, 21) # get_buy_signal_tema_rsi_strategy #dataframe['rsi'] = ta.RSI(dataframe) #bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) #dataframe['bb_lowerband'] = bollinger['lower'] #dataframe['bb_middleband'] = bollinger['mid'] #dataframe['bb_upperband'] = bollinger['upper'] #dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) return dataframe def get_market_condition_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: displacement = 30 ichimoku = ftt.ichimoku(dataframe, conversion_line_period=20, base_line_periods=60, laggin_span=120, displacement=displacement) dataframe['chikou_span'] = ichimoku['chikou_span'] dataframe['tenkan_sen'] = ichimoku['tenkan_sen'] dataframe['kijun_sen'] = ichimoku['kijun_sen'] dataframe['senkou_a'] = ichimoku['senkou_span_a'] dataframe['senkou_b'] = ichimoku['senkou_span_b'] dataframe['leading_senkou_span_a'] = ichimoku['leading_senkou_span_a'] dataframe['leading_senkou_span_b'] = ichimoku['leading_senkou_span_b'] dataframe['cloud_green'] = ichimoku['cloud_green'] * 1 dataframe['cloud_red'] = ichimoku['cloud_red'] * -1 ssl = SSLChannels_ATR(dataframe, 10) dataframe['sslDown'] = ssl[0] dataframe['sslUp'] = ssl[1] #dataframe['vfi'] = fta.VFI(dataframe, period=14) # Summary indicators dataframe['future_green'] = ichimoku['cloud_green'].shift(displacement).replace(np.nan,0).astype('int') * 2 dataframe['chikou_high'] = ((dataframe['chikou_span'] > dataframe['senkou_a']) & (dataframe['chikou_span'] > dataframe['senkou_b'])).shift(displacement).replace(np.nan,0).astype('int') dataframe['go_long'] = ((dataframe['tenkan_sen'] > dataframe['kijun_sen']) & (dataframe['close'] > dataframe['leading_senkou_span_a']) & (dataframe['close'] > dataframe['leading_senkou_span_b']) & (dataframe['future_green'] > 0) & (dataframe['chikou_high'] > 0)).replace(np.nan,0).astype('int') * 3 dataframe['max'] = dataframe['high'].rolling(3).max() dataframe['min'] = dataframe['low'].rolling(6).min() dataframe['upper'] = np.where(dataframe['max'] > dataframe['max'].shift(),1,0) dataframe['lower'] = np.where(dataframe['min'] < dataframe['min'].shift(),1,0) dataframe['up_trend'] = np.where(dataframe['upper'].rolling(5, min_periods=1).sum() != 0,1,0) dataframe['dn_trend'] = np.where(dataframe['lower'].rolling(5, min_periods=1).sum() != 0,1,0) return dataframe def get_custom_stoploss_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: bollinger_neutral = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=1) dataframe['bb_lowerband_neutral'] = bollinger_neutral['lower'] dataframe['bb_middleband_neutral'] = bollinger_neutral['mid'] dataframe['bb_upperband_neutral'] = bollinger_neutral['upper'] bollinger_trend = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb_lowerband_trend'] = bollinger_trend['lower'] dataframe['bb_middleband_trend'] = bollinger_trend['mid'] dataframe['bb_upperband_trend'] = bollinger_trend['upper'] dataframe['atr'] = ta.ATR(dataframe, timeperiod=14) dataframe['roc'] = ta.ROC(dataframe, timeperiod=9) dataframe['rmi'] = RMI(dataframe, length=24, mom=5) ssldown, sslup = SSLChannels_ATR(dataframe, length=21) dataframe['sroc'] = SROC(dataframe, roclen=21, emalen=13, smooth=21) dataframe['ssl-dir'] = np.where(sslup > ssldown,'up','down') dataframe['rmi-up'] = np.where(dataframe['rmi'] >= dataframe['rmi'].shift(),1,0) dataframe['rmi-up-trend'] = np.where(dataframe['rmi-up'].rolling(5).sum() >= 3,1,0) dataframe['candle-up'] = np.where(dataframe['close'] >= dataframe['close'].shift(),1,0) dataframe['candle-up-trend'] = np.where(dataframe['candle-up'].rolling(5).sum() >= 3,1,0) return dataframe # # Processing buy signals # def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( (self.get_buy_signal_awesome_macd(dataframe) == True) | (self.get_buy_signal_adx_momentum(dataframe) == True) | (self.get_buy_signal_adx_smas(dataframe) == True) | (self.get_buy_signal_asdts_rockwelltrading(dataframe) == True) | (self.get_buy_signal_averages_strategy(dataframe) == True) | (self.get_buy_signal_fisher_hull(dataframe) == True) | (self.get_buy_signal_gettin_moist(dataframe) == True) | (self.get_buy_signal_hlhb(dataframe) == True) | (self.get_buy_signal_macd_strategy_crossed(dataframe) == True) | (self.get_buy_signal_macd_strategy(dataframe) == True) | (self.get_buy_signal_pmax(dataframe) == True) | (self.get_buy_signal_quickie(dataframe) == True) | (self.get_buy_signal_scalp(dataframe) == True) | (self.get_buy_signal_simple(dataframe) == True) | (self.get_buy_signal_strategy001(dataframe) == True) | (self.get_buy_signal_technical_example_strategy(dataframe) == True) | (self.get_buy_signal_tema_rsi_strategy(dataframe) == True) ) & (dataframe['sslUp_inf'] > dataframe['sslDown_inf']) & (dataframe['up_trend_inf'] > 0) & (dataframe['go_long_inf'] > 0) # NOTE: I keep the volume checks of feels like it has not much benifit when trading leverage tokens, maybe im wrong!? #(dataframe['vfi'] < 0.0) & #(dataframe['volume'] > 0) ,'buy'] = 1 return dataframe def get_buy_signal_awesome_macd(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_awesome_macd.value == True) & (dataframe['macd'] > 0) & (dataframe['ao'] > 0) & (dataframe['ao'].shift() < 0) ) return signal def get_buy_signal_adx_momentum(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_adx_momentum.value == True) & (dataframe['adx'] > 25) & (dataframe['mom'] > 0) & (dataframe['plus_di'] > 25) & (dataframe['plus_di'] > dataframe['minus_di']) ) return signal def get_buy_signal_adx_smas(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_adx_smas.value == True) & (dataframe['adx'] > 25) & (qtpylib.crossed_above(dataframe['short'], dataframe['long'])) ) return signal def get_buy_signal_asdts_rockwelltrading(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_asdts_rockwelltrading.value == True) & (dataframe['macd'] > 0) & (dataframe['macdhist'].shift(1) < dataframe['macdhist']) & (dataframe['macd'] > dataframe['macdsignal']) ) return signal def get_buy_signal_averages_strategy(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_averages_strategy.value == True) & qtpylib.crossed_above(dataframe['maShort'], dataframe['maMedium']) ) return signal def get_buy_signal_fisher_hull(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_fisher_hull.value == True) & (dataframe['hma'] < dataframe['hma'].shift()) & (dataframe['cci'] <= -50.0) & (dataframe['fisher_rsi'] < -0.5) ) return signal def get_buy_signal_gettin_moist(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_gettin_moist.value == True) & (dataframe['primed']) & (dataframe['moist']) & (dataframe['throbbing']) & (dataframe['ready-to-go']) ) return signal def get_buy_signal_hlhb(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_hlhb.value == True) & (qtpylib.crossed_above(dataframe['rsi_10'], 50)) & (qtpylib.crossed_above(dataframe['ema5'], dataframe['ema10'])) & (dataframe['adx'] > 25) ) return signal def get_buy_signal_macd_strategy_crossed(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_macd_strategy_crossed.value == True) & qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']) & (dataframe['cci'] <= -50.0) ) return signal def get_buy_signal_macd_strategy(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_macd_strategy.value == True) & (dataframe['macd'] > dataframe['macdsignal']) & (dataframe['cci'] <= -50.0) ) return signal def get_buy_signal_pmax(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_pmax.value == True) & (qtpylib.crossed_above(dataframe['DEMA'], dataframe['pm_10_3_10_2'])) ) return signal def get_buy_signal_quickie(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_quickie.value == True) & (dataframe['adx'] > 30) & (dataframe['tema'] < dataframe['bb_middleband']) & (dataframe['tema'] > dataframe['tema'].shift(1)) & (dataframe['sma_200'] > dataframe['close']) ) return signal def get_buy_signal_scalp(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_scalp.value == True) & (dataframe['open'] < dataframe['ema_low']) & (dataframe['adx'] > 30) & ( (dataframe['fastk'] < 30) & (dataframe['fastd'] < 30) & (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) ) ) return signal def get_buy_signal_simple(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_simple.value == True) & (dataframe['macd'] > 0) # over 0 & (dataframe['macd'] > dataframe['macdsignal']) # over signal & (dataframe['bb_upperband'] > dataframe['bb_upperband'].shift(1)) # pointed up & (dataframe['rsi_7'] > 70) # optional filter, need to investigate ) return signal def get_buy_signal_strategy001(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_strategy001.value == True) & qtpylib.crossed_above(dataframe['ema50'], dataframe['ema100']) & (dataframe['ha_close'] < dataframe['ema20']) & (dataframe['ha_open'] > dataframe['ha_close']) # red bar ) return signal def get_buy_signal_technical_example_strategy(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_technical_example_strategy.value == True) & (dataframe['cmf'] < 0) ) return signal def get_buy_signal_tema_rsi_strategy(self, dataframe: DataFrame): signal = ( (self.buy_should_use_get_buy_signal_tema_rsi_strategy.value == True) & (qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30 (dataframe['tema'] <= dataframe['bb_middleband']) & # Guard: tema below BB middle (dataframe['tema'] > dataframe['tema'].shift(1)) ) return signal # # Processing sell signals # def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ (qtpylib.crossed_above(dataframe['sslDown_inf'], dataframe['sslUp_inf'])) & ( (qtpylib.crossed_below(dataframe['tenkan_sen_inf'], dataframe['kijun_sen_inf'])) |(qtpylib.crossed_below(dataframe['close_inf'], dataframe['kijun_sen_inf'])) ) #& # NOTE: I keep the volume checks of feels like it has not much benifit when trading leverage tokens, maybe im wrong!? #(dataframe['vfi'] < 0.0) & #(dataframe['volume'] > 0) ,'sell'] = 1 return dataframe # # Custom Stoploss # def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: trade_dur = int((current_time.timestamp() - trade.open_date_utc.timestamp()) // 60) if self.config['runmode'].value in ('live', 'dry_run'): dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) sroc = dataframe['sroc_inf'].iat[-1] bb_trailing = dataframe[self.cstp_bb_trailing_input.value].iat[-1] # If in backtest or hyperopt, get the indicator values out of the trades dict (Thanks @JoeSchr!) else: sroc = self.custom_trade_info[trade.pair]['sroc_inf'].loc[current_time]['sroc_inf'] bb_trailing = self.custom_trade_info[trade.pair][self.cstp_bb_trailing_input.value].loc[current_time][self.cstp_bb_trailing_input.value] if current_profit < self.cstp_threshold.value: if self.cstp_bail_how.value == 'roc' or self.cstp_bail_how.value == 'any': # Dynamic bailout based on rate of change if (sroc/100) <= self.cstp_bail_roc.value: return 0.001 if self.cstp_bail_how.value == 'time' or self.cstp_bail_how.value == 'any': # Dynamic bailout based on time if trade_dur > self.cstp_bail_time.value: return 0.001 if current_profit < self.cstp_trailing_only_offset_is_reached.value: if current_rate <= bb_trailing: return 0.001 else: return -1 desired_stoploss = current_profit / self.cstp_trailing_stop_profit_devider.value return max(min(desired_stoploss, self.cstp_trailing_max_stoploss.value), 0.025) # # Dynamic ROI # def min_roi_reached_dynamic(self, trade: Trade, current_profit: float, current_time: datetime, trade_dur: int) -> Tuple[Optional[int], Optional[float]]: minimal_roi = self.minimal_roi _, table_roi = self.min_roi_reached_entry(trade_dur) # see if we have the data we need to do this, otherwise fall back to the standard table if self.custom_trade_info and trade and trade.pair in self.custom_trade_info: if self.config['runmode'].value in ('live', 'dry_run'): dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=trade.pair, timeframe=self.timeframe) rmi_trend = dataframe['rmi-up-trend_inf'].iat[-1] candle_trend = dataframe['candle-up-trend_inf'].iat[-1] ssl_dir = dataframe['ssl-dir_inf'].iat[-1] # If in backtest or hyperopt, get the indicator values out of the trades dict (Thanks @JoeSchr!) else: rmi_trend = self.custom_trade_info[trade.pair]['rmi-up-trend_inf'].loc[current_time]['rmi-up-trend_inf'] candle_trend = self.custom_trade_info[trade.pair]['candle-up-trend_inf'].loc[current_time]['candle-up-trend_inf'] ssl_dir = self.custom_trade_info[trade.pair]['ssl-dir_inf'].loc[current_time]['ssl-dir_inf'] min_roi = table_roi max_profit = trade.calc_profit_ratio(trade.max_rate) pullback_value = (max_profit - self.droi_pullback_amount.value) in_trend = False if self.droi_trend_type.value == 'rmi' or self.droi_trend_type.value == 'any': if rmi_trend == 1: in_trend = True if self.droi_trend_type.value == 'ssl' or self.droi_trend_type.value == 'any': if ssl_dir == 'up': in_trend = True if self.droi_trend_type.value == 'candle' or self.droi_trend_type.value == 'any': if candle_trend == 1: in_trend = True # Force the ROI value high if in trend if (in_trend == True): min_roi = 100 # If pullback is enabled, allow to sell if a pullback from peak has happened regardless of trend if self.droi_pullback.value == True and (current_profit < pullback_value): if self.droi_pullback_respect_table.value == True: min_roi = table_roi else: min_roi = current_profit / 2 else: min_roi = table_roi return trade_dur, min_roi # Change here to allow loading of the dynamic_roi settings def min_roi_reached(self, trade: Trade, current_profit: float, current_time: datetime) -> bool: trade_dur = int((current_time.timestamp() - trade.open_date_utc.timestamp()) // 60) if self.use_dynamic_roi: _, roi = self.min_roi_reached_dynamic(trade, current_profit, current_time, trade_dur) else: _, roi = self.min_roi_reached_entry(trade_dur) if roi is None: return False else: return current_profit > roi # Get the current price from the exchange (or local cache) def get_current_price(self, pair: str, refresh: bool) -> float: if not refresh: rate = self.custom_current_price_cache.get(pair) # Check if cache has been invalidated if rate: return rate ask_strategy = self.config.get('ask_strategy', {}) if ask_strategy.get('use_order_book', False): ob = self.dp.orderbook(pair, 1) rate = ob[f"{ask_strategy['price_side']}s"][0][0] else: ticker = self.dp.ticker(pair) rate = ticker['last'] self.custom_current_price_cache[pair] = rate return rate # # Custom trade info # def populate_trades(self, pair: str) -> dict: # Initialize the trades dict if it doesn't exist, persist it otherwise if not pair in self.custom_trade_info: self.custom_trade_info[pair] = {} # init the temp dicts and set the trade stuff to false trade_data = {} trade_data['active_trade'] = False # active trade stuff only works in live and dry, not backtest if self.config['runmode'].value in ('live', 'dry_run'): # find out if we have an open trade for this pair active_trade = Trade.get_trades([Trade.pair == pair, Trade.is_open.is_(True),]).all() # if so, get some information if active_trade: # get current price and update the min/max rate current_rate = self.get_current_price(pair, True) active_trade[0].adjust_min_max_rates(current_rate) return trade_data # # Custom indicators # def RMI(dataframe, *, length=20, mom=5): """ Source: https://github.com/freqtrade/technical/blob/master/technical/indicators/indicators.py#L912 """ df = dataframe.copy() df['maxup'] = (df['close'] - df['close'].shift(mom)).clip(lower=0) df['maxdown'] = (df['close'].shift(mom) - df['close']).clip(lower=0) df.replace(np.nan,0) df["emaInc"] = ta.EMA(df, price='maxup', timeperiod=length) df["emaDec"] = ta.EMA(df, price='maxdown', timeperiod=length) df['RMI'] = np.where(df['emaDec'] == 0, 0, 100 - 100 / (1 + df["emaInc"] / df["emaDec"])) return df["RMI"] def SSLChannels_ATR(dataframe, length=7): """ SSL Channels with ATR: https://www.tradingview.com/script/SKHqWzql-SSL-ATR-channel/ Credit to @JimmyNixx for python """ df = dataframe.copy() df['ATR'] = ta.ATR(df, timeperiod=14) df['smaHigh'] = df['high'].rolling(length).mean() + df['ATR'] df['smaLow'] = df['low'].rolling(length).mean() - df['ATR'] df['hlv'] = np.where(df['close'] > df['smaHigh'], 1, np.where(df['close'] < df['smaLow'], -1, np.NAN)) df['hlv'] = df['hlv'].ffill() df['sslDown'] = np.where(df['hlv'] < 0, df['smaHigh'], df['smaLow']) df['sslUp'] = np.where(df['hlv'] < 0, df['smaLow'], df['smaHigh']) return df['sslDown'], df['sslUp'] def SROC(dataframe, roclen=21, emalen=13, smooth=21): df = dataframe.copy() roc = ta.ROC(df, timeperiod=roclen) ema = ta.EMA(df, timeperiod=emalen) sroc = ta.ROC(ema, timeperiod=smooth) return sroc

Frederic Collard

Hello Dear community, I have an update which may be of interrest for all. I downloaded the code provided by Loic in his message above, updated it with the hyperopt parameters released by Dutch Algotrading in his previous post, made some code formating here and there with "black" python formatter. On backtesting, I got outstanding results with no error. Lookahead bias did not give error neither and was succesfull (no bias detected). Link to current file : https://github.com/fcxpress/freqtrade/blob/main/user_data/strategies/MacheteV8b.py I tried the bot in dryrun on kucoin with an initial amount of 1000 USDT but the results are disapointing. It makes consistent gains of very small amounts (like 0,05 USDT per trade) and then sometimes losses (like 3 to 5 USDT) which in total after 4 days makes it significant loosses (loses 8 to 10 USDT a day). I'm sure this can be fixed and optimized. Probably there is something to do with a dynamic ROI. I'm using the config files and the static pairlist provided by Dutch Algotrading Here is an example of a small gain trade closed for ROI : Kucoin (dry): Exiting LRC/USDT (#88) Unrealized Profit: 0.24% (profit: 0.295 USDT / 0.295 USD) Exit Reason: roi Direction: Long Amount: 235.617 Open Rate: 0.522 USDT Current Rate: 0.524 USDT Exit Rate: 0.524 USDT Duration: 0:04:21 (4.3 min)

Dutch Algotrading

Hi Frederic, thanks for your informative update! I really appreciate this. Your findings can help the community to improve on things or can debunk some myths on the superhigh performances of these algos.

TheStarcalibur

Hi :-) there is a error i cant fix while running Machete_fixed and same for Machete. its in the last part of the code and has something to do with custom_stoploss and dynamic roi. if i set them to False, both work fine, but not effective. TypeError: LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low' 2024-03-14 20:26:08,877 - freqtrade.strategy.interface - WARNING - Unable to analyze candle (OHLCV) data for pair ZRX/USDT:USDT: LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low'

TheStarcalibur

Iam just not getting it, worked on both topics for a hole day O.O File "/home/freqtrade/.venv/lib/python3.10/site-packages/pandas/core/indexes/range.py", line 418, in get_loc raise KeyError(key) KeyError: 'rmi-up-trend_inf'

Frederic Collard

ZRX/USDT:USDT is a future pair. This strategy is for spot. Check your config file. You may want to use Dutch Algotrading's config files which includes pairlists.

Marek Hovadík

Yes I think you just need to alter the line 547 from this active_trade[0].adjust_min_max_rates(current_rate) to this active_trade[0].adjust_min_max_rates(current_rate, current_rate)

Adam Iulian

Same here: Unexpected error LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low' calling > Traceback (most recent call last): File "/freqtrade/freqtrade/strategy/strategy_wrapper.py", line 27, in wrapper return f(*args, **kwargs) ^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/strategy/interface.py", line 918, in _analyze_ticker_internal dataframe = self.analyze_ticker(dataframe, metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/strategy/interface.py", line 896, in analyze_ticker dataframe = self.advise_indicators(dataframe, metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/freqtrade/strategy/interface.py", line 1423, in advise_indicators return self.populate_indicators(dataframe, metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/user_data/strategies/MacheteV8b.py", line 197, in populate_indicators self.custom_trade_info[metadata['pair']] = self.populate_trades(metadata['pair']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/freqtrade/user_data/strategies/MacheteV8b.py", line 771, in populate_trades active_trade[0].adjust_min_max_rates(current_rate) TypeError: LocalTrade.adjust_min_max_rates() missing 1 required positional argument: 'current_price_low'

kisu mang

i also have some error like "KeyError: 'bb_lowerband_trend' Unexpected error 'bb_lowerband_trend'

Jan

Yeah this stuff doesnt work... waste of time... make proper guides preferably videos...