├── .gitignore ├── command ├── backtest.sh ├── download-data.sh ├── edge.sh ├── hyperopt.sh ├── plot-strategy.sh └── test-pairlist.sh ├── docker-compose.yml ├── docker ├── Dockerfile.aarch64 ├── Dockerfile.armhf ├── Dockerfile.custom ├── Dockerfile.develop ├── Dockerfile.jupyter ├── Dockerfile.plot └── docker-compose-jupyter.yml └── user_data ├── backtest_results └── .gitkeep ├── config-backtest.json ├── config.json ├── data └── .gitkeep ├── hyperopt.lock ├── hyperopt_results └── .gitkeep ├── hyperopts ├── AverageHyperopt.py ├── BinHV45HyperOpt.py ├── GodStraHo.py ├── HO-Strategy005.py ├── HO-SwingHighToSky.py ├── HeraclesHo.py ├── MACDStrategy_hyperopt.py ├── ReinforcedSmoothScalp_hyperopt.py ├── sample_hyperopt.py ├── sample_hyperopt_advanced.py └── sample_hyperopt_loss.py ├── logs └── .gitkeep ├── plot └── .gitkeep ├── strategies.zip └── strategies ├── ADXMomentum.py ├── AiewStra.py ├── AiewStraV2.py ├── BbandRsi.py ├── BearBull3.py ├── BigTrader.py ├── BigZ04_TSL3.py ├── BigZ04_TSL4.py ├── BinHV27.py ├── CCIStrategy.py ├── CDCV3HO3.py ├── CMCWinner.py ├── CofiBitStrategy.py ├── CombinedBinHClucAndMADV9.py ├── Combined_NFIv6_SMA.py ├── Combined_NFIv7_SMA.py ├── DevilStra.py ├── DoubleEMACrossoverWithTrend.py ├── ElliotV4.py ├── ElliotV5.py ├── ElliotV5HO.py ├── ElliotV5HOMod1.py ├── ElliotV5HOMod2.py ├── ElliotV5HOMod3.py ├── ElliotV7.py ├── ElliotV8HO.py ├── ElliotV8_orginal.py ├── ElliotV8_original_ichiv2.py ├── ElliotV8_original_ichiv3.py ├── GodStra.py ├── GodStraNew.py ├── GodStraNewOpt.py ├── GodStraNewOpt2.py ├── GodStraNewOpt3.py ├── GodStraNewOpt4.py ├── GodStraOpt.py ├── GodStraOpt2.py ├── Heracles.py ├── HeraclesOpt2.py ├── HeraclesOptimize.py ├── IchimokuV1.py ├── IchisV1.py ├── InformativeSample.py ├── MinMaxF.py ├── MultiMA_TSL.py ├── MultiMa.py ├── NASOSv4.py ├── NASOSv4HO.py ├── NFI7HO2.py ├── NFIV5HYPERALL.py ├── NostalgiaForInfinityNext.py ├── NostalgiaForInfinityV4.py ├── NostalgiaForInfinityV5.py ├── NostalgiaForInfinityV5MultiOffsetAndHO.py ├── NostalgiaForInfinityV6.py ├── NostalgiaForInfinityV7.py ├── NotAnotherSMAOffSetStrategy_V2.py ├── NotAnotherSMAOffsetStrategy.py ├── NotAnotherSMAOffsetStrategyHOv3.py ├── Obelisk_Ichimoku_Slow_v1_2.py ├── Obelisk_Ichimoku_ZEMA_v1.py ├── Obelisk_TradePro_Ichi_v2_2.py ├── RalliV1.py ├── SMA1CTE1.py ├── SMA1CTE2.py ├── SMA1Sell.py ├── SMAIP3.py ├── SMAOG.py ├── SMAOffsetProtectOptV1.py ├── SMAOffsetProtectOptV1Mod.py ├── Strategy001.py ├── Strategy001_custom_sell.py ├── Strategy002.py ├── Strategy003.py ├── Strategy004.py ├── Strategy005.py ├── Supertrend.py ├── Swing-High-To-Sky.py ├── TDSequentialStrategy.py ├── Zeus.py ├── Zeus1.py ├── adx_strategytsedit.py ├── bbrsittfv1.py ├── berlinguyinca ├── ADXMomentum.py ├── ASDTSRockwellTrading.py ├── AdxSmas.py ├── AverageStrategy.py ├── AwesomeMacd.py ├── BbandRsi.py ├── BinHV27.py ├── BinHV45.py ├── CCIStrategy.py ├── CMCWinner.py ├── ClucMay72018.py ├── CofiBitStrategy.py ├── CombinedBinHAndCluc.py ├── DoesNothingStrategy.py ├── EMASkipPump.py ├── Freqtrade_backtest_validation_freqtrade1.py ├── Low_BB.py ├── MACDStrategy.py ├── MACDStrategy_crossed.py ├── MultiRSI.py ├── Quickie.py ├── ReinforcedAverageStrategy.py ├── ReinforcedQuickie.py ├── ReinforcedSmoothScalp.py ├── Scalp.py ├── Simple.py ├── SmoothOperator.py ├── SmoothScalp.py ├── TDSequentialStrategy.py └── TechnicalExampleStrategy.py ├── custom_stoploss_with_psar.py ├── fixed_riskreward_loss.py ├── hlhb.py ├── hlhbOpt.py ├── mabStra.py ├── normalizer.py ├── sample_strategy.py ├── wtc.py └── wtcOpt.py /.gitignore: -------------------------------------------------------------------------------- 1 | user_data/tradesv3.sqlite 2 | user_data/data/* 3 | !user_data/data/.gitkeep 4 | 5 | user_data/logs/* 6 | !user_data/logs/.gitkeep 7 | 8 | 9 | user_data/backtest_results/* 10 | !user_data/backtest_results/.gitkeep 11 | 12 | 13 | user_data/plot/* 14 | !user_data/plot/.gitkeep 15 | 16 | user_data/hyperopt_results/* 17 | !user_data/hyperopt_results/.gitkeep -------------------------------------------------------------------------------- /command/backtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | docker-compose run --rm freqtrade backtesting --export trades --strategy-list ElliotV5HO NASOSv4HO --timerange=20211020- -c user_data/config-backtest.json -i 5m -------------------------------------------------------------------------------- /command/download-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose run --rm freqtrade download-data --days 30 -t 5m 1h -c user_data/config-backtest.json -------------------------------------------------------------------------------- /command/edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose run --rm freqtrade edge -s ElliotV5HOMod3 --timerange=20210807- -c user_data/config-backtest.json -i 5m -------------------------------------------------------------------------------- /command/hyperopt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | docker-compose run --rm freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces stoploss --strategy ElliotV5HOMod1 --timerange 20210715-20210815 --config user_data/config-hyperopt.json -j 1 -------------------------------------------------------------------------------- /command/plot-strategy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose run --rm freqtrade plot-dataframe --strategy ElliotV5HO -p CHR/BUSD -c user_data/config-backtest.json -i 5m -------------------------------------------------------------------------------- /command/test-pairlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose run --rm freqtrade test-pairlist --config user_data/config.json --quote BUSD --print-json -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3" 3 | services: 4 | freqtrade: 5 | # image: freqtradeorg/freqtrade:stable 6 | # image: freqtradeorg/freqtrade:develop 7 | # Use plotting image 8 | # image: freqtradeorg/freqtrade:develop_plot 9 | # Build step - only needed when additional dependencies are needed 10 | build: 11 | context: . 12 | dockerfile: "./docker/Dockerfile.custom" 13 | restart: unless-stopped 14 | container_name: freqtrade-custom 15 | volumes: 16 | - "./user_data:/freqtrade/user_data" 17 | # Expose api on port 8080 (localhost only) 18 | # Please read the https://www.freqtrade.io/en/latest/rest-api/ documentation 19 | # before enabling this. 20 | ports: 21 | - "8080:8080" 22 | # Default command used when running `docker compose up` 23 | command: > 24 | trade 25 | --logfile /freqtrade/user_data/logs/freqtrade.log 26 | --db-url sqlite:////freqtrade/user_data/tradesv3.sqlite 27 | --config /freqtrade/user_data/config.json 28 | --strategy NASOSv4HO 29 | -------------------------------------------------------------------------------- /docker/Dockerfile.aarch64: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/arm64/v8 python:3.9.4-slim-buster as base 2 | 3 | # Setup env 4 | ENV LANG C.UTF-8 5 | ENV LC_ALL C.UTF-8 6 | ENV PYTHONDONTWRITEBYTECODE 1 7 | ENV PYTHONFAULTHANDLER 1 8 | ENV PATH=/home/ftuser/.local/bin:$PATH 9 | ENV FT_APP_ENV="docker" 10 | 11 | # Prepare environment 12 | RUN mkdir /freqtrade \ 13 | && apt-get update \ 14 | && apt-get -y install sudo libatlas3-base curl sqlite3 libhdf5-serial-dev \ 15 | && apt-get clean \ 16 | && useradd -u 1000 -G sudo -U -m ftuser \ 17 | && chown ftuser:ftuser /freqtrade \ 18 | # Allow sudoers 19 | && echo "ftuser ALL=(ALL) NOPASSWD: /bin/chown" >> /etc/sudoers 20 | 21 | WORKDIR /freqtrade 22 | 23 | # Install dependencies 24 | FROM base as python-deps 25 | RUN apt-get update \ 26 | && apt-get -y install build-essential libssl-dev git libffi-dev libgfortran5 pkg-config cmake gcc \ 27 | && apt-get clean \ 28 | && pip install --upgrade pip 29 | 30 | # Install TA-lib 31 | COPY build_helpers/* /tmp/ 32 | RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib* 33 | ENV LD_LIBRARY_PATH /usr/local/lib 34 | 35 | # Install dependencies 36 | COPY --chown=ftuser:ftuser requirements.txt requirements-hyperopt.txt /freqtrade/ 37 | USER ftuser 38 | RUN pip install --user --no-cache-dir numpy \ 39 | && pip install --user --no-cache-dir -r requirements-hyperopt.txt 40 | 41 | # Copy dependencies to runtime-image 42 | FROM base as runtime-image 43 | COPY --from=python-deps /usr/local/lib /usr/local/lib 44 | ENV LD_LIBRARY_PATH /usr/local/lib 45 | 46 | COPY --from=python-deps --chown=ftuser:ftuser /home/ftuser/.local /home/ftuser/.local 47 | 48 | USER ftuser 49 | # Install and execute 50 | COPY --chown=ftuser:ftuser . /freqtrade/ 51 | 52 | RUN pip install -e . --user --no-cache-dir --no-build-isolation\ 53 | && mkdir /freqtrade/user_data/ \ 54 | && freqtrade install-ui 55 | 56 | ENTRYPOINT ["freqtrade"] 57 | # Default to trade mode 58 | CMD [ "trade" ] 59 | -------------------------------------------------------------------------------- /docker/Dockerfile.armhf: -------------------------------------------------------------------------------- 1 | FROM python:3.7.10-slim-buster as base 2 | 3 | # Setup env 4 | ENV LANG C.UTF-8 5 | ENV LC_ALL C.UTF-8 6 | ENV PYTHONDONTWRITEBYTECODE 1 7 | ENV PYTHONFAULTHANDLER 1 8 | ENV PATH=/home/ftuser/.local/bin:$PATH 9 | ENV FT_APP_ENV="docker" 10 | 11 | # Prepare environment 12 | RUN mkdir /freqtrade \ 13 | && apt-get update \ 14 | && apt-get -y install sudo libatlas3-base curl sqlite3 libhdf5-dev \ 15 | && apt-get clean \ 16 | && useradd -u 1000 -G sudo -U -m ftuser \ 17 | && chown ftuser:ftuser /freqtrade \ 18 | # Allow sudoers 19 | && echo "ftuser ALL=(ALL) NOPASSWD: /bin/chown" >> /etc/sudoers 20 | 21 | WORKDIR /freqtrade 22 | 23 | # Install dependencies 24 | FROM base as python-deps 25 | RUN apt-get update \ 26 | && apt-get -y install build-essential libssl-dev libffi-dev libgfortran5 pkg-config cmake gcc \ 27 | && apt-get clean \ 28 | && pip install --upgrade pip \ 29 | && echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf 30 | 31 | # Install TA-lib 32 | COPY build_helpers/* /tmp/ 33 | RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib* 34 | ENV LD_LIBRARY_PATH /usr/local/lib 35 | 36 | # Install dependencies 37 | COPY --chown=ftuser:ftuser requirements.txt /freqtrade/ 38 | USER ftuser 39 | RUN pip install --user --no-cache-dir numpy \ 40 | && pip install --user --no-cache-dir -r requirements.txt 41 | 42 | # Copy dependencies to runtime-image 43 | FROM base as runtime-image 44 | COPY --from=python-deps /usr/local/lib /usr/local/lib 45 | ENV LD_LIBRARY_PATH /usr/local/lib 46 | 47 | COPY --from=python-deps --chown=ftuser:ftuser /home/ftuser/.local /home/ftuser/.local 48 | 49 | USER ftuser 50 | # Install and execute 51 | COPY --chown=ftuser:ftuser . /freqtrade/ 52 | 53 | RUN pip install -e . --user --no-cache-dir --no-build-isolation\ 54 | && mkdir /freqtrade/user_data/ \ 55 | && freqtrade install-ui 56 | 57 | ENTRYPOINT ["freqtrade"] 58 | # Default to trade mode 59 | CMD [ "trade" ] 60 | -------------------------------------------------------------------------------- /docker/Dockerfile.custom: -------------------------------------------------------------------------------- 1 | FROM freqtradeorg/freqtrade:stable 2 | 3 | # Switch user to root if you must install something from apt 4 | # Don't forget to switch the user back below! 5 | # USER root 6 | 7 | # The below dependency - pyti - serves as an example. Please use whatever you need! 8 | RUN pip install --user pyti 9 | RUN pip install ta 10 | RUN pip install sklearn 11 | RUN pip install plotly==4.14.3 12 | RUN pip install pandas_ta 13 | # Install dependencies 14 | 15 | # USER ftuser 16 | 17 | -------------------------------------------------------------------------------- /docker/Dockerfile.develop: -------------------------------------------------------------------------------- 1 | FROM freqtradeorg/freqtrade:develop 2 | 3 | # Install dependencies 4 | COPY requirements-dev.txt /freqtrade/ 5 | 6 | RUN pip install numpy --user --no-cache-dir \ 7 | && pip install -r requirements-dev.txt --user --no-cache-dir 8 | 9 | # Empty the ENTRYPOINT to allow all commands 10 | ENTRYPOINT [] 11 | -------------------------------------------------------------------------------- /docker/Dockerfile.jupyter: -------------------------------------------------------------------------------- 1 | FROM freqtradeorg/freqtrade:develop_plot 2 | 3 | 4 | RUN pip install jupyterlab --user --no-cache-dir 5 | 6 | # Empty the ENTRYPOINT to allow all commands 7 | ENTRYPOINT [] 8 | -------------------------------------------------------------------------------- /docker/Dockerfile.plot: -------------------------------------------------------------------------------- 1 | ARG sourceimage=develop 2 | FROM freqtradeorg/freqtrade:${sourceimage} 3 | 4 | # Install dependencies 5 | COPY requirements-plot.txt /freqtrade/ 6 | 7 | RUN pip install -r requirements-plot.txt --user --no-cache-dir 8 | -------------------------------------------------------------------------------- /docker/docker-compose-jupyter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3" 3 | services: 4 | ft_jupyterlab: 5 | build: 6 | context: .. 7 | dockerfile: docker/Dockerfile.jupyter 8 | restart: unless-stopped 9 | container_name: freqtrade-plot 10 | ports: 11 | - "127.0.0.1:8888:8888" 12 | volumes: 13 | - "./user_data:/freqtrade/user_data" 14 | # Default command used when running `docker compose up` 15 | command: > 16 | jupyter lab --port=8888 --ip 0.0.0.0 --allow-root 17 | -------------------------------------------------------------------------------- /user_data/backtest_results/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/backtest_results/.gitkeep -------------------------------------------------------------------------------- /user_data/config-backtest.json: -------------------------------------------------------------------------------- 1 | { 2 | "max_open_trades": 2, 3 | "stake_currency": "BUSD", 4 | "stake_amount": "unlimited", 5 | "tradable_balance_ratio": 0.99, 6 | "fiat_display_currency": "USD", 7 | "dry_run": true, 8 | "cancel_open_orders_on_exit": true, 9 | "unfilledtimeout": { 10 | "buy": 10, 11 | "sell": 30, 12 | "unit": "minutes" 13 | }, 14 | "bid_strategy": { 15 | "price_side": "ask", 16 | "ask_last_balance": 0.0, 17 | "use_order_book": false, 18 | "order_book_top": 1, 19 | "check_depth_of_market": { 20 | "enabled": false, 21 | "bids_to_ask_delta": 1 22 | } 23 | }, 24 | "ask_strategy": { 25 | "price_side": "bid", 26 | "use_order_book": false, 27 | "order_book_min": 1, 28 | "order_book_max": 1 29 | }, 30 | "exchange": { 31 | "name": "binance", 32 | "key": "", 33 | "secret": "", 34 | "ccxt_config": { 35 | "enableRateLimit": true 36 | }, 37 | "ccxt_async_config": { 38 | "enableRateLimit": true, 39 | "rateLimit": 200 40 | }, 41 | "pair_whitelist": [ 42 | "CAKE/BUSD", 43 | "SOL/BUSD", 44 | "VET/BUSD", 45 | "FTM/BUSD", 46 | "DOGE/BUSD", 47 | "LTC/BUSD", 48 | "MATIC/BUSD", 49 | "LUNA/BUSD", 50 | "WAXP/BUSD", 51 | "LRC/BUSD", 52 | "ETH/BUSD", 53 | "IOTX/BUSD", 54 | "LINK/BUSD", 55 | "AVAX/BUSD", 56 | "XRP/BUSD", 57 | "SAND/BUSD", 58 | "DAR/BUSD", 59 | "MANA/BUSD", 60 | "IOTA/BUSD", 61 | "DOT/BUSD", 62 | "ADA/BUSD", 63 | "BTC/BUSD", 64 | "GALA/BUSD", 65 | "CHR/BUSD" 66 | ], 67 | "pair_blacklist": [] 68 | }, 69 | "pairlists": [{ "method": "StaticPairList" }], 70 | "edge": { 71 | "enabled": false, 72 | "process_throttle_secs": 3600, 73 | "calculate_since_number_of_days": 18, 74 | "allowed_risk": 0.5, 75 | "stoploss_range_min": -0.01, 76 | "stoploss_range_max": -0.15, 77 | "stoploss_range_step": -0.01, 78 | "minimum_winrate": 0.7, 79 | "minimum_expectancy": 0.2, 80 | "min_trade_number": 10, 81 | "max_trade_duration_minute": 1440, 82 | "remove_pumps": false 83 | }, 84 | "telegram": { 85 | "enabled": false, 86 | "token": "", 87 | "chat_id": "" 88 | }, 89 | "api_server": { 90 | "enabled": true, 91 | "listen_ip_address": "0.0.0.0", 92 | "listen_port": 8080, 93 | "verbosity": "error", 94 | "enable_openapi": false, 95 | "jwt_secret_key": "fc4eb9fb7863380b5b3b27b5624050183656ad4c77c682dbb937af88f4a4d0b4", 96 | "CORS_origins": [], 97 | "username": "username", 98 | "password": "password" 99 | }, 100 | "bot_name": "freqtrade", 101 | "initial_state": "running", 102 | "forcebuy_enable": false, 103 | "internals": { 104 | "process_throttle_secs": 5 105 | }, 106 | "dry_run_wallet": 29.59 107 | } 108 | -------------------------------------------------------------------------------- /user_data/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "max_open_trades": 2, 3 | "stake_currency": "BUSD", 4 | "stake_amount": "unlimited", 5 | "tradable_balance_ratio": 0.99, 6 | "fiat_display_currency": "THB", 7 | "dry_run_wallet": 29, 8 | "dry_run": true, 9 | "cancel_open_orders_on_exit": true, 10 | "timeframe": "5m", 11 | "unfilledtimeout": { 12 | "buy": 10, 13 | "sell": 30, 14 | "unit": "minutes" 15 | }, 16 | "bid_strategy": { 17 | "price_side": "ask", 18 | "ask_last_balance": 0.0, 19 | "use_order_book": false, 20 | "order_book_top": 1, 21 | "check_depth_of_market": { 22 | "enabled": false, 23 | "bids_to_ask_delta": 1 24 | } 25 | }, 26 | "ask_strategy": { 27 | "price_side": "bid", 28 | "use_order_book": false, 29 | "order_book_min": 1, 30 | "order_book_max": 1 31 | }, 32 | "order_types": { 33 | "buy": "limit", 34 | "sell": "limit", 35 | "stoploss": "market", 36 | "stoploss_on_exchange": false 37 | }, 38 | "order_time_in_force": { 39 | "buy": "gtc", 40 | "sell": "gtc" 41 | }, 42 | "exchange": { 43 | "name": "binance", 44 | "key": "", 45 | "secret": "", 46 | "ccxt_config": { 47 | "enableRateLimit": true 48 | }, 49 | "ccxt_async_config": { 50 | "enableRateLimit": true, 51 | "rateLimit": 100 52 | }, 53 | "pair_whitelist": [], 54 | "pair_blacklist": [ 55 | "BNB/BTC", 56 | "BUSD/USDT", 57 | "USDT/BUSD", 58 | "BNB*/.*", 59 | ".*BEAR/BUSD", 60 | ".*BULL/BUSD", 61 | ".*UP/BUSD", 62 | ".*DOWN/BUSD", 63 | ".*HEDGE/BUSD", 64 | "USDC/BUSD", 65 | "EUR/BUSD", 66 | "GBP/BUSD", 67 | "TUSD/BUSD" 68 | ] 69 | }, 70 | "pairlists": [ 71 | { 72 | "method": "VolumePairList", 73 | "number_assets": 25, 74 | "sort_key": "quoteVolume", 75 | "refresh_period": 1800 76 | }, 77 | { "method": "AgeFilter", "min_days_listed": 7 }, 78 | { "method": "SpreadFilter", "max_spread_ratio": 0.005 }, 79 | { "method": "PriceFilter", "min_price": 0.0001 }, 80 | { 81 | "method": "RangeStabilityFilter", 82 | "lookback_days": 3, 83 | "min_rate_of_change": 0.1, 84 | "refresh_period": 1440 85 | }, 86 | { 87 | "method": "VolatilityFilter", 88 | "lookback_days": 4, 89 | "min_volatility": 0.02, 90 | "max_volatility": 0.75, 91 | "refresh_period": 86400 92 | }, 93 | { "method": "ShuffleFilter", "seed": 42 } 94 | ], 95 | "edge": { 96 | "enabled": false, 97 | "process_throttle_secs": 3600, 98 | "calculate_since_number_of_days": 7, 99 | "allowed_risk": 0.01, 100 | "stoploss_range_min": -0.01, 101 | "stoploss_range_max": -0.1, 102 | "stoploss_range_step": -0.01, 103 | "minimum_winrate": 0.6, 104 | "minimum_expectancy": 0.2, 105 | "min_trade_number": 10, 106 | "max_trade_duration_minute": 1440, 107 | "remove_pumps": false 108 | }, 109 | "telegram": { 110 | "enabled": true, 111 | "token": "", 112 | "chat_id": "" 113 | }, 114 | "api_server": { 115 | "enabled": true, 116 | "listen_ip_address": "0.0.0.0", 117 | "listen_port": 8080, 118 | "verbosity": "error", 119 | "enable_openapi": false, 120 | "jwt_secret_key": "", 121 | "CORS_origins": [], 122 | "username": "username", 123 | "password": "password" 124 | }, 125 | "bot_name": "freqtrade", 126 | "initial_state": "running", 127 | "forcebuy_enable": true, 128 | "internals": { 129 | "process_throttle_secs": 5 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /user_data/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/data/.gitkeep -------------------------------------------------------------------------------- /user_data/hyperopt.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/hyperopt.lock -------------------------------------------------------------------------------- /user_data/hyperopt_results/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/hyperopt_results/.gitkeep -------------------------------------------------------------------------------- /user_data/hyperopts/AverageHyperopt.py: -------------------------------------------------------------------------------- 1 | import talib.abstract as ta 2 | from pandas import DataFrame 3 | from typing import Dict, Any, Callable, List 4 | from functools import reduce 5 | 6 | from skopt.space import Categorical, Dimension, Integer, Real 7 | 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | from freqtrade.optimize.hyperopt_interface import IHyperOpt 10 | 11 | shortRangeBegin = 10 12 | shortRangeEnd = 20 13 | mediumRangeBegin = 100 14 | mediumRangeEnd = 120 15 | 16 | 17 | class AverageHyperopt(IHyperOpt): 18 | """ 19 | Hyperopt file for optimizing AverageStrategy. 20 | Uses ranges of EMA periods to find the best parameter combination. 21 | """ 22 | 23 | @staticmethod 24 | def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: 25 | 26 | for short in range(shortRangeBegin, shortRangeEnd): 27 | dataframe[f'maShort({short})'] = ta.EMA(dataframe, timeperiod=short) 28 | 29 | for medium in range(mediumRangeBegin, mediumRangeEnd): 30 | dataframe[f'maMedium({medium})'] = ta.EMA(dataframe, timeperiod=medium) 31 | 32 | return dataframe 33 | 34 | @staticmethod 35 | def buy_strategy_generator(params: Dict[str, Any]) -> Callable: 36 | """ 37 | Define the buy strategy parameters to be used by hyperopt 38 | """ 39 | def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | """ 41 | Buy strategy Hyperopt will build and use 42 | """ 43 | conditions = [] 44 | # TRIGGERS 45 | if 'trigger' in params: 46 | trigger = [int(item) for item in params['trigger'].split('-')] 47 | 48 | conditions.append(qtpylib.crossed_above( 49 | dataframe[f"maShort({trigger[0]})"], 50 | dataframe[f"maMedium({trigger[1]})"]) 51 | ) 52 | 53 | # Check that volume is not 0 54 | conditions.append(dataframe['volume'] > 0) 55 | 56 | if conditions: 57 | dataframe.loc[ 58 | reduce(lambda x, y: x & y, conditions), 59 | 'buy'] = 1 60 | 61 | return dataframe 62 | 63 | return populate_buy_trend 64 | 65 | @staticmethod 66 | def indicator_space() -> List[Dimension]: 67 | """ 68 | Define your Hyperopt space for searching strategy parameters 69 | """ 70 | buyTriggerList = [] 71 | for short in range(shortRangeBegin, shortRangeEnd): 72 | for medium in range(mediumRangeBegin, mediumRangeEnd): 73 | """ 74 | The output will be '{short}-{long}' so we can split it on the trigger 75 | this will prevent an error on scikit-optimize not accepting tuples as 76 | first argument to Categorical 77 | """ 78 | buyTriggerList.append( 79 | '{}-{}'.format(short, medium) 80 | ) 81 | return [ 82 | Categorical(buyTriggerList, name='trigger') 83 | ] 84 | 85 | @staticmethod 86 | def sell_strategy_generator(params: Dict[str, Any]) -> Callable: 87 | """ 88 | Define the sell strategy parameters to be used by hyperopt 89 | """ 90 | def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 91 | """ 92 | Sell strategy Hyperopt will build and use 93 | """ 94 | # print(params) 95 | conditions = [] 96 | 97 | # TRIGGERS 98 | if 'sell-trigger' in params: 99 | trigger = [int(item) for item in params['sell-trigger'].split('-')] 100 | 101 | conditions.append(qtpylib.crossed_above( 102 | dataframe[f"maMedium({trigger[1]})"], 103 | dataframe[f"maShort({trigger[0]})"]) 104 | ) 105 | 106 | if conditions: 107 | dataframe.loc[ 108 | reduce(lambda x, y: x & y, conditions), 109 | 'sell'] = 1 110 | 111 | return dataframe 112 | 113 | return populate_sell_trend 114 | 115 | @staticmethod 116 | def sell_indicator_space() -> List[Dimension]: 117 | """ 118 | Define your Hyperopt space for searching sell strategy parameters 119 | """ 120 | sellTriggerList = [] 121 | for short in range(shortRangeBegin, shortRangeEnd): 122 | for medium in range(mediumRangeBegin, mediumRangeEnd): 123 | """ 124 | The output will be '{short}-{long}' so we can split it on the trigger 125 | this will prevent an error on scikit-optimize not accepting tuples as 126 | first argument to Categorical 127 | """ 128 | sellTriggerList.append( 129 | '{}-{}'.format(short, medium) 130 | ) 131 | 132 | return [ 133 | Categorical(sellTriggerList, name='sell-trigger') 134 | ] 135 | -------------------------------------------------------------------------------- /user_data/hyperopts/BinHV45HyperOpt.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | 3 | # --- Do not remove these libs --- 4 | from functools import reduce 5 | from typing import Any, Callable, Dict, List 6 | 7 | import numpy as np # noqa 8 | import pandas as pd # noqa 9 | from pandas import DataFrame 10 | from skopt.space import Categorical, Dimension, Integer, Real # noqa 11 | 12 | from freqtrade.optimize.hyperopt_interface import IHyperOpt 13 | 14 | # -------------------------------- 15 | # Add your lib to import here 16 | import talib.abstract as ta # noqa 17 | import freqtrade.vendor.qtpylib.indicators as qtpylib 18 | 19 | 20 | class BinHV45HyperOpt(IHyperOpt): 21 | """ 22 | Hyperopt file for optimizing BinHV45Strategy. 23 | Uses ranges to find best parameter combination for bbdelta, closedelta and tail 24 | of the buy strategy. 25 | 26 | Sell strategy is ignored, because it's ignored in BinHV45Strategy as well. 27 | This strategy therefor works without explicit sell signal therefor hyperopting 28 | for 'roi' is recommend as well 29 | 30 | Also, this is just ONE way to optimize this strategy - others might also include 31 | disabling certain conditions completely. This file is just a starting point, feel free 32 | to improve and PR. 33 | """ 34 | 35 | @staticmethod 36 | def buy_strategy_generator(params: Dict[str, Any]) -> Callable: 37 | """ 38 | Define the buy strategy parameters to be used by Hyperopt. 39 | """ 40 | def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 41 | """ 42 | Buy strategy Hyperopt will build and use. 43 | """ 44 | conditions = [] 45 | 46 | conditions.append(dataframe['lower'].shift().gt(0)) 47 | conditions.append(dataframe['bbdelta'].gt( 48 | dataframe['close'] * params['bbdelta'] / 1000)) 49 | conditions.append(dataframe['closedelta'].gt( 50 | dataframe['close'] * params['closedelta'] / 1000)) 51 | conditions.append(dataframe['tail'].lt(dataframe['bbdelta'] * params['tail'] / 1000)) 52 | conditions.append(dataframe['close'].lt(dataframe['lower'].shift())) 53 | conditions.append(dataframe['close'].le(dataframe['close'].shift())) 54 | 55 | # Check that the candle had volume 56 | conditions.append(dataframe['volume'] > 0) 57 | 58 | if conditions: 59 | dataframe.loc[ 60 | reduce(lambda x, y: x & y, conditions), 61 | 'buy'] = 1 62 | 63 | return dataframe 64 | 65 | return populate_buy_trend 66 | 67 | @staticmethod 68 | def indicator_space() -> List[Dimension]: 69 | """ 70 | Define your Hyperopt space for searching buy strategy parameters. 71 | """ 72 | return [ 73 | Integer(1, 15, name='bbdelta'), 74 | Integer(15, 20, name='closedelta'), 75 | Integer(20, 30, name='tail'), 76 | ] 77 | 78 | @staticmethod 79 | def sell_strategy_generator(params: Dict[str, Any]) -> Callable: 80 | """ 81 | Define the sell strategy parameters to be used by Hyperopt. 82 | """ 83 | def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 84 | """ 85 | no sell signal 86 | """ 87 | dataframe['sell'] = 0 88 | return dataframe 89 | 90 | return populate_sell_trend 91 | 92 | @staticmethod 93 | def sell_indicator_space() -> List[Dimension]: 94 | """ 95 | Define your Hyperopt space for searching sell strategy parameters. 96 | """ 97 | return [] 98 | -------------------------------------------------------------------------------- /user_data/hyperopts/HeraclesHo.py: -------------------------------------------------------------------------------- 1 | # Heracles Strategy Hyperopt 2 | # Author: @Mablue (Masoud Azizi) 3 | # github: https://github.com/mablue/ 4 | # IMPORTANT: INSTALL TA BEFOUR RUN: 5 | # :~$ pip install ta 6 | # freqtrade hyperopt --hyperopt GodStraHo --hyperopt-loss SharpeHyperOptLossDaily --gene all --strategy GodStra --config config.json -e 100 7 | 8 | # --- Do not remove these libs --- 9 | from functools import reduce 10 | from typing import Any, Callable, Dict, List 11 | 12 | import numpy as np # noqa 13 | import pandas as pd # noqa 14 | from pandas import DataFrame 15 | from skopt.space import Categorical, Dimension, Integer, Real # noqa 16 | 17 | from freqtrade.optimize.hyperopt_interface import IHyperOpt 18 | 19 | # -------------------------------- 20 | # Add your lib to import here 21 | # import talib.abstract as ta # noqa 22 | from ta import add_all_ta_features 23 | from ta.utils import dropna 24 | import freqtrade.vendor.qtpylib.indicators as qtpylib 25 | # this is your trading strategy DNA Size 26 | # you can change it and see the results... 27 | 28 | 29 | class HeraclesHo(IHyperOpt): 30 | 31 | @staticmethod 32 | def indicator_space() -> List[Dimension]: 33 | """ 34 | Define your Hyperopt space for searching buy strategy parameters. 35 | """ 36 | 37 | return [ 38 | Real(-0.1, 1.1, name='buy-div'), 39 | Integer(0, 5, name='DFINDShift'), 40 | Integer(0, 5, name='DFCRSShift'), 41 | ] 42 | 43 | @staticmethod 44 | def buy_strategy_generator(params: Dict[str, Any]) -> Callable: 45 | """ 46 | Define the buy strategy parameters to be used by Hyperopt. 47 | """ 48 | def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 49 | """ 50 | Buy strategy Hyperopt will build and use. 51 | """ 52 | conditions = [] 53 | 54 | IND = 'volatility_dcp' 55 | CRS = 'volatility_kcw' 56 | DFIND = dataframe[IND] 57 | DFCRS = dataframe[CRS] 58 | 59 | conditions.append( 60 | DFIND.shift(params['DFINDShift']).div( 61 | DFCRS.shift(params['DFCRSShift']) 62 | ) <= params['buy-div'] 63 | ) 64 | 65 | if conditions: 66 | dataframe.loc[ 67 | reduce(lambda x, y: x & y, conditions), 68 | 'buy'] = 1 69 | 70 | return dataframe 71 | 72 | return populate_buy_trend 73 | 74 | @ staticmethod 75 | def sell_indicator_space() -> List[Dimension]: 76 | """ 77 | Define your Hyperopt space for searching sell strategy parameters. 78 | """ 79 | return [ 80 | Real(1.e-10, 1.e-0, name='sell-rtol'), 81 | Real(1.e-16, 1.e-0, name='sell-atol'), 82 | Integer(0, 5, name='DFINDShift'), 83 | Integer(0, 5, name='DFCRSShift'), 84 | ] 85 | 86 | @ staticmethod 87 | def sell_strategy_generator(params: Dict[str, Any]) -> Callable: 88 | """ 89 | Define the sell strategy parameters to be used by Hyperopt. 90 | """ 91 | def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 92 | """ 93 | Sell strategy Hyperopt will build and use. 94 | """ 95 | conditions = [] 96 | 97 | IND = 'trend_ema_fast' 98 | CRS = 'trend_macd_signal' 99 | DFIND = dataframe[IND] 100 | DFCRS = dataframe[CRS] 101 | 102 | conditions.append( 103 | np.isclose( 104 | DFIND.shift(params['DFINDShift']), 105 | DFCRS.shift(params['DFCRSShift']), 106 | rtol=params['sell-rtol'], 107 | atol=params['sell-atol'] 108 | ) 109 | ) 110 | 111 | if conditions: 112 | dataframe.loc[ 113 | reduce(lambda x, y: x & y, conditions), 114 | 'sell']=1 115 | 116 | return dataframe 117 | 118 | return populate_sell_trend 119 | -------------------------------------------------------------------------------- /user_data/hyperopts/MACDStrategy_hyperopt.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | 3 | import talib.abstract as ta 4 | from pandas import DataFrame 5 | from typing import Dict, Any, Callable, List 6 | 7 | # import numpy as np 8 | from skopt.space import Categorical, Dimension, Integer, Real 9 | 10 | # import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | from freqtrade.optimize.hyperopt_interface import IHyperOpt 12 | 13 | class_name = 'MACDStrategy_hyperopt' 14 | 15 | 16 | # This class is a sample. Feel free to customize it. 17 | class MACDStrategy_hyperopt(IHyperOpt): 18 | """ 19 | This is an Example hyperopt to inspire you. - corresponding to MACDStrategy in this repository. 20 | 21 | To run this, best use the following command (adjust to your environment if needed): 22 | ``` 23 | freqtrade hyperopt --strategy MACDStrategy --hyperopt MACDStrategy_hyperopt --spaces buy sell 24 | ``` 25 | The idea is to optimize only the CCI value. 26 | - Buy side: CCI between -700 and 0 27 | - Sell side: CCI between 0 and 700 28 | 29 | More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md 30 | """ 31 | 32 | @staticmethod 33 | def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: 34 | 35 | macd = ta.MACD(dataframe) 36 | dataframe['macd'] = macd['macd'] 37 | dataframe['macdsignal'] = macd['macdsignal'] 38 | dataframe['macdhist'] = macd['macdhist'] 39 | dataframe['cci'] = ta.CCI(dataframe) 40 | 41 | return dataframe 42 | 43 | @staticmethod 44 | def buy_strategy_generator(params: Dict[str, Any]) -> Callable: 45 | """ 46 | Define the buy strategy parameters to be used by hyperopt 47 | """ 48 | def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 49 | """ 50 | Buy strategy Hyperopt will build and use 51 | """ 52 | dataframe.loc[ 53 | ( 54 | (dataframe['macd'] > dataframe['macdsignal']) & 55 | (dataframe['cci'] <= params['buy-cci-value']) & 56 | (dataframe['volume'] > 0) # Make sure Volume is not 0 57 | ), 58 | 'buy'] = 1 59 | 60 | return dataframe 61 | 62 | return populate_buy_trend 63 | 64 | @staticmethod 65 | def indicator_space() -> List[Dimension]: 66 | """ 67 | Define your Hyperopt space for searching strategy parameters 68 | """ 69 | return [ 70 | Integer(-700, 0, name='buy-cci-value'), 71 | ] 72 | 73 | @staticmethod 74 | def sell_strategy_generator(params: Dict[str, Any]) -> Callable: 75 | """ 76 | Define the sell strategy parameters to be used by hyperopt 77 | """ 78 | def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: 79 | """ 80 | Sell strategy Hyperopt will build and use 81 | """ 82 | dataframe.loc[ 83 | ( 84 | (dataframe['macd'] < dataframe['macdsignal']) & 85 | (dataframe['cci'] >= params['sell-cci-value']) 86 | ), 87 | 'sell'] = 1 88 | 89 | return dataframe 90 | 91 | return populate_sell_trend 92 | 93 | @staticmethod 94 | def sell_indicator_space() -> List[Dimension]: 95 | """ 96 | Define your Hyperopt space for searching sell strategy parameters 97 | """ 98 | return [ 99 | Integer(0, 700, name='sell-cci-value'), 100 | ] 101 | -------------------------------------------------------------------------------- /user_data/hyperopts/sample_hyperopt_loss.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from math import exp 3 | from typing import Dict 4 | 5 | from pandas import DataFrame 6 | 7 | from freqtrade.optimize.hyperopt import IHyperOptLoss 8 | 9 | 10 | # Define some constants: 11 | 12 | # set TARGET_TRADES to suit your number concurrent trades so its realistic 13 | # to the number of days 14 | TARGET_TRADES = 600 15 | # This is assumed to be expected avg profit * expected trade count. 16 | # For example, for 0.35% avg per trade (or 0.0035 as ratio) and 1100 trades, 17 | # self.expected_max_profit = 3.85 18 | # Check that the reported Σ% values do not exceed this! 19 | # Note, this is ratio. 3.85 stated above means 385Σ%. 20 | EXPECTED_MAX_PROFIT = 3.0 21 | 22 | # max average trade duration in minutes 23 | # if eval ends with higher value, we consider it a failed eval 24 | MAX_ACCEPTED_TRADE_DURATION = 300 25 | 26 | 27 | class SampleHyperOptLoss(IHyperOptLoss): 28 | """ 29 | Defines the default loss function for hyperopt 30 | This is intended to give you some inspiration for your own loss function. 31 | 32 | The Function needs to return a number (float) - which becomes smaller for better backtest 33 | results. 34 | """ 35 | 36 | @staticmethod 37 | def hyperopt_loss_function(results: DataFrame, trade_count: int, 38 | min_date: datetime, max_date: datetime, 39 | config: Dict, processed: Dict[str, DataFrame], 40 | *args, **kwargs) -> float: 41 | """ 42 | Objective function, returns smaller number for better results 43 | """ 44 | total_profit = results['profit_ratio'].sum() 45 | trade_duration = results['trade_duration'].mean() 46 | 47 | trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8) 48 | profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT) 49 | duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1) 50 | result = trade_loss + profit_loss + duration_loss 51 | return result 52 | -------------------------------------------------------------------------------- /user_data/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/logs/.gitkeep -------------------------------------------------------------------------------- /user_data/plot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/plot/.gitkeep -------------------------------------------------------------------------------- /user_data/strategies.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrgolfprat/ft_sample/d24c79b0d852e13757c6d523524b1660b19ec6e6/user_data/strategies.zip -------------------------------------------------------------------------------- /user_data/strategies/ADXMomentum.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | 6 | 7 | # -------------------------------- 8 | 9 | 10 | class ADXMomentum(IStrategy): 11 | """ 12 | 13 | author@: Gert Wohlgemuth 14 | 15 | converted from: 16 | 17 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/AdxMomentum.cs 18 | 19 | """ 20 | 21 | # Minimal ROI designed for the strategy. 22 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 23 | # This attribute will be overridden if the config file contains "minimal_roi" 24 | minimal_roi = { 25 | "0": 0.01 26 | } 27 | 28 | # Optimal stoploss designed for the strategy 29 | stoploss = -0.25 30 | 31 | # Optimal timeframe for the strategy 32 | timeframe = '1h' 33 | 34 | # Number of candles the strategy requires before producing valid signals 35 | startup_candle_count: int = 20 36 | 37 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 38 | dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) 39 | dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=25) 40 | dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=25) 41 | dataframe['sar'] = ta.SAR(dataframe) 42 | dataframe['mom'] = ta.MOM(dataframe, timeperiod=14) 43 | 44 | return dataframe 45 | 46 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | dataframe.loc[ 48 | ( 49 | (dataframe['adx'] > 25) & 50 | (dataframe['mom'] > 0) & 51 | (dataframe['plus_di'] > 25) & 52 | (dataframe['plus_di'] > dataframe['minus_di']) 53 | 54 | ), 55 | 'buy'] = 1 56 | return dataframe 57 | 58 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 59 | dataframe.loc[ 60 | ( 61 | (dataframe['adx'] > 25) & 62 | (dataframe['mom'] < 0) & 63 | (dataframe['minus_di'] > 25) & 64 | (dataframe['plus_di'] < dataframe['minus_di']) 65 | 66 | ), 67 | 'sell'] = 1 68 | return dataframe 69 | -------------------------------------------------------------------------------- /user_data/strategies/AiewStra.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | # flake8: noqa: F401 3 | 4 | # --- Do not remove these libs --- 5 | import numpy as np # noqa 6 | import pandas as pd # noqa 7 | from pandas import DataFrame 8 | 9 | from freqtrade.strategy import IStrategy 10 | from freqtrade.strategy import CategoricalParameter, DecimalParameter, IntParameter 11 | 12 | # -------------------------------- 13 | # Add your lib to import here 14 | import talib.abstract as ta 15 | import freqtrade.vendor.qtpylib.indicators as qtpylib 16 | import numpy # noqa 17 | from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter 18 | 19 | 20 | def EWO(dataframe, ema_length=5, ema2_length=35): 21 | df = dataframe.copy() 22 | ema1 = ta.EMA(df, timeperiod=ema_length) 23 | ema2 = ta.EMA(df, timeperiod=ema2_length) 24 | emadif = (ema1 - ema2) / df['close'] * 100 25 | return emadif 26 | 27 | 28 | class AiewStra(IStrategy): 29 | """ 30 | This is a strategy template to get you started. 31 | More information in https://www.freqtrade.io/en/latest/strategy-customization/ 32 | 33 | You can: 34 | :return: a Dataframe with all mandatory indicators for the strategies 35 | - Rename the class name (Do not forget to update class_name) 36 | - Add any methods you want to build your strategy 37 | - Add any lib you need to build your strategy 38 | 39 | You must keep: 40 | - the lib in the section "Do not remove these libs" 41 | - the methods: populate_indicators, populate_buy_trend, populate_sell_trend 42 | You should keep: 43 | - timeframe, minimal_roi, stoploss, trailing_* 44 | """ 45 | # Strategy interface version - allow new iterations of the strategy interface. 46 | # Check the documentation or the Sample strategy to get the latest version. 47 | INTERFACE_VERSION = 2 48 | 49 | # Minimal ROI designed for the strategy. 50 | # This attribute will be overridden if the config file contains "minimal_roi". 51 | minimal_roi = { 52 | "30": 0.01, 53 | "20": 0.014, 54 | "10": 0.025, 55 | "0": 0.03 56 | } 57 | 58 | # Optimal stoploss designed for the strategy. 59 | # This attribute will be overridden if the config file contains "stoploss". 60 | stoploss = -0.035 61 | # Trailing stoploss 62 | trailing_stop = True 63 | trailing_only_offset_is_reached = True 64 | trailing_stop_positive = 0.02 65 | trailing_stop_positive_offset = 0.04 # Disabled / not configured 66 | 67 | # Optimal timeframe for the strategy. 68 | timeframe = '5m' 69 | 70 | # Run "populate_indicators()" only for new candle. 71 | process_only_new_candles = False 72 | 73 | # These values can be overridden in the "ask_strategy" section in the config. 74 | use_sell_signal = False 75 | sell_profit_only = True 76 | ignore_roi_if_buy_signal = False 77 | 78 | # Number of candles the strategy requires before producing valid signals 79 | startup_candle_count: int = 30 80 | 81 | # Optional order type mapping. 82 | order_types = { 83 | 'buy': 'limit', 84 | 'sell': 'limit', 85 | 'trailing_stop_loss': 'limit', 86 | 'stoploss': 'limit', 87 | 'stoploss_on_exchange': False 88 | } 89 | 90 | # Optional order time in force. 91 | order_time_in_force = { 92 | 'buy': 'gtc', 93 | 'sell': 'gtc' 94 | } 95 | 96 | plot_config = { 97 | # Main plot indicators (Moving averages, ...) 98 | 'main_plot': { 99 | 'tema': {}, 100 | 'sar': {'color': 'white'}, 101 | }, 102 | 'subplots': { 103 | # Subplots - each dict defines one additional plot 104 | "MACD": { 105 | 'macd': {'color': 'blue'}, 106 | 'macdsignal': {'color': 'orange'}, 107 | }, 108 | "RSI": { 109 | 'rsi': {'color': 'red'}, 110 | } 111 | } 112 | } 113 | 114 | # BBPeriod 115 | 116 | def informative_pairs(self): 117 | 118 | return [] 119 | 120 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 121 | 122 | return dataframe 123 | 124 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 125 | 126 | dataframe.loc[ 127 | ( 128 | 129 | ), 130 | 'buy'] = 1 131 | 132 | return dataframe 133 | 134 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 135 | 136 | dataframe.loc[ 137 | ( 138 | dataframe['sell_signal'] 139 | ), 140 | 'sell'] = 1 141 | return dataframe 142 | -------------------------------------------------------------------------------- /user_data/strategies/BbandRsi.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | import freqtrade.vendor.qtpylib.indicators as qtpylib 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class BbandRsi(IStrategy): 12 | """ 13 | 14 | author@: Gert Wohlgemuth 15 | 16 | converted from: 17 | 18 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/BbandRsi.cs 19 | 20 | """ 21 | 22 | # Minimal ROI designed for the strategy. 23 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.015 27 | } 28 | 29 | # Optimal stoploss designed for the strategy 30 | stoploss = -0.03 31 | 32 | # Optimal timeframe for the strategy 33 | timeframe = '1h' 34 | startup_candle_count: int = 14 35 | 36 | offset = 14 37 | 38 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 39 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 40 | 41 | # Bollinger bands 42 | bollinger = qtpylib.bollinger_bands( 43 | qtpylib.typical_price(dataframe), window=20, stds=2) 44 | dataframe['bb_lowerband'] = bollinger['lower'] 45 | dataframe['bb_middleband'] = bollinger['mid'] 46 | dataframe['bb_upperband'] = bollinger['upper'] 47 | dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) 48 | 49 | dataframe["price_up"] = dataframe.at[self.offset, "close"] 50 | 51 | return dataframe 52 | 53 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 54 | dataframe.loc[ 55 | ( 56 | (dataframe['rsi'] < 30) & 57 | (dataframe['close'] < dataframe['bb_lowerband']) 58 | 59 | ), 60 | 'buy'] = 1 61 | return dataframe 62 | 63 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 64 | dataframe.loc[ 65 | ( 66 | (dataframe['rsi'] > 70) 67 | 68 | ), 69 | 'sell'] = 1 70 | return dataframe 71 | -------------------------------------------------------------------------------- /user_data/strategies/BearBull3.py: -------------------------------------------------------------------------------- 1 | from freqtrade.strategy import IStrategy, merge_informative_pair 2 | from pandas import DataFrame 3 | import talib.abstract as ta 4 | 5 | # based on BinHV45 strategy: https://github.com/freqtrade/freqtrade-strategies/blob/master/user_data/strategies/berlinguyinca/BinHV45.py 6 | # use at own risk 7 | 8 | class BearBull3(IStrategy): 9 | 10 | timeframe = '3m' # works best on short timeframes 3 or 5 min 11 | 12 | minimal_roi = { 13 | "0": 0.15, 14 | } 15 | 16 | stoploss = -0.15 17 | 18 | trailing_stop = True 19 | trailing_stop_positive = 0.005 20 | trailing_stop_positive_offset = 0.015 21 | trailing_only_offset_is_reached = True 22 | 23 | startup_candle_count = 200 24 | 25 | def informative_pairs(self): 26 | 27 | pairs = self.dp.current_whitelist() 28 | informative_pairs = [(pair, '2h') for pair in pairs] 29 | return informative_pairs 30 | 31 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 32 | 33 | # macd timeframe for trend detection 34 | macd_df = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='2h') 35 | macd_df['macdhist'] = ta.MACD(macd_df, fastperiod=10, slowperiod=20, signalperiod=10)['macdhist'] 36 | dataframe = merge_informative_pair(dataframe, macd_df, self.timeframe, '2h', ffill=True) 37 | 38 | # normal timeframe 39 | bb = ta.BBANDS(dataframe, timeperiod=40, nbdevup=2.0, nbdevdn=2.0) 40 | dataframe['mid'] = bb['middleband'] 41 | dataframe['lower'] = bb['lowerband'] 42 | dataframe['bbdelta'] = (dataframe['mid'] - dataframe['lower']).abs() 43 | # dataframe['pricedelta'] = (dataframe['open'] - dataframe['close']).abs() 44 | dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() 45 | dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs() 46 | return dataframe 47 | 48 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 49 | dataframe.loc[ 50 | ( 51 | ( 52 | ( 53 | dataframe['macdhist_2h'].lt(0) #Bear 54 | & 55 | dataframe['lower'].shift().gt(0) 56 | & 57 | dataframe['bbdelta'].gt(dataframe['close'] * 0.014) 58 | & 59 | dataframe['closedelta'].gt(dataframe['close'] * 0.008) 60 | & 61 | dataframe['tail'].lt(dataframe['bbdelta'] * 0.23) 62 | & 63 | dataframe['close'].lt(dataframe['lower'].shift()) 64 | & 65 | dataframe['close'].le(dataframe['close'].shift()) 66 | ) 67 | | 68 | ( 69 | dataframe['macdhist_2h'].gt(0) # Bull 70 | & 71 | dataframe['lower'].shift().gt(0) 72 | & 73 | dataframe['bbdelta'].gt(dataframe['close'] * 0.035) 74 | & 75 | dataframe['closedelta'].gt(dataframe['close'] * 0.007) 76 | & 77 | dataframe['tail'].lt(dataframe['bbdelta'] * 0.2) 78 | & 79 | dataframe['close'].lt(dataframe['lower'].shift()) 80 | & 81 | dataframe['close'].le(dataframe['close'].shift()) 82 | ) 83 | ) 84 | & 85 | (dataframe['volume'] > 0) 86 | ), 87 | 'buy'] = 1 88 | return dataframe 89 | 90 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 91 | """ 92 | no sell signal 93 | """ 94 | dataframe['sell'] = 0 95 | return dataframe 96 | -------------------------------------------------------------------------------- /user_data/strategies/CCIStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame, Series, DatetimeIndex, merge 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | 11 | 12 | class CCIStrategy(IStrategy): 13 | # Minimal ROI designed for the strategy. 14 | # This attribute will be overridden if the config file contains "minimal_roi" 15 | minimal_roi = { 16 | "0": 0.1 17 | } 18 | 19 | # Optimal stoploss designed for the strategy 20 | # This attribute will be overridden if the config file contains "stoploss" 21 | stoploss = -0.02 22 | 23 | # Optimal timeframe for the strategy 24 | timeframe = '1m' 25 | 26 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 27 | dataframe = self.resample(dataframe, self.timeframe, 5) 28 | 29 | dataframe['cci_one'] = ta.CCI(dataframe, timeperiod=170) 30 | dataframe['cci_two'] = ta.CCI(dataframe, timeperiod=34) 31 | dataframe['rsi'] = ta.RSI(dataframe) 32 | dataframe['mfi'] = ta.MFI(dataframe) 33 | 34 | dataframe['cmf'] = self.chaikin_mf(dataframe) 35 | 36 | # required for graphing 37 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 38 | dataframe['bb_lowerband'] = bollinger['lower'] 39 | dataframe['bb_upperband'] = bollinger['upper'] 40 | dataframe['bb_middleband'] = bollinger['mid'] 41 | 42 | return dataframe 43 | 44 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 45 | """ 46 | Based on TA indicators, populates the buy signal for the given dataframe 47 | :param dataframe: DataFrame 48 | :return: DataFrame with buy column 49 | """ 50 | dataframe.loc[ 51 | ( 52 | (dataframe['cci_one'] < -100) 53 | & (dataframe['cci_two'] < -100) 54 | & (dataframe['cmf'] < -0.1) 55 | & (dataframe['mfi'] < 25) 56 | 57 | # insurance 58 | & (dataframe['resample_medium'] > dataframe['resample_short']) 59 | & (dataframe['resample_long'] < dataframe['close']) 60 | 61 | ), 62 | 'buy'] = 1 63 | 64 | return dataframe 65 | 66 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 67 | """ 68 | Based on TA indicators, populates the sell signal for the given dataframe 69 | :param dataframe: DataFrame 70 | :return: DataFrame with buy column 71 | """ 72 | dataframe.loc[ 73 | ( 74 | (dataframe['cci_one'] > 100) 75 | & (dataframe['cci_two'] > 100) 76 | & (dataframe['cmf'] > 0.3) 77 | & (dataframe['resample_sma'] < dataframe['resample_medium']) 78 | & (dataframe['resample_medium'] < dataframe['resample_short']) 79 | 80 | ), 81 | 'sell'] = 1 82 | return dataframe 83 | 84 | def chaikin_mf(self, df, periods=20): 85 | close = df['close'] 86 | low = df['low'] 87 | high = df['high'] 88 | volume = df['volume'] 89 | 90 | mfv = ((close - low) - (high - close)) / (high - low) 91 | mfv = mfv.fillna(0.0) # float division by zero 92 | mfv *= volume 93 | cmf = mfv.rolling(periods).sum() / volume.rolling(periods).sum() 94 | 95 | return Series(cmf, name='cmf') 96 | 97 | def resample(self, dataframe, interval, factor): 98 | # defines the reinforcement logic 99 | # resampled dataframe to establish if we are in an uptrend, downtrend or sideways trend 100 | df = dataframe.copy() 101 | df = df.set_index(DatetimeIndex(df['date'])) 102 | ohlc_dict = { 103 | 'open': 'first', 104 | 'high': 'max', 105 | 'low': 'min', 106 | 'close': 'last' 107 | } 108 | df = df.resample(str(int(interval[:-1]) * factor) + 'min', label="right").agg(ohlc_dict) 109 | df['resample_sma'] = ta.SMA(df, timeperiod=100, price='close') 110 | df['resample_medium'] = ta.SMA(df, timeperiod=50, price='close') 111 | df['resample_short'] = ta.SMA(df, timeperiod=25, price='close') 112 | df['resample_long'] = ta.SMA(df, timeperiod=200, price='close') 113 | df = df.drop(columns=['open', 'high', 'low', 'close']) 114 | df = df.resample(interval[:-1] + 'min') 115 | df = df.interpolate(method='time') 116 | df['date'] = df.index 117 | df.index = range(len(df)) 118 | dataframe = merge(dataframe, df, on='date', how='left') 119 | return dataframe 120 | -------------------------------------------------------------------------------- /user_data/strategies/CMCWinner.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from pandas import DataFrame 5 | # -------------------------------- 6 | 7 | # Add your lib to import here 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | import numpy # noqa 11 | 12 | 13 | # This class is a sample. Feel free to customize it. 14 | class CMCWinner(IStrategy): 15 | """ 16 | This is a test strategy to inspire you. 17 | More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md 18 | 19 | You can: 20 | - Rename the class name (Do not forget to update class_name) 21 | - Add any methods you want to build your strategy 22 | - Add any lib you need to build your strategy 23 | 24 | You must keep: 25 | - the lib in the section "Do not remove these libs" 26 | - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, 27 | populate_sell_trend, hyperopt_space, buy_strategy_generator 28 | """ 29 | 30 | # Minimal ROI designed for the strategy. 31 | # This attribute will be overridden if the config file contains "minimal_roi" 32 | minimal_roi = { 33 | "40": 0.0, 34 | "30": 0.02, 35 | "20": 0.03, 36 | "0": 0.05 37 | } 38 | 39 | # Optimal stoploss designed for the strategy 40 | # This attribute will be overridden if the config file contains "stoploss" 41 | stoploss = -0.05 42 | 43 | # Optimal timeframe for the strategy 44 | timeframe = '15m' 45 | 46 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | """ 48 | Adds several different TA indicators to the given DataFrame 49 | 50 | Performance Note: For the best performance be frugal on the number of indicators 51 | you are using. Let uncomment only the indicator you are using in your strategies 52 | or your hyperopt configuration, otherwise you will waste your memory and CPU usage. 53 | """ 54 | 55 | # Commodity Channel Index: values Oversold:<-100, Overbought:>100 56 | dataframe['cci'] = ta.CCI(dataframe) 57 | 58 | # MFI 59 | dataframe['mfi'] = ta.MFI(dataframe) 60 | 61 | # CMO 62 | dataframe['cmo'] = ta.CMO(dataframe) 63 | 64 | return dataframe 65 | 66 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 67 | """ 68 | Based on TA indicators, populates the buy signal for the given dataframe 69 | :param dataframe: DataFrame 70 | :return: DataFrame with buy column 71 | """ 72 | dataframe.loc[ 73 | ( 74 | (dataframe['cci'].shift(1) < -100) & 75 | (dataframe['mfi'].shift(1) < 20) & 76 | (dataframe['cmo'].shift(1) < -50) 77 | ), 78 | 'buy'] = 1 79 | 80 | return dataframe 81 | 82 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 83 | """ 84 | Based on TA indicators, populates the sell signal for the given dataframe 85 | :param dataframe: DataFrame 86 | :return: DataFrame with buy column 87 | """ 88 | dataframe.loc[ 89 | ( 90 | (dataframe['cci'].shift(1) > 100) & 91 | (dataframe['mfi'].shift(1) > 80) & 92 | (dataframe['cmo'].shift(1) > 50) 93 | ), 94 | 'sell'] = 1 95 | return dataframe 96 | -------------------------------------------------------------------------------- /user_data/strategies/CofiBitStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | import freqtrade.vendor.qtpylib.indicators as qtpylib 3 | import talib.abstract as ta 4 | from freqtrade.strategy.interface import IStrategy 5 | from pandas import DataFrame 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class CofiBitStrategy(IStrategy): 12 | """ 13 | taken from slack by user CofiBit 14 | """ 15 | 16 | # Minimal ROI designed for the strategy. 17 | # This attribute will be overridden if the config file contains "minimal_roi" 18 | minimal_roi = { 19 | "40": 0.05, 20 | "30": 0.06, 21 | "20": 0.07, 22 | "0": 0.10 23 | } 24 | 25 | # Optimal stoploss designed for the strategy 26 | # This attribute will be overridden if the config file contains "stoploss" 27 | stoploss = -0.25 28 | 29 | # Optimal timeframe for the strategy 30 | timeframe = '5m' 31 | 32 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 33 | stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) 34 | dataframe['fastd'] = stoch_fast['fastd'] 35 | dataframe['fastk'] = stoch_fast['fastk'] 36 | dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') 37 | dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') 38 | dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') 39 | dataframe['adx'] = ta.ADX(dataframe) 40 | 41 | return dataframe 42 | 43 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 44 | """ 45 | Based on TA indicators, populates the buy signal for the given dataframe 46 | :param dataframe: DataFrame 47 | :return: DataFrame with buy column 48 | """ 49 | dataframe.loc[ 50 | ( 51 | (dataframe['open'] < dataframe['ema_low']) & 52 | (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) & 53 | # (dataframe['fastk'] > dataframe['fastd']) & 54 | (dataframe['fastk'] < 30) & 55 | (dataframe['fastd'] < 30) & 56 | (dataframe['adx'] > 30) 57 | ), 58 | 'buy'] = 1 59 | 60 | return dataframe 61 | 62 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 63 | """ 64 | Based on TA indicators, populates the sell signal for the given dataframe 65 | :param dataframe: DataFrame 66 | :return: DataFrame with buy column 67 | """ 68 | dataframe.loc[ 69 | ( 70 | (dataframe['open'] >= dataframe['ema_high']) 71 | ) | 72 | ( 73 | # (dataframe['fastk'] > 70) & 74 | # (dataframe['fastd'] > 70) 75 | (qtpylib.crossed_above(dataframe['fastk'], 70)) | 76 | (qtpylib.crossed_above(dataframe['fastd'], 70)) 77 | ), 78 | 'sell'] = 1 79 | 80 | return dataframe 81 | -------------------------------------------------------------------------------- /user_data/strategies/DoubleEMACrossoverWithTrend.py: -------------------------------------------------------------------------------- 1 | from freqtrade.strategy import IStrategy, merge_informative_pair 2 | from pandas import DataFrame 3 | import talib.abstract as ta 4 | import freqtrade.vendor.qtpylib.indicators as qtpylib 5 | import numpy # noqa 6 | 7 | 8 | class DoubleEMACrossoverWithTrend(IStrategy): 9 | 10 | """ 11 | DoubleEMACrossoverWithTrend 12 | author@: Paul Csapak 13 | github@: https://github.com/paulcpk/freqtrade-strategies-that-work 14 | 15 | How to use it? 16 | 17 | > freqtrade download-data --timeframes 1h --timerange=20180301-20200301 18 | > freqtrade backtesting --export trades -s DoubleEMACrossoverWithTrend --timeframe 1h --timerange=20180301-20200301 19 | > freqtrade plot-dataframe -s DoubleEMACrossoverWithTrend --indicators1 ema200 --timeframe 1h --timerange=20180301-20200301 20 | 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | # minimal_roi = { 26 | # "40": 0.0, 27 | # "30": 0.01, 28 | # "20": 0.02, 29 | # "0": 0.04 30 | # } 31 | 32 | # This attribute will be overridden if the config file contains "stoploss" 33 | stoploss = -0.2 34 | 35 | # Optimal timeframe for the strategy 36 | timeframe = '1h' 37 | 38 | # trailing stoploss 39 | trailing_stop = False 40 | trailing_stop_positive = 0.03 41 | trailing_stop_positive_offset = 0.04 42 | 43 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 44 | 45 | dataframe['ema9'] = ta.EMA(dataframe, timeperiod=9) 46 | dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21) 47 | dataframe['ema200'] = ta.EMA(dataframe, timeperiod=200) 48 | 49 | return dataframe 50 | 51 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 52 | 53 | dataframe.loc[ 54 | ( 55 | # fast ema crosses above slow ema 56 | (qtpylib.crossed_above(dataframe['ema9'], dataframe['ema21'])) & 57 | # Candle low is above EMA 58 | (dataframe['low'] > dataframe['ema200']) & 59 | # Ensure this candle had volume (important for backtesting) 60 | (dataframe['volume'] > 0) 61 | ), 62 | 'buy'] = 1 63 | return dataframe 64 | 65 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 66 | 67 | dataframe.loc[ 68 | ( 69 | # fast ema crosses below slow ema 70 | (qtpylib.crossed_below(dataframe['ema9'], dataframe['ema21'])) | 71 | # OR price is below trend ema 72 | (dataframe['low'] < dataframe['ema200']) 73 | ), 74 | 'sell'] = 1 75 | return dataframe 76 | -------------------------------------------------------------------------------- /user_data/strategies/Heracles.py: -------------------------------------------------------------------------------- 1 | # Heracles Strategy: Strongest Son of GodStra 2 | # ( With just 1 Genome! its a bacteria :D ) 3 | # Author: @Mablue (Masoud Azizi) 4 | # github: https://github.com/mablue/ 5 | # IMPORTANT:Add to your pairlists inside config.json (Under StaticPairList): 6 | # { 7 | # "method": "AgeFilter", 8 | # "min_days_listed": 100 9 | # }, 10 | # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) 11 | # ###################################################################### 12 | # Optimal config settings: 13 | # "max_open_trades": 100, 14 | # "stake_amount": "unlimited", 15 | 16 | # --- Do not remove these libs --- 17 | import logging 18 | 19 | from numpy.lib import math 20 | from freqtrade.strategy.interface import IStrategy 21 | from pandas import DataFrame 22 | # -------------------------------- 23 | 24 | # Add your lib to import here 25 | # import talib.abstract as ta 26 | import pandas as pd 27 | import ta 28 | from ta.utils import dropna 29 | import freqtrade.vendor.qtpylib.indicators as qtpylib 30 | from functools import reduce 31 | import numpy as np 32 | 33 | 34 | class Heracles(IStrategy): 35 | # 65/600: 2275 trades. 1438/7/830 W/D/L. 36 | # Avg profit 3.10%. Median profit 3.06%. 37 | # Total profit 113171 USDT ( 7062 Σ%). 38 | # Avg duration 345 min. Objective: -23.0 39 | 40 | # Buy hyperspace params: 41 | buy_params = { 42 | 'buy-cross-0': 'volatility_kcw', 43 | 'buy-indicator-0': 'volatility_dcp', 44 | 'buy-oper-0': '<', 45 | } 46 | 47 | # Sell hyperspace params: 48 | sell_params = { 49 | 'sell-cross-0': 'trend_macd_signal', 50 | 'sell-indicator-0': 'trend_ema_fast', 51 | 'sell-oper-0': '=', 52 | } 53 | 54 | # ROI table: 55 | minimal_roi = {"0": 0.15058, "33": 0.0433, "64": 0.0233, } 56 | 57 | # Stoploss: 58 | stoploss = -0.34338/2 59 | 60 | # Trailing stop: 61 | trailing_stop = True 62 | trailing_stop_positive = 0.02444 63 | trailing_stop_positive_offset = 0.04406 64 | trailing_only_offset_is_reached = True 65 | 66 | # Buy hypers 67 | timeframe = '1h' 68 | 69 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 70 | # Add all ta features 71 | # dataframe = dropna(dataframe) 72 | 73 | dataframe['volatility_kcw'] = ta.volatility.keltner_channel_wband( 74 | dataframe['high'], 75 | dataframe['low'], 76 | dataframe['close'], 77 | window=20, 78 | window_atr=10, 79 | fillna=False, 80 | original_version=True 81 | ) 82 | dataframe['volatility_dcp'] = ta.volatility.donchian_channel_pband( 83 | dataframe['high'], 84 | dataframe['low'], 85 | dataframe['close'], 86 | window=10, 87 | offset=0, 88 | fillna=False 89 | ) 90 | dataframe['trend_macd_signal'] = ta.trend.macd_signal( 91 | dataframe['close'], 92 | window_slow=26, 93 | window_fast=12, 94 | window_sign=9, 95 | fillna=False 96 | ) 97 | 98 | dataframe['trend_ema_fast'] = ta.trend.EMAIndicator( 99 | close=dataframe['close'], window=12, fillna=False 100 | ).ema_indicator() 101 | 102 | return dataframe 103 | 104 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 105 | 106 | IND = self.buy_params['buy-indicator-0'] 107 | CRS = self.buy_params['buy-cross-0'] 108 | DFIND = dataframe[IND] 109 | DFCRS = dataframe[CRS] 110 | 111 | dataframe.loc[ 112 | (DFIND < DFCRS), 113 | 'buy'] = 1 114 | 115 | return dataframe 116 | 117 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 118 | IND = self.sell_params['sell-indicator-0'] 119 | CRS = self.sell_params['sell-cross-0'] 120 | 121 | DFIND = dataframe[IND] 122 | DFCRS = dataframe[CRS] 123 | 124 | dataframe.loc[ 125 | (qtpylib.crossed_below(DFIND, DFCRS)), 126 | 'sell'] = 1 127 | 128 | return dataframe 129 | -------------------------------------------------------------------------------- /user_data/strategies/HeraclesOpt2.py: -------------------------------------------------------------------------------- 1 | # Heracles Strategy: Strongest Son of GodStra 2 | # ( With just 1 Genome! its a bacteria :D ) 3 | # Author: @Mablue (Masoud Azizi) 4 | # github: https://github.com/mablue/ 5 | # IMPORTANT:Add to your pairlists inside config.json (Under StaticPairList): 6 | # { 7 | # "method": "AgeFilter", 8 | # "min_days_listed": 100 9 | # }, 10 | # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) 11 | # ###################################################################### 12 | # Optimal config settings: 13 | # "max_open_trades": 100, 14 | # "stake_amount": "unlimited", 15 | 16 | # --- Do not remove these libs --- 17 | import logging 18 | 19 | from numpy.lib import math 20 | from freqtrade.strategy.interface import IStrategy 21 | from pandas import DataFrame 22 | # -------------------------------- 23 | 24 | # Add your lib to import here 25 | # import talib.abstract as ta 26 | import pandas as pd 27 | import ta 28 | from ta.utils import dropna 29 | import freqtrade.vendor.qtpylib.indicators as qtpylib 30 | from functools import reduce 31 | import numpy as np 32 | 33 | 34 | class HeraclesOpt2(IStrategy): 35 | # 65/600: 2275 trades. 1438/7/830 W/D/L. 36 | # Avg profit 3.10%. Median profit 3.06%. 37 | # Total profit 113171 USDT ( 7062 Σ%). 38 | # Avg duration 345 min. Objective: -23.0 39 | 40 | # Buy hyperspace params: 41 | buy_params = { 42 | "buy-div": 0.24933, 43 | "DFINDShift": 1, 44 | "DFCRSShift": 5, 45 | } 46 | 47 | # Sell hyperspace params: 48 | sell_params = { 49 | "sell-rtol": 0.88537, 50 | "sell-atol": 0.29868, 51 | "DFINDShift": 1, 52 | "DFCRSShift": 5, 53 | } 54 | 55 | # ROI table: 56 | minimal_roi = { 57 | "0": 0.621, 58 | "3100": 0.241, 59 | "6961": 0.078, 60 | "20515": 0 61 | } 62 | 63 | # Stoploss: 64 | stoploss = -0.041 65 | 66 | # Trailing stop: 67 | trailing_stop = True 68 | trailing_stop_positive = 0.24 69 | trailing_stop_positive_offset = 0.274 70 | trailing_only_offset_is_reached = False 71 | 72 | # Buy hypers 73 | timeframe = '12h' 74 | 75 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 76 | # Add all ta features 77 | dataframe = dropna(dataframe) 78 | 79 | dataframe['volatility_kcw'] = ta.volatility.keltner_channel_wband( 80 | dataframe['high'], 81 | dataframe['low'], 82 | dataframe['close'], 83 | window=20, 84 | window_atr=10, 85 | fillna=False, 86 | original_version=True 87 | ) 88 | dataframe['volatility_dcp'] = ta.volatility.donchian_channel_pband( 89 | dataframe['high'], 90 | dataframe['low'], 91 | dataframe['close'], 92 | window=10, 93 | offset=0, 94 | fillna=False 95 | ) 96 | dataframe['trend_macd_signal'] = ta.trend.macd_signal( 97 | dataframe['close'], 98 | window_slow=26, 99 | window_fast=12, 100 | window_sign=9, 101 | fillna=False 102 | ) 103 | 104 | dataframe['trend_ema_fast'] = ta.trend.EMAIndicator( 105 | close=dataframe['close'], window=12, fillna=False 106 | ).ema_indicator() 107 | 108 | return dataframe 109 | 110 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 111 | """ 112 | Buy strategy Hyperopt will build and use. 113 | """ 114 | conditions = [] 115 | 116 | IND = 'volatility_dcp' 117 | CRS = 'volatility_kcw' 118 | DFIND = dataframe[IND] 119 | DFCRS = dataframe[CRS] 120 | 121 | conditions.append( 122 | DFIND.shift(self.buy_params['DFINDShift']).div( 123 | DFCRS.shift(self.buy_params['DFCRSShift']) 124 | ) <= self.buy_params['buy-div'] 125 | ) 126 | 127 | if conditions: 128 | dataframe.loc[ 129 | reduce(lambda x, y: x & y, conditions), 130 | 'buy'] = 1 131 | 132 | return dataframe 133 | 134 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 135 | """ 136 | Sell strategy Hyperopt will build and use. 137 | """ 138 | conditions = [] 139 | 140 | IND = 'trend_ema_fast' 141 | CRS = 'trend_macd_signal' 142 | DFIND = dataframe[IND] 143 | DFCRS = dataframe[CRS] 144 | 145 | conditions.append( 146 | np.isclose( 147 | DFIND.shift(self.sell_params['DFINDShift']), 148 | DFCRS.shift(self.sell_params['DFCRSShift']), 149 | rtol=self.sell_params['sell-rtol'], 150 | atol=self.sell_params['sell-atol'] 151 | ) 152 | ) 153 | 154 | if conditions: 155 | dataframe.loc[ 156 | reduce(lambda x, y: x & y, conditions), 157 | 'sell']=1 158 | 159 | return dataframe 160 | -------------------------------------------------------------------------------- /user_data/strategies/HeraclesOptimize.py: -------------------------------------------------------------------------------- 1 | # Heracles Strategy: Strongest Son of GodStra 2 | # ( With just 1 Genome! its a bacteria :D ) 3 | # Author: @Mablue (Masoud Azizi) 4 | # github: https://github.com/mablue/ 5 | # IMPORTANT:Add to your pairlists inside config.json (Under StaticPairList): 6 | # { 7 | # "method": "AgeFilter", 8 | # "min_days_listed": 100 9 | # }, 10 | # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) 11 | # ###################################################################### 12 | # Optimal config settings: 13 | # "max_open_trades": 100, 14 | # "stake_amount": "unlimited", 15 | 16 | # --- Do not remove these libs --- 17 | import logging 18 | 19 | from numpy.lib import math 20 | from freqtrade.strategy.interface import IStrategy 21 | from pandas import DataFrame 22 | # -------------------------------- 23 | 24 | # Add your lib to import here 25 | # import talib.abstract as ta 26 | import pandas as pd 27 | import ta 28 | from ta.utils import dropna 29 | import freqtrade.vendor.qtpylib.indicators as qtpylib 30 | from functools import reduce 31 | import numpy as np 32 | 33 | 34 | class HeraclesOptimize(IStrategy): 35 | # 65/600: 2275 trades. 1438/7/830 W/D/L. 36 | # Avg profit 3.10%. Median profit 3.06%. 37 | # Total profit 113171 USDT ( 7062 Σ%). 38 | # Avg duration 345 min. Objective: -23.0 39 | 40 | buy_params = { 41 | 'buy-cross-0': 'volatility_kcw', 42 | 'buy-indicator-0': 'volatility_dcp', 43 | 'buy-oper-0': '<', 44 | } 45 | 46 | # Sell hyperspace params: 47 | sell_params = { 48 | 'sell-cross-0': 'trend_macd_signal', 49 | 'sell-indicator-0': 'trend_ema_fast', 50 | 'sell-oper-0': '=', 51 | } 52 | 53 | # ROI table: 54 | minimal_roi = { 55 | "0": 0.132, 56 | "2523": 0.093, 57 | "4187": 0.053, 58 | "16688": 0 59 | } 60 | 61 | # Stoploss: 62 | stoploss = -0.02 63 | 64 | # Trailing stop: 65 | trailing_stop = True 66 | trailing_stop_positive = 0.255 67 | trailing_stop_positive_offset = 0.328 68 | trailing_only_offset_is_reached = False 69 | 70 | # Buy hypers 71 | timeframe = '8h' 72 | 73 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 74 | # Add all ta features 75 | dataframe = dropna(dataframe) 76 | 77 | dataframe['volatility_kcw'] = ta.volatility.keltner_channel_wband( 78 | dataframe['high'], 79 | dataframe['low'], 80 | dataframe['close'], 81 | window=20, 82 | window_atr=10, 83 | fillna=False, 84 | original_version=True 85 | ) 86 | dataframe['volatility_dcp'] = ta.volatility.donchian_channel_pband( 87 | dataframe['high'], 88 | dataframe['low'], 89 | dataframe['close'], 90 | window=10, 91 | offset=0, 92 | fillna=False 93 | ) 94 | dataframe['trend_macd_signal'] = ta.trend.macd_signal( 95 | dataframe['close'], 96 | window_slow=26, 97 | window_fast=12, 98 | window_sign=9, 99 | fillna=False 100 | ) 101 | 102 | dataframe['trend_ema_fast'] = ta.trend.EMAIndicator( 103 | close=dataframe['close'], window=12, fillna=False 104 | ).ema_indicator() 105 | 106 | return dataframe 107 | 108 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 109 | 110 | IND = self.buy_params['buy-indicator-0'] 111 | CRS = self.buy_params['buy-cross-0'] 112 | DFIND = dataframe[IND] 113 | DFCRS = dataframe[CRS] 114 | 115 | dataframe.loc[ 116 | (DFIND < DFCRS), 117 | 'buy'] = 1 118 | 119 | return dataframe 120 | 121 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 122 | IND = self.sell_params['sell-indicator-0'] 123 | CRS = self.sell_params['sell-cross-0'] 124 | 125 | DFIND = dataframe[IND] 126 | DFCRS = dataframe[CRS] 127 | 128 | dataframe.loc[ 129 | (qtpylib.crossed_below(DFIND, DFCRS)), 130 | 'sell'] = 1 131 | 132 | return dataframe 133 | -------------------------------------------------------------------------------- /user_data/strategies/MinMaxF.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | from scipy.signal import argrelextrema 11 | import numpy as np 12 | 13 | 14 | class MinMaxF(IStrategy): 15 | 16 | minimal_roi = { 17 | "0": 10 18 | } 19 | 20 | stoploss = -0.05 21 | 22 | timeframe = '5m' 23 | 24 | trailing_stop = False 25 | 26 | process_only_new_candles = False 27 | 28 | startup_candle_count = 30 29 | 30 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 31 | 32 | dataframe_copy = dataframe.copy() 33 | frame_size = 250 34 | len_df = len(dataframe) 35 | dataframe['buy_signal'] = False 36 | dataframe['sell_signal'] = False 37 | lookback_size = 50 38 | # Let's calculate argrelextrema on separated data slices and get only last result to avoid lookahead bias! 39 | for i in range(len_df): 40 | if i + frame_size < len_df: 41 | slice = dataframe_copy[i: i+frame_size] 42 | min_peaks = argrelextrema( 43 | slice['close'].values, np.less, order=lookback_size) 44 | max_peaks = argrelextrema( 45 | slice['close'].values, np.greater, order=lookback_size) 46 | # Somehow we never getting last index of a frame as min or max. What a surprise :) 47 | # So lets take penultimate result and use it as a signal to buy/sell. 48 | if len(min_peaks[0]) and min_peaks[0][-1] == frame_size - 2: 49 | # signal that penultimate candle is min 50 | # lets buy here 51 | dataframe.at[i + frame_size, 'buy_signal'] = True 52 | if len(max_peaks[0]) and max_peaks[0][-1] == frame_size - 2: 53 | # oh it seams that penultimate candle is max 54 | # lets sell ASAP 55 | dataframe.at[i + frame_size, 'sell_signal'] = True 56 | 57 | if i + frame_size == len_df - 1: 58 | pass 59 | # print(min_peaks) 60 | 61 | # A 62 | # Wow what a pathetic results!!!Where is my Trillions of BTC?!?!?! | 63 | # Let's make it in a lookahead way to make more numbers in backtesting!! | 64 | # | 65 | # | 66 | # Comment this section!! ------------------------------------------------------| 67 | # Uncomment this section ASAP! 68 | # | 69 | # | 70 | # | 71 | # | 72 | # V 73 | 74 | # min_peaks = argrelextrema( 75 | # dataframe['close'].values, np.less, order=lookback_size) 76 | # max_peaks = argrelextrema( 77 | # dataframe['close'].values, np.greater, order=lookback_size) 78 | 79 | # for mp in min_peaks[0]: 80 | # dataframe.at[mp, 'buy_signal'] = True 81 | 82 | # for mp in max_peaks[0]: 83 | # dataframe.at[mp, 'sell_signal'] = True 84 | 85 | # Uhhh that's better! Ordering Lambo now! 86 | 87 | return dataframe 88 | 89 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 90 | # print(dataframe.tail(30)) 91 | 92 | dataframe.loc[ 93 | ( 94 | dataframe['buy_signal'] 95 | ), 96 | 'buy'] = 1 97 | 98 | return dataframe 99 | 100 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 101 | 102 | dataframe.loc[ 103 | ( 104 | dataframe['sell_signal'] 105 | ), 106 | 'sell'] = 1 107 | return dataframe 108 | -------------------------------------------------------------------------------- /user_data/strategies/MultiMa.py: -------------------------------------------------------------------------------- 1 | # MultiMa Strategy 2 | # Author: @Mablue (Masoud Azizi) 3 | # github: https://github.com/mablue/ 4 | # (First Hyperopt it.A hyperopt file is available) 5 | # 6 | # --- Do not remove these libs --- 7 | from freqtrade.strategy.hyper import IntParameter 8 | from freqtrade.strategy.interface import IStrategy 9 | from pandas import DataFrame 10 | # -------------------------------- 11 | 12 | # Add your lib to import here 13 | import talib.abstract as ta 14 | import freqtrade.vendor.qtpylib.indicators as qtpylib 15 | from functools import reduce 16 | 17 | 18 | class MultiMa(IStrategy): 19 | 20 | buy_ma_count = IntParameter(2, 10, default=10, space='buy') 21 | buy_ma_gap = IntParameter(2, 10, default=2, space='buy') 22 | buy_ma_shift = IntParameter(0, 10, default=0, space='buy') 23 | # buy_ma_rolling = IntParameter(0, 10, default=0, space='buy') 24 | 25 | sell_ma_count = IntParameter(2, 10, default=10, space='sell') 26 | sell_ma_gap = IntParameter(2, 10, default=2, space='sell') 27 | sell_ma_shift = IntParameter(0, 10, default=0, space='sell') 28 | # sell_ma_rolling = IntParameter(0, 10, default=0, space='sell') 29 | 30 | # ROI table: 31 | minimal_roi = { 32 | "0": 0.30873, 33 | "569": 0.16689, 34 | "3211": 0.06473, 35 | "7617": 0 36 | } 37 | 38 | # Stoploss: 39 | stoploss = -0.1 40 | 41 | # Buy hypers 42 | timeframe = '4h' 43 | 44 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 45 | 46 | # We will dinamicly generate the indicators 47 | # cuz this method just run one time in hyperopts 48 | # if you have static timeframes you can move first loop of buy and sell trends populators inside this method 49 | 50 | return dataframe 51 | 52 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 53 | 54 | for i in self.buy_ma_count.range: 55 | dataframe[f'buy-ma-{i+1}'] = ta.SMA(dataframe, 56 | timeperiod=int((i+1) * self.buy_ma_gap.value)) 57 | 58 | conditions = [] 59 | 60 | for i in self.buy_ma_count.range: 61 | if i > 1: 62 | shift = self.buy_ma_shift.value 63 | for shift in self.buy_ma_shift.range: 64 | conditions.append( 65 | dataframe[f'buy-ma-{i}'].shift(shift) > 66 | dataframe[f'buy-ma-{i-1}'].shift(shift) 67 | ) 68 | if conditions: 69 | dataframe.loc[ 70 | reduce(lambda x, y: x & y, conditions), 71 | 'buy']=1 72 | 73 | return dataframe 74 | 75 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 76 | for i in self.sell_ma_count.range: 77 | dataframe[f'sell-ma-{i+1}'] = ta.SMA(dataframe, 78 | timeperiod=int((i+1) * self.sell_ma_gap.value)) 79 | 80 | conditions = [] 81 | 82 | for i in self.sell_ma_count.range: 83 | if i > 1: 84 | shift = self.sell_ma_shift.value 85 | for shift in self.sell_ma_shift.range: 86 | conditions.append( 87 | dataframe[f'sell-ma-{i}'].shift(shift) < 88 | dataframe[f'sell-ma-{i-1}'].shift(shift) 89 | ) 90 | if conditions: 91 | dataframe.loc[ 92 | reduce(lambda x, y: x & y, conditions), 93 | 'sell']=1 94 | return dataframe 95 | -------------------------------------------------------------------------------- /user_data/strategies/SMA1CTE1.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import talib.abstract as ta 3 | from pandas import DataFrame 4 | from freqtrade.persistence import Trade 5 | from freqtrade.strategy import DecimalParameter, IntParameter 6 | from freqtrade.strategy.interface import IStrategy 7 | 8 | # Author @Jooopieeert#0239 9 | class SMA1CTE1(IStrategy): 10 | INTERFACE_VERSION = 2 11 | buy_params = { 12 | "base_nb_candles_buy": 18, 13 | "low_offset": 0.968, 14 | } 15 | sell_params = { 16 | "base_nb_candles_sell": 26, 17 | "high_offset": 0.985, 18 | } 19 | 20 | base_nb_candles_buy = IntParameter(16, 60, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 21 | base_nb_candles_sell = IntParameter(16, 60, default=sell_params['base_nb_candles_sell'], space='sell', optimize=False) 22 | low_offset = DecimalParameter(0.8, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 23 | high_offset = DecimalParameter(0.8, 1.1, default=sell_params['high_offset'], space='sell', optimize=False) 24 | 25 | timeframe = '5m' 26 | stoploss = -0.23 27 | minimal_roi = {"0": 10,} 28 | trailing_stop = False 29 | trailing_only_offset_is_reached = True 30 | trailing_stop_positive = 0.003 31 | trailing_stop_positive_offset = 0.018 32 | use_sell_signal = True 33 | sell_profit_only = False 34 | ignore_roi_if_buy_signal = False 35 | process_only_new_candles = True 36 | startup_candle_count = 400 37 | 38 | def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, 39 | rate: float, time_in_force: str, sell_reason: str, 40 | current_time: datetime, **kwargs) -> bool: 41 | dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 42 | last_candle = dataframe.iloc[-1] 43 | previous_candle_1 = dataframe.iloc[-2] 44 | if (last_candle is not None): 45 | if (sell_reason in ['roi','sell_signal','trailing_stop_loss']): 46 | if (last_candle['open'] > previous_candle_1['open']) and (last_candle['rsi_exit'] > 50) and (last_candle['rsi_exit'] > previous_candle_1['rsi_exit']): 47 | return False 48 | return True 49 | 50 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 51 | dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50) 52 | dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200) 53 | dataframe['rsi_exit'] = ta.RSI(dataframe, timeperiod=2) 54 | if not self.config['runmode'].value == 'hyperopt': 55 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 56 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 57 | return dataframe 58 | 59 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 60 | if self.config['runmode'].value == 'hyperopt': 61 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 62 | dataframe.loc[ 63 | ( 64 | (dataframe['ema_50'] > dataframe['ema_200']) & 65 | (dataframe['close'] > dataframe['ema_200']) & 66 | (dataframe['close'] < dataframe['ma_offset_buy']) & 67 | (dataframe['volume'] > 0) 68 | ), 69 | 'buy'] = 1 70 | return dataframe 71 | 72 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 73 | if self.config['runmode'].value == 'hyperopt': 74 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 75 | dataframe.loc[ 76 | ( 77 | (dataframe['close'] > dataframe['ma_offset_sell']) & 78 | (dataframe['volume'] > 0) 79 | ), 80 | 'sell'] = 1 81 | return dataframe 82 | -------------------------------------------------------------------------------- /user_data/strategies/SMA1CTE2.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import talib.abstract as ta 3 | from pandas import DataFrame 4 | from freqtrade.persistence import Trade 5 | from freqtrade.strategy import DecimalParameter, IntParameter 6 | from freqtrade.strategy.interface import IStrategy 7 | 8 | # Author @Jooopieeert#0239 9 | class SMA1CTE2(IStrategy): 10 | INTERFACE_VERSION = 2 11 | buy_params = { 12 | "base_nb_candles_buy": 18, 13 | "low_offset": 0.968, 14 | } 15 | sell_params = { 16 | "base_nb_candles_sell": 26, 17 | "high_offset": 0.985, 18 | } 19 | 20 | base_nb_candles_buy = IntParameter(16, 60, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 21 | base_nb_candles_sell = IntParameter(16, 60, default=sell_params['base_nb_candles_sell'], space='sell', optimize=False) 22 | low_offset = DecimalParameter(0.8, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 23 | high_offset = DecimalParameter(0.8, 1.1, default=sell_params['high_offset'], space='sell', optimize=False) 24 | 25 | timeframe = '5m' 26 | stoploss = -0.23 27 | minimal_roi = {"0": 10,} 28 | trailing_stop = False 29 | trailing_only_offset_is_reached = True 30 | trailing_stop_positive = 0.003 31 | trailing_stop_positive_offset = 0.018 32 | use_sell_signal = True 33 | sell_profit_only = False 34 | ignore_roi_if_buy_signal = False 35 | process_only_new_candles = True 36 | startup_candle_count = 400 37 | 38 | def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, 39 | rate: float, time_in_force: str, sell_reason: str, 40 | current_time: datetime, **kwargs) -> bool: 41 | dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 42 | last_candle = dataframe.iloc[-2] 43 | previous_candle_1 = dataframe.iloc[-3] 44 | if (last_candle is not None): 45 | if (sell_reason in ['roi','sell_signal','trailing_stop_loss']): 46 | if (last_candle['open'] > previous_candle_1['open']) and (last_candle['rsi_exit'] > 50) and (last_candle['rsi_exit'] > previous_candle_1['rsi_exit']): 47 | return False 48 | return True 49 | 50 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 51 | dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50) 52 | dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200) 53 | dataframe['rsi_exit'] = ta.RSI(dataframe, timeperiod=2) 54 | if not self.config['runmode'].value == 'hyperopt': 55 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 56 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 57 | return dataframe 58 | 59 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 60 | if self.config['runmode'].value == 'hyperopt': 61 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 62 | dataframe.loc[ 63 | ( 64 | (dataframe['ema_50'] > dataframe['ema_200']) & 65 | (dataframe['close'] > dataframe['ema_200']) & 66 | (dataframe['close'] < dataframe['ma_offset_buy']) & 67 | (dataframe['volume'] > 0) 68 | ), 69 | 'buy'] = 1 70 | return dataframe 71 | 72 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 73 | if self.config['runmode'].value == 'hyperopt': 74 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 75 | dataframe.loc[ 76 | ( 77 | (dataframe['close'] > dataframe['ma_offset_sell']) & 78 | (dataframe['volume'] > 0) 79 | ), 80 | 'sell'] = 1 81 | return dataframe 82 | -------------------------------------------------------------------------------- /user_data/strategies/SMA1Sell.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import talib.abstract as ta 3 | from pandas import DataFrame 4 | from freqtrade.persistence import Trade 5 | from freqtrade.strategy import DecimalParameter, IntParameter 6 | from freqtrade.strategy.interface import IStrategy 7 | 8 | # Author @Jooopieeert#0239 9 | class SMA1Sell(IStrategy): 10 | INTERFACE_VERSION = 2 11 | buy_params = { 12 | "base_nb_candles_buy": 18, 13 | "low_offset": 0.968, 14 | } 15 | sell_params = { 16 | "base_nb_candles_sell": 26, 17 | "high_offset": 0.985, 18 | } 19 | 20 | base_nb_candles_buy = IntParameter(16, 60, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 21 | base_nb_candles_sell = IntParameter(16, 60, default=sell_params['base_nb_candles_sell'], space='sell', optimize=False) 22 | low_offset = DecimalParameter(0.8, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 23 | high_offset = DecimalParameter(0.8, 1.1, default=sell_params['high_offset'], space='sell', optimize=False) 24 | 25 | timeframe = '5m' 26 | stoploss = -0.23 27 | minimal_roi = {"0": 10,} 28 | trailing_stop = False 29 | trailing_only_offset_is_reached = True 30 | trailing_stop_positive = 0.003 31 | trailing_stop_positive_offset = 0.018 32 | use_sell_signal = True 33 | sell_profit_only = False 34 | ignore_roi_if_buy_signal = False 35 | process_only_new_candles = True 36 | startup_candle_count = 400 37 | 38 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 39 | dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50) 40 | dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200) 41 | dataframe['rsi_exit'] = ta.RSI(dataframe, timeperiod=2) 42 | if not self.config['runmode'].value == 'hyperopt': 43 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 44 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 45 | return dataframe 46 | 47 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 48 | if self.config['runmode'].value == 'hyperopt': 49 | dataframe['ma_offset_buy'] = ta.SMA(dataframe, int(self.base_nb_candles_buy.value)) * self.low_offset.value 50 | dataframe.loc[ 51 | ( 52 | (dataframe['ema_50'] > dataframe['ema_200']) & 53 | (dataframe['close'] > dataframe['ema_200']) & 54 | (dataframe['close'] < dataframe['ma_offset_buy']) & 55 | (dataframe['volume'] > 0) 56 | ), 57 | 'buy'] = 1 58 | return dataframe 59 | 60 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 61 | if self.config['runmode'].value == 'hyperopt': 62 | dataframe['ma_offset_sell'] = ta.EMA(dataframe, int(self.base_nb_candles_sell.value)) * self.high_offset.value 63 | dataframe.loc[ 64 | ( 65 | (dataframe['close'] > dataframe['ma_offset_sell']) & 66 | ( 67 | (dataframe['open'] < dataframe['open'].shift(1)) | 68 | (dataframe['rsi_exit'] < 50) | 69 | (dataframe['rsi_exit'] < dataframe['rsi_exit'].shift(1)) 70 | ) & 71 | (dataframe['volume'] > 0) 72 | ), 73 | 'sell'] = 1 74 | return dataframe 75 | -------------------------------------------------------------------------------- /user_data/strategies/Strategy001.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | 12 | 13 | class Strategy001(IStrategy): 14 | """ 15 | Strategy 001 16 | author@: Gerald Lonlas 17 | github@: https://github.com/freqtrade/freqtrade-strategies 18 | 19 | How to use it? 20 | > python3 ./freqtrade/main.py -s Strategy001 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "60": 0.01, 27 | "30": 0.03, 28 | "20": 0.04, 29 | "0": 0.05 30 | } 31 | 32 | # Optimal stoploss designed for the strategy 33 | # This attribute will be overridden if the config file contains "stoploss" 34 | stoploss = -0.10 35 | 36 | # Optimal timeframe for the strategy 37 | timeframe = '5m' 38 | 39 | # trailing stoploss 40 | trailing_stop = False 41 | trailing_stop_positive = 0.01 42 | trailing_stop_positive_offset = 0.02 43 | 44 | # run "populate_indicators" only for new candle 45 | process_only_new_candles = False 46 | 47 | # Experimental settings (configuration will overide these if set) 48 | use_sell_signal = True 49 | sell_profit_only = True 50 | ignore_roi_if_buy_signal = False 51 | 52 | # Optional order type mapping 53 | order_types = { 54 | 'buy': 'limit', 55 | 'sell': 'limit', 56 | 'stoploss': 'market', 57 | 'stoploss_on_exchange': False 58 | } 59 | 60 | def informative_pairs(self): 61 | """ 62 | Define additional, informative pair/interval combinations to be cached from the exchange. 63 | These pair/interval combinations are non-tradeable, unless they are part 64 | of the whitelist as well. 65 | For more information, please consult the documentation 66 | :return: List of tuples in the format (pair, interval) 67 | Sample: return [("ETH/USDT", "5m"), 68 | ("BTC/USDT", "15m"), 69 | ] 70 | """ 71 | return [] 72 | 73 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 74 | """ 75 | Adds several different TA indicators to the given DataFrame 76 | 77 | Performance Note: For the best performance be frugal on the number of indicators 78 | you are using. Let uncomment only the indicator you are using in your strategies 79 | or your hyperopt configuration, otherwise you will waste your memory and CPU usage. 80 | """ 81 | 82 | dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20) 83 | dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) 84 | dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) 85 | 86 | heikinashi = qtpylib.heikinashi(dataframe) 87 | dataframe['ha_open'] = heikinashi['open'] 88 | dataframe['ha_close'] = heikinashi['close'] 89 | 90 | return dataframe 91 | 92 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 93 | """ 94 | Based on TA indicators, populates the buy signal for the given dataframe 95 | :param dataframe: DataFrame 96 | :return: DataFrame with buy column 97 | """ 98 | dataframe.loc[ 99 | ( 100 | qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) & 101 | (dataframe['ha_close'] > dataframe['ema20']) & 102 | (dataframe['ha_open'] < dataframe['ha_close']) # green bar 103 | ), 104 | 'buy'] = 1 105 | 106 | return dataframe 107 | 108 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 109 | """ 110 | Based on TA indicators, populates the sell signal for the given dataframe 111 | :param dataframe: DataFrame 112 | :return: DataFrame with buy column 113 | """ 114 | dataframe.loc[ 115 | ( 116 | qtpylib.crossed_above(dataframe['ema50'], dataframe['ema100']) & 117 | (dataframe['ha_close'] < dataframe['ema20']) & 118 | (dataframe['ha_open'] > dataframe['ha_close']) # red bar 119 | ), 120 | 'sell'] = 1 121 | return dataframe 122 | -------------------------------------------------------------------------------- /user_data/strategies/Strategy002.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | import numpy # noqa 12 | 13 | 14 | class Strategy002(IStrategy): 15 | """ 16 | Strategy 002 17 | author@: Gerald Lonlas 18 | github@: https://github.com/freqtrade/freqtrade-strategies 19 | 20 | How to use it? 21 | > python3 ./freqtrade/main.py -s Strategy002 22 | """ 23 | 24 | # Minimal ROI designed for the strategy. 25 | # This attribute will be overridden if the config file contains "minimal_roi" 26 | minimal_roi = { 27 | "60": 0.01, 28 | "30": 0.03, 29 | "20": 0.04, 30 | "0": 0.05 31 | } 32 | 33 | # Optimal stoploss designed for the strategy 34 | # This attribute will be overridden if the config file contains "stoploss" 35 | stoploss = -0.10 36 | 37 | # Optimal timeframe for the strategy 38 | timeframe = '5m' 39 | 40 | # trailing stoploss 41 | trailing_stop = False 42 | trailing_stop_positive = 0.01 43 | trailing_stop_positive_offset = 0.02 44 | 45 | # run "populate_indicators" only for new candle 46 | process_only_new_candles = False 47 | 48 | # Experimental settings (configuration will overide these if set) 49 | use_sell_signal = True 50 | sell_profit_only = True 51 | ignore_roi_if_buy_signal = False 52 | 53 | # Optional order type mapping 54 | order_types = { 55 | 'buy': 'limit', 56 | 'sell': 'limit', 57 | 'stoploss': 'market', 58 | 'stoploss_on_exchange': False 59 | } 60 | 61 | def informative_pairs(self): 62 | """ 63 | Define additional, informative pair/interval combinations to be cached from the exchange. 64 | These pair/interval combinations are non-tradeable, unless they are part 65 | of the whitelist as well. 66 | For more information, please consult the documentation 67 | :return: List of tuples in the format (pair, interval) 68 | Sample: return [("ETH/USDT", "5m"), 69 | ("BTC/USDT", "15m"), 70 | ] 71 | """ 72 | return [] 73 | 74 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 75 | """ 76 | Adds several different TA indicators to the given DataFrame 77 | 78 | Performance Note: For the best performance be frugal on the number of indicators 79 | you are using. Let uncomment only the indicator you are using in your strategies 80 | or your hyperopt configuration, otherwise you will waste your memory and CPU usage. 81 | """ 82 | 83 | # Stoch 84 | stoch = ta.STOCH(dataframe) 85 | dataframe['slowk'] = stoch['slowk'] 86 | 87 | # RSI 88 | dataframe['rsi'] = ta.RSI(dataframe) 89 | 90 | # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy) 91 | rsi = 0.1 * (dataframe['rsi'] - 50) 92 | dataframe['fisher_rsi'] = ( 93 | numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1) 94 | 95 | # Bollinger bands 96 | bollinger = qtpylib.bollinger_bands( 97 | qtpylib.typical_price(dataframe), window=20, stds=2) 98 | dataframe['bb_lowerband'] = bollinger['lower'] 99 | 100 | # SAR Parabol 101 | dataframe['sar'] = ta.SAR(dataframe) 102 | 103 | # Hammer: values [0, 100] 104 | dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe) 105 | 106 | return dataframe 107 | 108 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 109 | """ 110 | Based on TA indicators, populates the buy signal for the given dataframe 111 | :param dataframe: DataFrame 112 | :return: DataFrame with buy column 113 | """ 114 | dataframe.loc[ 115 | ( 116 | (dataframe['rsi'] < 30) & 117 | (dataframe['slowk'] < 20) & 118 | (dataframe['bb_lowerband'] > dataframe['close']) & 119 | (dataframe['CDLHAMMER'] == 100) 120 | ), 121 | 'buy'] = 1 122 | 123 | return dataframe 124 | 125 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 126 | """ 127 | Based on TA indicators, populates the sell signal for the given dataframe 128 | :param dataframe: DataFrame 129 | :return: DataFrame with buy column 130 | """ 131 | dataframe.loc[ 132 | ( 133 | (dataframe['sar'] > dataframe['close']) & 134 | (dataframe['fisher_rsi'] > 0.3) 135 | ), 136 | 'sell'] = 1 137 | return dataframe 138 | -------------------------------------------------------------------------------- /user_data/strategies/Swing-High-To-Sky.py: -------------------------------------------------------------------------------- 1 | from freqtrade.strategy.interface import IStrategy 2 | from typing import Dict, List 3 | from functools import reduce 4 | from pandas import DataFrame 5 | 6 | import talib.abstract as ta 7 | import freqtrade.vendor.qtpylib.indicators as qtpylib 8 | import numpy 9 | 10 | __author__ = "Kevin Ossenbrück" 11 | __copyright__ = "Free For Use" 12 | __credits__ = ["Bloom Trading, Mohsen Hassan"] 13 | __license__ = "MIT" 14 | __version__ = "1.0" 15 | __maintainer__ = "Kevin Ossenbrück" 16 | __email__ = "kevin.ossenbrueck@pm.de" 17 | __status__ = "Live" 18 | 19 | # CCI timerperiods and values 20 | cciBuyTP = 72 21 | cciBuyVal = -175 22 | cciSellTP = 66 23 | cciSellVal = -106 24 | 25 | # RSI timeperiods and values 26 | rsiBuyTP = 36 27 | rsiBuyVal = 90 28 | rsiSellTP = 45 29 | rsiSellVal = 88 30 | 31 | 32 | class SwingHighToSky(IStrategy): 33 | 34 | timeframe = '5m' 35 | 36 | # stoploss = -0.34338 37 | stoploss = -0.34338 38 | 39 | # minimal_roi = {"0": 0.27058, "33": 0.0853, "64": 0.04093, "244": 0} 40 | minimal_roi = {"0": 0.15058, "33": 0.0453, "64": 0.02333, "244": 0} 41 | 42 | def informative_pairs(self): 43 | return [] 44 | 45 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 46 | 47 | dataframe['cci-'+str(cciBuyTP)] = ta.CCI(dataframe, 48 | timeperiod=cciBuyTP) 49 | dataframe['cci-'+str(cciSellTP)] = ta.CCI(dataframe, 50 | timeperiod=cciSellTP) 51 | 52 | dataframe['rsi-'+str(rsiBuyTP)] = ta.RSI(dataframe, 53 | timeperiod=rsiBuyTP) 54 | dataframe['rsi-'+str(rsiSellTP)] = ta.RSI(dataframe, 55 | timeperiod=rsiSellTP) 56 | 57 | return dataframe 58 | 59 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 60 | 61 | dataframe.loc[ 62 | ( 63 | (dataframe['cci-'+str(cciBuyTP)] < cciBuyVal) & 64 | (dataframe['rsi-'+str(rsiBuyTP)] < rsiBuyVal) 65 | ), 66 | 'buy'] = 1 67 | 68 | return dataframe 69 | 70 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 71 | 72 | dataframe.loc[ 73 | ( 74 | (dataframe['cci-'+str(cciSellTP)] > cciSellVal) & 75 | (dataframe['rsi-'+str(rsiSellTP)] > rsiSellVal) 76 | ), 77 | 'sell'] = 1 78 | 79 | return dataframe 80 | -------------------------------------------------------------------------------- /user_data/strategies/Zeus.py: -------------------------------------------------------------------------------- 1 | # Zeus Strategy: First Generation of GodStra Strategy with maximum 2 | # AVG/MID profit in USDT 3 | # Author: @Mablue (Masoud Azizi) 4 | # github: https://github.com/mablue/ 5 | # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) 6 | # freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces buy sell roi --strategy Zeus 7 | # --- Do not remove these libs --- 8 | import logging 9 | from freqtrade.strategy.hyper import CategoricalParameter, DecimalParameter 10 | 11 | from numpy.lib import math 12 | from freqtrade.strategy.interface import IStrategy 13 | from pandas import DataFrame 14 | # -------------------------------- 15 | 16 | # Add your lib to import here 17 | # import talib.abstract as ta 18 | import pandas as pd 19 | import ta 20 | from ta.utils import dropna 21 | import freqtrade.vendor.qtpylib.indicators as qtpylib 22 | from functools import reduce 23 | import numpy as np 24 | 25 | 26 | class Zeus(IStrategy): 27 | 28 | # * 1/43: 86 trades. 72/6/8 Wins/Draws/Losses. Avg profit 12.66%. Median profit 11.99%. Total profit 0.10894395 BTC ( 108.94Σ%). Avg duration 3 days, 0:31:00 min. Objective: -48.48793 29 | # "max_open_trades": 10, 30 | # "stake_currency": "BTC", 31 | # "stake_amount": 0.01, 32 | # "tradable_balance_ratio": 0.99, 33 | # "timeframe": "4h", 34 | # "dry_run_wallet": 0.1, 35 | 36 | # Buy hyperspace params: 37 | buy_params = { 38 | "buy_cat": "R", "=R", "R", "=R", " DataFrame: 78 | # Add all ta features 79 | 80 | dataframe['trend_ichimoku_base'] = ta.trend.ichimoku_base_line( 81 | dataframe['high'], 82 | dataframe['low'], 83 | window1=9, 84 | window2=26, 85 | visual=False, 86 | fillna=False 87 | ) 88 | KST = ta.trend.KSTIndicator( 89 | close=dataframe['close'], 90 | roc1=10, 91 | roc2=15, 92 | roc3=20, 93 | roc4=30, 94 | window1=10, 95 | window2=10, 96 | window3=10, 97 | window4=15, 98 | nsig=9, 99 | fillna=False 100 | ) 101 | 102 | dataframe['trend_kst_diff'] = KST.kst_diff() 103 | 104 | # Normalization 105 | tib = dataframe['trend_ichimoku_base'] 106 | dataframe['trend_ichimoku_base'] = ( 107 | tib-tib.min())/(tib.max()-tib.min()) 108 | tkd = dataframe['trend_kst_diff'] 109 | dataframe['trend_kst_diff'] = (tkd-tkd.min())/(tkd.max()-tkd.min()) 110 | return dataframe 111 | 112 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 113 | conditions = [] 114 | IND = 'trend_ichimoku_base' 115 | REAL = self.buy_real.value 116 | OPR = self.buy_cat.value 117 | DFIND = dataframe[IND] 118 | # print(DFIND.mean()) 119 | if OPR == ">R": 120 | conditions.append(DFIND > REAL) 121 | elif OPR == "=R": 122 | conditions.append(np.isclose(DFIND, REAL)) 123 | elif OPR == " DataFrame: 134 | conditions = [] 135 | IND = 'trend_kst_diff' 136 | REAL = self.sell_real.value 137 | OPR = self.sell_cat.value 138 | DFIND = dataframe[IND] 139 | # print(DFIND.mean()) 140 | 141 | if OPR == ">R": 142 | conditions.append(DFIND > REAL) 143 | elif OPR == "=R": 144 | conditions.append(np.isclose(DFIND, REAL)) 145 | elif OPR == "R", "=R", "R", "=R", " DataFrame: 71 | # Add all ta features 72 | 73 | dataframe['trend_ichimoku_base'] = ta.trend.ichimoku_base_line( 74 | dataframe['high'], 75 | dataframe['low'], 76 | window1=9, 77 | window2=26, 78 | visual=False, 79 | fillna=False 80 | ) 81 | KST = ta.trend.KSTIndicator( 82 | close=dataframe['close'], 83 | roc1=10, 84 | roc2=15, 85 | roc3=20, 86 | roc4=30, 87 | window1=10, 88 | window2=10, 89 | window3=10, 90 | window4=15, 91 | nsig=9, 92 | fillna=False 93 | ) 94 | 95 | dataframe['trend_kst_diff'] = KST.kst_diff() 96 | 97 | # Normalization 98 | tib = dataframe['trend_ichimoku_base'] 99 | dataframe['trend_ichimoku_base'] = ( 100 | tib-tib.min())/(tib.max()-tib.min()) 101 | tkd = dataframe['trend_kst_diff'] 102 | dataframe['trend_kst_diff'] = (tkd-tkd.min())/(tkd.max()-tkd.min()) 103 | return dataframe 104 | 105 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 106 | conditions = [] 107 | IND = 'trend_ichimoku_base' 108 | REAL = self.buy_real.value 109 | OPR = self.buy_cat.value 110 | DFIND = dataframe[IND] 111 | # print(DFIND.mean()) 112 | if OPR == ">R": 113 | conditions.append(DFIND > REAL) 114 | elif OPR == "=R": 115 | conditions.append(np.isclose(DFIND, REAL)) 116 | elif OPR == " DataFrame: 127 | conditions = [] 128 | IND = 'trend_kst_diff' 129 | REAL = self.sell_real.value 130 | OPR = self.sell_cat.value 131 | DFIND = dataframe[IND] 132 | # print(DFIND.mean()) 133 | 134 | if OPR == ">R": 135 | conditions.append(DFIND > REAL) 136 | elif OPR == "=R": 137 | conditions.append(np.isclose(DFIND, REAL)) 138 | elif OPR == " DataFrame: 31 | 32 | # ADX 33 | dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) 34 | dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=25) 35 | dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=25) 36 | dataframe['sar'] = ta.SAR(dataframe) 37 | dataframe['mom'] = ta.MOM(dataframe, timeperiod=14) 38 | 39 | return dataframe 40 | 41 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 42 | dataframe.loc[ 43 | ( 44 | (dataframe['adx'] > 16) & 45 | (dataframe['minus_di'] > 4) & 46 | # (dataframe['plus_di'] > 33) & 47 | (qtpylib.crossed_above(dataframe['minus_di'], dataframe['plus_di'])) 48 | 49 | ), 50 | 'buy'] = 1 51 | return dataframe 52 | 53 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 54 | dataframe.loc[ 55 | ( 56 | (dataframe['adx'] > 43) & 57 | # (dataframe['minus_di'] > 22) & 58 | (dataframe['plus_di'] > 24) & 59 | (qtpylib.crossed_above(dataframe['plus_di'], dataframe['minus_di'])) 60 | 61 | ), 62 | 'sell'] = 1 63 | return dataframe 64 | 65 | # ... populate_* methods 66 | 67 | use_custom_stoploss = False 68 | 69 | def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, 70 | current_rate: float, current_profit: float, **kwargs) -> float: 71 | 72 | # Make sure you have the longest interval first - these conditions are evaluated from top to bottom. 73 | if current_time - timedelta(minutes=530) > trade.open_date_utc: 74 | return -0.05 75 | elif current_time - timedelta(minutes=210) > trade.open_date_utc: 76 | return -0.10 77 | return 1 78 | 79 | -------------------------------------------------------------------------------- /user_data/strategies/bbrsittfv1.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | import numpy as np # noqa 3 | import pandas as pd # noqa 4 | from pandas import DataFrame, Series 5 | import talib.abstract as ta 6 | from freqtrade.strategy import IStrategy, IntParameter 7 | import freqtrade.vendor.qtpylib.indicators as qtpylib 8 | pd.set_option("display.precision",8) 9 | 10 | class bbrsittfv1(IStrategy): 11 | INTERFACE_VERSION = 3 12 | 13 | stoploss = -0.99 14 | timeframe = '15m' 15 | 16 | ############################################################# 17 | 18 | #TTF 19 | ttf_length = IntParameter(1, 50, default=15) 20 | ttf_upperTrigger = IntParameter(1, 400, default=100) 21 | ttf_lowerTrigger = IntParameter(1, -400, default=-100) 22 | 23 | plot_config = { 24 | 'main_plot': { 25 | 'bb_upperband': {'color': 'blue'}, 26 | 'bb_middleband': {'color': 'white'}, 27 | 'bb_lowerband': {'color': 'yellow'}, 28 | }, 29 | 'subplots': { 30 | "RSI": { 31 | 'rsi': {'color': 'blue'}, 32 | 'rsiob': {'color': '#d3d3d3'}, 33 | 'rsios': {'color': '#d3d3d3'}, 34 | }, 35 | "TTF": { 36 | 'ttf': {'color': 'red'}, 37 | 'ttfhigh': {'color': '#d3d3d3'}, 38 | 'ttflow': {'color': '#d3d3d3'}, 39 | } 40 | } 41 | } 42 | 43 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 44 | 45 | # TTF - Trend Trigger Factor 46 | dataframe['ttf'] = ttf(dataframe, self.ttf_length.value) 47 | dataframe['ttfhigh'] = self.ttf_upperTrigger.value 48 | dataframe['ttflow'] = self.ttf_lowerTrigger.value 49 | 50 | # RSI 51 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 52 | dataframe['rsiob'] = 70 53 | dataframe['rsios'] = 30 54 | 55 | # Bollinger Bands 56 | bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) 57 | dataframe['bb_lowerband'] = bollinger['lower'] 58 | dataframe['bb_middleband'] = bollinger['mid'] 59 | dataframe['bb_upperband'] = bollinger['upper'] 60 | 61 | return dataframe 62 | 63 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 64 | dataframe.loc[ 65 | ( 66 | (dataframe['rsi'] < 30) & 67 | (dataframe['ttf'] < self.ttf_lowerTrigger.value) & 68 | (dataframe['close'] < dataframe['bb_lowerband']) 69 | ), 70 | 'buy'] = 1 71 | return dataframe 72 | 73 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 74 | dataframe.loc[ 75 | ( 76 | (dataframe['rsi'] > 70) & 77 | (dataframe['ttf'] > self.ttf_upperTrigger.value) & 78 | (dataframe['close'] > dataframe['bb_upperband']) 79 | ), 80 | 'sell'] = 1 81 | return dataframe 82 | 83 | def ttf(dataframe, ttf_length): 84 | # Thanks to FeelsGoodMan for the TTF Maths 85 | df = dataframe.copy() 86 | high, low = df['high'], df['low'] 87 | buyPower = high.rolling(ttf_length).max() - low.shift(ttf_length).fillna(99999).rolling(ttf_length).min() 88 | sellPower = high.shift(ttf_length).fillna(0).rolling(ttf_length).max() - low.rolling(ttf_length).min() 89 | 90 | ttf = 200 * (buyPower - sellPower) / (buyPower + sellPower) 91 | return Series(ttf, name ='ttf') -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/ADXMomentum.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | 6 | 7 | # -------------------------------- 8 | 9 | 10 | class ADXMomentum(IStrategy): 11 | """ 12 | 13 | author@: Gert Wohlgemuth 14 | 15 | converted from: 16 | 17 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/AdxMomentum.cs 18 | 19 | """ 20 | 21 | # Minimal ROI designed for the strategy. 22 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 23 | # This attribute will be overridden if the config file contains "minimal_roi" 24 | minimal_roi = { 25 | "0": 0.01 26 | } 27 | 28 | # Optimal stoploss designed for the strategy 29 | stoploss = -0.25 30 | 31 | # Optimal timeframe for the strategy 32 | timeframe = '1h' 33 | 34 | # Number of candles the strategy requires before producing valid signals 35 | startup_candle_count: int = 20 36 | 37 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 38 | dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) 39 | dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=25) 40 | dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=25) 41 | dataframe['sar'] = ta.SAR(dataframe) 42 | dataframe['mom'] = ta.MOM(dataframe, timeperiod=14) 43 | 44 | return dataframe 45 | 46 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | dataframe.loc[ 48 | ( 49 | (dataframe['adx'] > 25) & 50 | (dataframe['mom'] > 0) & 51 | (dataframe['plus_di'] > 25) & 52 | (dataframe['plus_di'] > dataframe['minus_di']) 53 | 54 | ), 55 | 'buy'] = 1 56 | return dataframe 57 | 58 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 59 | dataframe.loc[ 60 | ( 61 | (dataframe['adx'] > 25) & 62 | (dataframe['mom'] < 0) & 63 | (dataframe['minus_di'] > 25) & 64 | (dataframe['plus_di'] < dataframe['minus_di']) 65 | 66 | ), 67 | 'sell'] = 1 68 | return dataframe 69 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/ASDTSRockwellTrading.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | 12 | 13 | class ASDTSRockwellTrading(IStrategy): 14 | """ 15 | trading strategy based on the concept explained at https://www.youtube.com/watch?v=mmAWVmKN4J0 16 | author@: Gert Wohlgemuth 17 | 18 | idea: 19 | 20 | uptrend definition: 21 | MACD above 0 line AND above MACD signal 22 | 23 | 24 | downtrend definition: 25 | MACD below 0 line and below MACD signal 26 | 27 | sell definition: 28 | MACD below MACD signal 29 | 30 | it's basically a very simple MACD based strategy and we ignore the definition of the entry and exit points in this case, since the trading bot, will take of this already 31 | 32 | """ 33 | 34 | # Minimal ROI designed for the strategy. 35 | # This attribute will be overridden if the config file contains "minimal_roi" 36 | minimal_roi = { 37 | "60": 0.01, 38 | "30": 0.03, 39 | "20": 0.04, 40 | "0": 0.05 41 | } 42 | 43 | # Optimal stoploss designed for the strategy 44 | # This attribute will be overridden if the config file contains "stoploss" 45 | stoploss = -0.3 46 | 47 | # Optimal timeframe for the strategy 48 | timeframe = '5m' 49 | 50 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 51 | 52 | macd = ta.MACD(dataframe) 53 | dataframe['macd'] = macd['macd'] 54 | dataframe['macdsignal'] = macd['macdsignal'] 55 | dataframe['macdhist'] = macd['macdhist'] 56 | 57 | return dataframe 58 | 59 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 60 | """ 61 | Based on TA indicators, populates the buy signal for the given dataframe 62 | :param dataframe: DataFrame 63 | :return: DataFrame with buy column 64 | """ 65 | dataframe.loc[ 66 | ( 67 | (dataframe['macd'] > 0) & 68 | (dataframe['macd'] > dataframe['macdsignal']) 69 | ), 70 | 'buy'] = 1 71 | 72 | return dataframe 73 | 74 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 75 | """ 76 | Based on TA indicators, populates the sell signal for the given dataframe 77 | :param dataframe: DataFrame 78 | :return: DataFrame with buy column 79 | """ 80 | dataframe.loc[ 81 | ( 82 | (dataframe['macd'] < dataframe['macdsignal']) 83 | ), 84 | 'sell'] = 1 85 | return dataframe 86 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/AdxSmas.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | import freqtrade.vendor.qtpylib.indicators as qtpylib 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class AdxSmas(IStrategy): 12 | """ 13 | 14 | author@: Gert Wohlgemuth 15 | 16 | converted from: 17 | 18 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/AdxSmas.cs 19 | 20 | """ 21 | 22 | # Minimal ROI designed for the strategy. 23 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.1 27 | } 28 | 29 | # Optimal stoploss designed for the strategy 30 | stoploss = -0.25 31 | 32 | # Optimal timeframe for the strategy 33 | timeframe = '1h' 34 | 35 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 36 | dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) 37 | dataframe['short'] = ta.SMA(dataframe, timeperiod=3) 38 | dataframe['long'] = ta.SMA(dataframe, timeperiod=6) 39 | 40 | return dataframe 41 | 42 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 43 | dataframe.loc[ 44 | ( 45 | (dataframe['adx'] > 25) & 46 | (qtpylib.crossed_above(dataframe['short'], dataframe['long'])) 47 | 48 | ), 49 | 'buy'] = 1 50 | return dataframe 51 | 52 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 53 | dataframe.loc[ 54 | ( 55 | (dataframe['adx'] < 25) & 56 | (qtpylib.crossed_above(dataframe['long'], dataframe['short'])) 57 | 58 | ), 59 | 'sell'] = 1 60 | return dataframe 61 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/AverageStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | # -------------------------------- 5 | 6 | import talib.abstract as ta 7 | import freqtrade.vendor.qtpylib.indicators as qtpylib 8 | 9 | 10 | class AverageStrategy(IStrategy): 11 | """ 12 | 13 | author@: Gert Wohlgemuth 14 | 15 | idea: 16 | buys and sells on crossovers - doesn't really perfom that well and its just a proof of concept 17 | """ 18 | 19 | # Minimal ROI designed for the strategy. 20 | # This attribute will be overridden if the config file contains "minimal_roi" 21 | minimal_roi = { 22 | "0": 0.5 23 | } 24 | 25 | # Optimal stoploss designed for the strategy 26 | # This attribute will be overridden if the config file contains "stoploss" 27 | stoploss = -0.2 28 | 29 | # Optimal timeframe for the strategy 30 | timeframe = '4h' 31 | 32 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 33 | 34 | dataframe['maShort'] = ta.EMA(dataframe, timeperiod=8) 35 | dataframe['maMedium'] = ta.EMA(dataframe, timeperiod=21) 36 | 37 | return dataframe 38 | 39 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | """ 41 | Based on TA indicators, populates the buy signal for the given dataframe 42 | :param dataframe: DataFrame 43 | :return: DataFrame with buy column 44 | """ 45 | dataframe.loc[ 46 | ( 47 | qtpylib.crossed_above(dataframe['maShort'], dataframe['maMedium']) 48 | ), 49 | 'buy'] = 1 50 | 51 | return dataframe 52 | 53 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 54 | """ 55 | Based on TA indicators, populates the sell signal for the given dataframe 56 | :param dataframe: DataFrame 57 | :return: DataFrame with buy column 58 | """ 59 | dataframe.loc[ 60 | ( 61 | qtpylib.crossed_above(dataframe['maMedium'], dataframe['maShort']) 62 | ), 63 | 'sell'] = 1 64 | return dataframe 65 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/AwesomeMacd.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | import freqtrade.vendor.qtpylib.indicators as qtpylib 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class AwesomeMacd(IStrategy): 12 | """ 13 | 14 | author@: Gert Wohlgemuth 15 | 16 | converted from: 17 | 18 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/AwesomeMacd.cs 19 | 20 | """ 21 | 22 | # Minimal ROI designed for the strategy. 23 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.1 27 | } 28 | 29 | # Optimal stoploss designed for the strategy 30 | stoploss = -0.25 31 | 32 | # Optimal timeframe for the strategy 33 | timeframe = '1h' 34 | 35 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 36 | dataframe['adx'] = ta.ADX(dataframe, timeperiod=14) 37 | dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) 38 | 39 | macd = ta.MACD(dataframe) 40 | dataframe['macd'] = macd['macd'] 41 | dataframe['macdsignal'] = macd['macdsignal'] 42 | dataframe['macdhist'] = macd['macdhist'] 43 | 44 | return dataframe 45 | 46 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | dataframe.loc[ 48 | ( 49 | (dataframe['macd'] > 0) & 50 | (dataframe['ao'] > 0) & 51 | (dataframe['ao'].shift() < 0) 52 | 53 | ), 54 | 'buy'] = 1 55 | return dataframe 56 | 57 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 58 | dataframe.loc[ 59 | ( 60 | (dataframe['macd'] < 0) & 61 | (dataframe['ao'] < 0) & 62 | (dataframe['ao'].shift() > 0) 63 | 64 | ), 65 | 'sell'] = 1 66 | return dataframe 67 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/BbandRsi.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | import talib.abstract as ta 5 | import freqtrade.vendor.qtpylib.indicators as qtpylib 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class BbandRsi(IStrategy): 12 | """ 13 | 14 | author@: Gert Wohlgemuth 15 | 16 | converted from: 17 | 18 | https://github.com/sthewissen/Mynt/blob/master/src/Mynt.Core/Strategies/BbandRsi.cs 19 | 20 | """ 21 | 22 | # Minimal ROI designed for the strategy. 23 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.1 27 | } 28 | 29 | # Optimal stoploss designed for the strategy 30 | stoploss = -0.25 31 | 32 | # Optimal timeframe for the strategy 33 | timeframe = '1h' 34 | 35 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 36 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 37 | 38 | # Bollinger bands 39 | bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) 40 | dataframe['bb_lowerband'] = bollinger['lower'] 41 | dataframe['bb_middleband'] = bollinger['mid'] 42 | dataframe['bb_upperband'] = bollinger['upper'] 43 | 44 | return dataframe 45 | 46 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | dataframe.loc[ 48 | ( 49 | (dataframe['rsi'] < 30) & 50 | (dataframe['close'] < dataframe['bb_lowerband']) 51 | 52 | ), 53 | 'buy'] = 1 54 | return dataframe 55 | 56 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 57 | dataframe.loc[ 58 | ( 59 | (dataframe['rsi'] > 70) 60 | 61 | ), 62 | 'sell'] = 1 63 | return dataframe 64 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/BinHV45.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | import numpy as np 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | 12 | 13 | def bollinger_bands(stock_price, window_size, num_of_std): 14 | rolling_mean = stock_price.rolling(window=window_size).mean() 15 | rolling_std = stock_price.rolling(window=window_size).std() 16 | lower_band = rolling_mean - (rolling_std * num_of_std) 17 | 18 | return rolling_mean, lower_band 19 | 20 | 21 | class BinHV45(IStrategy): 22 | minimal_roi = { 23 | "0": 0.0125 24 | } 25 | 26 | stoploss = -0.05 27 | timeframe = '1m' 28 | 29 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 30 | mid, lower = bollinger_bands(dataframe['close'], window_size=40, num_of_std=2) 31 | dataframe['mid'] = np.nan_to_num(mid) 32 | dataframe['lower'] = np.nan_to_num(lower) 33 | dataframe['bbdelta'] = (dataframe['mid'] - dataframe['lower']).abs() 34 | dataframe['pricedelta'] = (dataframe['open'] - dataframe['close']).abs() 35 | dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() 36 | dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs() 37 | return dataframe 38 | 39 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | dataframe.loc[ 41 | ( 42 | dataframe['lower'].shift().gt(0) & 43 | dataframe['bbdelta'].gt(dataframe['close'] * 0.008) & 44 | dataframe['closedelta'].gt(dataframe['close'] * 0.0175) & 45 | dataframe['tail'].lt(dataframe['bbdelta'] * 0.25) & 46 | dataframe['close'].lt(dataframe['lower'].shift()) & 47 | dataframe['close'].le(dataframe['close'].shift()) 48 | ), 49 | 'buy'] = 1 50 | return dataframe 51 | 52 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 53 | """ 54 | no sell signal 55 | """ 56 | dataframe.loc[:, 'sell'] = 0 57 | return dataframe 58 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/CCIStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame, Series, DatetimeIndex, merge 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | 11 | 12 | class CCIStrategy(IStrategy): 13 | # Minimal ROI designed for the strategy. 14 | # This attribute will be overridden if the config file contains "minimal_roi" 15 | minimal_roi = { 16 | "0": 0.1 17 | } 18 | 19 | # Optimal stoploss designed for the strategy 20 | # This attribute will be overridden if the config file contains "stoploss" 21 | stoploss = -0.02 22 | 23 | # Optimal timeframe for the strategy 24 | timeframe = '1m' 25 | 26 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 27 | dataframe = self.resample(dataframe, self.timeframe, 5) 28 | 29 | dataframe['cci_one'] = ta.CCI(dataframe, timeperiod=170) 30 | dataframe['cci_two'] = ta.CCI(dataframe, timeperiod=34) 31 | dataframe['rsi'] = ta.RSI(dataframe) 32 | dataframe['mfi'] = ta.MFI(dataframe) 33 | 34 | dataframe['cmf'] = self.chaikin_mf(dataframe) 35 | 36 | # required for graphing 37 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 38 | dataframe['bb_lowerband'] = bollinger['lower'] 39 | dataframe['bb_upperband'] = bollinger['upper'] 40 | dataframe['bb_middleband'] = bollinger['mid'] 41 | 42 | return dataframe 43 | 44 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 45 | """ 46 | Based on TA indicators, populates the buy signal for the given dataframe 47 | :param dataframe: DataFrame 48 | :return: DataFrame with buy column 49 | """ 50 | dataframe.loc[ 51 | ( 52 | (dataframe['cci_one'] < -100) 53 | & (dataframe['cci_two'] < -100) 54 | & (dataframe['cmf'] < -0.1) 55 | & (dataframe['mfi'] < 25) 56 | 57 | # insurance 58 | & (dataframe['resample_medium'] > dataframe['resample_short']) 59 | & (dataframe['resample_long'] < dataframe['close']) 60 | 61 | ), 62 | 'buy'] = 1 63 | 64 | return dataframe 65 | 66 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 67 | """ 68 | Based on TA indicators, populates the sell signal for the given dataframe 69 | :param dataframe: DataFrame 70 | :return: DataFrame with buy column 71 | """ 72 | dataframe.loc[ 73 | ( 74 | (dataframe['cci_one'] > 100) 75 | & (dataframe['cci_two'] > 100) 76 | & (dataframe['cmf'] > 0.3) 77 | & (dataframe['resample_sma'] < dataframe['resample_medium']) 78 | & (dataframe['resample_medium'] < dataframe['resample_short']) 79 | 80 | ), 81 | 'sell'] = 1 82 | return dataframe 83 | 84 | def chaikin_mf(self, df, periods=20): 85 | close = df['close'] 86 | low = df['low'] 87 | high = df['high'] 88 | volume = df['volume'] 89 | 90 | mfv = ((close - low) - (high - close)) / (high - low) 91 | mfv = mfv.fillna(0.0) # float division by zero 92 | mfv *= volume 93 | cmf = mfv.rolling(periods).sum() / volume.rolling(periods).sum() 94 | 95 | return Series(cmf, name='cmf') 96 | 97 | def resample(self, dataframe, interval, factor): 98 | # defines the reinforcement logic 99 | # resampled dataframe to establish if we are in an uptrend, downtrend or sideways trend 100 | df = dataframe.copy() 101 | df = df.set_index(DatetimeIndex(df['date'])) 102 | ohlc_dict = { 103 | 'open': 'first', 104 | 'high': 'max', 105 | 'low': 'min', 106 | 'close': 'last' 107 | } 108 | df = df.resample(str(int(interval[:-1]) * factor) + 'min', label="right").agg(ohlc_dict) 109 | df['resample_sma'] = ta.SMA(df, timeperiod=100, price='close') 110 | df['resample_medium'] = ta.SMA(df, timeperiod=50, price='close') 111 | df['resample_short'] = ta.SMA(df, timeperiod=25, price='close') 112 | df['resample_long'] = ta.SMA(df, timeperiod=200, price='close') 113 | df = df.drop(columns=['open', 'high', 'low', 'close']) 114 | df = df.resample(interval[:-1] + 'min') 115 | df = df.interpolate(method='time') 116 | df['date'] = df.index 117 | df.index = range(len(df)) 118 | dataframe = merge(dataframe, df, on='date', how='left') 119 | return dataframe 120 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/CMCWinner.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from pandas import DataFrame 5 | # -------------------------------- 6 | 7 | # Add your lib to import here 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | import numpy # noqa 11 | 12 | 13 | # This class is a sample. Feel free to customize it. 14 | class CMCWinner(IStrategy): 15 | """ 16 | This is a test strategy to inspire you. 17 | More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md 18 | 19 | You can: 20 | - Rename the class name (Do not forget to update class_name) 21 | - Add any methods you want to build your strategy 22 | - Add any lib you need to build your strategy 23 | 24 | You must keep: 25 | - the lib in the section "Do not remove these libs" 26 | - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, 27 | populate_sell_trend, hyperopt_space, buy_strategy_generator 28 | """ 29 | 30 | # Minimal ROI designed for the strategy. 31 | # This attribute will be overridden if the config file contains "minimal_roi" 32 | minimal_roi = { 33 | "40": 0.0, 34 | "30": 0.02, 35 | "20": 0.03, 36 | "0": 0.05 37 | } 38 | 39 | # Optimal stoploss designed for the strategy 40 | # This attribute will be overridden if the config file contains "stoploss" 41 | stoploss = -0.05 42 | 43 | # Optimal timeframe for the strategy 44 | timeframe = '15m' 45 | 46 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 47 | """ 48 | Adds several different TA indicators to the given DataFrame 49 | 50 | Performance Note: For the best performance be frugal on the number of indicators 51 | you are using. Let uncomment only the indicator you are using in your strategies 52 | or your hyperopt configuration, otherwise you will waste your memory and CPU usage. 53 | """ 54 | 55 | # Commodity Channel Index: values Oversold:<-100, Overbought:>100 56 | dataframe['cci'] = ta.CCI(dataframe) 57 | 58 | # MFI 59 | dataframe['mfi'] = ta.MFI(dataframe) 60 | 61 | # CMO 62 | dataframe['cmo'] = ta.CMO(dataframe) 63 | 64 | return dataframe 65 | 66 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 67 | """ 68 | Based on TA indicators, populates the buy signal for the given dataframe 69 | :param dataframe: DataFrame 70 | :return: DataFrame with buy column 71 | """ 72 | dataframe.loc[ 73 | ( 74 | (dataframe['cci'].shift(1) < -100) & 75 | (dataframe['mfi'].shift(1) < 20) & 76 | (dataframe['cmo'].shift(1) < -50) 77 | ), 78 | 'buy'] = 1 79 | 80 | return dataframe 81 | 82 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 83 | """ 84 | Based on TA indicators, populates the sell signal for the given dataframe 85 | :param dataframe: DataFrame 86 | :return: DataFrame with buy column 87 | """ 88 | dataframe.loc[ 89 | ( 90 | (dataframe['cci'].shift(1) > 100) & 91 | (dataframe['mfi'].shift(1) > 80) & 92 | (dataframe['cmo'].shift(1) > 50) 93 | ), 94 | 'sell'] = 1 95 | return dataframe 96 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/ClucMay72018.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | from typing import Dict, List 11 | from functools import reduce 12 | from pandas import DataFrame, DatetimeIndex, merge 13 | # -------------------------------- 14 | 15 | import talib.abstract as ta 16 | import freqtrade.vendor.qtpylib.indicators as qtpylib 17 | import numpy # noqa 18 | 19 | 20 | class ClucMay72018(IStrategy): 21 | """ 22 | 23 | author@: Gert Wohlgemuth 24 | 25 | works on new objectify branch! 26 | 27 | """ 28 | 29 | # Minimal ROI designed for the strategy. 30 | # This attribute will be overridden if the config file contains "minimal_roi" 31 | minimal_roi = { 32 | "0": 0.01 33 | } 34 | 35 | # Optimal stoploss designed for the strategy 36 | # This attribute will be overridden if the config file contains "stoploss" 37 | stoploss = -0.05 38 | 39 | # Optimal timeframe for the strategy 40 | timeframe = '5m' 41 | 42 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 43 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=5) 44 | rsiframe = DataFrame(dataframe['rsi']).rename(columns={'rsi': 'close'}) 45 | dataframe['emarsi'] = ta.EMA(rsiframe, timeperiod=5) 46 | macd = ta.MACD(dataframe) 47 | dataframe['macd'] = macd['macd'] 48 | dataframe['adx'] = ta.ADX(dataframe) 49 | bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) 50 | dataframe['bb_lowerband'] = bollinger['lower'] 51 | dataframe['bb_middleband'] = bollinger['mid'] 52 | dataframe['bb_upperband'] = bollinger['upper'] 53 | dataframe['ema100'] = ta.EMA(dataframe, timeperiod=50) 54 | return dataframe 55 | 56 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 57 | """ 58 | Based on TA indicators, populates the buy signal for the given dataframe 59 | :param dataframe: DataFrame 60 | :return: DataFrame with buy column 61 | """ 62 | dataframe.loc[ 63 | ( 64 | (dataframe['close'] < dataframe['ema100']) & 65 | (dataframe['close'] < 0.985 * dataframe['bb_lowerband']) & 66 | (dataframe['volume'] < (dataframe['volume'].rolling(window=30).mean().shift(1) * 20)) 67 | ), 68 | 'buy'] = 1 69 | 70 | return dataframe 71 | 72 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 73 | """ 74 | Based on TA indicators, populates the sell signal for the given dataframe 75 | :param dataframe: DataFrame 76 | :return: DataFrame with buy column 77 | """ 78 | dataframe.loc[ 79 | ( 80 | (dataframe['close'] > dataframe['bb_middleband']) 81 | ), 82 | 'sell'] = 1 83 | return dataframe 84 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/CofiBitStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | import freqtrade.vendor.qtpylib.indicators as qtpylib 3 | import talib.abstract as ta 4 | from freqtrade.strategy.interface import IStrategy 5 | from pandas import DataFrame 6 | 7 | 8 | # -------------------------------- 9 | 10 | 11 | class CofiBitStrategy(IStrategy): 12 | """ 13 | taken from slack by user CofiBit 14 | """ 15 | 16 | # Minimal ROI designed for the strategy. 17 | # This attribute will be overridden if the config file contains "minimal_roi" 18 | minimal_roi = { 19 | "40": 0.05, 20 | "30": 0.06, 21 | "20": 0.07, 22 | "0": 0.10 23 | } 24 | 25 | # Optimal stoploss designed for the strategy 26 | # This attribute will be overridden if the config file contains "stoploss" 27 | stoploss = -0.25 28 | 29 | # Optimal timeframe for the strategy 30 | timeframe = '5m' 31 | 32 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 33 | stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) 34 | dataframe['fastd'] = stoch_fast['fastd'] 35 | dataframe['fastk'] = stoch_fast['fastk'] 36 | dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') 37 | dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') 38 | dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') 39 | dataframe['adx'] = ta.ADX(dataframe) 40 | 41 | return dataframe 42 | 43 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 44 | """ 45 | Based on TA indicators, populates the buy signal for the given dataframe 46 | :param dataframe: DataFrame 47 | :return: DataFrame with buy column 48 | """ 49 | dataframe.loc[ 50 | ( 51 | (dataframe['open'] < dataframe['ema_low']) & 52 | (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) & 53 | # (dataframe['fastk'] > dataframe['fastd']) & 54 | (dataframe['fastk'] < 30) & 55 | (dataframe['fastd'] < 30) & 56 | (dataframe['adx'] > 30) 57 | ), 58 | 'buy'] = 1 59 | 60 | return dataframe 61 | 62 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 63 | """ 64 | Based on TA indicators, populates the sell signal for the given dataframe 65 | :param dataframe: DataFrame 66 | :return: DataFrame with buy column 67 | """ 68 | dataframe.loc[ 69 | ( 70 | (dataframe['open'] >= dataframe['ema_high']) 71 | ) | 72 | ( 73 | # (dataframe['fastk'] > 70) & 74 | # (dataframe['fastd'] > 70) 75 | (qtpylib.crossed_above(dataframe['fastk'], 70)) | 76 | (qtpylib.crossed_above(dataframe['fastd'], 70)) 77 | ), 78 | 'sell'] = 1 79 | 80 | return dataframe 81 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/CombinedBinHAndCluc.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | import freqtrade.vendor.qtpylib.indicators as qtpylib 3 | import numpy as np 4 | # -------------------------------- 5 | import talib.abstract as ta 6 | from freqtrade.strategy.interface import IStrategy 7 | from pandas import DataFrame 8 | 9 | 10 | def bollinger_bands(stock_price, window_size, num_of_std): 11 | rolling_mean = stock_price.rolling(window=window_size).mean() 12 | rolling_std = stock_price.rolling(window=window_size).std() 13 | lower_band = rolling_mean - (rolling_std * num_of_std) 14 | return np.nan_to_num(rolling_mean), np.nan_to_num(lower_band) 15 | 16 | 17 | class CombinedBinHAndCluc(IStrategy): 18 | # Based on a backtesting: 19 | # - the best perfomance is reached with "max_open_trades" = 2 (in average for any market), 20 | # so it is better to increase "stake_amount" value rather then "max_open_trades" to get more profit 21 | # - if the market is constantly green(like in JAN 2018) the best performance is reached with 22 | # "max_open_trades" = 2 and minimal_roi = 0.01 23 | minimal_roi = { 24 | "0": 0.05 25 | } 26 | stoploss = -0.05 27 | timeframe = '5m' 28 | 29 | use_sell_signal = True 30 | sell_profit_only = True 31 | ignore_roi_if_buy_signal = False 32 | 33 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 34 | # strategy BinHV45 35 | mid, lower = bollinger_bands(dataframe['close'], window_size=40, num_of_std=2) 36 | dataframe['lower'] = lower 37 | dataframe['bbdelta'] = (mid - dataframe['lower']).abs() 38 | dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() 39 | dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs() 40 | # strategy ClucMay72018 41 | bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) 42 | dataframe['bb_lowerband'] = bollinger['lower'] 43 | dataframe['bb_middleband'] = bollinger['mid'] 44 | dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=50) 45 | dataframe['volume_mean_slow'] = dataframe['volume'].rolling(window=30).mean() 46 | 47 | return dataframe 48 | 49 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 50 | dataframe.loc[ 51 | ( # strategy BinHV45 52 | dataframe['lower'].shift().gt(0) & 53 | dataframe['bbdelta'].gt(dataframe['close'] * 0.008) & 54 | dataframe['closedelta'].gt(dataframe['close'] * 0.0175) & 55 | dataframe['tail'].lt(dataframe['bbdelta'] * 0.25) & 56 | dataframe['close'].lt(dataframe['lower'].shift()) & 57 | dataframe['close'].le(dataframe['close'].shift()) 58 | ) | 59 | ( # strategy ClucMay72018 60 | (dataframe['close'] < dataframe['ema_slow']) & 61 | (dataframe['close'] < 0.985 * dataframe['bb_lowerband']) & 62 | (dataframe['volume'] < (dataframe['volume_mean_slow'].shift(1) * 20)) 63 | ), 64 | 'buy' 65 | ] = 1 66 | return dataframe 67 | 68 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 69 | """ 70 | """ 71 | dataframe.loc[ 72 | (dataframe['close'] > dataframe['bb_middleband']), 73 | 'sell' 74 | ] = 1 75 | return dataframe 76 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/DoesNothingStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | # -------------------------------- 5 | 6 | 7 | class DoesNothingStrategy(IStrategy): 8 | """ 9 | 10 | author@: Gert Wohlgemuth 11 | 12 | just a skeleton 13 | 14 | """ 15 | 16 | # Minimal ROI designed for the strategy. 17 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 18 | # This attribute will be overridden if the config file contains "minimal_roi" 19 | minimal_roi = { 20 | "0": 0.01 21 | } 22 | 23 | # Optimal stoploss designed for the strategy 24 | stoploss = -0.25 25 | 26 | # Optimal timeframe for the strategy 27 | timeframe = '5m' 28 | 29 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 30 | return dataframe 31 | 32 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 33 | dataframe.loc[ 34 | ( 35 | ), 36 | 'buy'] = 1 37 | return dataframe 38 | 39 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | dataframe.loc[ 41 | ( 42 | ), 43 | 'sell'] = 1 44 | return dataframe 45 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/EMASkipPump.py: -------------------------------------------------------------------------------- 1 | from freqtrade.strategy.interface import IStrategy 2 | from typing import Dict, List 3 | from functools import reduce 4 | from pandas import DataFrame 5 | # -------------------------------- 6 | 7 | import talib.abstract as ta 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | import numpy # noqa 10 | 11 | 12 | class EMASkipPump(IStrategy): 13 | 14 | """ 15 | basic strategy, which trys to avoid pump and dump market conditions. Shared from the tradingview 16 | slack 17 | """ 18 | EMA_SHORT_TERM = 5 19 | EMA_MEDIUM_TERM = 12 20 | EMA_LONG_TERM = 21 21 | 22 | # Minimal ROI designed for the strategy. 23 | # we only sell after 100%, unless our sell points are found before 24 | minimal_roi = { 25 | "0": 0.1 26 | } 27 | 28 | # Optimal stoploss designed for the strategy 29 | # This attribute will be overridden if the config file contains "stoploss" 30 | # should be converted to a trailing stop loss 31 | stoploss = -0.05 32 | 33 | # Optimal timeframe for the strategy 34 | timeframe = '5m' 35 | 36 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 37 | """ Adds several different TA indicators to the given DataFrame 38 | """ 39 | 40 | dataframe['ema_{}'.format(self.EMA_SHORT_TERM)] = ta.EMA( 41 | dataframe, timeperiod=self.EMA_SHORT_TERM 42 | ) 43 | dataframe['ema_{}'.format(self.EMA_MEDIUM_TERM)] = ta.EMA( 44 | dataframe, timeperiod=self.EMA_MEDIUM_TERM 45 | ) 46 | dataframe['ema_{}'.format(self.EMA_LONG_TERM)] = ta.EMA( 47 | dataframe, timeperiod=self.EMA_LONG_TERM 48 | ) 49 | 50 | bollinger = qtpylib.bollinger_bands( 51 | qtpylib.typical_price(dataframe), window=20, stds=2 52 | ) 53 | dataframe['bb_lowerband'] = bollinger['lower'] 54 | dataframe['bb_middleband'] = bollinger['mid'] 55 | dataframe['bb_upperband'] = bollinger['upper'] 56 | 57 | dataframe['min'] = ta.MIN(dataframe, timeperiod=self.EMA_MEDIUM_TERM) 58 | dataframe['max'] = ta.MAX(dataframe, timeperiod=self.EMA_MEDIUM_TERM) 59 | 60 | return dataframe 61 | 62 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 63 | 64 | dataframe.loc[ 65 | (dataframe['volume'] < (dataframe['volume'].rolling(window=30).mean().shift(1) * 20)) & 66 | (dataframe['close'] < dataframe['ema_{}'.format(self.EMA_SHORT_TERM)]) & 67 | (dataframe['close'] < dataframe['ema_{}'.format(self.EMA_MEDIUM_TERM)]) & 68 | (dataframe['close'] == dataframe['min']) & 69 | (dataframe['close'] <= dataframe['bb_lowerband']), 70 | 'buy' 71 | ] = 1 72 | 73 | return dataframe 74 | 75 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 76 | 77 | dataframe.loc[ 78 | (dataframe['close'] > dataframe['ema_{}'.format(self.EMA_SHORT_TERM)]) & 79 | (dataframe['close'] > dataframe['ema_{}'.format(self.EMA_MEDIUM_TERM)]) & 80 | (dataframe['close'] >= dataframe['max']) & 81 | (dataframe['close'] >= dataframe['bb_upperband']), 82 | 'sell' 83 | ] = 1 84 | 85 | return dataframe 86 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/Freqtrade_backtest_validation_freqtrade1.py: -------------------------------------------------------------------------------- 1 | # Freqtrade_backtest_validation_freqtrade1.py 2 | # This script is 1 of a pair the other being freqtrade_backtest_validation_tradingview1 3 | # These should be executed on their respective platforms for the same coin/period/resolution 4 | # The purpose is to test Freqtrade backtest provides like results to a known industry platform. 5 | # 6 | # --- Do not remove these libs --- 7 | from freqtrade.strategy.interface import IStrategy 8 | from pandas import DataFrame 9 | # -------------------------------- 10 | 11 | # Add your lib to import here 12 | import talib.abstract as ta 13 | import freqtrade.vendor.qtpylib.indicators as qtpylib 14 | 15 | 16 | class Freqtrade_backtest_validation_freqtrade1(IStrategy): 17 | # Minimal ROI designed for the strategy. 18 | minimal_roi = { 19 | "40": 2.0, 20 | "30": 2.01, 21 | "20": 2.02, 22 | "0": 2.04 23 | } 24 | 25 | stoploss = -0.90 26 | timeframe = '1h' 27 | 28 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 29 | # SMA - Simple Moving Average 30 | dataframe['fastMA'] = ta.SMA(dataframe, timeperiod=14) 31 | dataframe['slowMA'] = ta.SMA(dataframe, timeperiod=28) 32 | return dataframe 33 | 34 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 35 | dataframe.loc[ 36 | ( 37 | (dataframe['fastMA'] > dataframe['slowMA']) 38 | ), 39 | 'buy'] = 1 40 | 41 | return dataframe 42 | 43 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 44 | dataframe.loc[ 45 | ( 46 | (dataframe['fastMA'] < dataframe['slowMA']) 47 | ), 48 | 'sell'] = 1 49 | return dataframe 50 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/Low_BB.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | from typing import Dict, List 11 | from functools import reduce 12 | from pandas import DataFrame, DatetimeIndex, merge 13 | # -------------------------------- 14 | 15 | import talib.abstract as ta 16 | import freqtrade.vendor.qtpylib.indicators as qtpylib 17 | 18 | 19 | # import numpy as np # noqa 20 | 21 | class Low_BB(IStrategy): 22 | """ 23 | 24 | author@: Thorsten 25 | 26 | works on new objectify branch! 27 | 28 | idea: 29 | buy after crossing .98 * lower_bb and sell if trailing stop loss is hit 30 | """ 31 | 32 | # Minimal ROI designed for the strategy. 33 | # This attribute will be overridden if the config file contains "minimal_roi" 34 | minimal_roi = { 35 | "0": 0.9, 36 | "1": 0.05, 37 | "10": 0.04, 38 | "15": 0.5 39 | } 40 | 41 | # Optimal stoploss designed for the strategy 42 | # This attribute will be overridden if the config file contains "stoploss" 43 | stoploss = -0.015 44 | 45 | # Optimal timeframe for the strategy 46 | timeframe = '1m' 47 | 48 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 49 | ################################################################################## 50 | # buy and sell indicators 51 | 52 | bollinger = qtpylib.bollinger_bands( 53 | qtpylib.typical_price(dataframe), window=20, stds=2 54 | ) 55 | dataframe['bb_lowerband'] = bollinger['lower'] 56 | dataframe['bb_middleband'] = bollinger['mid'] 57 | dataframe['bb_upperband'] = bollinger['upper'] 58 | 59 | macd = ta.MACD(dataframe) 60 | dataframe['macd'] = macd['macd'] 61 | dataframe['macdsignal'] = macd['macdsignal'] 62 | dataframe['macdhist'] = macd['macdhist'] 63 | 64 | # dataframe['cci'] = ta.CCI(dataframe) 65 | # dataframe['mfi'] = ta.MFI(dataframe) 66 | # dataframe['rsi'] = ta.RSI(dataframe, timeperiod=7) 67 | 68 | # dataframe['canbuy'] = np.NaN 69 | # dataframe['canbuy2'] = np.NaN 70 | # dataframe.loc[dataframe.close.rolling(49).min() <= 1.1 * dataframe.close, 'canbuy'] == 1 71 | # dataframe.loc[dataframe.close.rolling(600).max() < 1.2 * dataframe.close, 'canbuy'] = 1 72 | # dataframe.loc[dataframe.close.rolling(600).max() * 0.8 > dataframe.close, 'canbuy2'] = 1 73 | ################################################################################## 74 | # required for graphing 75 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 76 | dataframe['bb_lowerband'] = bollinger['lower'] 77 | dataframe['bb_upperband'] = bollinger['upper'] 78 | dataframe['bb_middleband'] = bollinger['mid'] 79 | 80 | return dataframe 81 | 82 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 83 | """ 84 | Based on TA indicators, populates the buy signal for the given dataframe 85 | :param dataframe: DataFrame 86 | :return: DataFrame with buy column 87 | """ 88 | dataframe.loc[ 89 | ( 90 | 91 | (dataframe['close'] <= 0.98 * dataframe['bb_lowerband']) 92 | 93 | ) 94 | , 95 | 'buy'] = 1 96 | 97 | return dataframe 98 | 99 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 100 | """ 101 | Based on TA indicators, populates the sell signal for the given dataframe 102 | :param dataframe: DataFrame 103 | :return: DataFrame with buy column 104 | """ 105 | dataframe.loc[ 106 | (), 107 | 'sell'] = 1 108 | return dataframe 109 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/MACDStrategy.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | 11 | 12 | class MACDStrategy(IStrategy): 13 | """ 14 | 15 | author@: Gert Wohlgemuth 16 | 17 | idea: 18 | 19 | uptrend definition: 20 | MACD above MACD signal 21 | and CCI < -50 22 | 23 | downtrend definition: 24 | MACD below MACD signal 25 | and CCI > 100 26 | 27 | """ 28 | 29 | # Minimal ROI designed for the strategy. 30 | # This attribute will be overridden if the config file contains "minimal_roi" 31 | minimal_roi = { 32 | "60": 0.01, 33 | "30": 0.03, 34 | "20": 0.04, 35 | "0": 0.05 36 | } 37 | 38 | # Optimal stoploss designed for the strategy 39 | # This attribute will be overridden if the config file contains "stoploss" 40 | stoploss = -0.3 41 | 42 | # Optimal timeframe for the strategy 43 | timeframe = '5m' 44 | 45 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 46 | 47 | macd = ta.MACD(dataframe) 48 | dataframe['macd'] = macd['macd'] 49 | dataframe['macdsignal'] = macd['macdsignal'] 50 | dataframe['macdhist'] = macd['macdhist'] 51 | dataframe['cci'] = ta.CCI(dataframe) 52 | 53 | return dataframe 54 | 55 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 56 | """ 57 | Based on TA indicators, populates the buy signal for the given dataframe 58 | :param dataframe: DataFrame 59 | :return: DataFrame with buy column 60 | """ 61 | dataframe.loc[ 62 | ( 63 | (dataframe['macd'] > dataframe['macdsignal']) & 64 | (dataframe['cci'] <= -50.0) 65 | ), 66 | 'buy'] = 1 67 | 68 | return dataframe 69 | 70 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 71 | """ 72 | Based on TA indicators, populates the sell signal for the given dataframe 73 | :param dataframe: DataFrame 74 | :return: DataFrame with buy column 75 | """ 76 | dataframe.loc[ 77 | ( 78 | (dataframe['macd'] < dataframe['macdsignal']) & 79 | (dataframe['cci'] >= 100.0) 80 | ), 81 | 'sell'] = 1 82 | 83 | return dataframe 84 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/MACDStrategy_crossed.py: -------------------------------------------------------------------------------- 1 | 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | 9 | import talib.abstract as ta 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | 12 | 13 | class MACDStrategy_crossed(IStrategy): 14 | """ 15 | buy: 16 | MACD crosses MACD signal above 17 | and CCI < -50 18 | sell: 19 | MACD crosses MACD signal below 20 | and CCI > 100 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "60": 0.01, 27 | "30": 0.03, 28 | "20": 0.04, 29 | "0": 0.05 30 | } 31 | 32 | # Optimal stoploss designed for the strategy 33 | # This attribute will be overridden if the config file contains "stoploss" 34 | stoploss = -0.3 35 | 36 | # Optimal timeframe for the strategy 37 | timeframe = '5m' 38 | 39 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | 41 | macd = ta.MACD(dataframe) 42 | dataframe['macd'] = macd['macd'] 43 | dataframe['macdsignal'] = macd['macdsignal'] 44 | dataframe['macdhist'] = macd['macdhist'] 45 | dataframe['cci'] = ta.CCI(dataframe) 46 | 47 | return dataframe 48 | 49 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 50 | """ 51 | Based on TA indicators, populates the buy signal for the given dataframe 52 | :param dataframe: DataFrame 53 | :return: DataFrame with buy column 54 | """ 55 | dataframe.loc[ 56 | ( 57 | qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']) & 58 | (dataframe['cci'] <= -50.0) 59 | ), 60 | 'buy'] = 1 61 | 62 | return dataframe 63 | 64 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 65 | """ 66 | Based on TA indicators, populates the sell signal for the given dataframe 67 | :param dataframe: DataFrame 68 | :return: DataFrame with buy column 69 | """ 70 | dataframe.loc[ 71 | ( 72 | qtpylib.crossed_below(dataframe['macd'], dataframe['macdsignal']) & 73 | (dataframe['cci'] >= 100.0) 74 | ), 75 | 'sell'] = 1 76 | 77 | return dataframe 78 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/MultiRSI.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from pandas import DataFrame 4 | # -------------------------------- 5 | import talib.abstract as ta 6 | from technical.util import resample_to_interval, resampled_merge 7 | 8 | 9 | class MultiRSI(IStrategy): 10 | """ 11 | 12 | author@: Gert Wohlgemuth 13 | 14 | based on work from Creslin 15 | 16 | """ 17 | minimal_roi = { 18 | "0": 0.01 19 | } 20 | 21 | # Optimal stoploss designed for the strategy 22 | stoploss = -0.05 23 | 24 | # Optimal timeframe for the strategy 25 | timeframe = '5m' 26 | 27 | def get_ticker_indicator(self): 28 | return int(self.timeframe[:-1]) 29 | 30 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 31 | 32 | dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5) 33 | dataframe['sma200'] = ta.SMA(dataframe, timeperiod=200) 34 | 35 | # resample our dataframes 36 | dataframe_short = resample_to_interval(dataframe, self.get_ticker_indicator() * 2) 37 | dataframe_long = resample_to_interval(dataframe, self.get_ticker_indicator() * 8) 38 | 39 | # compute our RSI's 40 | dataframe_short['rsi'] = ta.RSI(dataframe_short, timeperiod=14) 41 | dataframe_long['rsi'] = ta.RSI(dataframe_long, timeperiod=14) 42 | 43 | # merge dataframe back together 44 | dataframe = resampled_merge(dataframe, dataframe_short) 45 | dataframe = resampled_merge(dataframe, dataframe_long) 46 | 47 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 48 | 49 | dataframe.fillna(method='ffill', inplace=True) 50 | 51 | return dataframe 52 | 53 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 54 | dataframe.loc[ 55 | ( 56 | # must be bearish 57 | (dataframe['sma5'] >= dataframe['sma200']) & 58 | (dataframe['rsi'] < (dataframe['resample_{}_rsi'.format(self.get_ticker_indicator() * 8)] - 20)) 59 | ), 60 | 'buy'] = 1 61 | return dataframe 62 | 63 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 64 | dataframe.loc[ 65 | ( 66 | (dataframe['rsi'] > dataframe['resample_{}_rsi'.format(self.get_ticker_indicator()*2)]) & 67 | (dataframe['rsi'] > dataframe['resample_{}_rsi'.format(self.get_ticker_indicator()*8)]) 68 | ), 69 | 'sell'] = 1 70 | return dataframe 71 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/Quickie.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | 11 | 12 | class Quickie(IStrategy): 13 | """ 14 | 15 | author@: Gert Wohlgemuth 16 | 17 | idea: 18 | momentum based strategie. The main idea is that it closes trades very quickly, while avoiding excessive losses. Hence a rather moderate stop loss in this case 19 | """ 20 | 21 | # Minimal ROI designed for the strategy. 22 | # This attribute will be overridden if the config file contains "minimal_roi" 23 | minimal_roi = { 24 | "100": 0.01, 25 | "30": 0.03, 26 | "15": 0.06, 27 | "10": 0.15, 28 | } 29 | 30 | # Optimal stoploss designed for the strategy 31 | # This attribute will be overridden if the config file contains "stoploss" 32 | stoploss = -0.25 33 | 34 | # Optimal timeframe for the strategy 35 | timeframe = '5m' 36 | 37 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 38 | macd = ta.MACD(dataframe) 39 | dataframe['macd'] = macd['macd'] 40 | dataframe['macdsignal'] = macd['macdsignal'] 41 | dataframe['macdhist'] = macd['macdhist'] 42 | 43 | dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) 44 | dataframe['sma_200'] = ta.SMA(dataframe, timeperiod=200) 45 | dataframe['sma_50'] = ta.SMA(dataframe, timeperiod=200) 46 | 47 | dataframe['adx'] = ta.ADX(dataframe) 48 | 49 | # required for graphing 50 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 51 | dataframe['bb_lowerband'] = bollinger['lower'] 52 | dataframe['bb_middleband'] = bollinger['mid'] 53 | dataframe['bb_upperband'] = bollinger['upper'] 54 | 55 | return dataframe 56 | 57 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 58 | dataframe.loc[ 59 | ( 60 | (dataframe['adx'] > 30) & 61 | (dataframe['tema'] < dataframe['bb_middleband']) & 62 | (dataframe['tema'] > dataframe['tema'].shift(1)) & 63 | (dataframe['sma_200'] > dataframe['close']) 64 | 65 | ), 66 | 'buy'] = 1 67 | return dataframe 68 | 69 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 70 | dataframe.loc[ 71 | ( 72 | (dataframe['adx'] > 70) & 73 | (dataframe['tema'] > dataframe['bb_middleband']) & 74 | (dataframe['tema'] < dataframe['tema'].shift(1)) 75 | ), 76 | 'sell'] = 1 77 | return dataframe 78 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/ReinforcedAverageStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame, merge, DatetimeIndex 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | from technical.util import resample_to_interval, resampled_merge 11 | from freqtrade.exchange import timeframe_to_minutes 12 | 13 | 14 | class ReinforcedAverageStrategy(IStrategy): 15 | """ 16 | 17 | author@: Gert Wohlgemuth 18 | 19 | idea: 20 | buys and sells on crossovers - doesn't really perfom that well and its just a proof of concept 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.5 27 | } 28 | 29 | # Optimal stoploss designed for the strategy 30 | # This attribute will be overridden if the config file contains "stoploss" 31 | stoploss = -0.2 32 | 33 | # Optimal timeframe for the strategy 34 | timeframe = '4h' 35 | 36 | # trailing stoploss 37 | trailing_stop = False 38 | trailing_stop_positive = 0.01 39 | trailing_stop_positive_offset = 0.02 40 | trailing_only_offset_is_reached = False 41 | 42 | # run "populate_indicators" only for new candle 43 | process_only_new_candles = False 44 | 45 | # Experimental settings (configuration will overide these if set) 46 | use_sell_signal = True 47 | sell_profit_only = False 48 | ignore_roi_if_buy_signal = False 49 | 50 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 51 | 52 | dataframe['maShort'] = ta.EMA(dataframe, timeperiod=8) 53 | dataframe['maMedium'] = ta.EMA(dataframe, timeperiod=21) 54 | ################################################################################## 55 | # required for graphing 56 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 57 | dataframe['bb_lowerband'] = bollinger['lower'] 58 | dataframe['bb_upperband'] = bollinger['upper'] 59 | dataframe['bb_middleband'] = bollinger['mid'] 60 | self.resample_interval = timeframe_to_minutes(self.timeframe) * 12 61 | dataframe_long = resample_to_interval(dataframe, self.resample_interval) 62 | dataframe_long['sma'] = ta.SMA(dataframe_long, timeperiod=50, price='close') 63 | dataframe = resampled_merge(dataframe, dataframe_long, fill_na=True) 64 | 65 | return dataframe 66 | 67 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 68 | """ 69 | Based on TA indicators, populates the buy signal for the given dataframe 70 | :param dataframe: DataFrame 71 | :return: DataFrame with buy column 72 | """ 73 | 74 | dataframe.loc[ 75 | ( 76 | qtpylib.crossed_above(dataframe['maShort'], dataframe['maMedium']) & 77 | (dataframe['close'] > dataframe[f'resample_{self.resample_interval}_sma']) & 78 | (dataframe['volume'] > 0) 79 | ), 80 | 'buy'] = 1 81 | 82 | return dataframe 83 | 84 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 85 | """ 86 | Based on TA indicators, populates the sell signal for the given dataframe 87 | :param dataframe: DataFrame 88 | :return: DataFrame with buy column 89 | """ 90 | dataframe.loc[ 91 | ( 92 | qtpylib.crossed_above(dataframe['maMedium'], dataframe['maShort']) & 93 | (dataframe['volume'] > 0) 94 | ), 95 | 'sell'] = 1 96 | return dataframe 97 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/ReinforcedSmoothScalp.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from freqtrade.strategy import timeframe_to_minutes 4 | from pandas import DataFrame 5 | from technical.util import resample_to_interval, resampled_merge 6 | import numpy # noqa 7 | # -------------------------------- 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | 11 | 12 | class ReinforcedSmoothScalp(IStrategy): 13 | """ 14 | this strategy is based around the idea of generating a lot of potentatils buys and make tiny profits on each trade 15 | 16 | we recommend to have at least 60 parallel trades at any time to cover non avoidable losses 17 | """ 18 | 19 | # Minimal ROI designed for the strategy. 20 | # This attribute will be overridden if the config file contains "minimal_roi" 21 | minimal_roi = { 22 | "0": 0.02 23 | } 24 | # Optimal stoploss designed for the strategy 25 | # This attribute will be overridden if the config file contains "stoploss" 26 | # should not be below 3% loss 27 | 28 | stoploss = -0.1 29 | # Optimal timeframe for the strategy 30 | # the shorter the better 31 | timeframe = '1m' 32 | 33 | # resample factor to establish our general trend. Basically don't buy if a trend is not given 34 | resample_factor = 5 35 | 36 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 37 | tf_res = timeframe_to_minutes(self.timeframe) * 5 38 | df_res = resample_to_interval(dataframe, tf_res) 39 | df_res['sma'] = ta.SMA(df_res, 50, price='close') 40 | dataframe = resampled_merge(dataframe, df_res, fill_na=True) 41 | dataframe['resample_sma'] = dataframe[f'resample_{tf_res}_sma'] 42 | 43 | dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') 44 | dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') 45 | dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') 46 | stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) 47 | dataframe['fastd'] = stoch_fast['fastd'] 48 | dataframe['fastk'] = stoch_fast['fastk'] 49 | dataframe['adx'] = ta.ADX(dataframe) 50 | dataframe['cci'] = ta.CCI(dataframe, timeperiod=20) 51 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 52 | dataframe['mfi'] = ta.MFI(dataframe) 53 | 54 | # required for graphing 55 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 56 | dataframe['bb_lowerband'] = bollinger['lower'] 57 | dataframe['bb_upperband'] = bollinger['upper'] 58 | dataframe['bb_middleband'] = bollinger['mid'] 59 | 60 | return dataframe 61 | 62 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 63 | dataframe.loc[ 64 | ( 65 | ( 66 | (dataframe['open'] < dataframe['ema_low']) & 67 | (dataframe['adx'] > 30) & 68 | (dataframe['mfi'] < 30) & 69 | ( 70 | (dataframe['fastk'] < 30) & 71 | (dataframe['fastd'] < 30) & 72 | (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) 73 | ) & 74 | (dataframe['resample_sma'] < dataframe['close']) 75 | ) 76 | # | 77 | # # try to get some sure things independent of resample 78 | # ((dataframe['rsi'] - dataframe['mfi']) < 10) & 79 | # (dataframe['mfi'] < 30) & 80 | # (dataframe['cci'] < -200) 81 | ), 82 | 'buy'] = 1 83 | return dataframe 84 | 85 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 86 | dataframe.loc[ 87 | ( 88 | ( 89 | ( 90 | (dataframe['open'] >= dataframe['ema_high']) 91 | 92 | ) | 93 | ( 94 | (qtpylib.crossed_above(dataframe['fastk'], 70)) | 95 | (qtpylib.crossed_above(dataframe['fastd'], 70)) 96 | 97 | ) 98 | ) & (dataframe['cci'] > 100) 99 | ) 100 | , 101 | 'sell'] = 1 102 | return dataframe 103 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/Scalp.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | import talib.abstract as ta 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | # -------------------------------- 10 | import talib.abstract as ta 11 | import freqtrade.vendor.qtpylib.indicators as qtpylib 12 | 13 | 14 | class Scalp(IStrategy): 15 | """ 16 | this strategy is based around the idea of generating a lot of potentatils buys and make tiny profits on each trade 17 | 18 | we recommend to have at least 60 parallel trades at any time to cover non avoidable losses. 19 | 20 | Recommended is to only sell based on ROI for this strategy 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # This attribute will be overridden if the config file contains "minimal_roi" 25 | minimal_roi = { 26 | "0": 0.01 27 | } 28 | # Optimal stoploss designed for the strategy 29 | # This attribute will be overridden if the config file contains "stoploss" 30 | # should not be below 3% loss 31 | 32 | stoploss = -0.04 33 | # Optimal timeframe for the strategy 34 | # the shorter the better 35 | timeframe = '1m' 36 | 37 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 38 | dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') 39 | dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') 40 | dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') 41 | stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) 42 | dataframe['fastd'] = stoch_fast['fastd'] 43 | dataframe['fastk'] = stoch_fast['fastk'] 44 | dataframe['adx'] = ta.ADX(dataframe) 45 | 46 | # required for graphing 47 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 48 | dataframe['bb_lowerband'] = bollinger['lower'] 49 | dataframe['bb_upperband'] = bollinger['upper'] 50 | dataframe['bb_middleband'] = bollinger['mid'] 51 | 52 | return dataframe 53 | 54 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 55 | dataframe.loc[ 56 | ( 57 | (dataframe['open'] < dataframe['ema_low']) & 58 | (dataframe['adx'] > 30) & 59 | ( 60 | (dataframe['fastk'] < 30) & 61 | (dataframe['fastd'] < 30) & 62 | (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) 63 | ) 64 | ), 65 | 'buy'] = 1 66 | return dataframe 67 | 68 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 69 | dataframe.loc[ 70 | ( 71 | (dataframe['open'] >= dataframe['ema_high']) 72 | ) | 73 | ( 74 | (qtpylib.crossed_above(dataframe['fastk'], 70)) | 75 | (qtpylib.crossed_above(dataframe['fastd'], 70)) 76 | ), 77 | 'sell'] = 1 78 | return dataframe 79 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/Simple.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | 8 | import talib.abstract as ta 9 | import freqtrade.vendor.qtpylib.indicators as qtpylib 10 | 11 | 12 | class Simple(IStrategy): 13 | """ 14 | 15 | author@: Gert Wohlgemuth 16 | 17 | idea: 18 | this strategy is based on the book, 'The Simple Strategy' and can be found in detail here: 19 | 20 | https://www.amazon.com/Simple-Strategy-Powerful-Trading-Futures-ebook/dp/B00E66QPCG/ref=sr_1_1?ie=UTF8&qid=1525202675&sr=8-1&keywords=the+simple+strategy 21 | """ 22 | 23 | # Minimal ROI designed for the strategy. 24 | # adjust based on market conditions. We would recommend to keep it low for quick turn arounds 25 | # This attribute will be overridden if the config file contains "minimal_roi" 26 | minimal_roi = { 27 | "0": 0.01 28 | } 29 | 30 | # Optimal stoploss designed for the strategy 31 | # This attribute will be overridden if the config file contains "stoploss" 32 | stoploss = -0.25 33 | 34 | # Optimal timeframe for the strategy 35 | timeframe = '5m' 36 | 37 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 38 | # MACD 39 | macd = ta.MACD(dataframe) 40 | dataframe['macd'] = macd['macd'] 41 | dataframe['macdsignal'] = macd['macdsignal'] 42 | dataframe['macdhist'] = macd['macdhist'] 43 | 44 | # RSI 45 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=7) 46 | 47 | # required for graphing 48 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=12, stds=2) 49 | dataframe['bb_lowerband'] = bollinger['lower'] 50 | dataframe['bb_upperband'] = bollinger['upper'] 51 | dataframe['bb_middleband'] = bollinger['mid'] 52 | 53 | return dataframe 54 | 55 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 56 | dataframe.loc[ 57 | ( 58 | ( 59 | (dataframe['macd'] > 0) # over 0 60 | & (dataframe['macd'] > dataframe['macdsignal']) # over signal 61 | & (dataframe['bb_upperband'] > dataframe['bb_upperband'].shift(1)) # pointed up 62 | & (dataframe['rsi'] > 70) # optional filter, need to investigate 63 | ) 64 | ), 65 | 'buy'] = 1 66 | return dataframe 67 | 68 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 69 | # different strategy used for sell points, due to be able to duplicate it to 100% 70 | dataframe.loc[ 71 | ( 72 | (dataframe['rsi'] > 80) 73 | ), 74 | 'sell'] = 1 75 | return dataframe 76 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/SmoothScalp.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | from freqtrade.strategy.interface import IStrategy 3 | from typing import Dict, List 4 | from functools import reduce 5 | from pandas import DataFrame 6 | # -------------------------------- 7 | import talib.abstract as ta 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | from typing import Dict, List 10 | from functools import reduce 11 | from pandas import DataFrame, DatetimeIndex, merge 12 | # -------------------------------- 13 | import talib.abstract as ta 14 | import freqtrade.vendor.qtpylib.indicators as qtpylib 15 | import numpy # noqa 16 | 17 | 18 | class SmoothScalp(IStrategy): 19 | """ 20 | this strategy is based around the idea of generating a lot of potentatils buys and make tiny profits on each trade 21 | 22 | we recommend to have at least 60 parallel trades at any time to cover non avoidable losses 23 | """ 24 | 25 | # Minimal ROI designed for the strategy. 26 | # This attribute will be overridden if the config file contains "minimal_roi" 27 | minimal_roi = { 28 | "0": 0.01 29 | } 30 | # Optimal stoploss designed for the strategy 31 | # This attribute will be overridden if the config file contains "stoploss" 32 | # should not be below 3% loss 33 | 34 | stoploss = -0.5 35 | # Optimal timeframe for the strategy 36 | # the shorter the better 37 | timeframe = '1m' 38 | 39 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 40 | dataframe['ema_high'] = ta.EMA(dataframe, timeperiod=5, price='high') 41 | dataframe['ema_close'] = ta.EMA(dataframe, timeperiod=5, price='close') 42 | dataframe['ema_low'] = ta.EMA(dataframe, timeperiod=5, price='low') 43 | stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) 44 | dataframe['fastd'] = stoch_fast['fastd'] 45 | dataframe['fastk'] = stoch_fast['fastk'] 46 | dataframe['adx'] = ta.ADX(dataframe) 47 | dataframe['cci'] = ta.CCI(dataframe, timeperiod=20) 48 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 49 | dataframe['mfi'] = ta.MFI(dataframe) 50 | 51 | # required for graphing 52 | bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) 53 | dataframe['bb_lowerband'] = bollinger['lower'] 54 | dataframe['bb_upperband'] = bollinger['upper'] 55 | dataframe['bb_middleband'] = bollinger['mid'] 56 | 57 | macd = ta.MACD(dataframe) 58 | dataframe['macd'] = macd['macd'] 59 | dataframe['macdsignal'] = macd['macdsignal'] 60 | dataframe['macdhist'] = macd['macdhist'] 61 | dataframe['cci'] = ta.CCI(dataframe) 62 | 63 | return dataframe 64 | 65 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 66 | dataframe.loc[ 67 | ( 68 | ( 69 | (dataframe['open'] < dataframe['ema_low']) & 70 | (dataframe['adx'] > 30) & 71 | (dataframe['mfi'] < 30) & 72 | ( 73 | (dataframe['fastk'] < 30) & 74 | (dataframe['fastd'] < 30) & 75 | (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) 76 | ) & 77 | (dataframe['cci'] < -150) 78 | ) 79 | 80 | ), 81 | 'buy'] = 1 82 | return dataframe 83 | 84 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 85 | dataframe.loc[ 86 | ( 87 | ( 88 | ( 89 | (dataframe['open'] >= dataframe['ema_high']) 90 | 91 | ) | 92 | ( 93 | (qtpylib.crossed_above(dataframe['fastk'], 70)) | 94 | (qtpylib.crossed_above(dataframe['fastd'], 70)) 95 | 96 | ) 97 | ) & (dataframe['cci'] > 150) 98 | ) 99 | , 100 | 'sell'] = 1 101 | return dataframe 102 | -------------------------------------------------------------------------------- /user_data/strategies/berlinguyinca/TechnicalExampleStrategy.py: -------------------------------------------------------------------------------- 1 | from pandas import DataFrame 2 | from technical.indicators import cmf 3 | 4 | from freqtrade.strategy.interface import IStrategy 5 | 6 | 7 | class TechnicalExampleStrategy(IStrategy): 8 | minimal_roi = { 9 | "0": 0.01 10 | } 11 | 12 | stoploss = -0.05 13 | 14 | # Optimal timeframe for the strategy 15 | timeframe = '5m' 16 | 17 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 18 | dataframe['cmf'] = cmf(dataframe, 21) 19 | 20 | return dataframe 21 | 22 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 23 | dataframe.loc[ 24 | ( 25 | ( 26 | (dataframe['cmf'] < 0) 27 | 28 | ) 29 | ), 30 | 'buy'] = 1 31 | return dataframe 32 | 33 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 34 | # different strategy used for sell points, due to be able to duplicate it to 100% 35 | dataframe.loc[ 36 | ( 37 | (dataframe['cmf'] > 0) 38 | ), 39 | 'sell'] = 1 40 | return dataframe 41 | -------------------------------------------------------------------------------- /user_data/strategies/custom_stoploss_with_psar.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | # isort: skip_file 3 | # --- Do not remove these libs --- 4 | import numpy as np # noqa 5 | import pandas as pd # noqa 6 | from pandas import DataFrame 7 | 8 | from freqtrade.strategy.interface import IStrategy 9 | 10 | # -------------------------------- 11 | # Add your lib to import here 12 | import talib.abstract as ta 13 | import freqtrade.vendor.qtpylib.indicators as qtpylib 14 | from datetime import datetime 15 | from freqtrade.persistence import Trade 16 | 17 | 18 | class CustomStoplossWithPSAR(IStrategy): 19 | """ 20 | this is an example class, implementing a PSAR based trailing stop loss 21 | you are supposed to take the `custom_stoploss()` and `populate_indicators()` 22 | parts and adapt it to your own strategy 23 | 24 | the populate_buy_trend() function is pretty nonsencial 25 | """ 26 | timeframe = '1h' 27 | stoploss = -0.2 28 | custom_info = {} 29 | use_custom_stoploss = True 30 | 31 | def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, 32 | current_rate: float, current_profit: float, **kwargs) -> float: 33 | 34 | result = 1 35 | if self.custom_info and pair in self.custom_info and trade: 36 | # using current_time directly (like below) will only work in backtesting/hyperopt. 37 | # in live / dry-run, it'll be really the current time 38 | relative_sl = None 39 | if self.dp: 40 | # so we need to get analyzed_dataframe from dp 41 | dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) 42 | # only use .iat[-1] in callback methods, never in "populate_*" methods. 43 | # see: https://www.freqtrade.io/en/latest/strategy-customization/#common-mistakes-when-developing-strategies 44 | last_candle = dataframe.iloc[-1].squeeze() 45 | relative_sl = last_candle['sar'] 46 | 47 | if (relative_sl is not None): 48 | # print("custom_stoploss().relative_sl: {}".format(relative_sl)) 49 | # calculate new_stoploss relative to current_rate 50 | new_stoploss = (current_rate - relative_sl) / current_rate 51 | # turn into relative negative offset required by `custom_stoploss` return implementation 52 | result = new_stoploss - 1 53 | 54 | # print("custom_stoploss() -> {}".format(result)) 55 | return result 56 | 57 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 58 | dataframe['sar'] = ta.SAR(dataframe) 59 | if self.dp.runmode.value in ('backtest', 'hyperopt'): 60 | self.custom_info[metadata['pair']] = dataframe[['date', 'sar']].copy().set_index('date') 61 | 62 | # all "normal" indicators: 63 | # e.g. 64 | # dataframe['rsi'] = ta.RSI(dataframe) 65 | return dataframe 66 | 67 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 68 | """ 69 | Placeholder Strategy: buys when SAR is smaller then candle before 70 | Based on TA indicators, populates the buy signal for the given dataframe 71 | :param dataframe: DataFrame 72 | :return: DataFrame with buy column 73 | """ 74 | dataframe.loc[ 75 | ( 76 | (dataframe['sar'] < dataframe['sar'].shift()) 77 | ), 78 | 'buy'] = 1 79 | 80 | return dataframe 81 | 82 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 83 | """ 84 | Placeholder Strategy: does nothing 85 | Based on TA indicators, populates the sell signal for the given dataframe 86 | :param dataframe: DataFrame 87 | :return: DataFrame with buy column 88 | """ 89 | # Deactivated sell signal to allow the strategy to work correctly 90 | dataframe.loc[:, 'sell'] = 0 91 | return dataframe 92 | -------------------------------------------------------------------------------- /user_data/strategies/hlhb.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | 3 | import numpy as np # noqa 4 | import pandas as pd # noqa 5 | from pandas import DataFrame 6 | from freqtrade.strategy import IStrategy 7 | import talib.abstract as ta 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | 10 | 11 | class hlhb(IStrategy): 12 | """ 13 | The HLHB ("Huck loves her bucks!") System simply aims to catch short-term forex trends. 14 | More information in https://www.babypips.com/trading/forex-hlhb-system-explained 15 | """ 16 | 17 | INTERFACE_VERSION = 2 18 | 19 | position_stacking = "True" 20 | 21 | # Minimal ROI designed for the strategy. 22 | # This attribute will be overridden if the config file contains "minimal_roi". 23 | minimal_roi = { 24 | "0": 0.6225, 25 | "703": 0.2187, 26 | "2849": 0.0363, 27 | "5520": 0 28 | } 29 | 30 | # Optimal stoploss designed for the strategy. 31 | # This attribute will be overridden if the config file contains "stoploss". 32 | stoploss = -0.3211 33 | 34 | # Trailing stoploss 35 | trailing_stop = True 36 | trailing_stop_positive = 0.0117 37 | trailing_stop_positive_offset = 0.0186 38 | trailing_only_offset_is_reached = True 39 | 40 | # Optimal timeframe for the strategy. 41 | timeframe = '4h' 42 | 43 | # Run "populate_indicators()" only for new candle. 44 | process_only_new_candles = True 45 | 46 | # These values can be overridden in the "ask_strategy" section in the config. 47 | use_sell_signal = True 48 | sell_profit_only = False 49 | ignore_roi_if_buy_signal = True 50 | 51 | # Number of candles the strategy requires before producing valid signals 52 | startup_candle_count: int = 30 53 | 54 | # Optional order type mapping. 55 | order_types = { 56 | 'buy': 'limit', 57 | 'sell': 'limit', 58 | 'stoploss': 'market', 59 | 'stoploss_on_exchange': False 60 | } 61 | 62 | # Optional order time in force. 63 | order_time_in_force = { 64 | 'buy': 'gtc', 65 | 'sell': 'gtc' 66 | } 67 | 68 | plot_config = { 69 | # Main plot indicators (Moving averages, ...) 70 | 'main_plot': { 71 | 'ema5': {}, 72 | 'ema10': {}, 73 | }, 74 | 'subplots': { 75 | # Subplots - each dict defines one additional plot 76 | "RSI": { 77 | 'rsi': {'color': 'red'}, 78 | }, 79 | "ADX": { 80 | 'adx': {}, 81 | } 82 | } 83 | } 84 | 85 | def informative_pairs(self): 86 | return [] 87 | 88 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 89 | dataframe['hl2'] = (dataframe["close"] + dataframe["open"]) / 2 90 | 91 | # Momentum Indicators 92 | # ------------------------------------ 93 | 94 | # RSI 95 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=10, price='hl2') 96 | 97 | # # EMA - Exponential Moving Average 98 | dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) 99 | dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) 100 | 101 | # ADX 102 | dataframe['adx'] = ta.ADX(dataframe) 103 | 104 | return dataframe 105 | 106 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 107 | dataframe.loc[ 108 | ( 109 | (qtpylib.crossed_above(dataframe['rsi'], 50)) & 110 | (qtpylib.crossed_above(dataframe['ema5'], dataframe['ema10'])) & 111 | (dataframe['adx'] > 25) & 112 | (dataframe['volume'] > 0) # Make sure Volume is not 0 113 | ), 114 | 'buy'] = 1 115 | 116 | return dataframe 117 | 118 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 119 | dataframe.loc[ 120 | ( 121 | (qtpylib.crossed_below(dataframe['rsi'], 50)) & 122 | (qtpylib.crossed_below(dataframe['ema5'], dataframe['ema10'])) & 123 | (dataframe['adx'] > 25) & 124 | (dataframe['volume'] > 0) # Make sure Volume is not 0 125 | ), 126 | 'sell'] = 1 127 | return dataframe 128 | 129 | -------------------------------------------------------------------------------- /user_data/strategies/hlhbOpt.py: -------------------------------------------------------------------------------- 1 | # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement 2 | 3 | import numpy as np # noqa 4 | import pandas as pd # noqa 5 | from pandas import DataFrame 6 | from freqtrade.strategy import IStrategy 7 | import talib.abstract as ta 8 | import freqtrade.vendor.qtpylib.indicators as qtpylib 9 | 10 | 11 | class hlhbOpt(IStrategy): 12 | """ 13 | The HLHB ("Huck loves her bucks!") System simply aims to catch short-term forex trends. 14 | More information in https://www.babypips.com/trading/forex-hlhb-system-explained 15 | """ 16 | 17 | INTERFACE_VERSION = 2 18 | 19 | position_stacking = "True" 20 | 21 | # Minimal ROI designed for the strategy. 22 | # This attribute will be overridden if the config file contains "minimal_roi". 23 | # ROI table: 24 | minimal_roi = { 25 | "0": 0.677, 26 | "1264": 0.097, 27 | "1885": 0.037, 28 | "6913": 0 29 | } 30 | 31 | # Stoploss: 32 | stoploss = -0.02 33 | 34 | # Trailing stop: 35 | trailing_stop = True 36 | trailing_stop_positive = 0.132 37 | trailing_stop_positive_offset = 0.221 38 | trailing_only_offset_is_reached = False 39 | 40 | # Optimal timeframe for the strategy. 41 | timeframe = '4h' 42 | 43 | # Run "populate_indicators()" only for new candle. 44 | process_only_new_candles = True 45 | 46 | # These values can be overridden in the "ask_strategy" section in the config. 47 | use_sell_signal = True 48 | sell_profit_only = False 49 | ignore_roi_if_buy_signal = True 50 | 51 | # Number of candles the strategy requires before producing valid signals 52 | startup_candle_count: int = 30 53 | 54 | # Optional order type mapping. 55 | order_types = { 56 | 'buy': 'limit', 57 | 'sell': 'limit', 58 | 'stoploss': 'market', 59 | 'stoploss_on_exchange': False 60 | } 61 | 62 | # Optional order time in force. 63 | order_time_in_force = { 64 | 'buy': 'gtc', 65 | 'sell': 'gtc' 66 | } 67 | 68 | plot_config = { 69 | # Main plot indicators (Moving averages, ...) 70 | 'main_plot': { 71 | 'ema5': {}, 72 | 'ema10': {}, 73 | }, 74 | 'subplots': { 75 | # Subplots - each dict defines one additional plot 76 | "RSI": { 77 | 'rsi': {'color': 'red'}, 78 | }, 79 | "ADX": { 80 | 'adx': {}, 81 | } 82 | } 83 | } 84 | 85 | def informative_pairs(self): 86 | return [] 87 | 88 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 89 | dataframe['hl2'] = (dataframe["close"] + dataframe["open"]) / 2 90 | 91 | # Momentum Indicators 92 | # ------------------------------------ 93 | 94 | # RSI 95 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=10, price='hl2') 96 | 97 | # # EMA - Exponential Moving Average 98 | dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) 99 | dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) 100 | 101 | # ADX 102 | dataframe['adx'] = ta.ADX(dataframe) 103 | 104 | return dataframe 105 | 106 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 107 | dataframe.loc[ 108 | ( 109 | (qtpylib.crossed_above(dataframe['rsi'], 50)) & 110 | (qtpylib.crossed_above(dataframe['ema5'], dataframe['ema10'])) & 111 | (dataframe['adx'] > 25) & 112 | (dataframe['volume'] > 0) # Make sure Volume is not 0 113 | ), 114 | 'buy'] = 1 115 | 116 | return dataframe 117 | 118 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 119 | dataframe.loc[ 120 | ( 121 | (qtpylib.crossed_below(dataframe['rsi'], 50)) & 122 | (qtpylib.crossed_below(dataframe['ema5'], dataframe['ema10'])) & 123 | (dataframe['adx'] > 25) & 124 | (dataframe['volume'] > 0) # Make sure Volume is not 0 125 | ), 126 | 'sell'] = 1 127 | return dataframe 128 | -------------------------------------------------------------------------------- /user_data/strategies/mabStra.py: -------------------------------------------------------------------------------- 1 | # Author: @Mablue (Masoud Azizi) 2 | # github: https://github.com/mablue/ 3 | # IMPORTANT: DO NOT USE IT WITHOUT HYPEROPT: 4 | # freqtrade hyperopt --hyperopt mabStraHo --hyperopt-loss SharpeHyperOptLoss --spaces all --strategy mabStra --config config.json -e 100 5 | 6 | # --- Do not remove these libs --- 7 | from freqtrade.strategy.hyper import IntParameter, DecimalParameter 8 | from freqtrade.strategy.interface import IStrategy 9 | from pandas import DataFrame 10 | # -------------------------------- 11 | 12 | # Add your lib to import here 13 | import talib.abstract as ta 14 | import freqtrade.vendor.qtpylib.indicators as qtpylib 15 | 16 | 17 | class mabStra(IStrategy): 18 | # buy params 19 | buy_mojo_ma_timeframe = IntParameter(2, 100, default=7, space='buy') 20 | buy_fast_ma_timeframe = IntParameter(2, 100, default=14, space='buy') 21 | buy_slow_ma_timeframe = IntParameter(2, 100, default=28, space='buy') 22 | buy_div_max = DecimalParameter(0, 2, decimals=4, default=2.25446, space='buy') 23 | buy_div_min = DecimalParameter(0, 2, decimals=4, default=0.29497, space='buy') 24 | # sell params 25 | sell_mojo_ma_timeframe = IntParameter(2, 100, default=7, space='sell') 26 | sell_fast_ma_timeframe = IntParameter(2, 100, default=14, space='sell') 27 | sell_slow_ma_timeframe = IntParameter(2, 100, default=28, space='sell') 28 | sell_div_max = DecimalParameter(0, 2, decimals=4, default=1.54593, space='sell') 29 | sell_div_min = DecimalParameter(0, 2, decimals=4, default=2.81436, space='sell') 30 | 31 | stoploss = -0.1 32 | 33 | # Optimal timeframe use it in your config 34 | timeframe = '4h' 35 | 36 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 37 | # SMA - ex Moving Average 38 | dataframe['buy-mojoMA'] = ta.SMA(dataframe, 39 | timeperiod=self.buy_mojo_ma_timeframe.value) 40 | dataframe['buy-fastMA'] = ta.SMA(dataframe, 41 | timeperiod=self.buy_fast_ma_timeframe.value) 42 | dataframe['buy-slowMA'] = ta.SMA(dataframe, 43 | timeperiod=self.buy_slow_ma_timeframe.value) 44 | dataframe['sell-mojoMA'] = ta.SMA(dataframe, 45 | timeperiod=self.sell_mojo_ma_timeframe.value) 46 | dataframe['sell-fastMA'] = ta.SMA(dataframe, 47 | timeperiod=self.sell_fast_ma_timeframe.value) 48 | dataframe['sell-slowMA'] = ta.SMA(dataframe, 49 | timeperiod=self.sell_slow_ma_timeframe.value) 50 | return dataframe 51 | 52 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 53 | 54 | dataframe.loc[ 55 | ( 56 | (dataframe['buy-mojoMA'].div(dataframe['buy-fastMA']) 57 | > self.buy_div_min.value) & 58 | (dataframe['buy-mojoMA'].div(dataframe['buy-fastMA']) 59 | < self.buy_div_max.value) & 60 | (dataframe['buy-fastMA'].div(dataframe['buy-slowMA']) 61 | > self.buy_div_min.value) & 62 | (dataframe['buy-fastMA'].div(dataframe['buy-slowMA']) 63 | < self.buy_div_max.value) 64 | ), 65 | 'buy'] = 1 66 | 67 | return dataframe 68 | 69 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 70 | dataframe.loc[ 71 | ( 72 | (dataframe['sell-fastMA'].div(dataframe['sell-mojoMA']) 73 | > self.sell_div_min.value) & 74 | (dataframe['sell-fastMA'].div(dataframe['sell-mojoMA']) 75 | < self.sell_div_max.value) & 76 | (dataframe['sell-slowMA'].div(dataframe['sell-fastMA']) 77 | > self.sell_div_min.value) & 78 | (dataframe['sell-slowMA'].div(dataframe['sell-fastMA']) 79 | < self.sell_div_max.value) 80 | ), 81 | 'sell'] = 1 82 | return dataframe 83 | -------------------------------------------------------------------------------- /user_data/strategies/normalizer.py: -------------------------------------------------------------------------------- 1 | import freqtrade.vendor.qtpylib.indicators as qtpylib 2 | import numpy as np 3 | import talib.abstract as ta 4 | from freqtrade.strategy.interface import IStrategy 5 | from pandas import DataFrame 6 | from datetime import datetime, timedelta 7 | 8 | 9 | """ 10 | =============== SUMMARY METRICS =============== 11 | | Metric | Value | 12 | |-----------------------+---------------------| 13 | | Backtesting from | 2021-05-01 00:00:00 | 14 | | Backtesting to | 2021-06-09 17:00:00 | 15 | | Max open trades | 10 | 16 | | | | 17 | | Total trades | 447 | 18 | | Starting balance | 1000.000 USDT | 19 | | Final balance | 1714.575 USDT | 20 | | Absolute profit | 714.575 USDT | 21 | | Total profit % | 71.46% | 22 | | Trades per day | 11.46 | 23 | | Avg. stake amount | 180.278 USDT | 24 | | Total trade volume | 80584.326 USDT | 25 | | | | 26 | | Best Pair | ALICE/USDT 24.7% | 27 | | Worst Pair | HARD/USDT -35.15% | 28 | | Best trade | PSG/USDT 17.98% | 29 | | Worst trade | XVS/USDT -26.03% | 30 | | Best day | 351.588 USDT | 31 | | Worst day | -256.636 USDT | 32 | | Days win/draw/lose | 25 / 8 / 4 | 33 | | Avg. Duration Winners | 1:36:00 | 34 | | Avg. Duration Loser | 9:33:00 | 35 | | | | 36 | | Min balance | 962.929 USDT | 37 | | Max balance | 1714.575 USDT | 38 | | Drawdown | 240.78% | 39 | | Drawdown | 289.267 USDT | 40 | | Drawdown high | 252.196 USDT | 41 | | Drawdown low | -37.071 USDT | 42 | | Drawdown Start | 2021-05-19 03:00:00 | 43 | | Drawdown End | 2021-05-19 20:00:00 | 44 | | Market change | -34.99% | 45 | =============================================== 46 | 47 | """ 48 | 49 | 50 | class NormalizerStrategy(IStrategy): 51 | INTERFACE_VERSION = 2 52 | 53 | minimal_roi = { 54 | "0": 0.18 55 | } 56 | 57 | stoploss = -0.99 # effectively disabled. 58 | 59 | timeframe = '1h' 60 | 61 | # Sell signal 62 | use_sell_signal = True 63 | sell_profit_only = True 64 | sell_profit_offset = 0.001 # it doesn't meant anything, just to guarantee there is a minimal profit. 65 | ignore_roi_if_buy_signal = True 66 | 67 | # Trailing stoploss 68 | trailing_stop = True 69 | trailing_only_offset_is_reached = True 70 | trailing_stop_positive = 0.01 71 | trailing_stop_positive_offset = 0.015 72 | 73 | # Custom stoploss 74 | use_custom_stoploss = True 75 | 76 | # Run "populate_indicators()" only for new candle. 77 | process_only_new_candles = False 78 | 79 | # Number of candles the strategy requires before producing valid signals 80 | startup_candle_count: int = 610 81 | 82 | # Optional order type mapping. 83 | order_types = { 84 | 'buy': 'limit', 85 | 'sell': 'limit', 86 | 'stoploss': 'market', 87 | 'stoploss_on_exchange': False 88 | } 89 | 90 | def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, 91 | current_rate: float, current_profit: float, **kwargs) -> float: 92 | # Manage losing trades and open room for better ones. 93 | if (current_profit < 0) & (current_time - timedelta(minutes=300) > trade.open_date_utc): 94 | return 0.01 95 | return 0.99 96 | 97 | def fischer_norm(self, x, lookback): 98 | res = np.zeros_like(x) 99 | for i in range(lookback, len(x)): 100 | x_min = np.min(x[i-lookback: i +1]) 101 | x_max = np.max(x[i-lookback: i +1]) 102 | #res[i] = (2*(x[i] - x_min) / (x_max - x_min)) - 1 103 | res[i] = (x[i] - x_min) / (x_max - x_min) 104 | return res 105 | 106 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 107 | lookback = [13, 21, 34, 55, 89, 144, 233, 377, 610] 108 | for look in lookback: 109 | dataframe[f"norm_{look}"] = self.fischer_norm(dataframe["close"].values, look) 110 | collist = [col for col in dataframe.columns if col.startswith("norm")] 111 | dataframe["pct_sum"] = dataframe[collist].sum(axis=1) 112 | 113 | 114 | 115 | return dataframe 116 | 117 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 118 | dataframe.loc[ 119 | (dataframe['pct_sum'] < .2) & 120 | (dataframe['volume'] > 0) # Make sure Volume is not 0 121 | , 122 | 'buy' 123 | ] = 1 124 | return dataframe 125 | 126 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 127 | dataframe.loc[ 128 | (dataframe['pct_sum'] > 8) & 129 | (dataframe['volume'] > 0) # Make sure Volume is not 0 130 | , 131 | 'sell' 132 | ] = 1 133 | return dataframe --------------------------------------------------------------------------------