海底暴风雪

富在术数不在劳身,利在局势不在力耕

freqtrade 强化学习 实操

数据下载

freqtrade download-data --config ./user_data/future_freqai_config.json

回测

命令

freqtrade backtesting --config ./user_data/future_freqai_config.json --strategy ichiV1 --strategy-path ./freqtrade-strategies/strategies/ichiV1/ --timerange 20230807-20240107 --freqaimodel MyActionRLEnv

配置文件
future_freqai_config.json

{
    "max_open_trades": 10,
    "stake_currency": "USDT",
    "stake_amount": 25,
    "tradable_balance_ratio": 0.99,
    "fiat_display_currency": "USD",
    "timeframe": "5m",
    "dry_run": true,
    "dry_run_wallet": 230,
    "cancel_open_orders_on_exit": false,
    "trading_mode": "futures",
    // 期货交易时,必须设置保证金模式
    "margin_mode": "isolated",
    "unfilledtimeout": {
        "entry": 10,
        "exit": 10,
        "exit_timeout_count": 0,
        "unit": "minutes"
    },
    "entry_pricing": {
        "price_side": "same",
        "use_order_book": true,
        "order_book_top": 1,
        "price_last_balance": 0.0,
        "check_depth_of_market": {
            "enabled": false,
            "bids_to_ask_delta": 1
        }
    },
    "exit_pricing":{
        "price_side": "same",
        "use_order_book": true,
        "order_book_top": 1
    },
    "exchange": {
        "name": "binance",
        "key": "",
        "secret": "",
        "ccxt_config": {},
        "ccxt_async_config": {},
        "pair_whitelist": [
            "BTC/USDT:USDT",
            "BCH/USDT:USDT",
            "ETH/USDT:USDT",
            "LINK/USDT:USDT",
            "LTC/USDT:USDT",
            "SOL/USDT:USDT",
            "BNB/USDT:USDT",
            "XRP/USDT:USDT",
            "ADA/USDT:USDT",
            "DOT/USDT:USDT",
            "ETC/USDT:USDT",
            "ALGO/USDT:USDT"
            // "1000BONK/USDT:USDT",
            // "1000FLOKI/USDT:USDT",
            // "1000LUNC/USDT:USDT",
            // "1000PEPE/USDT:USDT",
            // // "1000RATS/USDT:USDT",
            // "1000SATS/USDT:USDT",
            // "1000SHIB/USDT:USDT",
            // "1000XEC/USDT:USDT",
            // "1INCH/USDT:USDT",
            // "AAVE/USDT:USDT",
            // // "ACE/USDT:USDT",
            // "ACH/USDT:USDT",
            // "ADA/USDT:USDT",
            // "AGIX/USDT:USDT",
            // "AGLD/USDT:USDT",
            // "ALGO/USDT:USDT",
            // "ALICE/USDT:USDT",
            // "ALPHA/USDT:USDT",
            // "AMB/USDT:USDT",
            // "ANKR/USDT:USDT",
            // "ANT/USDT:USDT",
            // "APE/USDT:USDT",
            // "API3/USDT:USDT",
            // "APT/USDT:USDT",
            // "AR/USDT:USDT",
            // "ARB/USDT:USDT",
            // "ARK/USDT:USDT",
            // "ARKM/USDT:USDT",
            // "ARPA/USDT:USDT",
            // "ASTR/USDT:USDT",
            // "ATA/USDT:USDT",
            // "ATOM/USDT:USDT",
            // // "AUCTION/USDT:USDT",
            // "AUDIO/USDT:USDT",
            // "AVAX/USDT:USDT",
            // "AXS/USDT:USDT",
            // "BADGER/USDT:USDT",
            // "BAKE/USDT:USDT",
            // "BAL/USDT:USDT",
            // "BAND/USDT:USDT",
            // "BAT/USDT:USDT",
            // "BCH/USDT:USDT",
            // "BEAMX/USDT:USDT",
            // "BEL/USDT:USDT",
            // "BICO/USDT:USDT",
            // "BIGTIME/USDT:USDT",
            // "BLUEBIRD/USDT:USDT",
            // "BLUR/USDT:USDT",
            // "BLZ/USDT:USDT",
            // // "BNB/USDC:USDC",
            // "BNB/USDT:USDT",
            // "BNT/USDT:USDT",
            // "BNX/USDT:USDT",
            // "BOND/USDT:USDT",
            // "BSV/USDT:USDT",
            // // "BTC/USDC:USDC",
            // "BTC/USDT:USDT",
            // "BTCDOM/USDT:USDT",
            // "C98/USDT:USDT",
            // "CAKE/USDT:USDT",
            // "CELO/USDT:USDT",
            // "CELR/USDT:USDT",
            // "CFX/USDT:USDT",
            // "CHR/USDT:USDT",
            // "CHZ/USDT:USDT",
            // "CKB/USDT:USDT",
            // "COMBO/USDT:USDT",
            // "COMP/USDT:USDT",
            // "COTI/USDT:USDT",
            // "CRV/USDT:USDT",
            // "CTK/USDT:USDT",
            // "CTSI/USDT:USDT",
            // "CVX/USDT:USDT",
            // "CYBER/USDT:USDT",
            // "DAR/USDT:USDT",
            // "DASH/USDT:USDT",
            // "DEFI/USDT:USDT",
            // "DENT/USDT:USDT",
            // "DGB/USDT:USDT",
            // "DODOX/USDT:USDT",
            // "DOGE/USDT:USDT",
            // "DOT/USDT:USDT",
            // "DUSK/USDT:USDT",
            // "DYDX/USDT:USDT",
            // "EDU/USDT:USDT",
            // "EGLD/USDT:USDT",
            // "ENJ/USDT:USDT",
            // "ENS/USDT:USDT",
            // "EOS/USDT:USDT",
            // "ETC/USDT:USDT",
            // // "ETH/BTC:BTC",
            // // "ETH/USDC:USDC",
            // "ETH/USDT:USDT",
            // "ETHW/USDT:USDT",
            // "FET/USDT:USDT",
            // "FIL/USDT:USDT",
            // "FLM/USDT:USDT",
            // "FLOW/USDT:USDT",
            // "FOOTBALL/USDT:USDT",
            // "FRONT/USDT:USDT",
            // "FTM/USDT:USDT",
            // "FXS/USDT:USDT",
            // "GAL/USDT:USDT",
            // "GALA/USDT:USDT",
            // "GAS/USDT:USDT",
            // "GLMR/USDT:USDT",
            // "GMT/USDT:USDT",
            // "GMX/USDT:USDT",
            // "GRT/USDT:USDT",
            // "GTC/USDT:USDT",
            // "HBAR/USDT:USDT",
            // "HFT/USDT:USDT",
            // "HIFI/USDT:USDT",
            // "HIGH/USDT:USDT",
            // "HOOK/USDT:USDT",
            // "HOT/USDT:USDT",
            // "ICP/USDT:USDT",
            // "ICX/USDT:USDT",
            // "ID/USDT:USDT",
            // "IDEX/USDT:USDT",
            // "ILV/USDT:USDT",
            // "IMX/USDT:USDT",
            // "INJ/USDT:USDT",
            // "IOST/USDT:USDT",
            // "IOTA/USDT:USDT",
            // "IOTX/USDT:USDT",
            // "JASMY/USDT:USDT",
            // "JOE/USDT:USDT",
            // "JTO/USDT:USDT",
            // "KAS/USDT:USDT",
            // "KAVA/USDT:USDT",
            // "KEY/USDT:USDT",
            // "KLAY/USDT:USDT",
            // "KNC/USDT:USDT",
            // "KSM/USDT:USDT",
            // "LDO/USDT:USDT",
            // "LEVER/USDT:USDT",
            // "LINA/USDT:USDT",
            // "LINK/USDT:USDT",
            // "LIT/USDT:USDT",
            // "LOOM/USDT:USDT",
            // "LPT/USDT:USDT",
            // "LQTY/USDT:USDT",
            // "LRC/USDT:USDT",
            // "LTC/USDT:USDT",
            // "LUNA2/USDT:USDT",
            // "MAGIC/USDT:USDT",
            // "MANA/USDT:USDT",
            // "MASK/USDT:USDT",
            // "MATIC/USDT:USDT",
            // "MAV/USDT:USDT",
            // "MBL/USDT:USDT",
            // "MDT/USDT:USDT",
            // "MEME/USDT:USDT",
            // "MINA/USDT:USDT",
            // "MKR/USDT:USDT",
            // // "MOVR/USDT:USDT",
            // "MTL/USDT:USDT",
            // "NEAR/USDT:USDT",
            // "NEO/USDT:USDT",
            // // "NFP/USDT:USDT",
            // "NKN/USDT:USDT",
            // "NMR/USDT:USDT",
            // "NTRN/USDT:USDT",
            // "OCEAN/USDT:USDT",
            // "OGN/USDT:USDT",
            // "OMG/USDT:USDT",
            // "ONE/USDT:USDT",
            // "ONG/USDT:USDT",
            // "ONT/USDT:USDT",
            // "OP/USDT:USDT",
            // "ORBS/USDT:USDT",
            // "ORDI/USDT:USDT",
            // "OXT/USDT:USDT",
            // "PENDLE/USDT:USDT",
            // "PEOPLE/USDT:USDT",
            // "PERP/USDT:USDT",
            // "PHB/USDT:USDT",
            // "POLYX/USDT:USDT",
            // "POWR/USDT:USDT",
            // "PYTH/USDT:USDT",
            // "QNT/USDT:USDT",
            // "QTUM/USDT:USDT",
            // "RAD/USDT:USDT",
            // "RDNT/USDT:USDT",
            // "REEF/USDT:USDT",
            // "REN/USDT:USDT",
            // "RIF/USDT:USDT",
            // "RLC/USDT:USDT",
            // "RNDR/USDT:USDT",
            // "ROSE/USDT:USDT",
            // "RSR/USDT:USDT",
            // "RUNE/USDT:USDT",
            // "RVN/USDT:USDT",
            // "SAND/USDT:USDT",
            // "SEI/USDT:USDT",
            // "SFP/USDT:USDT",
            // "SKL/USDT:USDT",
            // "SLP/USDT:USDT",
            // "SNT/USDT:USDT",
            // "SNX/USDT:USDT",
            // // "SOL/USDC:USDC",
            // "SOL/USDT:USDT",
            // "SPELL/USDT:USDT",
            // "SSV/USDT:USDT",
            // "STEEM/USDT:USDT",
            // "STG/USDT:USDT",
            // "STMX/USDT:USDT",
            // "STORJ/USDT:USDT",
            // "STPT/USDT:USDT",
            // "STRAX/USDT:USDT",
            // "STX/USDT:USDT",
            // "SUI/USDT:USDT",
            // "SUPER/USDT:USDT",
            // "SUSHI/USDT:USDT",
            // "SXP/USDT:USDT",
            // "T/USDT:USDT",
            // "THETA/USDT:USDT",
            // "TIA/USDT:USDT",
            // "TLM/USDT:USDT",
            // "TOKEN/USDT:USDT",
            // "TRB/USDT:USDT",
            // "TRU/USDT:USDT",
            // "TRX/USDT:USDT",
            // "TWT/USDT:USDT",
            // "UMA/USDT:USDT",
            // "UNFI/USDT:USDT",
            // "UNI/USDT:USDT",
            // // "USDC/USDT:USDT",
            // "USTC/USDT:USDT",
            // "VET/USDT:USDT",
            // "WAVES/USDT:USDT",
            // "WAXP/USDT:USDT",
            // "WLD/USDT:USDT",
            // "WOO/USDT:USDT",
            // "XEM/USDT:USDT",
            // "XLM/USDT:USDT",
            // "XMR/USDT:USDT",
            // // "XRP/USDC:USDC",
            // "XRP/USDT:USDT",
            // "XTZ/USDT:USDT",
            // "XVG/USDT:USDT",
            // "XVS/USDT:USDT",
            // "YFI/USDT:USDT",
            // "YGG/USDT:USDT",
            // "ZEC/USDT:USDT",
            // "ZEN/USDT:USDT",
            // "ZIL/USDT:USDT",
            // "ZRX/USDT:USDT"
          ],
        "pair_blacklist": [
          ]
    },
    "pairlists": [

        {
          "method":"StaticPairList",
        },
        
    ],
    "telegram": {
        "enabled": false,
        "token": "",
        "chat_id": ""
    },
    "loglevel": "DEBUG",
    "api_server": {
        "enabled": true,
        "listen_ip_address": "0.0.0.0",
        "listen_port": 8080,
        "verbosity": "error",
        "enable_openapi": false,
        "jwt_secret_key": "62026bd9b80cdc748f0a401288b39df3031ef927a7991c59cee2975836a8b71a",
        "ws_token": "",
        "CORS_origins": [],
        "username": "",
        "password": ""
    },
    "bot_name": "freqtrade",
    "initial_state": "running",
    "force_entry_enable": false,
    "internals": {
        "process_throttle_secs": 5
    },
    "freqai": {
        "enabled": true,
        "purge_old_models": 0,
        "train_period_days": 7,
        "backtest_period_days": 3,
        "live_retrain_hours": 0,
        "identifier": "1234",
        "feature_parameters": {
            "include_timeframes": [
                //"3m",
                "5m",
                // "15m",
                // "1h"
            ],
            "include_corr_pairlist": [
                "BTC/USDT:USDT",
            "BCH/USDT:USDT",
            "ETH/USDT:USDT",
            "LINK/USDT:USDT",
            "LTC/USDT:USDT",
            "SOL/USDT:USDT",
            "BNB/USDT:USDT",
            "XRP/USDT:USDT",
            "ADA/USDT:USDT",
            "DOT/USDT:USDT",
            "ETC/USDT:USDT",
            "ALGO/USDT:USDT",
            //"LUNA/USDT:USDT"


            // "1000BONK/USDT:USDT",
            // "1000FLOKI/USDT:USDT",
            // "1000LUNC/USDT:USDT",
            // "1000PEPE/USDT:USDT",
            // // "1000RATS/USDT:USDT",
            // "1000SATS/USDT:USDT",
            // "1000SHIB/USDT:USDT",
            // "1000XEC/USDT:USDT",
            // "1INCH/USDT:USDT",
            // "AAVE/USDT:USDT",
            // // "ACE/USDT:USDT",
            // "ACH/USDT:USDT",
            // "ADA/USDT:USDT",
            // "AGIX/USDT:USDT",
            // "AGLD/USDT:USDT",
            // "ALGO/USDT:USDT",
            // "ALICE/USDT:USDT",
            // "ALPHA/USDT:USDT",
            // "AMB/USDT:USDT",
            // "ANKR/USDT:USDT",
            // "ANT/USDT:USDT",
            // "APE/USDT:USDT",
            // "API3/USDT:USDT",
            // "APT/USDT:USDT",
            // "AR/USDT:USDT",
            // "ARB/USDT:USDT",
            // "ARK/USDT:USDT",
            // "ARKM/USDT:USDT",
            // "ARPA/USDT:USDT",
            // "ASTR/USDT:USDT",
            // "ATA/USDT:USDT",
            // "ATOM/USDT:USDT",
            // // "AUCTION/USDT:USDT",
            // "AUDIO/USDT:USDT",
            // "AVAX/USDT:USDT",
            // "AXS/USDT:USDT",
            // "BADGER/USDT:USDT",
            // "BAKE/USDT:USDT",
            // "BAL/USDT:USDT",
            // "BAND/USDT:USDT",
            // "BAT/USDT:USDT",
            // "BCH/USDT:USDT",
            // "BEAMX/USDT:USDT",
            // "BEL/USDT:USDT",
            // "BICO/USDT:USDT",
            // "BIGTIME/USDT:USDT",
            // "BLUEBIRD/USDT:USDT",
            // "BLUR/USDT:USDT",
            // "BLZ/USDT:USDT",
            // // "BNB/USDC:USDC",
            // "BNB/USDT:USDT",
            // "BNT/USDT:USDT",
            // "BNX/USDT:USDT",
            // "BOND/USDT:USDT",
            // "BSV/USDT:USDT",
            // // "BTC/USDC:USDC",
            // "BTC/USDT:USDT",
            // "BTCDOM/USDT:USDT",
            // "C98/USDT:USDT",
            // "CAKE/USDT:USDT",
            // "CELO/USDT:USDT",
            // "CELR/USDT:USDT",
            // "CFX/USDT:USDT",
            // "CHR/USDT:USDT",
            // "CHZ/USDT:USDT",
            // "CKB/USDT:USDT",
            // "COMBO/USDT:USDT",
            // "COMP/USDT:USDT",
            // "COTI/USDT:USDT",
            // "CRV/USDT:USDT",
            // "CTK/USDT:USDT",
            // "CTSI/USDT:USDT",
            // "CVX/USDT:USDT",
            // "CYBER/USDT:USDT",
            // "DAR/USDT:USDT",
            // "DASH/USDT:USDT",
            // "DEFI/USDT:USDT",
            // "DENT/USDT:USDT",
            // "DGB/USDT:USDT",
            // "DODOX/USDT:USDT",
            // "DOGE/USDT:USDT",
            // "DOT/USDT:USDT",
            // "DUSK/USDT:USDT",
            // "DYDX/USDT:USDT",
            // "EDU/USDT:USDT",
            // "EGLD/USDT:USDT",
            // "ENJ/USDT:USDT",
            // "ENS/USDT:USDT",
            // "EOS/USDT:USDT",
            // "ETC/USDT:USDT",
            // // "ETH/BTC:BTC",
            // // "ETH/USDC:USDC",
            // "ETH/USDT:USDT",
            // "ETHW/USDT:USDT",
            // "FET/USDT:USDT",
            // "FIL/USDT:USDT",
            // "FLM/USDT:USDT",
            // "FLOW/USDT:USDT",
            // "FOOTBALL/USDT:USDT",
            // "FRONT/USDT:USDT",
            // "FTM/USDT:USDT",
            // "FXS/USDT:USDT",
            // "GAL/USDT:USDT",
            // "GALA/USDT:USDT",
            // "GAS/USDT:USDT",
            // "GLMR/USDT:USDT",
            // "GMT/USDT:USDT",
            // "GMX/USDT:USDT",
            // "GRT/USDT:USDT",
            // "GTC/USDT:USDT",
            // "HBAR/USDT:USDT",
            // "HFT/USDT:USDT",
            // "HIFI/USDT:USDT",
            // "HIGH/USDT:USDT",
            // "HOOK/USDT:USDT",
            // "HOT/USDT:USDT",
            // "ICP/USDT:USDT",
            // "ICX/USDT:USDT",
            // "ID/USDT:USDT",
            // "IDEX/USDT:USDT",
            // "ILV/USDT:USDT",
            // "IMX/USDT:USDT",
            // "INJ/USDT:USDT",
            // "IOST/USDT:USDT",
            // "IOTA/USDT:USDT",
            // "IOTX/USDT:USDT",
            // "JASMY/USDT:USDT",
            // "JOE/USDT:USDT",
            // "JTO/USDT:USDT",
            // "KAS/USDT:USDT",
            // "KAVA/USDT:USDT",
            // "KEY/USDT:USDT",
            // "KLAY/USDT:USDT",
            // "KNC/USDT:USDT",
            // "KSM/USDT:USDT",
            // "LDO/USDT:USDT",
            // "LEVER/USDT:USDT",
            // "LINA/USDT:USDT",
            // "LINK/USDT:USDT",
            // "LIT/USDT:USDT",
            // "LOOM/USDT:USDT",
            // "LPT/USDT:USDT",
            // "LQTY/USDT:USDT",
            // "LRC/USDT:USDT",
            // "LTC/USDT:USDT",
            // "LUNA2/USDT:USDT",
            // "MAGIC/USDT:USDT",
            // "MANA/USDT:USDT",
            // "MASK/USDT:USDT",
            // "MATIC/USDT:USDT",
            // "MAV/USDT:USDT",
            // "MBL/USDT:USDT",
            // "MDT/USDT:USDT",
            // "MEME/USDT:USDT",
            // "MINA/USDT:USDT",
            // "MKR/USDT:USDT",
            // // "MOVR/USDT:USDT",
            // "MTL/USDT:USDT",
            // "NEAR/USDT:USDT",
            // "NEO/USDT:USDT",
            // // "NFP/USDT:USDT",
            // "NKN/USDT:USDT",
            // "NMR/USDT:USDT",
            // "NTRN/USDT:USDT",
            // "OCEAN/USDT:USDT",
            // "OGN/USDT:USDT",
            // "OMG/USDT:USDT",
            // "ONE/USDT:USDT",
            // "ONG/USDT:USDT",
            // "ONT/USDT:USDT",
            // "OP/USDT:USDT",
            // "ORBS/USDT:USDT",
            // "ORDI/USDT:USDT",
            // "OXT/USDT:USDT",
            // "PENDLE/USDT:USDT",
            // "PEOPLE/USDT:USDT",
            // "PERP/USDT:USDT",
            // "PHB/USDT:USDT",
            // "POLYX/USDT:USDT",
            // "POWR/USDT:USDT",
            // "PYTH/USDT:USDT",
            // "QNT/USDT:USDT",
            // "QTUM/USDT:USDT",
            // "RAD/USDT:USDT",
            // "RDNT/USDT:USDT",
            // "REEF/USDT:USDT",
            // "REN/USDT:USDT",
            // "RIF/USDT:USDT",
            // "RLC/USDT:USDT",
            // "RNDR/USDT:USDT",
            // "ROSE/USDT:USDT",
            // "RSR/USDT:USDT",
            // "RUNE/USDT:USDT",
            // "RVN/USDT:USDT",
            // "SAND/USDT:USDT",
            // "SEI/USDT:USDT",
            // "SFP/USDT:USDT",
            // "SKL/USDT:USDT",
            // "SLP/USDT:USDT",
            // "SNT/USDT:USDT",
            // "SNX/USDT:USDT",
            // // "SOL/USDC:USDC",
            // "SOL/USDT:USDT",
            // "SPELL/USDT:USDT",
            // "SSV/USDT:USDT",
            // "STEEM/USDT:USDT",
            // "STG/USDT:USDT",
            // "STMX/USDT:USDT",
            // "STORJ/USDT:USDT",
            // "STPT/USDT:USDT",
            // "STRAX/USDT:USDT",
            // "STX/USDT:USDT",
            // "SUI/USDT:USDT",
            // "SUPER/USDT:USDT",
            // "SUSHI/USDT:USDT",
            // "SXP/USDT:USDT",
            // "T/USDT:USDT",
            // "THETA/USDT:USDT",
            // "TIA/USDT:USDT",
            // "TLM/USDT:USDT",
            // "TOKEN/USDT:USDT",
            // "TRB/USDT:USDT",
            // "TRU/USDT:USDT",
            // "TRX/USDT:USDT",
            // "TWT/USDT:USDT",
            // "UMA/USDT:USDT",
            // "UNFI/USDT:USDT",
            // "UNI/USDT:USDT",
            // // "USDC/USDT:USDT",
            // "USTC/USDT:USDT",
            // "VET/USDT:USDT",
            // "WAVES/USDT:USDT",
            // "WAXP/USDT:USDT",
            // "WLD/USDT:USDT",
            // "WOO/USDT:USDT",
            // "XEM/USDT:USDT",
            // "XLM/USDT:USDT",
            // "XMR/USDT:USDT",
            // // "XRP/USDC:USDC",
            // "XRP/USDT:USDT",
            // "XTZ/USDT:USDT",
            // "XVG/USDT:USDT",
            // "XVS/USDT:USDT",
            // "YFI/USDT:USDT",
            // "YGG/USDT:USDT",
            // "ZEC/USDT:USDT",
            // "ZEN/USDT:USDT",
            // "ZIL/USDT:USDT",
            // "ZRX/USDT:USDT"
            ],
            "label_period_candles": 20,
            "include_shifted_candles": 2,
            "DI_threshold": 0.9,
            "weight_factor": 0.9,
            "principal_component_analysis": false,
            "use_SVM_to_remove_outliers": true,
            "indicator_periods_candles": [
                10,
                20
            ],
            "plot_feature_importances": 0
        },
        "data_split_parameters": {
            "test_size": 0.33,
            "random_state": 1
        },
        "model_training_parameters": {},
        "rl_config": {
            "train_cycles": 25,
            // "add_state_info": true,
            "add_state_info": false,
            "max_trade_duration_candles": 300,
            "max_training_drawdown_pct": 0.02,
            "cpu_count": 8,
            "model_type": "PPO",
            "policy_type": "MlpPolicy",
            "model_reward_parameters": {
                "rr": 1,
                "profit_aim": 0.025
            }
        }
    },
    
}

AImodel文件

from freqtrade.freqai.prediction_models.ReinforcementLearner import ReinforcementLearner
from freqtrade.freqai.RL.Base5ActionRLEnv import Actions, Base5ActionRLEnv, Positions

class MyActionRLEnv(ReinforcementLearner):
    class MyRLEnv(Base5ActionRLEnv):
        def calculate_reward(self, action: int) -> float:
            # 基础判断:如果行动无效,则给予惩罚
            if not self._is_valid(action):
                # print(f"action: {action}")
                return -2

            pnl = self.get_unrealized_profit()
            factor = 100
            pair = self.pair.replace(':', '')

            # 假设策略使用RSI指标
            rsi_now = self.raw_features[f"%-rsi-period_10_shift-1_{pair}_"
                            f"{self.config['timeframe']}"].iloc[self._current_tick]

            # print(f"action: {action}, rsi_now:{rsi_now}, ")
            
            # 进入交易的奖励机制
            if action in (Actions.Long_enter.value, Actions.Short_enter.value) and self._position == Positions.Neutral:
                if rsi_now < 40:
                    factor = 40 / rsi_now
                else:
                    factor = 1
                
                return 25 * factor

            # 不进入交易的惩罚
            if action == Actions.Neutral.value and self._position == Positions.Neutral:
                return -1

            # 交易持续时间奖励/惩罚
            max_trade_duration = self.rl_config.get('max_trade_duration_candles', 300)
            trade_duration = self._current_tick - self._last_trade_tick
            if trade_duration <= max_trade_duration:
                factor *= 1.5
            elif trade_duration > max_trade_duration:
                factor *= 0.5

            # 保持交易状态的惩罚
            if self._position in (Positions.Short, Positions.Long) and action == Actions.Neutral.value:
                return -1 * trade_duration / max_trade_duration

            # 关闭长/短仓位的奖励
            if action in (Actions.Long_exit.value, Actions.Short_exit.value) and \
                (self._position == Positions.Long or self._position == Positions.Short):
                if pnl > self.profit_aim * self.rr:
                    factor *= self.rl_config['model_reward_parameters'].get('win_reward_factor', 2)
                return float(pnl * factor)

            return 0.

策略文件

# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy import IntParameter
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import pandas as pd  # noqa
pd.options.mode.chained_assignment = None  # default='warn'
import technical.indicators as ftt
from functools import reduce
from datetime import datetime, timedelta
from freqtrade.strategy import merge_informative_pair
import numpy as np
from freqtrade.strategy import stoploss_from_open

from typing import Dict



class ichiV1(IStrategy):

    # NOTE: settings as of the 25th july 21
    # Buy hyperspace params:
    buy_params = {
        "buy_trend_above_senkou_level": 1,
        "buy_trend_bullish_level": 1,
        "buy_fan_magnitude_shift_value": 3,
        "buy_min_fan_magnitude_gain": 1.002 # NOTE: Good value (Win% ~70%), alot of trades
        #"buy_min_fan_magnitude_gain": 1.008 # NOTE: Very save value (Win% ~90%), only the biggest moves 1.008,
    }

    # Sell hyperspace params:
    # NOTE: was 15m but kept bailing out in dryrun
    sell_params = {
        "sell_trend_indicator": "trend_close_2h",
    }

    # ROI table:
    minimal_roi = {
        "0": 0.059,
        "10": 0.037,
        "41": 0.012,
        "114": 0
    }

    # Stoploss:
    stoploss = -0.275

    # Optimal timeframe for the strategy
    timeframe = '5m'

    startup_candle_count = 96
    # process_only_new_candles = False
    process_only_new_candles = True

    trailing_stop = False
    #trailing_stop_positive = 0.002
    #trailing_stop_positive_offset = 0.025
    #trailing_only_offset_is_reached = True

    # use_sell_signal = True
    use_exit_signal = True
    # sell_profit_only = False
    exit_profit_only = False
    # ignore_roi_if_buy_signal = False
    ignore_roi_if_entry_signal = False

    plot_config = {
        'main_plot': {
            # fill area between senkou_a and senkou_b
            'senkou_a': {
                'color': 'green', #optional
                'fill_to': 'senkou_b',
                'fill_label': 'Ichimoku Cloud', #optional
                'fill_color': 'rgba(255,76,46,0.2)', #optional
            },
            # plot senkou_b, too. Not only the area to it.
            'senkou_b': {},
            'trend_close_5m': {'color': '#FF5733'},
            'trend_close_15m': {'color': '#FF8333'},
            'trend_close_30m': {'color': '#FFB533'},
            'trend_close_1h': {'color': '#FFE633'},
            'trend_close_2h': {'color': '#E3FF33'},
            'trend_close_4h': {'color': '#C4FF33'},
            'trend_close_6h': {'color': '#61FF33'},
            'trend_close_8h': {'color': '#33FF7D'}
        },
        'subplots': {
            'fan_magnitude': {
                'fan_magnitude': {}
            },
            'fan_magnitude_gain': {
                'fan_magnitude_gain': {}
            },
            "MACD": {
                'macd': {'color': 'blue'},
                'macdsignal': {'color': 'orange'},
            },
            "RSI": {
                'rsi': {'color': 'red'},
            },
            "Up_or_down": {
                '&s-up_or_down': {'color': 'green'},
            }
        }
    }

    buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
    sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True)
    short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
    exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)

    def feature_engineering_expand_all(self, dataframe: DataFrame, period: int,
                                       metadata: Dict, **kwargs) -> DataFrame:

        dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
        dataframe["%-mfi-period"] = ta.MFI(dataframe, timeperiod=period)
        dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
        dataframe["%-sma-period"] = ta.SMA(dataframe, timeperiod=period)
        dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
        dataframe["%-ad-period"] = ta.AD(dataframe, timeperiod=period)
        dataframe["%-adosc-period"] = ta.ADOSC(dataframe, timeperiod=period)
        dataframe["%-adxr-period"] = ta.ADXR(dataframe, timeperiod=period)
        dataframe["%-apo-period"] = ta.APO(dataframe, timeperiod=period)
        dataframe["%-wma-period"] = ta.WMA(dataframe, timeperiod=period)
        # dataframe["%-stoch-period"] = ta.STOCH(dataframe, timeperiod=period)
        dataframe["%-atr-period"] = ta.ATR(dataframe, timeperiod=period)
        dataframe["%-avgprice-period"] = ta.AVGPRICE(dataframe, timeperiod=period)
        # dataframe["%-macd-period"] = ta.MACD(dataframe, timeperiod=period)
        dataframe["%-mom-period"] = ta.MOM(dataframe, timeperiod=period)
        dataframe["%-cci-period"] = ta.CCI(dataframe, timeperiod=period)
        dataframe["%-sar-period"] = ta.SAR(dataframe, timeperiod=period)
        dataframe["%-obv-period"] = ta.OBV(dataframe, timeperiod=period)
      



        bollinger = qtpylib.bollinger_bands(
            qtpylib.typical_price(dataframe), window=period, stds=2.2
        )
        dataframe["bb_lowerband-period"] = bollinger["lower"]
        dataframe["bb_middleband-period"] = bollinger["mid"]
        dataframe["bb_upperband-period"] = bollinger["upper"]

        dataframe["%-bb_width-period"] = (
            dataframe["bb_upperband-period"]
            - dataframe["bb_lowerband-period"]
        ) / dataframe["bb_middleband-period"]
        dataframe["%-close-bb_lower-period"] = (
            dataframe["close"] / dataframe["bb_lowerband-period"]
        )

        dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)

        dataframe["%-relative_volume-period"] = (
            dataframe["volume"] / dataframe["volume"].rolling(period).mean()
        )

        return dataframe

    def feature_engineering_expand_basic(
            self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame:
        # dataframe["%-pct-change"] = dataframe["close"].pct_change()
        dataframe["%-raw_close"] = dataframe["close"]
        dataframe["%-raw_open"] = dataframe["open"]
        dataframe["%-raw_high"] = dataframe["high"]
        dataframe["%-raw_low"] = dataframe["low"]
        # dataframe["%-raw_quote_asset_volume"] = dataframe["quote_asset_volume"]
        # dataframe["%-raw_trades"] = dataframe["trades"]
        # dataframe["%-raw_taker_buy_base_asset_volume"] = dataframe["taker_buy_base_asset_volume"]
        # dataframe["%-raw_taker_buy_quote_asset_volume"] = dataframe["taker_buy_quote_asset_volume"]
        return dataframe

    def feature_engineering_standard(
            self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame:

        dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
        dataframe["%-hour_of_day"] = dataframe["date"].dt.hour

        dataframe["%-raw_close"] = dataframe["close"]
        dataframe["%-raw_open"] = dataframe["open"]
        dataframe["%-raw_high"] = dataframe["high"]
        dataframe["%-raw_low"] = dataframe["low"]
        
        # dataframe["%-hour_of_day"] = dataframe["date"].dt.hour
        # dataframe["%-hour_of_day"] = dataframe["date"].dt.hour
        # dataframe["%-hour_of_day"] = dataframe["date"].dt.hour
        return dataframe

    def set_freqai_targets(self, dataframe: DataFrame, metadata: Dict, **kwargs) -> DataFrame:

        # print("调用freqai\n\n\n")
        # self.freqai.class_names = ["down", "up"]

        a = np.where(dataframe["close"].shift(-50) >
                                              dataframe["close"], "up", "down")
        
        # # print(111, a)
        # dataframe['&s-up_or_down'] = a
        # dataframe['&s-close_price'] = dataframe['close'].shift(-100)
        # print(dataframe['date'], dataframe['date'].shift(-100))
        dataframe["&-action"] = 0
        return dataframe



    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        dataframe = self.freqai.start(dataframe, metadata, self)
        print(dataframe)

        heikinashi = qtpylib.heikinashi(dataframe)
        # dataframe['open'] = heikinashi['open']
        #dataframe['close'] = heikinashi['close']
        dataframe['high'] = heikinashi['high']
        dataframe['low'] = heikinashi['low']

        dataframe['trend_close_5m'] = dataframe['close']
        dataframe['trend_close_15m'] = ta.EMA(dataframe['close'], timeperiod=3)
        dataframe['trend_close_30m'] = ta.EMA(dataframe['close'], timeperiod=6)
        dataframe['trend_close_1h'] = ta.EMA(dataframe['close'], timeperiod=12)
        dataframe['trend_close_2h'] = ta.EMA(dataframe['close'], timeperiod=24)
        dataframe['trend_close_4h'] = ta.EMA(dataframe['close'], timeperiod=48)
        dataframe['trend_close_6h'] = ta.EMA(dataframe['close'], timeperiod=72)
        dataframe['trend_close_8h'] = ta.EMA(dataframe['close'], timeperiod=96)

        dataframe['trend_open_5m'] = dataframe['open']
        dataframe['trend_open_15m'] = ta.EMA(dataframe['open'], timeperiod=3)
        dataframe['trend_open_30m'] = ta.EMA(dataframe['open'], timeperiod=6)
        dataframe['trend_open_1h'] = ta.EMA(dataframe['open'], timeperiod=12)
        dataframe['trend_open_2h'] = ta.EMA(dataframe['open'], timeperiod=24)
        dataframe['trend_open_4h'] = ta.EMA(dataframe['open'], timeperiod=48)
        dataframe['trend_open_6h'] = ta.EMA(dataframe['open'], timeperiod=72)
        dataframe['trend_open_8h'] = ta.EMA(dataframe['open'], timeperiod=96)

        dataframe['fan_magnitude'] = (dataframe['trend_close_1h'] / dataframe['trend_close_8h'])
        dataframe['fan_magnitude_gain'] = dataframe['fan_magnitude'] / dataframe['fan_magnitude'].shift(1)

        ichimoku = ftt.ichimoku(dataframe, conversion_line_period=20, base_line_periods=60, laggin_span=120, displacement=30)
        dataframe['chikou_span'] = ichimoku['chikou_span']
        dataframe['tenkan_sen'] = ichimoku['tenkan_sen']
        dataframe['kijun_sen'] = ichimoku['kijun_sen']
        dataframe['senkou_a'] = ichimoku['senkou_span_a']
        dataframe['senkou_b'] = ichimoku['senkou_span_b']
        dataframe['leading_senkou_span_a'] = ichimoku['leading_senkou_span_a']
        dataframe['leading_senkou_span_b'] = ichimoku['leading_senkou_span_b']
        dataframe['cloud_green'] = ichimoku['cloud_green']
        dataframe['cloud_red'] = ichimoku['cloud_red']

        dataframe['atr'] = ta.ATR(dataframe)

        return dataframe


    # def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        conditions = []
        short_conditions = []

        # Trending market
        if self.buy_params['buy_trend_above_senkou_level'] >= 1:
            conditions.append(dataframe['trend_close_5m'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_5m'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_5m'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_5m'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 2:
            conditions.append(dataframe['trend_close_15m'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_15m'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_15m'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_15m'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 3:
            conditions.append(dataframe['trend_close_30m'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_30m'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_30m'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_30m'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 4:
            conditions.append(dataframe['trend_close_1h'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_1h'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_1h'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_1h'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 5:
            conditions.append(dataframe['trend_close_2h'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_2h'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_2h'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_2h'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 6:
            conditions.append(dataframe['trend_close_4h'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_4h'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_4h'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_4h'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 7:
            conditions.append(dataframe['trend_close_6h'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_6h'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_6h'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_6h'] < dataframe['senkou_b'])

        if self.buy_params['buy_trend_above_senkou_level'] >= 8:
            conditions.append(dataframe['trend_close_8h'] > dataframe['senkou_a'])
            conditions.append(dataframe['trend_close_8h'] > dataframe['senkou_b'])

            short_conditions.append(dataframe['trend_close_8h'] < dataframe['senkou_a'])
            short_conditions.append(dataframe['trend_close_8h'] < dataframe['senkou_b'])

        # Trends bullish
        if self.buy_params['buy_trend_bullish_level'] >= 1:
            conditions.append(dataframe['trend_close_5m'] > dataframe['trend_open_5m'])
            short_conditions.append(dataframe['trend_close_5m'] < dataframe['trend_open_5m'])

        if self.buy_params['buy_trend_bullish_level'] >= 2:
            conditions.append(dataframe['trend_close_15m'] > dataframe['trend_open_15m'])
            short_conditions.append(dataframe['trend_close_15m'] < dataframe['trend_open_15m'])

        if self.buy_params['buy_trend_bullish_level'] >= 3:
            conditions.append(dataframe['trend_close_30m'] > dataframe['trend_open_30m'])
            short_conditions.append(dataframe['trend_close_30m'] < dataframe['trend_open_30m'])

        if self.buy_params['buy_trend_bullish_level'] >= 4:
            conditions.append(dataframe['trend_close_1h'] > dataframe['trend_open_1h'])
            short_conditions.append(dataframe['trend_close_1h'] < dataframe['trend_open_1h'])

        if self.buy_params['buy_trend_bullish_level'] >= 5:
            conditions.append(dataframe['trend_close_2h'] > dataframe['trend_open_2h'])
            short_conditions.append(dataframe['trend_close_2h'] < dataframe['trend_open_2h'])

        if self.buy_params['buy_trend_bullish_level'] >= 6:
            conditions.append(dataframe['trend_close_4h'] > dataframe['trend_open_4h'])
            short_conditions.append(dataframe['trend_close_4h'] < dataframe['trend_open_4h'])

        if self.buy_params['buy_trend_bullish_level'] >= 7:
            conditions.append(dataframe['trend_close_6h'] > dataframe['trend_open_6h'])
            short_conditions.append(dataframe['trend_close_6h'] < dataframe['trend_open_6h'])

        if self.buy_params['buy_trend_bullish_level'] >= 8:
            conditions.append(dataframe['trend_close_8h'] > dataframe['trend_open_8h'])
            short_conditions.append(dataframe['trend_close_8h'] < dataframe['trend_open_8h'])

        # Trends magnitude
        conditions.append(dataframe['fan_magnitude_gain'] >= self.buy_params['buy_min_fan_magnitude_gain'])
        conditions.append(dataframe['fan_magnitude'] > 1)

        short_conditions.append(dataframe['fan_magnitude_gain'] < self.buy_params['buy_min_fan_magnitude_gain'])
        short_conditions.append(dataframe['fan_magnitude'] < 1)

        for x in range(self.buy_params['buy_fan_magnitude_shift_value']):
            conditions.append(dataframe['fan_magnitude'].shift(x+1) < dataframe['fan_magnitude'])
            short_conditions.append(dataframe['fan_magnitude'].shift(x+1) > dataframe['fan_magnitude'])

        if conditions:
            pass
            # dataframe.loc[
            #     reduce(lambda x, y: x & y, conditions),
            #     'buy'] = 1
            # dataframe.loc[
            #     (dataframe['&s-up_or_down'] == "up"),
            #     'enter_long'] = 1

            # dataframe.loc[
            #     (dataframe['&s-up_or_down'] == "down"),
            #     'enter_short'] = 1
            # dataframe.loc[
            #     reduce(lambda x, y: x & y, conditions),
            #     'enter_long'] = 1

            # dataframe.loc[
            #     reduce(lambda x, y: x & y, short_conditions),
            #     'enter_short'] = 1


        enter_long_conditions = [dataframe["do_predict"] == 1, dataframe["&-action"] == 1]

        if enter_long_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, enter_long_conditions), ["enter_long", "enter_tag"]
            ] = (1, "long")

        enter_short_conditions = [dataframe["do_predict"] == 1, dataframe["&-action"] == 3]

        if enter_short_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, enter_short_conditions), ["enter_short", "enter_tag"]
            ] = (1, "short")

        return dataframe


    # def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        # conditions = []

        # conditions.append(qtpylib.crossed_below(dataframe['trend_close_5m'], dataframe[self.sell_params['sell_trend_indicator']]))

        # if conditions:
        #     # dataframe.loc[
        #     #     reduce(lambda x, y: x & y, conditions),
        #     #     'sell'] = 1
        #     dataframe.loc[
        #         reduce(lambda x, y: x & y, conditions),
        #         'exit_short'] = 1
        #     dataframe.loc[
        #         reduce(lambda x, y: x & y, conditions),
        #         'exit_long'] = 1

        # 定义移动平均线
        short_window = 10  # 短期窗口
        long_window = 30   # 长期窗口

        # 计算移动平均线
        dataframe['short_ma'] = dataframe['close'].rolling(window=short_window).mean()
        dataframe['long_ma'] = dataframe['close'].rolling(window=long_window).mean()

        # 定义进入空头的条件
        short_conditions = []
        short_conditions.append(dataframe['short_ma'] < dataframe['long_ma'])

        # 定义进入多头的条件
        long_conditions = []
        long_conditions.append(dataframe['short_ma'] > dataframe['long_ma'])

        # # 应用多头和空头条件
        # if short_conditions:
        #     dataframe.loc[reduce(lambda x, y: x & y, short_conditions), 'exit_short'] = 1

        # if long_conditions:
        #     dataframe.loc[reduce(lambda x, y: x & y, long_conditions), 'exit_long'] = 1

        # print(dataframe["do_predict"])

        exit_long_conditions = [dataframe["do_predict"] == 1, dataframe["&-action"] == 2]
        if exit_long_conditions:
            dataframe.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1

        exit_short_conditions = [dataframe["do_predict"] == 1, dataframe["&-action"] == 4]
        if exit_short_conditions:
            dataframe.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1


        return dataframe

搜索

文章分类