From df3c607e5724508506d2a7125494d1db38a891d7 Mon Sep 17 00:00:00 2001 From: crypto_rahino Date: Fri, 19 Mar 2021 11:13:07 +0200 Subject: [PATCH] first --- .env/bin/.last_result.json | 1 + .env/bin/Activate.ps1 | 241 +++++++++++ .../.gitkeep => .env/bin/__init__.py | 0 .env/bin/activate | 76 ++++ .env/bin/activate.csh | 37 ++ .env/bin/activate.fish | 75 ++++ .env/bin/chardetect | 8 + .env/bin/coverage | 8 + .env/bin/coverage-3.8 | 8 + .env/bin/coverage3 | 8 + .env/bin/coveralls | 8 + .env/bin/data_analysis.py | 159 +++++++ .env/bin/dmypy | 8 + .env/bin/easy_install | 8 + .env/bin/easy_install-3.8 | 8 + .env/bin/f2py | 8 + .env/bin/f2py3 | 8 + .env/bin/f2py3.8 | 8 + .env/bin/flake8 | 8 + .env/bin/freqtrade | 12 + .env/bin/isort | 8 + .env/bin/isort-identify-imports | 8 + .env/bin/jsonschema | 8 + .env/bin/jupyter | 8 + .env/bin/jupyter-kernel | 8 + .env/bin/jupyter-kernelspec | 8 + .env/bin/jupyter-migrate | 8 + .env/bin/jupyter-nbconvert | 8 + .env/bin/jupyter-run | 8 + .env/bin/jupyter-troubleshoot | 8 + .env/bin/jupyter-trust | 8 + .env/bin/mypy | 8 + .env/bin/mypyc | 55 +++ .env/bin/pip | 8 + .env/bin/pip3 | 8 + .env/bin/pip3.8 | 8 + .env/bin/pt2to3 | 8 + .env/bin/ptdump | 8 + .env/bin/ptrepack | 8 + .env/bin/pttree | 8 + .env/bin/py.test | 8 + .env/bin/pycodestyle | 8 + .env/bin/pyflakes | 8 + .env/bin/pygmentize | 8 + .env/bin/pytest | 8 + .env/bin/python | 1 + .env/bin/python3 | 1 + .env/bin/python3.8 | 1 + .env/bin/stubgen | 8 + .env/bin/stubtest | 8 + .env/bin/tabulate | 8 + .../bin/user_data/__init__.py | 0 .../bin/user_data/backtest_results}/.gitkeep | 0 .../backtest_results/.last_result.json | 1 + .env/bin/user_data/config_adausdt_1m.json | 86 ++++ .env/bin/user_data/config_binance.json | 84 ++++ .../user_data/config_binance_multiple.json | 91 ++++ .env/bin/user_data/config_btcusdt_1m.json | 86 ++++ .env/bin/user_data/config_dogeusdt_1m.json | 86 ++++ .../config_ethusdt_1h_high_risk.json | 86 ++++ .env/bin/user_data/config_ethusdt_1m.json | 86 ++++ .../config_ethusdt_1m_sellonlyprofit.json | 91 ++++ .../bin/user_data/config_ethusdt_safe_1h.json | 91 ++++ .env/bin/user_data/config_ltcusdt_1h.json | 91 ++++ .../bin/user_data/hyperopt.lock | 0 .../hyperopt_results/.last_result.json | 1 + .../hyperopt_results/ada2_results.txt | 151 +++++++ .../user_data/hyperopt_results/crypto_rahino | 38 ++ .../hyperopt_results/ehtusdt3_profit | 136 ++++++ .../hyperopt_results/eth2_safe_1h_sharpe.txt | 128 ++++++ .../hyperopt_results/ethusdt2_360_results | 119 ++++++ .../strg1_dogeusdt_sortino_result.txt | 121 ++++++ .../strg1_ethusd2_results_sharpe.txt | 122 ++++++ .../strg1_ethusd2_results_sortino.txt | 138 ++++++ .../bin/user_data/hyperopts}/.gitkeep | 0 .../bin/user_data/hyperopts/__init__.py | 0 .env/bin/user_data/hyperopts/advanced.py | 168 ++++++++ .../bin/user_data/hyperopts/advanced_hyper.py | 304 +++++++++++++ .env/bin/user_data/hyperopts/full_hyper.py | 168 ++++++++ .env/bin/user_data/hyperopts/hyper1.py | 393 +++++++++++++++++ .env/bin/user_data/hyperopts/hyper1_1.py | 393 +++++++++++++++++ .env/bin/user_data/hyperopts/hyper2.py | 176 ++++++++ .env/bin/user_data/hyperopts/hyper_adausdt.py | 388 +++++++++++++++++ .../bin/user_data/hyperopts/hyper_adausdt2.py | 256 +++++++++++ .../bin/user_data/hyperopts/hyper_adausdt3.py | 356 ++++++++++++++++ .../bin/user_data/hyperopts/hyper_dogeusdt.py | 402 ++++++++++++++++++ .../bin/user_data/hyperopts/hyper_ethusdt2.py | 240 +++++++++++ .../bin/user_data/hyperopts/hyper_ethusdt3.py | 285 +++++++++++++ .../hyperopts/hyper_ethusdt_high_risk.py | 290 +++++++++++++ .../user_data/hyperopts/hyper_ltcusdt_1h.py | 240 +++++++++++ .../user_data/hyperopts/hyper_ltcusdt_1hpy | 240 +++++++++++ .env/bin/user_data/hyperopts/macd_hyper.py | 173 ++++++++ .../hyperopts/quick_ethusdt_1m_hyper.py | 219 ++++++++++ .env/bin/user_data/logs/.gitkeep | 0 .env/bin/user_data/notebooks/.gitkeep | 0 .env/bin/user_data/strategies/.gitkeep | 0 .env/bin/user_data/strategies/__init__.py | 0 .../user_data/strategies/data_eth_usdt_1m.py | 216 ++++++++++ .../strategies/ethusdt2_safe_prod1.py | 208 +++++++++ .../user_data/strategies/ethusdt_high_risk.py | 214 ++++++++++ .env/bin/user_data/strategies/ltcusdt_1h.py | 189 ++++++++ .env/bin/user_data/strategies/macd_strg.py | 301 +++++++++++++ .../user_data/strategies/quick_btcusdt_1m.py | 196 +++++++++ .../user_data/strategies/quick_ethusdt_1m.py | 197 +++++++++ .../user_data/strategies/strg1_ada_usdt_1m.py | 205 +++++++++ .../user_data/strategies/strg1_btc_usdt_1m.py | 199 +++++++++ .../strategies/strg1_doge_usdt_1m.py | 216 ++++++++++ .../user_data/strategies/strg1_eth_usdt_1m.py | 233 ++++++++++ .../strategies/strg1_eth_usdt_1m_prod.py | 216 ++++++++++ .../user_data/strategies/strg2_ada_usdt_1m.py | 189 ++++++++ .../strategies/strg2_ada_usdt_1m_prod.py | 189 ++++++++ .../strategies/strg2_ada_usdt_1m_sharpe.py | 178 ++++++++ .../user_data/strategies/strg2_eth_usdt_1m.py | 231 ++++++++++ .../strategies/strg2_eth_usdt_1m_360_30_15.py | 212 +++++++++ .../strategies/strg2_eth_usdt_1m_safe_prod.py | 231 ++++++++++ .../user_data/strategies/strg3_ada_usdt_1m.py | 199 +++++++++ .../user_data/strategies/strg3_eth_usdt_1m.py | 237 +++++++++++ .../strg3_eth_usdt_1m_sellonlyprofit.py | 219 ++++++++++ .env/bin/user_data/strategies/strtg2.py | 281 ++++++++++++ .env/bin/uvicorn | 8 + .gitignore | 8 +- extract_features.py | 8 + freqtrade/hyperopts/sample_hyperopt.py | 208 +++++++++ .../hyperopts/sample_hyperopt_advanced.py | 306 +++++++++++++ freqtrade/hyperopts/sample_hyperopt_loss.py | 49 +++ .../notebooks/strategy_analysis_example.ipynb | 360 ++++++++++++++++ freqtrade/plot/plotting.py | 2 + freqtrade/strategies/sample_strategy.py | 366 ++++++++++++++++ freqtrade/user_data/backtest_results/.gitkeep | 0 freqtrade/user_data/data/.gitkeep | 0 freqtrade/user_data/hyperopts/.gitkeep | 0 freqtrade/user_data/logs/.gitkeep | 0 freqtrade/user_data/notebooks/.gitkeep | 0 freqtrade/user_data/strategies/.gitkeep | 0 hyper_parser.py | 15 + utils.py | 92 ++++ 136 files changed, 13669 insertions(+), 4 deletions(-) create mode 100644 .env/bin/.last_result.json create mode 100644 .env/bin/Activate.ps1 rename user_data/backtest_results/.gitkeep => .env/bin/__init__.py (100%) create mode 100644 .env/bin/activate create mode 100644 .env/bin/activate.csh create mode 100644 .env/bin/activate.fish create mode 100755 .env/bin/chardetect create mode 100755 .env/bin/coverage create mode 100755 .env/bin/coverage-3.8 create mode 100755 .env/bin/coverage3 create mode 100755 .env/bin/coveralls create mode 100644 .env/bin/data_analysis.py create mode 100755 .env/bin/dmypy create mode 100755 .env/bin/easy_install create mode 100755 .env/bin/easy_install-3.8 create mode 100755 .env/bin/f2py create mode 100755 .env/bin/f2py3 create mode 100755 .env/bin/f2py3.8 create mode 100755 .env/bin/flake8 create mode 100755 .env/bin/freqtrade create mode 100755 .env/bin/isort create mode 100755 .env/bin/isort-identify-imports create mode 100755 .env/bin/jsonschema create mode 100755 .env/bin/jupyter create mode 100755 .env/bin/jupyter-kernel create mode 100755 .env/bin/jupyter-kernelspec create mode 100755 .env/bin/jupyter-migrate create mode 100755 .env/bin/jupyter-nbconvert create mode 100755 .env/bin/jupyter-run create mode 100755 .env/bin/jupyter-troubleshoot create mode 100755 .env/bin/jupyter-trust create mode 100755 .env/bin/mypy create mode 100755 .env/bin/mypyc create mode 100755 .env/bin/pip create mode 100755 .env/bin/pip3 create mode 100755 .env/bin/pip3.8 create mode 100755 .env/bin/pt2to3 create mode 100755 .env/bin/ptdump create mode 100755 .env/bin/ptrepack create mode 100755 .env/bin/pttree create mode 100755 .env/bin/py.test create mode 100755 .env/bin/pycodestyle create mode 100755 .env/bin/pyflakes create mode 100755 .env/bin/pygmentize create mode 100755 .env/bin/pytest create mode 120000 .env/bin/python create mode 120000 .env/bin/python3 create mode 120000 .env/bin/python3.8 create mode 100755 .env/bin/stubgen create mode 100755 .env/bin/stubtest create mode 100755 .env/bin/tabulate rename user_data/data/.gitkeep => .env/bin/user_data/__init__.py (100%) rename {user_data/hyperopts => .env/bin/user_data/backtest_results}/.gitkeep (100%) create mode 100644 .env/bin/user_data/backtest_results/.last_result.json create mode 100644 .env/bin/user_data/config_adausdt_1m.json create mode 100644 .env/bin/user_data/config_binance.json create mode 100644 .env/bin/user_data/config_binance_multiple.json create mode 100644 .env/bin/user_data/config_btcusdt_1m.json create mode 100644 .env/bin/user_data/config_dogeusdt_1m.json create mode 100644 .env/bin/user_data/config_ethusdt_1h_high_risk.json create mode 100644 .env/bin/user_data/config_ethusdt_1m.json create mode 100644 .env/bin/user_data/config_ethusdt_1m_sellonlyprofit.json create mode 100644 .env/bin/user_data/config_ethusdt_safe_1h.json create mode 100644 .env/bin/user_data/config_ltcusdt_1h.json rename user_data/logs/.gitkeep => .env/bin/user_data/hyperopt.lock (100%) mode change 100644 => 100755 create mode 100644 .env/bin/user_data/hyperopt_results/.last_result.json create mode 100644 .env/bin/user_data/hyperopt_results/ada2_results.txt create mode 100644 .env/bin/user_data/hyperopt_results/crypto_rahino create mode 100644 .env/bin/user_data/hyperopt_results/ehtusdt3_profit create mode 100644 .env/bin/user_data/hyperopt_results/eth2_safe_1h_sharpe.txt create mode 100644 .env/bin/user_data/hyperopt_results/ethusdt2_360_results create mode 100644 .env/bin/user_data/hyperopt_results/strg1_dogeusdt_sortino_result.txt create mode 100644 .env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sharpe.txt create mode 100644 .env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sortino.txt rename {user_data/notebooks => .env/bin/user_data/hyperopts}/.gitkeep (100%) rename user_data/strategies/.gitkeep => .env/bin/user_data/hyperopts/__init__.py (100%) create mode 100644 .env/bin/user_data/hyperopts/advanced.py create mode 100644 .env/bin/user_data/hyperopts/advanced_hyper.py create mode 100644 .env/bin/user_data/hyperopts/full_hyper.py create mode 100644 .env/bin/user_data/hyperopts/hyper1.py create mode 100644 .env/bin/user_data/hyperopts/hyper1_1.py create mode 100644 .env/bin/user_data/hyperopts/hyper2.py create mode 100644 .env/bin/user_data/hyperopts/hyper_adausdt.py create mode 100644 .env/bin/user_data/hyperopts/hyper_adausdt2.py create mode 100644 .env/bin/user_data/hyperopts/hyper_adausdt3.py create mode 100644 .env/bin/user_data/hyperopts/hyper_dogeusdt.py create mode 100644 .env/bin/user_data/hyperopts/hyper_ethusdt2.py create mode 100644 .env/bin/user_data/hyperopts/hyper_ethusdt3.py create mode 100644 .env/bin/user_data/hyperopts/hyper_ethusdt_high_risk.py create mode 100644 .env/bin/user_data/hyperopts/hyper_ltcusdt_1h.py create mode 100644 .env/bin/user_data/hyperopts/hyper_ltcusdt_1hpy create mode 100644 .env/bin/user_data/hyperopts/macd_hyper.py create mode 100644 .env/bin/user_data/hyperopts/quick_ethusdt_1m_hyper.py create mode 100644 .env/bin/user_data/logs/.gitkeep create mode 100644 .env/bin/user_data/notebooks/.gitkeep create mode 100644 .env/bin/user_data/strategies/.gitkeep create mode 100644 .env/bin/user_data/strategies/__init__.py create mode 100644 .env/bin/user_data/strategies/data_eth_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/ethusdt2_safe_prod1.py create mode 100644 .env/bin/user_data/strategies/ethusdt_high_risk.py create mode 100644 .env/bin/user_data/strategies/ltcusdt_1h.py create mode 100644 .env/bin/user_data/strategies/macd_strg.py create mode 100644 .env/bin/user_data/strategies/quick_btcusdt_1m.py create mode 100644 .env/bin/user_data/strategies/quick_ethusdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg1_ada_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg1_btc_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg1_doge_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg1_eth_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg1_eth_usdt_1m_prod.py create mode 100644 .env/bin/user_data/strategies/strg2_ada_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg2_ada_usdt_1m_prod.py create mode 100644 .env/bin/user_data/strategies/strg2_ada_usdt_1m_sharpe.py create mode 100644 .env/bin/user_data/strategies/strg2_eth_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg2_eth_usdt_1m_360_30_15.py create mode 100644 .env/bin/user_data/strategies/strg2_eth_usdt_1m_safe_prod.py create mode 100644 .env/bin/user_data/strategies/strg3_ada_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg3_eth_usdt_1m.py create mode 100644 .env/bin/user_data/strategies/strg3_eth_usdt_1m_sellonlyprofit.py create mode 100644 .env/bin/user_data/strategies/strtg2.py create mode 100755 .env/bin/uvicorn create mode 100644 extract_features.py create mode 100644 freqtrade/hyperopts/sample_hyperopt.py create mode 100644 freqtrade/hyperopts/sample_hyperopt_advanced.py create mode 100644 freqtrade/hyperopts/sample_hyperopt_loss.py create mode 100644 freqtrade/notebooks/strategy_analysis_example.ipynb create mode 100644 freqtrade/strategies/sample_strategy.py create mode 100644 freqtrade/user_data/backtest_results/.gitkeep create mode 100644 freqtrade/user_data/data/.gitkeep create mode 100644 freqtrade/user_data/hyperopts/.gitkeep create mode 100644 freqtrade/user_data/logs/.gitkeep create mode 100644 freqtrade/user_data/notebooks/.gitkeep create mode 100644 freqtrade/user_data/strategies/.gitkeep create mode 100644 hyper_parser.py create mode 100644 utils.py diff --git a/.env/bin/.last_result.json b/.env/bin/.last_result.json new file mode 100644 index 000000000..8039c524f --- /dev/null +++ b/.env/bin/.last_result.json @@ -0,0 +1 @@ +{"latest_backtest":"backtest_strg2_ETHUSDT_1m_prod1-2021-02-25_20-07-44.json"} \ No newline at end of file diff --git a/.env/bin/Activate.ps1 b/.env/bin/Activate.ps1 new file mode 100644 index 000000000..2fb3852c3 --- /dev/null +++ b/.env/bin/Activate.ps1 @@ -0,0 +1,241 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/user_data/backtest_results/.gitkeep b/.env/bin/__init__.py similarity index 100% rename from user_data/backtest_results/.gitkeep rename to .env/bin/__init__.py diff --git a/.env/bin/activate b/.env/bin/activate new file mode 100644 index 000000000..544a26882 --- /dev/null +++ b/.env/bin/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/yakov/PycharmProjects/freqtrade/.env" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(.env) " != x ] ; then + PS1="(.env) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r +fi diff --git a/.env/bin/activate.csh b/.env/bin/activate.csh new file mode 100644 index 000000000..339ab2759 --- /dev/null +++ b/.env/bin/activate.csh @@ -0,0 +1,37 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/yakov/PycharmProjects/freqtrade/.env" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if (".env" != "") then + set env_name = ".env" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/.env/bin/activate.fish b/.env/bin/activate.fish new file mode 100644 index 000000000..3abccfdcd --- /dev/null +++ b/.env/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/yakov/PycharmProjects/freqtrade/.env" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(.env) " + printf "%s%s" "(.env) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/.env/bin/chardetect b/.env/bin/chardetect new file mode 100755 index 000000000..4eba84c2b --- /dev/null +++ b/.env/bin/chardetect @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from chardet.cli.chardetect import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/coverage b/.env/bin/coverage new file mode 100755 index 000000000..0d37f85d4 --- /dev/null +++ b/.env/bin/coverage @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from coverage.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/coverage-3.8 b/.env/bin/coverage-3.8 new file mode 100755 index 000000000..0d37f85d4 --- /dev/null +++ b/.env/bin/coverage-3.8 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from coverage.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/coverage3 b/.env/bin/coverage3 new file mode 100755 index 000000000..0d37f85d4 --- /dev/null +++ b/.env/bin/coverage3 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from coverage.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/coveralls b/.env/bin/coveralls new file mode 100755 index 000000000..2c8e8c39c --- /dev/null +++ b/.env/bin/coveralls @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from coveralls.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/data_analysis.py b/.env/bin/data_analysis.py new file mode 100644 index 000000000..6a90e9a58 --- /dev/null +++ b/.env/bin/data_analysis.py @@ -0,0 +1,159 @@ +from pathlib import Path +from freqtrade.configuration import Configuration +from freqtrade.data.dataprovider import DataProvider +from freqtrade.data.history import load_pair_history +from freqtrade.resolvers import StrategyResolver +from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats +from freqtrade.data.btanalysis import load_trades_from_db +from freqtrade.data.btanalysis import analyze_trade_parallelism +from freqtrade.plot.plotting import generate_candlestick_graph + +import matplotlib + +# # Customize these according to your needs. +# +# # Initialize empty configuration object +from freqtrade.strategy import IStrategy + +config = Configuration.from_files(["user_data/config_ltcusdt_1h.json"]) +# # Optionally, use existing configuration file +# config = Configuration.from_files(["config.json"]) +# +# # Define some constants +# config["timeframe"] = "1m" +# # Name of the strategy class +config["strategy"] = "ltcusdt_1h" +# # Location of the data +data_location = Path(config['user_data_dir'], 'data', 'binance') +# # Pair to analyze - Only use one pair here +pair = "LTC/USDT" +# +# # Load data using values set above +# +candles = load_pair_history(datadir=data_location, + timeframe=config["timeframe"], + pair=pair) +# +# # Confirm success +# print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}") +# +# # Load strategy using values set above +# +dataprovider = DataProvider(config, config['exchange']) +IStrategy.dp = dataprovider +strategy = StrategyResolver.load_strategy(config) +# +# # Generate buy/sell signals using strategy +df = strategy.analyze_ticker(candles, {'pair': pair}) +# +# col = df.columns +# +# # Report results +# print(f"Generated {df['buy'].sum()} buy signals") +data = df.set_index('date', drop=False) + + +# # if backtest_dir points to a directory, it'll automatically load the last backtest file. +# stats = load_backtest_stats(backtest_dir) +# # You can get the full backtest statistics by using the following command. +# # This contains all information used to generate the backtest result. +# +# strategy = config["strategy"] +# # All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well. +# # Example usages: +# print(stats['strategy'][strategy]['results_per_pair']) +# # Get pairlist used for this backtest +# print(stats['strategy'][strategy]['pairlist']) +# # Get market change (average change of all pairs from start to end of the backtest period) +# print(stats['strategy'][strategy]['market_change']) +# # Maximum drawdown () +# print(stats['strategy'][strategy]['max_drawdown']) +# # Maximum drawdown start and end +# print(stats['strategy'][strategy]['drawdown_start']) +# print(stats['strategy'][strategy]['drawdown_end']) +# +# # Get strategy comparison (only relevant if multiple strategies were compared) +# print(stats['strategy_comparison']) +# +# # Load backtested trades as dataframe +# print(f"backtest {backtest_dir}") +# trades = load_backtest_data(backtest_dir) + +# # Show value-counts per pair +# trades.groupby("pair")["sell_reason"].value_counts() + +# Fetch trades from database + + +# Display results +# trades.groupby("pair")["sell_reason"].value_counts() + + +def plot_db(path): + trades = load_trades_from_db(path) + # Analyze the above + parallel_trades = analyze_trade_parallelism(trades, '1m') + parallel_trades.plot() + trades_red = trades.loc[trades['pair'] == pair] + # Limit graph period to keep plotly quick and reactive + # Filter trades to one pair + data_red = data['2021-01-15':'2021-01-23'] + # Generate candlestick graph + graph = generate_candlestick_graph(pair=pair, + data=data_red, + trades=trades_red, + indicators1=['tsf_mid'], + indicators2=['correl_tsf_mid_close', 'correl_angle_short_close', + 'correl_angle_long_close', 'correl_hist_close'] + ) + graph.show() + + +def plot_backtest(start_date, stop_date): + backtest_dir = config["user_data_dir"] / "backtest_results" + strategy = config["strategy"] + + trades = load_backtest_data(backtest_dir) + stats = load_backtest_stats(backtest_dir) + parallel_trades = analyze_trade_parallelism(trades, '1h') + parallel_trades = parallel_trades[start_date:stop_date] + parallel_trades.plot() + # All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well. + # Example usages: + print(stats['strategy'][strategy]['results_per_pair']) + # Get pairlist used for this backtest + print(stats['strategy'][strategy]['pairlist']) + # Get market change (average change of all pairs from start to end of the backtest period) + print(stats['strategy'][strategy]['market_change']) + # Maximum drawdown () + print(stats['strategy'][strategy]['max_drawdown']) + # Maximum drawdown start and end + print(stats['strategy'][strategy]['drawdown_start']) + print(stats['strategy'][strategy]['drawdown_end']) + + # Get strategy comparison (only relevant if multiple strategies were compared) + print(stats['strategy_comparison']) + + # Load backtested trades as dataframe + print(f"backtest {backtest_dir}") + # Show value-counts per pair + trades.groupby("pair")["sell_reason"].value_counts() + + # trades_red = trades[start_date:stop_date] + + # Limit graph period to keep plotly quick and reactive + # Filter trades to one pair + data_red = data[start_date:stop_date] + # Generate candlestick graph + graph = generate_candlestick_graph(pair=pair, + data=data_red, + trades=trades, + indicators1=['sar', 'tsf_mid'], + indicators2=['sine', 'leadsine', 'angle_trend_mid', 'inphase', 'quadrature' ] + ) + + graph.show() + + +plot_backtest(start_date='2020-01-01', stop_date='2021-03-18') + diff --git a/.env/bin/dmypy b/.env/bin/dmypy new file mode 100755 index 000000000..4b9d7bb54 --- /dev/null +++ b/.env/bin/dmypy @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from mypy.dmypy.client import console_entry +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_entry()) diff --git a/.env/bin/easy_install b/.env/bin/easy_install new file mode 100755 index 000000000..b0f7efff1 --- /dev/null +++ b/.env/bin/easy_install @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/easy_install-3.8 b/.env/bin/easy_install-3.8 new file mode 100755 index 000000000..b0f7efff1 --- /dev/null +++ b/.env/bin/easy_install-3.8 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from setuptools.command.easy_install import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/f2py b/.env/bin/f2py new file mode 100755 index 000000000..0ea81dbfa --- /dev/null +++ b/.env/bin/f2py @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/f2py3 b/.env/bin/f2py3 new file mode 100755 index 000000000..0ea81dbfa --- /dev/null +++ b/.env/bin/f2py3 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/f2py3.8 b/.env/bin/f2py3.8 new file mode 100755 index 000000000..0ea81dbfa --- /dev/null +++ b/.env/bin/f2py3.8 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/flake8 b/.env/bin/flake8 new file mode 100755 index 000000000..f4b553593 --- /dev/null +++ b/.env/bin/flake8 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from flake8.main.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/freqtrade b/.env/bin/freqtrade new file mode 100755 index 000000000..d156f07d8 --- /dev/null +++ b/.env/bin/freqtrade @@ -0,0 +1,12 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# EASY-INSTALL-ENTRY-SCRIPT: 'freqtrade','console_scripts','freqtrade' +__requires__ = 'freqtrade' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('freqtrade', 'console_scripts', 'freqtrade')() + ) diff --git a/.env/bin/isort b/.env/bin/isort new file mode 100755 index 000000000..07f1a7d03 --- /dev/null +++ b/.env/bin/isort @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/isort-identify-imports b/.env/bin/isort-identify-imports new file mode 100755 index 000000000..27a00dc74 --- /dev/null +++ b/.env/bin/isort-identify-imports @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import identify_imports_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(identify_imports_main()) diff --git a/.env/bin/jsonschema b/.env/bin/jsonschema new file mode 100755 index 000000000..bc0cd0132 --- /dev/null +++ b/.env/bin/jsonschema @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jsonschema.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter b/.env/bin/jupyter new file mode 100755 index 000000000..38057355f --- /dev/null +++ b/.env/bin/jupyter @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.command import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter-kernel b/.env/bin/jupyter-kernel new file mode 100755 index 000000000..2565ed630 --- /dev/null +++ b/.env/bin/jupyter-kernel @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.kernelapp import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter-kernelspec b/.env/bin/jupyter-kernelspec new file mode 100755 index 000000000..a359d3cf7 --- /dev/null +++ b/.env/bin/jupyter-kernelspec @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.kernelspecapp import KernelSpecApp +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(KernelSpecApp.launch_instance()) diff --git a/.env/bin/jupyter-migrate b/.env/bin/jupyter-migrate new file mode 100755 index 000000000..0be91b8e1 --- /dev/null +++ b/.env/bin/jupyter-migrate @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.migrate import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter-nbconvert b/.env/bin/jupyter-nbconvert new file mode 100755 index 000000000..5fee1e8f6 --- /dev/null +++ b/.env/bin/jupyter-nbconvert @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from nbconvert.nbconvertapp import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter-run b/.env/bin/jupyter-run new file mode 100755 index 000000000..e04fccd90 --- /dev/null +++ b/.env/bin/jupyter-run @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_client.runapp import RunApp +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(RunApp.launch_instance()) diff --git a/.env/bin/jupyter-troubleshoot b/.env/bin/jupyter-troubleshoot new file mode 100755 index 000000000..27b16d4f9 --- /dev/null +++ b/.env/bin/jupyter-troubleshoot @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from jupyter_core.troubleshoot import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/jupyter-trust b/.env/bin/jupyter-trust new file mode 100755 index 000000000..322824ba0 --- /dev/null +++ b/.env/bin/jupyter-trust @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from nbformat.sign import TrustNotebookApp +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(TrustNotebookApp.launch_instance()) diff --git a/.env/bin/mypy b/.env/bin/mypy new file mode 100755 index 000000000..101390d31 --- /dev/null +++ b/.env/bin/mypy @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from mypy.__main__ import console_entry +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_entry()) diff --git a/.env/bin/mypyc b/.env/bin/mypyc new file mode 100755 index 000000000..37839eb83 --- /dev/null +++ b/.env/bin/mypyc @@ -0,0 +1,55 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +"""Mypyc command-line tool. + +Usage: + + $ mypyc foo.py [...] + $ python3 -c 'import foo' # Uses compiled 'foo' + + +This is just a thin wrapper that generates a setup.py file that uses +mypycify, suitable for prototyping and testing. +""" + +import os +import os.path +import subprocess +import sys +import tempfile +import time + +base_path = os.path.join(os.path.dirname(__file__), '..') + +setup_format = """\ +from distutils.core import setup +from mypyc.build import mypycify + +setup(name='mypyc_output', + ext_modules=mypycify({}, opt_level="{}"), +) +""" + +def main() -> None: + build_dir = 'build' # can this be overridden?? + try: + os.mkdir(build_dir) + except FileExistsError: + pass + + opt_level = os.getenv("MYPYC_OPT_LEVEL", '3') + + setup_file = os.path.join(build_dir, 'setup.py') + with open(setup_file, 'w') as f: + f.write(setup_format.format(sys.argv[1:], opt_level)) + + # We don't use run_setup (like we do in the test suite) because it throws + # away the error code from distutils, and we don't care about the slight + # performance loss here. + env = os.environ.copy() + base_path = os.path.join(os.path.dirname(__file__), '..') + env['PYTHONPATH'] = base_path + os.pathsep + env.get('PYTHONPATH', '') + cmd = subprocess.run([sys.executable, setup_file, 'build_ext', '--inplace'], env=env) + sys.exit(cmd.returncode) + +if __name__ == '__main__': + main() diff --git a/.env/bin/pip b/.env/bin/pip new file mode 100755 index 000000000..5ce62f60d --- /dev/null +++ b/.env/bin/pip @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pip3 b/.env/bin/pip3 new file mode 100755 index 000000000..5ce62f60d --- /dev/null +++ b/.env/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pip3.8 b/.env/bin/pip3.8 new file mode 100755 index 000000000..5ce62f60d --- /dev/null +++ b/.env/bin/pip3.8 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pt2to3 b/.env/bin/pt2to3 new file mode 100755 index 000000000..7c731c11f --- /dev/null +++ b/.env/bin/pt2to3 @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from tables.scripts.pt2to3 import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/ptdump b/.env/bin/ptdump new file mode 100755 index 000000000..5de341e64 --- /dev/null +++ b/.env/bin/ptdump @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from tables.scripts.ptdump import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/ptrepack b/.env/bin/ptrepack new file mode 100755 index 000000000..8afe6d147 --- /dev/null +++ b/.env/bin/ptrepack @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from tables.scripts.ptrepack import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pttree b/.env/bin/pttree new file mode 100755 index 000000000..88ef9dcc7 --- /dev/null +++ b/.env/bin/pttree @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from tables.scripts.pttree import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/py.test b/.env/bin/py.test new file mode 100755 index 000000000..ac6cbee6d --- /dev/null +++ b/.env/bin/py.test @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/.env/bin/pycodestyle b/.env/bin/pycodestyle new file mode 100755 index 000000000..328b02b5d --- /dev/null +++ b/.env/bin/pycodestyle @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pycodestyle import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/.env/bin/pyflakes b/.env/bin/pyflakes new file mode 100755 index 000000000..7f2fefe9c --- /dev/null +++ b/.env/bin/pyflakes @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pyflakes.api import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pygmentize b/.env/bin/pygmentize new file mode 100755 index 000000000..aaecf59a7 --- /dev/null +++ b/.env/bin/pygmentize @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pygments.cmdline import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/pytest b/.env/bin/pytest new file mode 100755 index 000000000..ac6cbee6d --- /dev/null +++ b/.env/bin/pytest @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/.env/bin/python b/.env/bin/python new file mode 120000 index 000000000..4e58b606c --- /dev/null +++ b/.env/bin/python @@ -0,0 +1 @@ +python3.8 \ No newline at end of file diff --git a/.env/bin/python3 b/.env/bin/python3 new file mode 120000 index 000000000..4e58b606c --- /dev/null +++ b/.env/bin/python3 @@ -0,0 +1 @@ +python3.8 \ No newline at end of file diff --git a/.env/bin/python3.8 b/.env/bin/python3.8 new file mode 120000 index 000000000..02a138965 --- /dev/null +++ b/.env/bin/python3.8 @@ -0,0 +1 @@ +/usr/bin/python3.8 \ No newline at end of file diff --git a/.env/bin/stubgen b/.env/bin/stubgen new file mode 100755 index 000000000..34110d3fb --- /dev/null +++ b/.env/bin/stubgen @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from mypy.stubgen import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/stubtest b/.env/bin/stubtest new file mode 100755 index 000000000..96013824b --- /dev/null +++ b/.env/bin/stubtest @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from mypy.stubtest import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.env/bin/tabulate b/.env/bin/tabulate new file mode 100755 index 000000000..2d2f9fa24 --- /dev/null +++ b/.env/bin/tabulate @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from tabulate import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/user_data/data/.gitkeep b/.env/bin/user_data/__init__.py similarity index 100% rename from user_data/data/.gitkeep rename to .env/bin/user_data/__init__.py diff --git a/user_data/hyperopts/.gitkeep b/.env/bin/user_data/backtest_results/.gitkeep similarity index 100% rename from user_data/hyperopts/.gitkeep rename to .env/bin/user_data/backtest_results/.gitkeep diff --git a/.env/bin/user_data/backtest_results/.last_result.json b/.env/bin/user_data/backtest_results/.last_result.json new file mode 100644 index 000000000..414261fa6 --- /dev/null +++ b/.env/bin/user_data/backtest_results/.last_result.json @@ -0,0 +1 @@ +{"latest_backtest":"ltcusdt_1h-2021-03-19_10-50-25.json"} \ No newline at end of file diff --git a/.env/bin/user_data/config_adausdt_1m.json b/.env/bin/user_data/config_adausdt_1m.json new file mode 100644 index 000000000..bf70cff70 --- /dev/null +++ b/.env/bin/user_data/config_adausdt_1m.json @@ -0,0 +1,86 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 300.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": true, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": true, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": true, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ADA/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "adausdt_strg2_1m", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_binance.json b/.env/bin/user_data/config_binance.json new file mode 100644 index 000000000..25f418550 --- /dev/null +++ b/.env/bin/user_data/config_binance.json @@ -0,0 +1,84 @@ +{ + "max_open_trades": 3, + "stake_currency": "BTC", + "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/BTC" ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_binance_multiple.json b/.env/bin/user_data/config_binance_multiple.json new file mode 100644 index 000000000..63def2442 --- /dev/null +++ b/.env/bin/user_data/config_binance_multiple.json @@ -0,0 +1,91 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/USDT", + "AAVE/USDT", + "XRP/USDT", + "DOGE/USDT", + "BTC/USDT", + "ADA/USDT", + "TRX/XRP" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_btcusdt_1m.json b/.env/bin/user_data/config_btcusdt_1m.json new file mode 100644 index 000000000..936f01e45 --- /dev/null +++ b/.env/bin/user_data/config_btcusdt_1m.json @@ -0,0 +1,86 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 1000.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": true, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "BTC/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_dogeusdt_1m.json b/.env/bin/user_data/config_dogeusdt_1m.json new file mode 100644 index 000000000..fe431a892 --- /dev/null +++ b/.env/bin/user_data/config_dogeusdt_1m.json @@ -0,0 +1,86 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 600.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": true, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": true, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "DOGE/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_ethusdt_1h_high_risk.json b/.env/bin/user_data/config_ethusdt_1h_high_risk.json new file mode 100644 index 000000000..ab0a3d84c --- /dev/null +++ b/.env/bin/user_data/config_ethusdt_1h_high_risk.json @@ -0,0 +1,86 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 100.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": true, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "ethusdt_high_risk", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_ethusdt_1m.json b/.env/bin/user_data/config_ethusdt_1m.json new file mode 100644 index 000000000..e152c31c2 --- /dev/null +++ b/.env/bin/user_data/config_ethusdt_1m.json @@ -0,0 +1,86 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 100.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": false, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": true + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_ethusdt_1m_sellonlyprofit.json b/.env/bin/user_data/config_ethusdt_1m_sellonlyprofit.json new file mode 100644 index 000000000..a6794e914 --- /dev/null +++ b/.env/bin/user_data/config_ethusdt_1m_sellonlyprofit.json @@ -0,0 +1,91 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 100, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1m", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": true, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": true, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": true, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": true, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": true, + "token": "1677121989:AAE5xmC884801M6xDDHu3rz7gPnZdnIqpU0", + "chat_id": "1288347675", + "keyboard": [ + ["/daily", "/stats", "/balance", "/profit"], + ["/status table", "/performance", "/trades"], + ["/reload_config", "/count", "/logs"] + ] + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "freqtrade", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_ethusdt_safe_1h.json b/.env/bin/user_data/config_ethusdt_safe_1h.json new file mode 100644 index 000000000..7745ce303 --- /dev/null +++ b/.env/bin/user_data/config_ethusdt_safe_1h.json @@ -0,0 +1,91 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 100.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1h", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": true + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ETH/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": true, + "token": "1661670711:AAEjHFL_wnvc-hN0V8NKe0G53mzrz9rWnzk", + "chat_id": "1288347675", + "keyboard": [ + ["/daily", "/stats", "/balance", "/profit"], + ["/status table", "/performance"], + ["/reload_config", "/count", "/logs", "/status", "/trades"] + ] + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "ethusdt_2_safe_1h", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/.env/bin/user_data/config_ltcusdt_1h.json b/.env/bin/user_data/config_ltcusdt_1h.json new file mode 100644 index 000000000..ed8e062d8 --- /dev/null +++ b/.env/bin/user_data/config_ltcusdt_1h.json @@ -0,0 +1,91 @@ +{ + "max_open_trades": 3, + "stake_currency": "USDT", + "stake_amount": 100.0, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "USD", + "timeframe": "1h", + "dry_run": true, + "position_stacking": true, + "cancel_open_orders_on_exit": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "use_order_book": false, + "ask_last_balance": 0.0, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": true, + "order_book_min": 1, + "order_book_max": 1, + "use_sell_signal": true, + "sell_profit_only": true, + "ignore_roi_if_buy_signal": true + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "LTC/USDT" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "1661670711:AAEjHFL_wnvc-hN0V8NKe0G53mzrz9rWnzk", + "chat_id": "1288347675", + "keyboard": [ + ["/daily", "/stats", "/balance", "/profit"], + ["/status table", "/performance"], + ["/reload_config", "/count", "/logs", "/status", "/trades"] + ] + }, + "api_server": { + "enabled": false, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "verbosity": "error", + "jwt_secret_key": "somethingrandom", + "CORS_origins": [], + "username": "freqtrader", + "password": "SuperSecurePassword" + }, + "bot_name": "ethusdt_2_safe_1h", + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/user_data/logs/.gitkeep b/.env/bin/user_data/hyperopt.lock old mode 100644 new mode 100755 similarity index 100% rename from user_data/logs/.gitkeep rename to .env/bin/user_data/hyperopt.lock diff --git a/.env/bin/user_data/hyperopt_results/.last_result.json b/.env/bin/user_data/hyperopt_results/.last_result.json new file mode 100644 index 000000000..1d801f786 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/.last_result.json @@ -0,0 +1 @@ +{"latest_hyperopt":"hyperopt_results_2021-02-11_22-07-24.pickle"} \ No newline at end of file diff --git a/.env/bin/user_data/hyperopt_results/ada2_results.txt b/.env/bin/user_data/hyperopt_results/ada2_results.txt new file mode 100644 index 000000000..267df58a5 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/ada2_results.txt @@ -0,0 +1,151 @@ +(freqtrade-conda) crypto_rahino@fretrade-1:~/freqtrade$ freqtrade hyperopt --config user_data/config_adausdt_1m.json --hyperopt hyper_adausdt2 --hyperopt-loss OnlyProfitHyperOptLoss --strategy strg2_ADAUSDT_1m -e 500 --spaces all -i 1m --eps +2021-02-15 21:47:44,613 - freqtrade.configuration.configuration - INFO - Using config: user_data/config_adausdt_1m.json ... +2021-02-15 21:47:44,614 - freqtrade.loggers - INFO - Verbosity set to 0 +2021-02-15 21:47:44,614 - freqtrade.configuration.configuration - INFO - Parameter -i/--timeframe detected ... Using timeframe: 1m ... +2021-02-15 21:47:44,614 - freqtrade.configuration.configuration - INFO - Parameter --enable-position-stacking detected ... +2021-02-15 21:47:44,614 - freqtrade.configuration.configuration - INFO - Using max_open_trades: 3 ... +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Using user-data directory: /home/crypto_rahino/freqtrade/user_data ... +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Using data directory: /home/crypto_rahino/freqtrade/user_data/data/binance ... +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Overriding timeframe with Command line argument +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Using Hyperopt class name: hyper_adausdt2 +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Parameter --epochs detected ... Will run Hyperopt with for 500 epochs ... +2021-02-15 21:47:44,615 - freqtrade.configuration.configuration - INFO - Parameter -s/--spaces detected: ['all'] +2021-02-15 21:47:44,616 - freqtrade.configuration.configuration - INFO - Parameter -j/--job-workers detected: -1 +2021-02-15 21:47:44,616 - freqtrade.configuration.configuration - INFO - Parameter --min-trades detected: 1 +2021-02-15 21:47:44,616 - freqtrade.configuration.configuration - INFO - Using Hyperopt loss class name: OnlyProfitHyperOptLoss +2021-02-15 21:47:44,616 - freqtrade.configuration.check_exchange - INFO - Checking exchange... +2021-02-15 21:47:44,616 - freqtrade.configuration.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team. +2021-02-15 21:47:44,616 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration. +2021-02-15 21:47:44,616 - freqtrade.configuration.config_validation - INFO - Validating configuration ... +2021-02-15 21:47:44,618 - freqtrade.commands.optimize_commands - INFO - Starting freqtrade in Hyperopt mode +2021-02-15 21:47:44,618 - filelock - INFO - Lock 140464320763024 acquired on /home/crypto_rahino/freqtrade/user_data/hyperopt.lock +2021-02-15 21:47:44,618 - freqtrade.exchange.exchange - INFO - Instance is running with dry_run enabled +2021-02-15 21:47:44,618 - freqtrade.exchange.exchange - INFO - Using CCXT 1.40.99 +2021-02-15 21:47:44,618 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True} +2021-02-15 21:47:44,624 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True, 'rateLimit': 200} +2021-02-15 21:47:44,629 - freqtrade.exchange.exchange - INFO - Using Exchange "Binance" +2021-02-15 21:47:45,396 - freqtrade.resolvers.exchange_resolver - INFO - Using resolved exchange 'Binance'... +2021-02-15 21:47:45,408 - freqtrade.resolvers.iresolver - INFO - Using resolved strategy strg2_ADAUSDT_1m from '/home/crypto_rahino/freqtrade/user_data/strategies/strg2_ada_usdt_1m.py'... +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'timeframe' with value in config file: 1m. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_currency' with value in config file: USDT. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_amount' with value in config file: 100.0. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'unfilledtimeout' with value in config file: {'buy': 10, 'sell': 30}. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'use_sell_signal' with value in config file: True. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'sell_profit_only' with value in config file: False. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'ignore_roi_if_buy_signal' with value in config file: False. +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using minimal_roi: {'0': 0.06310332385111853, '38': 0.0689051965930711, '69': 0.029484368494376897, '165': 0} +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using timeframe: 1m +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stoploss: -0.21 +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop: True +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop_positive: 0.05 +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop_positive_offset: 0.06 +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_only_offset_is_reached: True +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_custom_stoploss: False +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using process_only_new_candles: False +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_types: {'buy': 'limit', 'sell': 'limit', 'stoploss': 'market', 'stoploss_on_exchange': False} +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_time_in_force: {'buy': 'gtc', 'sell': 'gtc'} +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_currency: USDT +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_amount: 100.0 +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using startup_candle_count: 30 +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using unfilledtimeout: {'buy': 10, 'sell': 30} +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_sell_signal: True +2021-02-15 21:47:45,409 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using sell_profit_only: False +2021-02-15 21:47:45,410 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_roi_if_buy_signal: False +2021-02-15 21:47:45,410 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using sell_profit_offset: 0.0 +2021-02-15 21:47:45,410 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using disable_dataframe_checks: False +2021-02-15 21:47:45,410 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_buying_expired_candle_after: 0 +2021-02-15 21:47:45,410 - freqtrade.configuration.config_validation - INFO - Validating configuration ... +2021-02-15 21:47:45,412 - freqtrade.resolvers.iresolver - INFO - Using resolved pairlist StaticPairList from '/home/crypto_rahino/freqtrade/freqtrade/plugins/pairlist/StaticPairList.py'... +2021-02-15 21:47:45,417 - freqtrade.resolvers.iresolver - INFO - Using resolved hyperopt hyper_adausdt2 from '/home/crypto_rahino/freqtrade/user_data/hyperopts/hyper_adausdt2.py'... +2021-02-15 21:47:45,418 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_indicators() method. Using populate_indicators from the strategy. +2021-02-15 21:47:45,418 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_buy_trend() method. Using populate_buy_trend from the strategy. +2021-02-15 21:47:45,418 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_sell_trend() method. Using populate_sell_trend from the strategy. +2021-02-15 21:47:45,423 - freqtrade.resolvers.iresolver - INFO - Using resolved hyperoptloss OnlyProfitHyperOptLoss from '/home/crypto_rahino/freqtrade/freqtrade/optimize/hyperopt_loss_onlyprofit.py'... +2021-02-15 21:47:45,423 - freqtrade.optimize.hyperopt - INFO - Removing `/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_tickerdata.pkl`. +2021-02-15 21:47:45,468 - freqtrade.optimize.hyperopt - INFO - Using optimizer random state: 2757 +2021-02-15 21:47:45,468 - freqtrade.data.history.history_utils - INFO - Using indicator startup period: 30 ... +2021-02-15 21:47:49,773 - numexpr.utils - INFO - NumExpr defaulting to 4 threads. +2021-02-15 21:47:50,721 - freqtrade.data.converter - INFO - Missing data fillup for ADA/USDT: before: 1486512 - after: 1491400 +2021-02-15 21:47:50,734 - freqtrade.optimize.backtesting - INFO - Loading data from 2018-04-17 04:02:00 up to 2021-02-15 20:41:00 (1035 days).. +2021-02-15 21:47:50,734 - freqtrade.configuration.timerange - WARNING - Moving start-date by 30 candles to account for startup time. +2021-02-15 21:47:51,159 - freqtrade.optimize.hyperopt - INFO - Hyperopting with data from 2018-04-17 04:32:00 up to 2021-02-15 20:41:00 (1035 days).. +2021-02-15 21:47:51,571 - freqtrade.optimize.hyperopt - INFO - Found 4 CPU cores. Let's make them scream! +2021-02-15 21:47:51,571 - freqtrade.optimize.hyperopt - INFO - Number of parallel jobs set as: -1 +2021-02-15 21:47:51,604 - freqtrade.optimize.hyperopt - INFO - Effective number of parallel workers used: 4 ++--------+---------+----------+------------------+--------------+-----------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-----------------------------------+----------------+-------------| +| * Best | 1/500 | 13083 | 5904 5218 1961 | -0.17% | -2,277.75976620 USDT (-2,275.48%) | 313.5 m | 8.58495 | +| * Best | 2/500 | 10 | 0 0 10 | -1.08% | -10.79632666 USDT (-10.79%) | 25.9 m | 1.03595 | +| * Best | 4/500 | 3 | 3 0 0 | 2.09% | 6.28261765 USDT (6.28%) | 62.0 m | 0.97908 | +| * Best | 5/500 | 192 | 127 52 13 | 0.61% | 118.07243091 USDT (117.95%) | 179.2 m | 0.60682 | +/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/site-packages/joblib/externals/loky/process_executor.py:688: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak. + warnings.warn( +| Best | 39/500 | 714 | 380 266 68 | 0.47% | 336.09087695 USDT (335.76%) | 330.8 m | -0.11918 | +| Best | 56/500 | 601 | 395 168 38 | 0.57% | 340.28337587 USDT (339.94%) | 255.5 m | -0.13314 | +Exception ignored in: + [Epoch 60 of 500 ( 12%)] |████████████/ | [ETA: 4:32:28, Elapsed Time: 0:37:09]2021-02-15 22:28:46,048 - ccxt.base.exchange - WARNING - binance requires to release all resources with an explicit call to the .close() coroutine. If you are using the exchange instance with async coroutines, add exchange.close() to your code into a place when you're done with the exchange and don't need the exchange instance anymore (at the end of your async coroutine). +2021-02-15 22:28:46,050 - asyncio - ERROR - Unclosed client session +client_session: +2021-02-15 22:28:46,051 - asyncio - ERROR - Unclosed connector +connections: ['[(, 632.889510459)]'] +connector: +Traceback (most recent call last): + File "/home/crypto_rahino/freqtrade/freqtrade/exchange/exchange.py", line 145, in __del__ + asyncio.get_event_loop().run_until_complete(self._api_async.close()) + File "/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/asyncio/events.py", line 642, in get_event_loop + raise RuntimeError('There is no current event loop in thread %r.' +RuntimeError: There is no current event loop in thread 'QueueFeederThread'. +| Best | 186/500 | 775 | 404 322 49 | 0.48% | 372.14918360 USDT (371.78%) | 289.4 m | -0.23926 | +| Best | 241/500 | 580 | 328 233 19 | 0.74% | 429.37941015 USDT (428.95%) | 418.5 m | -0.42984 | + [Epoch 500 of 500 (100%)] || | [Time: 5:11:12, Elapsed Time: 5:11:12] +2021-02-16 03:02:48,826 - freqtrade.optimize.hyperopt - INFO - 500 epochs saved to '/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_results_2021-02-15_21-47-45.pickle'. + +Best result: + + 241/500: 580 trades. 328/233/19 Wins/Draws/Losses. Avg profit 0.74%. Median profit 0.44%. Total profit 429.37941015 USDT ( 428.95Σ%). Avg duration 418.5 min. Objective: -0.42984 + + + # Buy hyperspace params: + buy_params = { + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.65672, + 'macd-enabled': True, + 'macdhist-value': -0.00188, + 'mfi-enabled': True, + 'mfi-value': 38, + 'sar-enabled': False, + 'sar-value': 69, + 'trigger': 'bol_mid' + } + + # Sell hyperspace params: + sell_params = { + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': 0.1749, + 'macd-enabled': True, + 'macdhist-value_sell': -0.00354, + 'mfi-enabled': True, + 'mfi-value_sell': 55.23156, + 'sar-enabled': False, + 'sar-value_sell': 0.44967, + 'trigger': 'bol_mid' + } + + # ROI table: + minimal_roi = { + "0": 0.2516, + "18": 0.07762, + "65": 0.02142, + "158": 0 + } + + # Stoploss: + stoploss = -0.17102 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.30581 + trailing_stop_positive_offset = 0.36224 + trailing_only_offset_is_reached = True + diff --git a/.env/bin/user_data/hyperopt_results/crypto_rahino b/.env/bin/user_data/hyperopt_results/crypto_rahino new file mode 100644 index 000000000..ac743e04d --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/crypto_rahino @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEAqCTffWhcv3s+xJhKG4dcX2o1H+Tlth7CY/zpVt8hhLcnfw4fMl+w +ekW0JstHV55DWrkyI5B3EWSJwhPIGhRJySn+wBraRdV5/q4fsg7lj3GasWa5QQ1Q5BxdXz +2+jDohUmbAZUOglaLkrWHn46WXyRlUvUWKEdDw+Om7eMtN8NSz8xhtgZ7J4eiC3ZN6OEsl +klWpOOCOtYcJVzzXxAupQbnJnBsbKWoIbWLw4pT1B/6O1ez6TrB3cAAjTu5G1tx0cXghAH +Cjap+BukeAI1feHHr7M6koMQco3EUfO9QAm6KbBywFA+doVJCbptQLKWL/QbyJnkLgp6E4 +BbUb70JAqdUW22HlHHXw/W9jFN5dWOXsZSm6tQpfof8cuCgFP2xM4R7CwE3GPJ/1BnDngx +5HP/V8D4twcI1KLUldC+9P3sv3gfV8l77rhI13sF8RSeE/WmhGzGyn+AGGQx5AAwN+BSKu +7h1fDVI7choXGtGEGNP9KcsR3S+ZednWet9AE2PfAAAFiHsWPBN7FjwTAAAAB3NzaC1yc2 +EAAAGBAKgk331oXL97PsSYShuHXF9qNR/k5bYewmP86VbfIYS3J38OHzJfsHpFtCbLR1ee +Q1q5MiOQdxFkicITyBoUSckp/sAa2kXVef6uH7IO5Y9xmrFmuUENUOQcXV89vow6IVJmwG +VDoJWi5K1h5+Oll8kZVL1FihHQ8Pjpu3jLTfDUs/MYbYGeyeHogt2TejhLJZJVqTjgjrWH +CVc818QLqUG5yZwbGylqCG1i8OKU9Qf+jtXs+k6wd3AAI07uRtbcdHF4IQBwo2qfgbpHgC +NX3hx6+zOpKDEHKNxFHzvUAJuimwcsBQPnaFSQm6bUCyli/0G8iZ5C4KehOAW1G+9CQKnV +Ftth5Rx18P1vYxTeXVjl7GUpurUKX6H/HLgoBT9sTOEewsBNxjyf9QZw54MeRz/1fA+LcH +CNSi1JXQvvT97L94H1fJe+64SNd7BfEUnhP1poRsxsp/gBhkMeQAMDfgUiru4dXw1SO3Ia +FxrRhBjT/SnLEd0vmXnZ1nrfQBNj3wAAAAMBAAEAAAGBAIkJzFAkT3sMEmMeD0ASeTmWkQ +eWgZWFyj69sNtJbcMBlyIZO1nN3UI6LxJzGIkThqeZSoDry+8T9qaDgtGmeWCHZoXhHMZP +r2bfORvgwj2/hClTpGadWLEhYQQviW42LlQ/RE0D6gwqv5+DrP+/RU7z4zmDRH0ywkLMFC +vl3ncKlELrRMygwr7oxkeaW8Enlc6HHC0r74OJNBayktPIAUF9DxC4ktGVBptISTUR3AaQ +9I7r3jFl52IT6rL4xil1b+sbhXl+mzOClsMchKmCab33jWmAAAPEGwQUJEfFMh5WnLb4FQ +0rM144nm0eAkDZ0neV8wjwNZt451uHmC0zD0VmWdb8Nybo8U0Ob2Su7mz3P59N2qUS2cyg +LdNkCAjanWo8EzFfzyitkleOG1f0cZD45e+fdHfS28CMkDKDU8Edwe2OztT3HsDoSJQfNF +sRYlP02bNB/AkCZMQbnThNOyIgWXV05bKYcQpT6TpDbIjMHLMimFsHVCGJFAPHkvcoaQAA +AMEArDL1ncfLLis1qF+KdI3TICAanB7uziX4NkM7v38gMl9+zKkToT/pCKM8giApcsTjo1 +Xk1GKQZveYq0zEqzSts1vhr2coDjNBAIBWxC2riReQ7tMhHn/DrNr3seSBzon9LwP7MAQX +zhfMSWMoh63dkJFeFYD0ASL/RhhF0iGwHnjcGttEHMtDYmG93J0Xj0gA/d/ZixWjjkopU2 +qd7dr/QtqkeuNpqeg2iHznO+tzHRWGFkxe1ghT9VTX54EraaJ0AAAAwQDbN1IpzCC0Is6h +/fQtDxpSzsfbKu+Q/b/maJN8Ow6PII5RqMPiEWCi0d9s5NxdTa+E4iuG0YQiFvEeB3we3I +j0yj0g08TWY7Q4M0piitAX6H55qa2wMAzWE1ACAUZXKwRvJH2oquY0TdYd93oH/XNTBLxC +ikqfbgqRuLVlTzLhYRAxC09us4wd0VY+/pzQO/Qu7L/2TBYnmXxceSJUF6MzLJEYZFHRUD +MrqzyoKuZH92JP2fm1J2L7d9UDBQed95MAAADBAMRbsWkLWh8osbTVogmpTQ2MJiaWiGX3 +U+FvBKcuMLetD3Kf8vWxWkhTm3zYVp3mKavHZjiEXMb1wKBu0MTktNpu4rHMY6LxEKvpIB +2Guq0Vnu3J9OqF/AKkHGiwrUZiH0tr8ca2whC5UysrWk8vBso7ta48w/NWKrfxJAoDFsML +CrDF2EVHftKyv6v5n063quBfgS4sWBz0oghsUH4ao/C/j8anB6X8j4aBAr7G9t2kIh0bc3 +2UvPoF0ohWQ+j6BQAAAA1jcnlwdG9fcmFoaW5vAQIDBA== +-----END OPENSSH PRIVATE KEY----- diff --git a/.env/bin/user_data/hyperopt_results/ehtusdt3_profit b/.env/bin/user_data/hyperopt_results/ehtusdt3_profit new file mode 100644 index 000000000..b9a08bfcd --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/ehtusdt3_profit @@ -0,0 +1,136 @@ + + 172/300: 9 trades. 6/3/0 Wins/Draws/Losses. Avg profit 1.45%. Median profit 0.93%. Total profit 0.13055133 USDT ( 13.04Σ%). Avg duration 77.0 min. Objective: 0.95653 + + + # Buy hyperspace params: + buy_params = { + 'angle_long-enabled': True, + 'angle_long-value': -8, + 'angle_mid-enabled': True, + 'angle_mid-value': -27, + 'angle_short-enabled': True, + 'angle_short-value': 10, + 'cci-enabled': False, + 'cci-value': -59, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value': 0.21787, + 'correl_angle_mid_close-enabled': True, + 'correl_angle_mid_close-value': 0.44494, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value': -0.9378, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value': 0.06954, + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.75227, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value': 0.59611, + 'correl_ht_sine_close-enabled': False, + 'correl_ht_sine_close-value': 0.64922, + 'correl_mfi_close-enabled': True, + 'correl_mfi_close-value': -0.97597, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value': 0.0799, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value': 0.46867, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value': 0.27662, + 'ema-enabled': False, + 'ema-value': 15, + 'ema_bol-enabled': False, + 'ema_bol-value': 9, + 'ht_phase-enabled': False, + 'ht_phase1-value': -36, + 'ht_phase2-value': 255, + 'ht_trendline-enabled': False, + 'ht_trendline-value': -0.02648, + 'ht_trendmode-enabled': False, + 'ht_trendmode-value': 0, + 'inphase-enabled': True, + 'inphase-value': -0.03953, + 'macd-enabled': True, + 'macdhist-value': 0.23545, + 'mfi-enabled': True, + 'mfi-value': 57, + 'trigger': 'cci', + 'tsf_long-enabled': True, + 'tsf_long-value': -3, + 'tsf_mid-enabled': False, + 'tsf_mid-value': -98, + 'tsf_short-enabled': False, + 'tsf_short-value': -22 + } + + # Sell hyperspace params: + sell_params = { + 'angle_long-enabled': True, + 'angle_long-value_sell': -19, + 'angle_mid-enabled': True, + 'angle_mid-value_sell': 30, + 'angle_short-enabled': True, + 'angle_short-value_sell': -9, + 'cci-enabled': False, + 'cci-value_sell': -83, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value_sell': 0.2552, + 'correl_angle_mid_close-enabled': True, + 'correl_angle_mid_close-value_sell': 0.46789, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value_sell': 0.57124, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value_sell': 0.65996, + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': 0.41353, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value_sell': -0.98429, + 'correl_ht_sine_close-enabled': False, + 'correl_ht_sine_close-value_sell': 0.66294, + 'correl_mfi_close-enabled': True, + 'correl_mfi_close-value_sell': -0.4065, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value_sell': -0.99299, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value_sell': 0.5597, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value_sell': -0.9004, + 'ema-enabled': False, + 'ema-value_sell': 24, + 'ema_bol-enabled': False, + 'ema_bol-value_sell': 19, + 'ht_phase-enabled': False, + 'ht_phase1-value_sell': 228, + 'ht_phase2-value_sell': -19, + 'ht_trendline-enabled': False, + 'ht_trendline-value_sell': -0.01794, + 'ht_trendmode-enabled': False, + 'ht_trendmode-value_sell': 0, + 'inphase-enabled': True, + 'inphase-value_sell': 0.00585, + 'macd-enabled': True, + 'macdhist-value_sell': -6.78881, + 'mfi-value_sell': 67, + 'trigger': 'cci', + 'tsf_long-enabled': True, + 'tsf_long-value_sell': 66, + 'tsf_mid-enabled': False, + 'tsf_mid-value_sell': -3, + 'tsf_short-enabled': False, + 'tsf_short-value_sell': 1 + } + + # ROI table: + minimal_roi = { + "0": 0.19091, + "17": 0.07922, + "45": 0.01411, + "59": 0 + } + + # Stoploss: + stoploss = -0.05668 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.27147 + trailing_stop_positive_offset = 0.31663 + trailing_only_offset_is_reached = False + diff --git a/.env/bin/user_data/hyperopt_results/eth2_safe_1h_sharpe.txt b/.env/bin/user_data/hyperopt_results/eth2_safe_1h_sharpe.txt new file mode 100644 index 000000000..350996484 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/eth2_safe_1h_sharpe.txt @@ -0,0 +1,128 @@ +(freqtrade-conda) crypto_rahino@fretrade-1:~/freqtrade$ freqtrade hyperopt --config user_data/config_ethusdt_safe_1h.json --hyperopt hyper_ethusdt2 --hyperopt-loss SharpeHyperOptLoss --strategy strg2_ETHUSDT_1h_prod1 -e 300 --spaces all --timerange 20190101- +2021-02-28 20:54:23,663 - freqtrade.configuration.configuration - INFO - Using config: user_data/config_ethusdt_safe_1h.json ... +2021-02-28 20:54:23,663 - freqtrade.loggers - INFO - Verbosity set to 0 +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Using max_open_trades: 3 ... +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Parameter --timerange detected: 20190101- ... +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Using user-data directory: /home/crypto_rahino/freqtrade/user_data ... +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Using data directory: /home/crypto_rahino/freqtrade/user_data/data/binance ... +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Using Hyperopt class name: hyper_ethusdt2 +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Parameter --epochs detected ... Will run Hyperopt with for 300 epochs ... +2021-02-28 20:54:23,664 - freqtrade.configuration.configuration - INFO - Parameter -s/--spaces detected: ['all'] +2021-02-28 20:54:23,665 - freqtrade.configuration.configuration - INFO - Parameter -j/--job-workers detected: -1 +2021-02-28 20:54:23,665 - freqtrade.configuration.configuration - INFO - Parameter --min-trades detected: 1 +2021-02-28 20:54:23,665 - freqtrade.configuration.configuration - INFO - Using Hyperopt loss class name: SharpeHyperOptLoss +2021-02-28 20:54:23,665 - freqtrade.configuration.check_exchange - INFO - Checking exchange... +2021-02-28 20:54:23,665 - freqtrade.configuration.check_exchange - INFO - Exchange "binance" is officially supported by the Freqtrade development team. +2021-02-28 20:54:23,665 - freqtrade.configuration.configuration - INFO - Using pairlist from configuration. +2021-02-28 20:54:23,665 - freqtrade.configuration.config_validation - INFO - Validating configuration ... +2021-02-28 20:54:23,667 - freqtrade.commands.optimize_commands - INFO - Starting freqtrade in Hyperopt mode +2021-02-28 20:54:23,667 - filelock - INFO - Lock 140536302744960 acquired on /home/crypto_rahino/freqtrade/user_data/hyperopt.lock +2021-02-28 20:54:23,667 - freqtrade.exchange.exchange - INFO - Instance is running with dry_run enabled +2021-02-28 20:54:23,667 - freqtrade.exchange.exchange - INFO - Using CCXT 1.40.99 +2021-02-28 20:54:23,667 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True} +2021-02-28 20:54:23,673 - freqtrade.exchange.exchange - INFO - Applying additional ccxt config: {'enableRateLimit': True, 'rateLimit': 200} +2021-02-28 20:54:23,678 - freqtrade.exchange.exchange - INFO - Using Exchange "Binance" +2021-02-28 20:54:24,878 - freqtrade.resolvers.exchange_resolver - INFO - Using resolved exchange 'Binance'... +2021-02-28 20:54:24,884 - freqtrade.resolvers.iresolver - INFO - Using resolved strategy strg2_ETHUSDT_1h_prod1 from '/home/crypto_rahino/freqtrade/user_data/strategies/ethusdt2_safe_prod1.py'... +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'timeframe' with value in config file: 1h. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_currency' with value in config file: USDT. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'stake_amount' with value in config file: 100.0. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'unfilledtimeout' with value in config file: {'buy': 10, 'sell': 30}. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'use_sell_signal' with value in config file: True. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'sell_profit_only' with value in config file: False. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Override strategy 'ignore_roi_if_buy_signal' with value in config file: False. +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using minimal_roi: {'0': 0.14918562374415067, '500': 0.058385372968253246, '2000': 0.02650295809826818, '1500': 0} +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using timeframe: 1h +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stoploss: -0.23 +2021-02-28 20:54:24,885 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop: True +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop_positive: 0.04 +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_stop_positive_offset: 0.07 +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using trailing_only_offset_is_reached: True +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_custom_stoploss: False +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using process_only_new_candles: False +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_types: {'buy': 'market', 'sell': 'market', 'stoploss': 'market', 'stoploss_on_exchange': False} +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using order_time_in_force: {'buy': 'gtc', 'sell': 'gtc'} +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_currency: USDT +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using stake_amount: 100.0 +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using startup_candle_count: 0 +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using unfilledtimeout: {'buy': 10, 'sell': 30} +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using use_sell_signal: True +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using sell_profit_only: False +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_roi_if_buy_signal: False +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using sell_profit_offset: 0.0 +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using disable_dataframe_checks: False +2021-02-28 20:54:24,886 - freqtrade.resolvers.strategy_resolver - INFO - Strategy using ignore_buying_expired_candle_after: 0 +2021-02-28 20:54:24,887 - freqtrade.configuration.config_validation - INFO - Validating configuration ... +2021-02-28 20:54:24,889 - freqtrade.resolvers.iresolver - INFO - Using resolved pairlist StaticPairList from '/home/crypto_rahino/freqtrade/freqtrade/plugins/pairlist/StaticPairList.py'... +2021-02-28 20:54:24,898 - freqtrade.resolvers.iresolver - INFO - Using resolved hyperopt hyper_ethusdt2 from '/home/crypto_rahino/freqtrade/user_data/hyperopts/hyper_ethusdt2.py'... +2021-02-28 20:54:24,898 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_indicators() method. Using populate_indicators from the strategy. +2021-02-28 20:54:24,898 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_buy_trend() method. Using populate_buy_trend from the strategy. +2021-02-28 20:54:24,898 - freqtrade.resolvers.hyperopt_resolver - INFO - Hyperopt class does not provide populate_sell_trend() method. Using populate_sell_trend from the strategy. +2021-02-28 20:54:24,907 - freqtrade.resolvers.iresolver - INFO - Using resolved hyperoptloss SharpeHyperOptLoss from '/home/crypto_rahino/freqtrade/freqtrade/optimize/hyperopt_loss_sharpe.py'... +2021-02-28 20:54:24,908 - freqtrade.optimize.hyperopt - INFO - Using optimizer random state: 32325 +2021-02-28 20:54:24,966 - numexpr.utils - INFO - NumExpr defaulting to 4 threads. +2021-02-28 20:54:25,041 - freqtrade.data.converter - INFO - Missing data fillup for ETH/USDT: before: 18908 - after: 18954 +2021-02-28 20:54:25,042 - freqtrade.optimize.backtesting - INFO - Loading data from 2019-01-01 00:00:00 up to 2021-02-28 17:00:00 (789 days).. +2021-02-28 20:54:25,133 - freqtrade.optimize.hyperopt - INFO - Hyperopting with data from 2019-01-01 00:00:00 up to 2021-02-28 17:00:00 (789 days).. +2021-02-28 20:54:25,139 - freqtrade.optimize.hyperopt - INFO - Found 4 CPU cores. Let's make them scream! +2021-02-28 20:54:25,139 - freqtrade.optimize.hyperopt - INFO - Number of parallel jobs set as: -1 +2021-02-28 20:54:25,184 - freqtrade.optimize.hyperopt - INFO - Effective number of parallel workers used: 4 ++--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| +| * Best | 2/300 | 2235 | 895 120 1220 | -0.20% | -441.54732382 USDT (-441.11%) | 790.9 m | 5.51805 | +| * Best | 6/300 | 788 | 341 389 58 | 0.20% | 155.51998858 USDT (155.36%) | 3,753.7 m | -0.4659 | +| * Best | 13/300 | 738 | 382 232 124 | 0.50% | 372.56940254 USDT (372.20%) | 3,831.4 m | -1.16905 | +| * Best | 19/300 | 1044 | 474 105 465 | 0.33% | 341.31744129 USDT (340.98%) | 1,497.9 m | -1.68198 | +| * Best | 25/300 | 709 | 360 308 41 | 0.94% | 668.46193419 USDT (667.79%) | 4,734.6 m | -2.16973 | +| Best | 207/300 | 782 | 427 304 51 | 0.82% | 638.26843226 USDT (637.63%) | 3,986.9 m | -2.28832 | + [Epoch 300 of 300 (100%)] || | [Time: 0:12:33, Elapsed Time: 0:12:33] +2021-02-28 21:07:07,336 - freqtrade.optimize.hyperopt - INFO - 300 epochs saved to '/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_results_2021-02-28_20-54-24.pickle'. + +Best result: + + 207/300: 782 trades. 427/304/51 Wins/Draws/Losses. Avg profit 0.82%. Median profit 1.26%. Total profit 638.26843226 USDT ( 637.63Σ%). Avg duration 3986.9 min. Objective: -2.28832 + + + # Buy hyperspace params: + buy_params = { + 'angle_tsf_mid-enabled': True, + 'angle_tsf_mid-value': 31, + 'ao-enabled': False, + 'ao1-value': 49, + 'ao2-value': 37, + 'rsi-enabled': False, + 'rsi1-value': 9, + 'rsi2-value': 79, + 'trigger': 'ao_cross_dw' + } + + # Sell hyperspace params: + sell_params = { + 'angle_tsf_mid-enabled': True, + 'angle_tsf_mid-value_sell': 83, + 'ao-enabled': False, + 'ao1-value_sell': -11, + 'ao2-value_sell': 20, + 'rsi-enabled': False, + 'rsi1-value_sell': 16, + 'rsi2-value_sell': 77, + 'trigger': 'ao_cross_dw' + } + + # ROI table: + minimal_roi = { + "0": 0.0681, + "976": 0.05144, + "1656": 0.01257, + "1963": 0 + } + + # Stoploss: + stoploss = -0.22706 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.27174 + trailing_stop_positive_offset = 0.29437 + trailing_only_offset_is_reached = Fals diff --git a/.env/bin/user_data/hyperopt_results/ethusdt2_360_results b/.env/bin/user_data/hyperopt_results/ethusdt2_360_results new file mode 100644 index 000000000..e9e2823d0 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/ethusdt2_360_results @@ -0,0 +1,119 @@ ++--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| +| * Best | 1/300 | 1 | 1 0 0 | 1.87% | 0.01873046 USDT (1.87%) | 79.0 m | 0.99376 | +| * Best | 10/300 | 1 | 1 0 0 | 8.07% | 0.08076779 USDT (8.07%) | 43.0 m | 0.9731 | +/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/site-packages/joblib/externals/loky/process_executor.py:688: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak. + warnings.warn( +| * Best | 14/300 | 64 | 26 36 2 | 0.35% | 0.22444174 USDT (22.42%) | 562.1 m | 0.92526 | +/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/site-packages/joblib/externals/loky/process_executor.py:688: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak. + warnings.warn( +| * Best | 18/300 | 34 | 23 11 0 | 1.66% | 0.56510634 USDT (56.45%) | 95.7 m | 0.81182 | +/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/site-packages/joblib/externals/loky/process_executor.py:688: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak. + warnings.warn( +Exception ignored in: + [Epoch 68 of 300 ( 22%)] |████████████████████████/ | [ETA: 0:59:50, Elapsed Time: 0:17:32]2021-02-19 14:13:21,283 - ccxt.base.exchange - WARNING - binance requires to release all resources with an explicit call to the .close() coroutine. If you are using the exchange instance with async coroutines, add exchange.close() to your code into a place when you're done with the exchange and don't need the exchange instance anymore (at the end of your async coroutine). +2021-02-19 14:13:21,285 - asyncio - ERROR - Unclosed client session +client_session: +2021-02-19 14:13:21,286 - asyncio - ERROR - Unclosed connector +connections: ['[(, 18883.246767892)]'] +connector: +Traceback (most recent call last): + File "/home/crypto_rahino/freqtrade/freqtrade/exchange/exchange.py", line 145, in __del__ + asyncio.get_event_loop().run_until_complete(self._api_async.close()) + File "/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/asyncio/events.py", line 642, in get_event_loop + raise RuntimeError('There is no current event loop in thread %r.' +RuntimeError: There is no current event loop in thread 'QueueFeederThread'. +| Best | 70/300 | 110 | 68 35 7 | 0.56% | 0.61298127 USDT (61.24%) | 245.8 m | 0.79588 | +| Best | 149/300 | 474 | 248 206 20 | 0.39% | 1.86796545 USDT (186.61%) | 393.6 m | 0.37797 | + [Epoch 300 of 300 (100%)] || | [Time: 2:00:50, Elapsed Time: 2:00:50] +2021-02-19 15:56:39,657 - freqtrade.optimize.hyperopt - INFO - 300 epochs saved to '/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_results_2021-02-19_13-55-11.pickle'. + +Best result: + + 149/300: 474 trades. 248/206/20 Wins/Draws/Losses. Avg profit 0.39%. Median profit 0.20%. Total profit 1.86796545 USDT ( 186.61Σ%). Avg duration 393.6 min. Objective: 0.37797 + + + # Buy hyperspace params: + buy_params = { + 'angle_long-enabled': False, + 'angle_long-value': -11, + 'angle_short-enabled': True, + 'angle_short-value': -40, + 'correl_angle_long_close-enabled': False, + 'correl_angle_long_close-value': 0.80594, + 'correl_angle_short_close-enabled': True, + 'correl_angle_short_close-value': -0.23132, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value': 0.00945, + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.42804, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value': 0.12126, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value': 0.54723, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value': 0.6971, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value': -0.52876, + 'macd-enabled': True, + 'macdhist-value': 1, + 'mfi-enabled': False, + 'mfi-value': 32, + 'trigger': 'bol_high', + 'tsf_mid-enabled': False, + 'tsf_mid-value': -67, + 'tsf_short-enabled': False, + 'tsf_short-value': 2 + } + + # Sell hyperspace params: + sell_params = { + 'angle_long-enabled': False, + 'angle_long-value_sell': 31, + 'angle_short-enabled': True, + 'angle_short-value_sell': 36, + 'correl_angle_long_close-enabled': False, + 'correl_angle_long_close-value_sell': -0.82504, + 'correl_angle_short_close-enabled': True, + 'correl_angle_short_close-value_sell': 0.72362, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value_sell': -0.57569, + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': 0.40219, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value_sell': 0.36141, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value_sell': -0.6346, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value_sell': -0.72611, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value_sell': -0.74928, + 'macd-enabled': True, + 'macdhist-value_sell': -4, + 'mfi-enabled': False, + 'mfi-value_sell': 78, + 'trigger': 'bol_high', + 'tsf_mid-enabled': False, + 'tsf_mid-value_sell': 90, + 'tsf_short-enabled': False, + 'tsf_short-value_sell': -71 + } + + # ROI table: + minimal_roi = { + "0": 0.14689, + "23": 0.07987, + "40": 0.03243, + "136": 0 + } + + # Stoploss: + stoploss = -0.18934 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.02891 + trailing_stop_positive_offset = 0.05001 + trailing_only_offset_is_reached = True + diff --git a/.env/bin/user_data/hyperopt_results/strg1_dogeusdt_sortino_result.txt b/.env/bin/user_data/hyperopt_results/strg1_dogeusdt_sortino_result.txt new file mode 100644 index 000000000..9bc3e1370 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/strg1_dogeusdt_sortino_result.txt @@ -0,0 +1,121 @@ ++--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| +| * Best | 30/300 | 527 | 287 186 54 | 0.18% | 0.95172018 USDT (95.08%) | 820.9 m | -0.7889 | +| Best | 43/300 | 386 | 225 130 31 | 0.32% | 1.25468221 USDT (125.34%) | 399.1 m | -1.50724 | +| Best | 92/300 | 132 | 91 37 4 | 1.45% | 1.91635024 USDT (191.44%) | 158.7 m | -1.796 | +| Best | 100/300 | 684 | 372 291 21 | 0.26% | 1.76455458 USDT (176.28%) | 679.4 m | -1.91233 | +| Best | 131/300 | 1936 | 1108 692 136 | 0.25% | 4.85130056 USDT (484.65%) | 1,201.8 m | -2.79078 | +| Best | 270/300 | 8 | 6 2 0 | 0.28% | 0.02219733 USDT (2.22%) | 2,454.4 m | -9,004.65032 | + [Epoch 300 of 300 (100%)] || | [Time: 1:23:04, Elapsed Time: 1:23:04] +2021-02-08 01:20:27,607 - freqtrade.optimize.hyperopt - INFO - 300 epochs saved to '/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/hyperopt_results/hyperopt_results_2021-02-07_23-57-04.pickle'. + +Best result: + + 270/300: 8 trades. 6/2/0 Wins/Draws/Losses. Avg profit 0.28%. Median profit 0.16%. Total profit 0.02219733 USDT ( 2.22Σ%). Avg duration 2454.4 min. Objective: -9004.65032 + + + # Buy hyperspace params: + buy_params = { + 'angle_long-enabled': False, + 'angle_long-value': 69, + 'angle_mid-enabled': True, + 'angle_mid-value': -30, + 'angle_short-enabled': False, + 'angle_short-value': -51, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value': 0.01945, + 'correl_angle_mid_close-enabled': True, + 'correl_angle_mid_close-value': 0.80691, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value': 0.79822, + 'correl_close_last_close-enabled': True, + 'correl_close_last_close-value': 0.13071, + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.99955, + 'correl_hist_close-enabled': True, + 'correl_hist_close-value': -0.4257, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value': -0.05654, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value': 0.08529, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value': 0.98883, + 'correl_tsf_short_close-enabled': True, + 'correl_tsf_short_close-value': -0.74093, + 'ema-enabled': True, + 'ema-value': -0.22445, + 'macd-enabled': False, + 'macd-value': 0.31501, + 'macdhist-value': 0.4072, + 'mfi-enabled': True, + 'mfi-value': 0.8919, + 'trigger': 'ma_cross', + 'tsf_long-enabled': False, + 'tsf_long-value': 46, + 'tsf_mid-enabled': False, + 'tsf_mid-value': -50, + 'tsf_short-enabled': False, + 'tsf_short-value': 68 + } + + # Sell hyperspace params: + sell_params = { + 'angle_long-enabled': False, + 'angle_long-value_sell': -74, + 'angle_mid-enabled': True, + 'angle_mid-value_sell': -29, + 'angle_short-enabled': False, + 'angle_short-value_sell': 89, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value_sell': -0.31549, + 'correl_angle_mid_close-enabled': True, + 'correl_angle_mid_close-value_sell': 0.12343, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value_sell': 0.75309, + 'correl_close_last_close-enabled': True, + 'correl_close_last_close-value_sell': 0.895, + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': -0.90613, + 'correl_hist_close-enabled': True, + 'correl_hist_close-value_sell': 0.4866, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value_sell': 0.50188, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value_sell': 0.04306, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value_sell': -0.33186, + 'correl_tsf_short_close-enabled': True, + 'correl_tsf_short_close-value_sell': -0.25287, + 'ema-enabled': True, + 'ema-value_sell': 0.88304, + 'macd-enabled': False, + 'macd-value_sell': -0.49075, + 'macdhist-value_sell': -0.19491, + 'mfi-enabled': True, + 'mfi-value_sell': 0.63614, + 'trigger': 'ma_cross', + 'tsf_long-enabled': False, + 'tsf_long-value_sell': -52, + 'tsf_mid-enabled': False, + 'tsf_mid-value_sell': 12, + 'tsf_short-enabled': False, + 'tsf_short-value_sell': 84 + } + + # ROI table: + minimal_roi = { + "0": 0.21377, + "22": 0.08011, + "72": 0.01195, + "150": 0 + } + + # Stoploss: + stoploss = -0.23077 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.26744 + trailing_stop_positive_offset = 0.31499 + trailing_only_offset_is_reached = True diff --git a/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sharpe.txt b/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sharpe.txt new file mode 100644 index 000000000..2eb67d738 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sharpe.txt @@ -0,0 +1,122 @@ ++--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| +| * Best | 9/500 | 1 | 1 0 0 | 3.20% | 0.03207524 USDT +| * Best | 11/500 | 10 | 8 1 1 | 1.91% | 0.19162864 USDT (19.14%) | 96.1 m | -0.04427 | +| Best | 34/500 | 3 | 3 0 0 | 7.38% | 0.22165792 USDT (22.14%) | 25.7 m | -0.12983 | +| Best | 40/500 | 27 | 19 1 7 | 1.60% | 0.43147803 USDT (43.10%) | 82.6 m | -0.14711 | +| Best | 85/500 | 28 | 22 6 0 | 3.83% | 1.07257599 USDT (107.15%) | 88.2 m | -0.67739 | +| Best | 465/500 | 29 | 28 1 0 | 3.68% | 1.06848739 USDT (106.74%) | 50.7 m | -0.88123 | + [Epoch 500 of 500 (100%)] || | [Time: 2:33:04, Elapsed Time: 2:33:04] +2021-02-06 20:14:22,295 - freqtrade.optimize.hyperopt - INFO - 500 epochs saved to '/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_results_2021-02-06_17-40-43.pickle'. + +Best result: + + 465/500: 29 trades. 28/1/0 Wins/Draws/Losses. Avg profit 3.68%. Median profit 2.96%. Total profit 1.06848739 USDT ( 106.74Σ%). Avg duration 50.7 min. Objective: -0.88123 + + + # Buy hyperspace params: + buy_params = { + 'angle_long-enabled': False, + 'angle_long-value': 48, + 'angle_mid-enabled': True, + 'angle_mid-value': -81, + 'angle_short-enabled': False, + 'angle_short-value': 81, + 'correl_angle_long_close-enabled': False, + 'correl_angle_long_close-value': 0.48169, + 'correl_angle_mid_close-enabled': False, + 'correl_angle_mid_close-value': 0.43412, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value': -0.81921, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value': -0.5165, + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.3266, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value': 0.10357, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value': -0.09038, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value': 0.63061, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value': 0.88061, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value': 0.54129, + 'ema-enabled': True, + 'ema-value': 0.77515, + 'macd-enabled': False, + 'macd-value': -0.99604, + 'macdhist-value': -0.64655, + 'mfi-enabled': False, + 'mfi-value': -0.80583, + 'trigger': 'bol_low', + 'tsf_long-enabled': False, + 'tsf_long-value': 13, + 'tsf_mid-enabled': False, + 'tsf_mid-value': -5, + 'tsf_short-enabled': False, + 'tsf_short-value': -78 + } + + # Sell hyperspace params: + sell_params = { + 'angle_long-enabled': False, + 'angle_long-value_sell': -62, + 'angle_mid-enabled': True, + 'angle_mid-value_sell': -32, + 'angle_short-enabled': False, + 'angle_short-value_sell': -88, + 'correl_angle_long_close-enabled': False, + 'correl_angle_long_close-value_sell': -0.79045, + 'correl_angle_mid_close-enabled': False, + 'correl_angle_mid_close-value_sell': -0.54329, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value_sell': -0.72088, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value_sell': 0.77057, + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': -0.51244, + 'correl_hist_close-enabled': False, + 'correl_hist_close-value_sell': 0.32559, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value_sell': 0.54261, + 'correl_tsf_long_close-enabled': False, + 'correl_tsf_long_close-value_sell': 0.97774, + 'correl_tsf_mid_close-enabled': False, + 'correl_tsf_mid_close-value_sell': -0.12538, + 'correl_tsf_short_close-enabled': False, + 'correl_tsf_short_close-value_sell': -0.02653, + 'ema-enabled': True, + 'ema-value_sell': 0.85393, + 'macd-enabled': False, + 'macd-value_sell': 0.60307, + 'macdhist-value_sell': 0.66489, + 'mfi-enabled': False, + 'mfi-value_sell': 0.04703, + 'trigger': 'bol_low', + 'tsf_long-enabled': False, + 'tsf_long-value_sell': -44, + 'tsf_mid-enabled': False, + 'tsf_mid-value_sell': 41, + 'tsf_short-enabled': False, + 'tsf_short-value_sell': 25 + } + + # ROI table: + minimal_roi = { + "0": 0.17601, + "15": 0.05004, + "39": 0.02337, + "158": 0 + } + + # Stoploss: + stoploss = -0.19269 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.3265 + trailing_stop_positive_offset = 0.34828 + trailing_only_offset_is_reached = True + diff --git a/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sortino.txt b/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sortino.txt new file mode 100644 index 000000000..1ff8febe5 --- /dev/null +++ b/.env/bin/user_data/hyperopt_results/strg1_ethusd2_results_sortino.txt @@ -0,0 +1,138 @@ + ++--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------| +| * Best | 3/500 | 1 | 0 1 0 | 0.00% | -- | 419.0 m | 20 | +| * Best | 4/500 | 3754 | 1384 399 1971 | -0.18% | -6.72272549 USDT (-671.60%) | 121.9 m | 10.8055 | +Exception ignored in: + [Epoch 4 of 500 ( 0%)] |\ | [ETA: 0:00:26, Elapsed Time: 0:00:00]2021-02-06 14:40:46,035 - ccxt.base.exchange - WARNING - binance requires to release all resources with an explicit call to the .close() coroutine. If you are using the exchange instance with async coroutines, add exchange.close() to your code into a place when you're done with the exchange and don't need the exchange instance anymore (at the end of your async coroutine). +2021-02-06 14:40:46,036 - asyncio - ERROR - Unclosed client session +client_session: +2021-02-06 14:40:46,037 - asyncio - ERROR - Unclosed connector +connections: ['[(, 628.93462627)]'] +connector: +Traceback (most recent call last): + File "/home/crypto_rahino/freqtrade/freqtrade/exchange/exchange.py", line 145, in __del__ + asyncio.get_event_loop().run_until_complete(self._api_async.close()) + File "/home/crypto_rahino/anaconda3/envs/freqtrade-conda/lib/python3.9/asyncio/events.py", line 642, in get_event_loop + raise RuntimeError('There is no current event loop in thread %r.' +RuntimeError: There is no current event loop in thread 'QueueFeederThread'. +| * Best | 6/500 | 58 | 27 6 25 | 0.07% | 0.03832727 USDT (3.83%) | 92.8 m | -0.01122 | +| Best | 36/500 | 509 | 259 178 72 | 0.06% | 0.31490048 USDT (31.46%) | 277.4 m | -0.02974 | +| Best | 46/500 | 4 | 3 0 1 | 3.65% | 0.14631439 USDT (14.62%) | 14.5 m | -0.06469 | +| Best | 50/500 | 755 | 385 220 150 | 0.09% | 0.71414894 USDT (71.34%) | 62.6 m | -0.29416 | +| Best | 53/500 | 10 | 7 1 2 | 1.23% | 0.12302166 USDT (12.29%) | 61.3 m | -0.33487 | + [Epoch 81 of 500 ( 16%)] |█████████████████- | [ETA: 1:19:36, Elapsed Time: 0:15:2 [E [Epoch 93 of 500 ( 18%)] |███████████████████/ | [ETA: 1:25:44, Elapsed Time: 0:1| Best | 146/500 | 12 | 10 1 1 | 2.37% | 0.28436729 USDT (28.41%) | 69.3 m | -0.9252 | + [Epoch 500 of 500 (100%)] || | [Time: 2:47:19, Elapsed Time: 2:47:19] +2021-02-06 17:28:05,529 - freqtrade.optimize.hyperopt - INFO - 500 epochs saved to '/home/crypto_rahino/freqtrade/user_data/hyperopt_results/hyperopt_results_2021-02-06_14-39-46.pickle'. + +Best result: + + 146/500: 12 trades. 10/1/1 Wins/Draws/Losses. Avg profit 2.37%. Median profit 3.13%. Total profit 0.28436729 USDT ( 28.41Σ%). Avg duration 69.3 min. Objective: -0.92520 + + + # Buy hyperspace params: + buy_params = { + 'angle_long-enabled': False, + 'angle_long-value': 35, + 'angle_mid-enabled': True, + 'angle_mid-value': -90, + 'angle_short-enabled': False, + 'angle_short-value': 40, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value': 0.62864, + 'correl_angle_mid_close-enabled': False, + 'correl_angle_mid_close-value': 0.53883, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value': -0.64865, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value': -0.70565, + 'correl_h_l-enabled': True, + 'correl_h_l-value': 0.2461, + 'correl_hist_close-enabled': True, + 'correl_hist_close-value': -0.47549, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value': 0.24276, + 'correl_tsf_long_close-enabled': True, + 'correl_tsf_long_close-value': 0.04288, + 'correl_tsf_mid_close-enabled': True, + 'correl_tsf_mid_close-value': 0.85552, + 'correl_tsf_short_close-enabled': True, + 'correl_tsf_short_close-value': -0.03676, + 'ema-enabled': False, + 'ema-value': -0.81462, + 'macd-enabled': True, + 'macd-value': -0.24225, + 'macdhist-value': 0.18187, + 'mfi-enabled': True, + 'mfi-value': -0.10135, + 'trigger': 'mfi', + 'tsf_long-enabled': True, + 'tsf_long-value': 26, + 'tsf_mid-enabled': True, + 'tsf_mid-value': -28, + 'tsf_short-enabled': False, + 'tsf_short-value': 41 + } + + # Sell hyperspace params: + sell_params = { + 'angle_long-enabled': False, + 'angle_long-value_sell': -79, + 'angle_mid-enabled': True, + 'angle_mid-value_sell': -43, + 'angle_short-enabled': False, + 'angle_short-value_sell': -32, + 'correl_angle_long_close-enabled': True, + 'correl_angle_long_close-value_sell': -0.95367, + 'correl_angle_mid_close-enabled': False, + 'correl_angle_mid_close-value_sell': -0.49912, + 'correl_angle_short_close-enabled': False, + 'correl_angle_short_close-value_sell': -0.48721, + 'correl_close_last_close-enabled': False, + 'correl_close_last_close-value_sell': 0.39565, + 'correl_h_l-enabled': True, + 'correl_h_l-value_sell': 0.00872, + 'correl_hist_close-enabled': True, + 'correl_hist_close-value_sell': -0.78322, + 'correl_mfi_close-enabled': False, + 'correl_mfi_close-value_sell': -0.49244, + 'correl_tsf_long_close-enabled': True, + 'correl_tsf_long_close-value_sell': -0.23956, + 'correl_tsf_mid_close-enabled': True, + 'correl_tsf_mid_close-value_sell': 0.13165, + 'correl_tsf_short_close-enabled': True, + 'correl_tsf_short_close-value_sell': 0.55515, + 'ema-enabled': False, + 'ema-value_sell': 0.13069, + 'macd-enabled': True, + 'macd-value_sell': 0.41516, + 'macdhist-value_sell': -0.21624, + 'mfi-enabled': True, + 'mfi-value_sell': 0.76911, + 'trigger': 'mfi', + 'tsf_long-enabled': True, + 'tsf_long-value_sell': -56, + 'tsf_mid-enabled': True, + 'tsf_mid-value_sell': 4, + 'tsf_short-enabled': False, + 'tsf_short-value_sell': -78 + } + + # ROI table: + minimal_roi = { + "0": 0.06009, + "10": 0.04274, + "42": 0.03274, + "90": 0 + } + + # Stoploss: + stoploss = -0.12967 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.17644 + trailing_stop_positive_offset = 0.19954 + trailing_only_offset_is_reached = False + diff --git a/user_data/notebooks/.gitkeep b/.env/bin/user_data/hyperopts/.gitkeep similarity index 100% rename from user_data/notebooks/.gitkeep rename to .env/bin/user_data/hyperopts/.gitkeep diff --git a/user_data/strategies/.gitkeep b/.env/bin/user_data/hyperopts/__init__.py similarity index 100% rename from user_data/strategies/.gitkeep rename to .env/bin/user_data/hyperopts/__init__.py diff --git a/.env/bin/user_data/hyperopts/advanced.py b/.env/bin/user_data/hyperopts/advanced.py new file mode 100644 index 000000000..d5a53db4b --- /dev/null +++ b/.env/bin/user_data/hyperopts/advanced.py @@ -0,0 +1,168 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class advanced(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('mfi-enabled'): + conditions.append(dataframe['mfi'] < params['mfi-value']) + if params.get('fastd-enabled'): + conditions.append(dataframe['fastd'] < params['fastd-value']) + if params.get('adx-enabled'): + conditions.append(dataframe['adx'] > params['adx-value']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'bb_lower': + conditions.append(dataframe['close'] < dataframe['bb_lowerband']) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['sar'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('sell-mfi-enabled'): + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if params.get('sell-fastd-enabled'): + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if params.get('sell-adx-enabled'): + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if params.get('sell-rsi-enabled'): + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] \ No newline at end of file diff --git a/.env/bin/user_data/hyperopts/advanced_hyper.py b/.env/bin/user_data/hyperopts/advanced_hyper.py new file mode 100644 index 000000000..076ae115d --- /dev/null +++ b/.env/bin/user_data/hyperopts/advanced_hyper.py @@ -0,0 +1,304 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class AdvancedSampleHyperOpt(IHyperOpt): + """ + This is a sample hyperopt to inspire you. + Feel free to customize it. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Rename the class name to some unique name. + - Add any methods you want to build your hyperopt. + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need the + 'roi' and the 'stoploss' spaces that differ from the defaults offered by Freqtrade. + + This sample illustrates how to override these methods. + """ + # @staticmethod + # def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: + # """ + # This method can also be loaded from the strategy, if it doesn't exist in the hyperopt class. + # """ + # dataframe['adx'] = ta.ADX(dataframe) + # macd = ta.MACD(dataframe) + # dataframe['macd'] = macd['macd'] + # dataframe['macdsignal'] = macd['macdsignal'] + # dataframe['mfi'] = ta.MFI(dataframe) + # dataframe['rsi'] = ta.RSI(dataframe) + # stoch_fast = ta.STOCHF(dataframe) + # dataframe['fastd'] = stoch_fast['fastd'] + # dataframe['minus_di'] = ta.MINUS_DI(dataframe) + # # Bollinger bands + # bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) + # dataframe['bb_lowerband'] = bollinger['lower'] + # dataframe['bb_upperband'] = bollinger['upper'] + # dataframe['sar'] = ta.SAR(dataframe) + # return dataframe + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by hyperopt + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use + """ + conditions = [] + # GUARDS AND TRENDS + if 'mfi-enabled' in params and params['mfi-enabled']: + conditions.append(dataframe['mfi'] < params['mfi-value']) + if 'fastd-enabled' in params and params['fastd-enabled']: + conditions.append(dataframe['fastd'] < params['fastd-value']) + if 'adx-enabled' in params and params['adx-enabled']: + conditions.append(dataframe['adx'] > params['adx-value']) + if 'rsi-enabled' in params and params['rsi-enabled']: + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'bb_midd': + conditions.append(qtpylib.crossed_above(dataframe['close'], dataframe['bb_middleband'])) + if params['trigger'] == 'bb_low': + conditions.append(qtpylib.crossed_above(dataframe['close'], dataframe['bb_lowerband'])) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching strategy parameters + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by hyperopt + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use + """ + # print(params) + conditions = [] + # GUARDS AND TRENDS + if 'sell-mfi-enabled' in params and params['sell-mfi-enabled']: + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if 'sell-fastd-enabled' in params and params['sell-fastd-enabled']: + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if 'sell-adx-enabled' in params and params['sell-adx-enabled']: + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if 'sell-rsi-enabled' in params and params['sell-rsi-enabled']: + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.35, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. + Can be a copy of the corresponding method from the strategy, + or will be loaded from the strategy. + Must align to populate_indicators used (either from this File, or from the strategy) + Only used when --spaces does not include buy + """ + dataframe.loc[ + ( + (dataframe['close'] < dataframe['bb_lowerband']) & + (dataframe['mfi'] < 16) & + (dataframe['adx'] > 25) & + (dataframe['rsi'] < 21) + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. + Can be a copy of the corresponding method from the strategy, + or will be loaded from the strategy. + Must align to populate_indicators used (either from this File, or from the strategy) + Only used when --spaces does not include sell + """ + dataframe.loc[ + ( + (qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) & + (dataframe['fastd'] > 54) + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/hyperopts/full_hyper.py b/.env/bin/user_data/hyperopts/full_hyper.py new file mode 100644 index 000000000..8af52388b --- /dev/null +++ b/.env/bin/user_data/hyperopts/full_hyper.py @@ -0,0 +1,168 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class full_hyper(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('mfi-enabled'): + conditions.append(dataframe['mfi'] < params['mfi-value']) + if params.get('fastd-enabled'): + conditions.append(dataframe['fastd'] < params['fastd-value']) + if params.get('adx-enabled'): + conditions.append(dataframe['adx'] > params['adx-value']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'bb_lower': + conditions.append(dataframe['close'] < dataframe['bb_lowerband']) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['sar'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('sell-mfi-enabled'): + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if params.get('sell-fastd-enabled'): + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if params.get('sell-adx-enabled'): + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if params.get('sell-rsi-enabled'): + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] \ No newline at end of file diff --git a/.env/bin/user_data/hyperopts/hyper1.py b/.env/bin/user_data/hyperopts/hyper1.py new file mode 100644 index 000000000..eef7ab593 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper1.py @@ -0,0 +1,393 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper1(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_long']) > params['tsf_long-value']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value'] < dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value'] < (dataframe['close'] - dataframe['ema'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value'] < (dataframe['ema'] - dataframe['middleband'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value'] < dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_low': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['lowerband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ma'], dataframe['ema'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_above( + dataframe['mfi'], 25)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-100, 100, name='tsf_long-value'), + Integer(-100, 100, name='tsf_mid-value'), + Integer(-100, 100, name='tsf_short-value'), + Integer(-50, 50, name='angle_short-value'), + Integer(-50, 50, name='angle_long-value'), + Integer(-50, 50, name='angle_mid-value'), + Real(0, 1, name='correl_h_l-value'), + Real(-1, 1, name='correl_close_last_close-value'), + Real(0, 1, name='correl_tsf_long_close-value'), + Real(-1, 1, name='correl_tsf_mid_close-value'), + Real(-1, 1, name='correl_tsf_short_close-value'), + Real(-1, 1, name='correl_angle_short_close-value'), + Real(0, 1, name='correl_angle_mid_close-value'), + Real(0, 1, name='correl_angle_long_close-value'), + Real(-1, 1, name='correl_hist_close-value'), + Real(-1, 1, name='correl_mfi_close-value'), + Integer(10, 60, name='mfi-value'), + Integer(-50, 50, name='ema-value'), + Integer(-50, 50, name='ema_bol-value'), + Integer(-1, 5, name='macdhist-value'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_low', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['tsf_long'] - dataframe['close']) > params['tsf_long-value_sell']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value_sell']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value_sell']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value_sell']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value_sell']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value_sell']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value_sell'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value_sell'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value_sell'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value_sell'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value_sell'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value_sell'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value_sell'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value_sell'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value_sell'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value_sell'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value_sell'] > dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value_sell'] < (dataframe['ema'] - dataframe['close'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value_sell'] < (dataframe['middleband'] - dataframe['ema'])) + conditions.append(params['macdhist-value_sell'] > dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_high': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['upperband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_below( + dataframe['ema'], dataframe['middleband'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_below( + dataframe['mfi'], 60)) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-100, 100, name='tsf_long-value_sell'), + Integer(-100, 100, name='tsf_mid-value_sell'), + Integer(-100, 100, name='tsf_short-value_sell'), + Integer(-50, 50, name='angle_short-value_sell'), + Integer(-50, 50, name='angle_long-value_sell'), + Integer(-50, 50, name='angle_mid-value_sell'), + Real(-1, 1, name='correl_h_l-value_sell'), + Real(-1, 1, name='correl_close_last_close-value_sell'), + Real(-1, 1, name='correl_tsf_long_close-value_sell'), + Real(-1, 1, name='correl_tsf_mid_close-value_sell'), + Real(-1, 1, name='correl_tsf_short_close-value_sell'), + Real(-1, 1, name='correl_angle_short_close-value_sell'), + Real(-1, 1, name='correl_angle_mid_close-value_sell'), + Real(-1, 1, name='correl_angle_long_close-value_sell'), + Real(-1, 1, name='correl_hist_close-value_sell'), + Real(-1, 1, name='correl_mfi_close-value_sell'), + Integer(40, 100, name='mfi-value_sell'), + Integer(-5, 50, name='ema-value_sell'), + Integer(-5, 50, name='ema_bol-value_sell'), + Integer(-10, 20, name='macdhist-value_sell'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_high', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper1_1.py b/.env/bin/user_data/hyperopts/hyper1_1.py new file mode 100644 index 000000000..eef7ab593 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper1_1.py @@ -0,0 +1,393 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper1(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_long']) > params['tsf_long-value']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value'] < dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value'] < (dataframe['close'] - dataframe['ema'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value'] < (dataframe['ema'] - dataframe['middleband'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value'] < dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_low': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['lowerband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ma'], dataframe['ema'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_above( + dataframe['mfi'], 25)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-100, 100, name='tsf_long-value'), + Integer(-100, 100, name='tsf_mid-value'), + Integer(-100, 100, name='tsf_short-value'), + Integer(-50, 50, name='angle_short-value'), + Integer(-50, 50, name='angle_long-value'), + Integer(-50, 50, name='angle_mid-value'), + Real(0, 1, name='correl_h_l-value'), + Real(-1, 1, name='correl_close_last_close-value'), + Real(0, 1, name='correl_tsf_long_close-value'), + Real(-1, 1, name='correl_tsf_mid_close-value'), + Real(-1, 1, name='correl_tsf_short_close-value'), + Real(-1, 1, name='correl_angle_short_close-value'), + Real(0, 1, name='correl_angle_mid_close-value'), + Real(0, 1, name='correl_angle_long_close-value'), + Real(-1, 1, name='correl_hist_close-value'), + Real(-1, 1, name='correl_mfi_close-value'), + Integer(10, 60, name='mfi-value'), + Integer(-50, 50, name='ema-value'), + Integer(-50, 50, name='ema_bol-value'), + Integer(-1, 5, name='macdhist-value'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_low', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['tsf_long'] - dataframe['close']) > params['tsf_long-value_sell']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value_sell']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value_sell']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value_sell']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value_sell']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value_sell']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value_sell'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value_sell'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value_sell'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value_sell'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value_sell'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value_sell'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value_sell'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value_sell'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value_sell'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value_sell'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value_sell'] > dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value_sell'] < (dataframe['ema'] - dataframe['close'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value_sell'] < (dataframe['middleband'] - dataframe['ema'])) + conditions.append(params['macdhist-value_sell'] > dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_high': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['upperband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_below( + dataframe['ema'], dataframe['middleband'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_below( + dataframe['mfi'], 60)) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-100, 100, name='tsf_long-value_sell'), + Integer(-100, 100, name='tsf_mid-value_sell'), + Integer(-100, 100, name='tsf_short-value_sell'), + Integer(-50, 50, name='angle_short-value_sell'), + Integer(-50, 50, name='angle_long-value_sell'), + Integer(-50, 50, name='angle_mid-value_sell'), + Real(-1, 1, name='correl_h_l-value_sell'), + Real(-1, 1, name='correl_close_last_close-value_sell'), + Real(-1, 1, name='correl_tsf_long_close-value_sell'), + Real(-1, 1, name='correl_tsf_mid_close-value_sell'), + Real(-1, 1, name='correl_tsf_short_close-value_sell'), + Real(-1, 1, name='correl_angle_short_close-value_sell'), + Real(-1, 1, name='correl_angle_mid_close-value_sell'), + Real(-1, 1, name='correl_angle_long_close-value_sell'), + Real(-1, 1, name='correl_hist_close-value_sell'), + Real(-1, 1, name='correl_mfi_close-value_sell'), + Integer(40, 100, name='mfi-value_sell'), + Integer(-5, 50, name='ema-value_sell'), + Integer(-5, 50, name='ema_bol-value_sell'), + Integer(-10, 20, name='macdhist-value_sell'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_high', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper2.py b/.env/bin/user_data/hyperopts/hyper2.py new file mode 100644 index 000000000..fe33e9d44 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper2.py @@ -0,0 +1,176 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper2(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('uo-enabled'): + conditions.append(dataframe['uo'] > params['uo_h']) + if params.get('angle-enabled'): + conditions.append(dataframe['angle'] > params['angle_h']) + if params.get('sar-enabled'): + conditions.append(params['sar_ratio'] < (dataframe['sar'] - dataframe['close'])) + conditions.append(params['sar_shift'] > (dataframe['sar'] - dataframe['sar'].shift(3))) + if params.get('macd-enabled'): + conditions.append(params['macd_value'] > dataframe['macd']) + conditions.append(params['macdhist_value'] > dataframe['macdhist']) + conditions.append(params['macdhist_shift'] < (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['sar'] + )) + if params['trigger'] == 'angle': + conditions.append(qtpylib.crossed_above( + dataframe['angle'], 0 + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + conditions.append(dataframe['angle'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(0, 100, name='uo_h'), + Real(-1, 1, name='angle_h'), + Real(0, 1, name='sar_ratio'), + Real(0, 1, name='sar_shift'), + Real(-1, 1, name='macd_value'), + Real(-1, 1, name='macdhist_value'), + Real(-1, 1, name='macdhist_shift'), + Categorical([True, False], name='angle-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical(['sar'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('sell-uo-enabled'): + conditions.append(dataframe['uo'] > params['uo_l_s']) + if params.get('angle-enabled'): + conditions.append(params['angle_h_s'] < dataframe['angle']) + if params.get('sar-enabled'): + conditions.append(params['sar_ratio_s'] < (dataframe['sar'] - dataframe['close'])) + conditions.append(params['sar_shift_s'] < (dataframe['sar'] - dataframe['sar'].shift(3))) + if params.get('macd-enabled'): + conditions.append(params['macd_value_s'] > dataframe['macd']) + conditions.append(params['macdhist_value_s'] > dataframe['macdhist']) + conditions.append(params['macdhist_shift_s'] > (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(0, 100, name='uo_l_s'), + Real(-1, 1, name='angle_h_s'), + Real(0, 1, name='sar_ratio_s'), + Real(0, 1, name='sar_shift_s'), + Real(-1, 1, name='macd_value_s'), + Real(-1, 1, name='macdhist_value_s'), + Real(-1, 1, name='macdhist_shift_s'), + Categorical([True, False], name='sell-uo-enabled'), + Categorical([True, False], name='sell-angle-enabled'), + Categorical([True, False], name='sell-sar-enabled'), + Categorical([True, False], name='sell-macd-enabled'), + Categorical(['sell-angle', 'sell-macd_cross_signal', 'sell-sar_reversal'], name='trigger') + ] diff --git a/.env/bin/user_data/hyperopts/hyper_adausdt.py b/.env/bin/user_data/hyperopts/hyper_adausdt.py new file mode 100644 index 000000000..1fa56c60b --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_adausdt.py @@ -0,0 +1,388 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_adausdt(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_long']) < params['tsf_long-value']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_mid']) < params['tsf_mid-value']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_short']) < params['tsf_short-value']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value'] < dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value'] < (dataframe['close'] - dataframe['ema'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value'] < (dataframe['ema'] - dataframe['middleband'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value'] < dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_low': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['lowerband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_above( + dataframe['mfi'], 25)) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(0.019, 0.7, name='tsf_long-value'), + Real(0.019, 0.7, name='tsf_mid-value'), + Real(0.17, 0.7, name='tsf_short-value'), + Real(-0.26, 0.23, name='angle_short-value'), + Real(-0.018, 0.023, name='angle_long-value'), + Real(-0.026, 0.028, name='angle_mid-value'), + Real(0, 1, name='correl_h_l-value'), + Real(-1, 1, name='correl_close_last_close-value'), + Real(0, 1, name='correl_tsf_long_close-value'), + Real(-1, 1, name='correl_tsf_mid_close-value'), + Real(-1, 1, name='correl_tsf_short_close-value'), + Real(-1, 1, name='correl_angle_short_close-value'), + Real(0, 1, name='correl_angle_mid_close-value'), + Real(0, 1, name='correl_angle_long_close-value'), + Real(-1, 1, name='correl_hist_close-value'), + Real(-1, 1, name='correl_mfi_close-value'), + Integer(10, 60, name='mfi-value'), + Real(0.18, 0.7, name='ema-value'), + Real(-0.018, 0.015, name='ema_bol-value'), + Real(-0.0042, 0.003, name='macdhist-value'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['sar', 'mfi', 'macd_cross_signal', 'bol_low', 'bol_mid'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['tsf_long'] - dataframe['close']) > params['tsf_long-value_sell']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value_sell']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value_sell']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value_sell']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value_sell']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value_sell']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value_sell'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value_sell'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value_sell'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value_sell'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value_sell'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value_sell'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value_sell'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value_sell'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value_sell'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value_sell'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value_sell'] > dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value_sell'] < (dataframe['ema'] - dataframe['close'])) + if params.get('sar-enabled'): + conditions.append(params['sar-value_sell'] < (dataframe['close'] - dataframe['sar'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value_sell'] < (dataframe['middleband'] - dataframe['ema'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value_sell'] > dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_high': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['upperband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(0.019, 0.7, name='tsf_long-value_sell'), + Real(0.019, 0.7, name='tsf_mid-value_sell'), + Real(0.17, 0.7, name='tsf_short-value_sell'), + Real(-0.26, 0.23, name='angle_short-value_sell'), + Real(-0.018, 0.023, name='angle_long-value_sell'), + Real(-0.026, 0.028, name='angle_mid-value_sell'), + Real(0, 1, name='correl_h_l-value_sell'), + Real(-1, 1, name='correl_close_last_close-value_sell'), + Real(0, 1, name='correl_tsf_long_close-value_sell'), + Real(-1, 1, name='correl_tsf_mid_close-value_sell'), + Real(-1, 1, name='correl_tsf_short_close-value_sell'), + Real(-1, 1, name='correl_angle_short_close-value_sell'), + Real(0, 1, name='correl_angle_mid_close-value_sell'), + Real(0, 1, name='correl_angle_long_close-value_sell'), + Real(-1, 1, name='correl_hist_close-value_sell'), + Real(-1, 1, name='correl_mfi_close-value_sell'), + Real(10, 60, name='mfi-value_sell'), + Real(0.018, 0.7, name='ema-value_sell'), + Real(0.017, 0.7, name='sar-value_sell'), + Real(-0.018, 0.015, name='ema_bol-value_sell'), + Real(-0.0042, 0.003, name='macdhist-value_sell'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['sar', 'macd_cross_signal', 'bol_low', 'bol_mid'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_adausdt2.py b/.env/bin/user_data/hyperopts/hyper_adausdt2.py new file mode 100644 index 000000000..36a6f82aa --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_adausdt2.py @@ -0,0 +1,256 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_adausdt2(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value'] < dataframe['correl_h_l']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value'] < dataframe['mfi']) + if params.get('sar-enabled'): + conditions.append(params['sar-value'] < (dataframe['close'] - dataframe['sar'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value'] < dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_low': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['lowerband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_above( + dataframe['mfi'], 25)) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(-1, 1, name='correl_h_l-value'), + Integer(10, 60, name='mfi-value'), + Integer(-112, 158, name='sar-value'), + Real(-0.0042, 0.003, name='macdhist-value'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical(['sar', 'mfi', 'macd_cross_signal', 'bol_low', 'bol_mid'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value_sell'] < dataframe['correl_h_l']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value_sell'] > dataframe['mfi']) + if params.get('sar-enabled'): + conditions.append(params['sar-value_sell'] < (dataframe['close'] - dataframe['sar'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value_sell'] > dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_high': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['upperband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'])) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(0, 1, name='correl_h_l-value_sell'), + Real(10, 60, name='mfi-value_sell'), + Real(0.017, 0.7, name='sar-value_sell'), + Real(-0.0042, 0.003, name='macdhist-value_sell'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical(['sar', 'macd_cross_signal', 'bol_low', 'bol_mid'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_adausdt3.py b/.env/bin/user_data/hyperopts/hyper_adausdt3.py new file mode 100644 index 000000000..c0fbc9115 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_adausdt3.py @@ -0,0 +1,356 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_adausdt3(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('aroon-enabled'): + conditions.append((dataframe['aroon_up'] - dataframe['aroon_down']) > params['aroon-value']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] > params['rsi-value']) + if params.get('ul-enabled'): + conditions.append(dataframe['ul'] > params['ul-value']) + if params.get('stoch_ratio-enabled'): + conditions.append((dataframe['slowk'] - dataframe['slowd']) > params['stoch_ratio-value']) + if params.get('stoch-enabled'): + conditions.append(dataframe['slowk'] > params['stoch-value']) + if params.get('ht_phase-enabled'): + conditions.append(dataframe['ht_phase'] < params['ht_phase-value']) + if params.get('inphase-enabled'): + conditions.append(dataframe['inphase'] > params['inphase-value']) + if params.get('quadrature-enabled'): + conditions.append(dataframe['quadrature'] > params['quadrature-value']) + if params.get('ht_trendmode-enabled'): + conditions.append(dataframe['ht_trendmode'] > params['ht_trendmode-value']) + if params.get('correl_sine_trend-enabled'): + conditions.append(params['correl_sine_trend-value'] < dataframe['correl_sine_trend']) + if params.get('ht_trendline-enabled'): + conditions.append(params['ht_trendline-value'] < (dataframe['ht_trendline'] - dataframe['close'])) + if params.get('ht_sine-enabled'): + conditions.append(params['ht_sine-value'] < (dataframe['ht_sine'] - dataframe['leadsine'])) + if params.get('correl_sine_trend-enabled'): + conditions.append(params['correl_sine_trend-value'] < dataframe['correl_sine_trend']) + if params.get('correl_ht_sine_trend-enabled'): + conditions.append(params['correl_ht_sine_trend-value'] < dataframe['correl_ht_sine_trend']) + if params.get('correl_ht_sine_close-enabled'): + conditions.append(params['correl_ht_sine_close-value'] < dataframe['correl_ht_sine_close']) + if params.get('cci-enabled'): + conditions.append(params['cci-value'] < dataframe['cci']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'phasor': + conditions.append(qtpylib.crossed_above( + dataframe['quadrature'], dataframe['inphase'] + )) + if params['trigger'] == 'ht_trendmode': + conditions.append(qtpylib.crossed_above( + dataframe['ht_trendmode'], 0 + )) + if params['trigger'] == 'ht_sine': + conditions.append(qtpylib.crossed_above( + dataframe['leadsine'], dataframe['ht_sine'] + )) + if params['trigger'] == 'aroon_osc': + conditions.append(qtpylib.crossed_above( + dataframe['aroonosc'], 0)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-100, 100, name='aroon-value'), + Real(2.4, 100, name='rsi-value'), + Real(0, 100, name='ul-value'), + Real(-42, 42, name='stoch_ratio-value'), + Integer(0, 100, name='stoch-value'), + Real(-0.025, 0.0238, name='inphase-value'), + Real(-0.0741, 0.047, name='quadrature-value'), + Integer(0, 1, name='ht_trendmode-value'), + Real(-1, 1, name='correl_sine_trend-value'), + Real(-1, 1, name='ht_trendline-value'), + Real(-0.76, 0.76, name='ht_sine-value'), + Real(-1, 1, name='correl_sine_trend-value'), + Real(-1, 1, name='correl_ht_sine_trend-value'), + Real(-1, 1, name='correl_ht_sine_close-value'), + Integer(-1000, 1000, name='cci-value'), + Integer(-44, 310, name='ht_phase-value'), + + Categorical([True, False], name='aroon-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical([True, False], name='ul-enabled'), + Categorical([True, False], name='stoch_ratio-enabled'), + Categorical([True, False], name='stoch-enabled'), + Categorical([True, False], name='inphase-enabled'), + Categorical([True, False], name='ht_phase-enabled'), + Categorical([True, False], name='correl_sine_trend-enabled'), + Categorical([True, False], name='quadrature-enabled'), + Categorical([True, False], name='ht_trendline-enabled'), + Categorical([True, False], name='correl_sine_trend-enabled'), + Categorical([True, False], name='correl_ht_sine_trend-enabled'), + Categorical([True, False], name='cci-enabled'), + Categorical(['ht_sine', 'phasor', 'macd_cross_signal', 'aroon_osc', 'ht_trendmode'], + name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('aroon-enabled'): + conditions.append((dataframe['aroon_down'] - dataframe['aroon_up']) > params['aroon-value_sell']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] < params['rsi-value_sell']) + if params.get('ul-enabled'): + conditions.append(dataframe['ul'] < params['ul-value_sell']) + if params.get('stoch_ratio-enabled'): + conditions.append((dataframe['slowd'] - dataframe['slowk']) > params['stoch_ratio-value_sell']) + if params.get('stoch-enabled'): + conditions.append(dataframe['slowk'] < params['stoch-value_sell']) + if params.get('ht_phase-enabled'): + conditions.append(dataframe['ht_phase'] < params['ht_phase-value_sell']) + if params.get('inphase-enabled'): + conditions.append(dataframe['inphase'] > params['inphase-value_sell']) + if params.get('quadrature-enabled'): + conditions.append(dataframe['quadrature'] > params['quadrature-value_sell']) + if params.get('ht_trendmode-enabled'): + conditions.append(dataframe['ht_trendmode'] < params['ht_trendmode-value']) + if params.get('correl_sine_trend-enabled'): + conditions.append(params['correl_sine_trend-value_sell'] < dataframe['correl_sine_trend']) + if params.get('ht_trendline-enabled'): + conditions.append(params['ht_trendline-value_sell'] > (dataframe['close'] - dataframe['ht_trendline'])) + if params.get('ht_sine-enabled'): + conditions.append(params['ht_sine-value_sell'] < (dataframe['ht_trendline'] - dataframe['ht_sine'])) + if params.get('correl_sine_trend-enabled'): + conditions.append(params['correl_sine_trend-value_sell'] < dataframe['correl_sine_trend']) + if params.get('correl_ht_sine_trend-enabled'): + conditions.append(params['correl_ht_sine_trend-value_sell'] < dataframe['correl_ht_sine_trend']) + if params.get('correl_ht_sine_close-enabled'): + conditions.append(params['correl_ht_sine_close-value_sell'] < dataframe['correl_ht_sine_close']) + if params.get('cci-enabled'): + conditions.append(params['cci-value'] < dataframe['cci']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'phasor': + conditions.append(qtpylib.crossed_below( + dataframe['quadrature'], dataframe['inphase'] + )) + if params['trigger'] == 'ht_trendmode': + conditions.append(qtpylib.crossed_below( + dataframe['ht_trendmode'], 1 + )) + if params['trigger'] == 'ht_sine': + conditions.append(qtpylib.crossed_below( + dataframe['leadsine'], dataframe['ht_sine'] + )) + if params['trigger'] == 'aroon_osc': + conditions.append(qtpylib.crossed_below( + dataframe['aroonosc'], 0)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-100, 100, name='aroon-value_sell'), + Real(2.4, 100, name='rsi-value_sell'), + Real(0, 100, name='ul-value_sell'), + Real(-42, 42, name='stoch_ratio-value_sell'), + Integer(0, 100, name='stoch-value_sell'), + Real(-0.025, 0.0238, name='inphase-value_sell'), + Real(-0.0741, 0.047, name='quadrature-value_sell'), + Real(-1, 1, name='correl_sine_trend-value_sell'), + Real(-1, 1, name='ht_trendline-value_sell'), + Real(-0.76, 0.76, name='ht_sine-value_sell'), + Real(-1, 1, name='correl_sine_trend-value_sell'), + Real(-1, 1, name='correl_ht_sine_trend-value_sell'), + Real(-1, 1, name='correl_ht_sine_close-value_sell'), + Integer(-1000, 1000, name='cci-value_sell'), + Integer(-44, 310, name='ht_phase-value_sell'), + Integer(0, 1, name='ht_trendmode-value_sell'), + + Categorical([True, False], name='aroon-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical([True, False], name='ul-enabled'), + Categorical([True, False], name='stoch_ratio-enabled'), + Categorical([True, False], name='stoch-enabled'), + Categorical([True, False], name='inphase-enabled'), + Categorical([True, False], name='ht_phase-enabled'), + Categorical([True, False], name='correl_sine_trend-enabled'), + Categorical([True, False], name='quadrature-enabled'), + Categorical([True, False], name='ht_trendline-enabled'), + Categorical([True, False], name='correl_sine_trend-enabled'), + Categorical([True, False], name='correl_ht_sine_trend-enabled'), + Categorical([True, False], name='cci-enabled'), + Categorical( + ['ht_sine', 'aroon_osc', 'ht_trendmode', 'phasor', 'macd_cross_signal'], + name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_dogeusdt.py b/.env/bin/user_data/hyperopts/hyper_dogeusdt.py new file mode 100644 index 000000000..e82875fd7 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_dogeusdt.py @@ -0,0 +1,402 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_dogeusdt(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_long']) < params['tsf_long-value']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_mid']) < params['tsf_mid-value']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['close'] - dataframe['tsf_short']) < params['tsf_short-value']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value'] < dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value'] < (dataframe['close'] - dataframe['ema'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value'] < (dataframe['ema'] - dataframe['middleband'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value'] < dataframe['macdhist']) + if params.get('sar-enabled'): + conditions.append(params['sar-value_sell'] < (dataframe['close'] - dataframe['sar'])) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_low': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['lowerband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ma'], dataframe['ema'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'mfi': + conditions.append(qtpylib.crossed_above( + dataframe['mfi'], 25)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(-0.03, 0.027, name='tsf_long-value'), + Real(-0.023, 0.026, name='tsf_mid-value'), + Real(-0.0102, 0.009, name='tsf_short-value'), + Real(-0.136, 0.143, name='angle_short-value'), + Real(-0.0069, 0.009, name='angle_long-value'), + Real(-0.0154, 0.02, name='angle_mid-value'), + Real(0, 1, name='correl_h_l-value'), + Real(-1, 1, name='correl_close_last_close-value'), + Real(0, 1, name='correl_tsf_long_close-value'), + Real(-1, 1, name='correl_tsf_mid_close-value'), + Real(-1, 1, name='correl_tsf_short_close-value'), + Real(-1, 1, name='correl_angle_short_close-value'), + Real(0, 1, name='correl_angle_mid_close-value'), + Real(0, 1, name='correl_angle_long_close-value'), + Real(-1, 1, name='correl_hist_close-value'), + Real(-1, 1, name='correl_mfi_close-value'), + Integer(10, 60, name='mfi-value'), + Real(0.0012, 0.08, name='ema-value'), + Real(-0.0087, 0.009, name='ema_bol-value'), + Real(-0.02, 0.02, name='sar-value'), + Real(-0.0021, 0.00163, name='macdhist-value'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_low', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('tsf_long-enabled'): + conditions.append((dataframe['tsf_long'] - dataframe['close']) > params['tsf_long-value_sell']) + if params.get('tsf_mid-enabled'): + conditions.append((dataframe['tsf_mid'] - dataframe['close']) > params['tsf_mid-value_sell']) + if params.get('tsf_short-enabled'): + conditions.append((dataframe['tsf_short'] - dataframe['close']) > params['tsf_short-value_sell']) + if params.get('angle_short-enabled'): + conditions.append(dataframe['angle_short'] > params['angle_short-value_sell']) + if params.get('angle_mid-enabled'): + conditions.append(dataframe['angle_mid'] > params['angle_mid-value_sell']) + if params.get('angle_long-enabled'): + conditions.append(dataframe['angle_long'] > params['angle_long-value_sell']) + if params.get('correl_h_l-enabled'): + conditions.append(params['correl_h_l-value_sell'] < dataframe['correl_h_l']) + if params.get('correl_close_last_close-enabled'): + conditions.append(params['correl_close_last_close-value_sell'] < dataframe['correl_close_last_close']) + if params.get('correl_tsf_long_close-enabled'): + conditions.append(params['correl_tsf_long_close-value_sell'] < dataframe['correl_tsf_long_close']) + if params.get('correl_tsf_mid_close-enabled'): + conditions.append(params['correl_tsf_mid_close-value_sell'] < dataframe['correl_tsf_mid_close']) + if params.get('correl_tsf_short_close-enabled'): + conditions.append(params['correl_tsf_short_close-value_sell'] < dataframe['correl_tsf_short_close']) + if params.get('correl_angle_short_close-enabled'): + conditions.append(params['correl_angle_short_close-value_sell'] < dataframe['correl_angle_short_close']) + if params.get('correl_angle_mid_close-enabled'): + conditions.append(params['correl_angle_mid_close-value_sell'] < dataframe['correl_angle_mid_close']) + if params.get('correl_angle_long_close-enabled'): + conditions.append(params['correl_angle_long_close-value_sell'] < dataframe['correl_angle_long_close']) + if params.get('correl_hist_close-enabled'): + conditions.append(params['correl_hist_close-value_sell'] < dataframe['correl_hist_close']) + if params.get('correl_mfi_close-enabled'): + conditions.append(params['correl_mfi_close-value_sell'] < dataframe['correl_mfi_close']) + if params.get('mfi-enabled'): + conditions.append(params['mfi-value_sell'] > dataframe['mfi']) + if params.get('ema-enabled'): + conditions.append(params['ema-value_sell'] < (dataframe['ema'] - dataframe['close'])) + if params.get('sar-enabled'): + conditions.append(params['sar-value_sell'] < (dataframe['close'] - dataframe['sar'])) + if params.get('ema_bol-enabled'): + conditions.append(params['ema_bol-value_sell'] < (dataframe['middleband'] - dataframe['ema'])) + if params.get('macd-enabled'): + conditions.append(params['macdhist-value_sell'] > dataframe['macdhist']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'bol_high': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['upperband'] + )) + if params['trigger'] == 'bol_mid': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['middleband'] + )) + if params['trigger'] == 'ma_cross': + conditions.append(qtpylib.crossed_below( + dataframe['ema'], dataframe['middleband'])) + if params['trigger'] == 'ema_cross': + conditions.append(qtpylib.crossed_below( + dataframe['close'], dataframe['ema'])) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(-0.03, 0.027, name='tsf_long-value_sell'), + Real(-0.023, 0.026, name='tsf_mid-value_sell'), + Real(-0.0102, 0.009, name='tsf_short-value_sell'), + Real(-0.136, 0.143, name='angle_short-value_sell'), + Real(-0.0069, 0.009, name='angle_long-value_sell'), + Real(-0.0154, 0.02, name='angle_mid-value_sell'), + Real(0, 1, name='correl_h_l-value_sell'), + Real(-1, 1, name='correl_close_last_close-value_sell'), + Real(0, 1, name='correl_tsf_long_close-value_sell'), + Real(-1, 1, name='correl_tsf_mid_close-value_sell'), + Real(-1, 1, name='correl_tsf_short_close-value_sell'), + Real(-1, 1, name='correl_angle_short_close-value_sell'), + Real(0, 1, name='correl_angle_mid_close-value_sell'), + Real(0, 1, name='correl_angle_long_close-value_sell'), + Real(-1, 1, name='correl_hist_close-value_sell'), + Real(-1, 1, name='correl_mfi_close-value_sell'), + Integer(10, 60, name='mfi-value_sell'), + Real(0.0012, 0.08, name='ema-value_sell'), + Real(-0.0087, 0.009, name='ema_bol-value_sell'), + Real(-0.02, 0.02, name='sar-value_sell'), + Real(-0.0021, 0.00163, name='macdhist-value_sell'), + Categorical([True, False], name='angle_short-enabled'), + Categorical([True, False], name='angle_long-enabled'), + Categorical([True, False], name='angle_mid-enabled'), + Categorical([True, False], name='tsf_long-enabled'), + Categorical([True, False], name='tsf_mid-enabled'), + Categorical([True, False], name='tsf_short-enabled'), + Categorical([True, False], name='correl_h_l-enabled'), + Categorical([True, False], name='correl_close_last_close-enabled'), + Categorical([True, False], name='correl_tsf_long_close-enabled'), + Categorical([True, False], name='correl_tsf_short_close-enabled'), + Categorical([True, False], name='correl_tsf_mid_close-enabled'), + Categorical([True, False], name='correl_angle_short_close-enabled'), + Categorical([True, False], name='correl_angle_mid_close-enabled'), + Categorical([True, False], name='correl_angle_long_close-enabled'), + Categorical([True, False], name='correl_mfi_close-enabled'), + Categorical([True, False], name='correl_hist_close-enabled'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='ema-enabled'), + Categorical([True, False], name='sar-enabled'), + Categorical([True, False], name='ema_bol-enabled'), + Categorical(['mfi', 'macd_cross_signal', 'bol_low', 'bol_mid', 'ma_cross'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_ethusdt2.py b/.env/bin/user_data/hyperopts/hyper_ethusdt2.py new file mode 100644 index 000000000..7a95c8d4f --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_ethusdt2.py @@ -0,0 +1,240 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_ethusdt2(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value']) + conditions.append(dataframe['ao'] < params['ao2-value']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] < params['angle_tsf_mid-value']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value'] < dataframe['rsi']) + conditions.append(params['rsi2-value'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'ao_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ao'], 0 + )) + if params['trigger'] == 'angle_tsf_mid_cross_up': + conditions.append(qtpylib.crossed_above( + dataframe['angle_tsf_mid'], -50 + )) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value'), + Integer(-50, 50, name='ao2-value'), + Integer(-87, 85, name='angle_tsf_mid-value'), + Integer(8, 92, name='rsi1-value'), + Integer(8, 92, name='rsi2-value'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['ao_cross', 'angle_tsf_mid_cross_up'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value_sell']) + conditions.append(dataframe['ao'] < params['ao2-value_sell']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] > params['angle_tsf_mid-value_sell']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value_sell'] < dataframe['rsi']) + conditions.append(params['rsi2-value_sell'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'ao_cross_dw': + conditions.append(qtpylib.crossed_below( + dataframe['ao'], 0 + )) + if params['trigger'] == 'angle_tsf_mid_cross_dw': + conditions.append(qtpylib.crossed_below( + dataframe['angle_tsf_mid'], 50 + )) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value_sell'), + Integer(-50, 50, name='ao2-value_sell'), + Integer(-87, 85, name='angle_tsf_mid-value_sell'), + Integer(8, 92, name='rsi1-value_sell'), + Integer(8, 92, name='rsi2-value_sell'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['angle_tsf_mid_cross_dw', 'ao_cross_dw'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(60, 600, name='roi_t1'), + Integer(300, 1000, name='roi_t2'), + Integer(500, 1500, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_ethusdt3.py b/.env/bin/user_data/hyperopts/hyper_ethusdt3.py new file mode 100644 index 000000000..b9bbe00f2 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_ethusdt3.py @@ -0,0 +1,285 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_ethusdt3(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('correl_h_l_30-enabled'): + conditions.append(params['correl_h_l_30-value'] < dataframe['correl_h_l_30']) + if params.get('correl_h_l_10-enabled'): + conditions.append(params['correl_h_l_10-value'] < dataframe['correl_h_l_10']) + if params.get('correl_h_l_3-enabled'): + conditions.append(params['correl_h_l_3-value'] < dataframe['correl_h_l_3']) + if params.get('cci_45-enabled'): + conditions.append(params['cci_45-value'] > dataframe['cci_45']) + if params.get('cci_30-enabled'): + conditions.append(params['cci_30-value'] > dataframe['cci_30']) + if params.get('natr-enabled'): + conditions.append(params['natr-value'] < dataframe['natr']) + if params.get('trend_line-enabled'): + conditions.append(params['trend_line-value'] < (dataframe['trend_line'] - dataframe['close'])) + + # TRIGGERS + if 'trigger' in params: + + if params['trigger'] == 'correl_h_l_3': + conditions.append(qtpylib.crossed_above( + dataframe['correl_h_l_30'], 0)) + if params['trigger'] == 'correl_h_l_10': + conditions.append(qtpylib.crossed_above( + dataframe['correl_h_l_3'], 0)) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + if params['trigger'] == 'cci_30': + conditions.append(qtpylib.crossed_above( + dataframe['cci_30'], -50)) + if params['trigger'] == 'cci_45': + conditions.append(qtpylib.crossed_above( + dataframe['cci_45'], -50)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(0.0, 4.2, name='natr-value'), + Integer(-139, 105, name='trend_line-value'), + Real(-1, 1, name='correl_h_l_3-value'), + Real(-1, 1, name='correl_h_l_30-value'), + Real(-1, 1, name='correl_h_l_10-value'), + Integer(-200, 200, name='cci_30-value'), + Integer(-200, 200, name='cci_45-value'), + Categorical([True, False], name='correl_h_l_3-enabled'), + Categorical([True, False], name='correl_h_l_30-enabled'), + Categorical([True, False], name='correl_h_l_10-enabled'), + Categorical([True, False], name='cci_30-enabled'), + Categorical([True, False], name='cci_45-enabled'), + Categorical([True, False], name='trend_line-enabled'), + Categorical([True, False], name='natr-enabled'), + + Categorical( + ['sar', 'correl_h_l_3', 'correl_h_l_10' 'cci_45', 'cci_30'], + name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('correl_h_l_30-enabled'): + conditions.append(params['correl_h_l_30-value_sell'] < dataframe['correl_h_l_30']) + if params.get('correl_h_l_10-enabled'): + conditions.append(params['correl_h_l_10-value_sell'] < dataframe['correl_h_l_10']) + if params.get('correl_h_l_3-enabled'): + conditions.append(params['correl_h_l_3-value_sell'] < dataframe['correl_h_l_3']) + if params.get('cci_45-enabled'): + conditions.append(params['cci_45-value_sell'] > dataframe['cci_45']) + if params.get('cci_30-enabled'): + conditions.append(params['cci_30-value_sell'] > dataframe['cci_30']) + if params.get('natr-enabled'): + conditions.append(params['natr-value_sell'] < dataframe['natr']) + if params.get('trend_line-enabled'): + conditions.append(params['trend_line-value_sell'] < (dataframe['trend_line'] - dataframe['close'])) + + # TRIGGERS + if 'trigger' in params: + + if params['trigger'] == 'correl_h_l_3': + conditions.append(qtpylib.crossed_above( + dataframe['correl_h_l_30'], 0)) + if params['trigger'] == 'correl_h_l_10': + conditions.append(qtpylib.crossed_above( + dataframe['correl_h_l_3'], 0)) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + if params['trigger'] == 'cci_30': + conditions.append(qtpylib.crossed_above( + dataframe['cci_30'], -50)) + if params['trigger'] == 'cci_45': + conditions.append(qtpylib.crossed_above( + dataframe['cci_45'], -50)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(0.0, 4.2, name='natr-value_sell'), + Integer(-139, 105, name='trend_line-value_sell'), + Real(-1, 1, name='correl_h_l_3-value_sell'), + Real(-1, 1, name='correl_h_l_30-value_sell'), + Real(-1, 1, name='correl_h_l_10-value_sell'), + Integer(-200, 200, name='cci_30-value_sell'), + Integer(-200, 200, name='cci_45-value_sell'), + Categorical([True, False], name='correl_h_l_3-enabled'), + Categorical([True, False], name='correl_h_l_30-enabled'), + Categorical([True, False], name='correl_h_l_10-enabled'), + Categorical([True, False], name='cci_30-enabled'), + Categorical([True, False], name='cci_45-enabled'), + Categorical([True, False], name='trend_line-enabled'), + Categorical([True, False], name='natr-enabled'), + + Categorical( + ['sar', 'correl_h_l_3', 'correl_h_l_10' 'cci_45', 'cci_30'], + name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_ethusdt_high_risk.py b/.env/bin/user_data/hyperopts/hyper_ethusdt_high_risk.py new file mode 100644 index 000000000..d76bb1cf2 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_ethusdt_high_risk.py @@ -0,0 +1,290 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_ethusdt_high_risk(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao-value']) + if params.get('vwap_short-enabled'): + conditions.append(params['vwap_short-value'] > dataframe['vwap_short']) + if params.get('correl_h_l_3-enabled'): + conditions.append(params['correl_h_l_3-value'] < dataframe['correl_h_l_3']) + if params.get('cci_45-enabled'): + conditions.append(params['cci_45-value'] > dataframe['cci_45']) + if params.get('cci_30-enabled'): + conditions.append(params['cci_30-value'] > dataframe['cci_30']) + if params.get('natr-enabled'): + conditions.append(params['natr-value'] < dataframe['natr']) + if params.get('trend_line-enabled'): + conditions.append(params['trend_line-value'] < (dataframe['trend_line'] - dataframe['close'])) + + # TRIGGERS + if 'trigger' in params: + + if 'trigger' in params: + if params['trigger'] == 'ao_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ao'], 0 + )) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + if params['trigger'] == 'cci_30': + conditions.append(qtpylib.crossed_above( + dataframe['cci_30'], -50)) + if params['trigger'] == 'cci_45': + conditions.append(qtpylib.crossed_above( + dataframe['cci_45'], -50)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(0.0, 4.2, name='ao-value'), + Integer(-139, 105, name='trend_line-value'), + Real(-1, 1, name='correl_h_l_3-value'), + Real(-1, 1, name='correl_h_l_30-value'), + Real(-1, 1, name='correl_h_l_10-value'), + Integer(-200, 200, name='cci_30-value'), + Integer(-200, 200, name='cci_45-value'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='correl_h_l_30-enabled'), + Categorical([True, False], name='correl_h_l_10-enabled'), + Categorical([True, False], name='cci_30-enabled'), + Categorical([True, False], name='cci_45-enabled'), + Categorical([True, False], name='trend_line-enabled'), + Categorical([True, False], name='natr-enabled'), + + Categorical( + ['ao_cross', 'macd_cross_signal', 'correl_h_l_10' 'cci_45', 'cci_30'], + name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('correl_h_l_30-enabled'): + conditions.append(params['correl_h_l_30-value_sell'] < dataframe['correl_h_l_30']) + if params.get('correl_h_l_10-enabled'): + conditions.append(params['correl_h_l_10-value_sell'] < dataframe['correl_h_l_10']) + if params.get('correl_h_l_3-enabled'): + conditions.append(params['correl_h_l_3-value_sell'] < dataframe['correl_h_l_3']) + if params.get('cci_45-enabled'): + conditions.append(params['cci_45-value_sell'] > dataframe['cci_45']) + if params.get('cci_30-enabled'): + conditions.append(params['cci_30-value_sell'] > dataframe['cci_30']) + if params.get('natr-enabled'): + conditions.append(params['natr-value_sell'] < dataframe['natr']) + if params.get('trend_line-enabled'): + conditions.append(params['trend_line-value_sell'] < (dataframe['trend_line'] - dataframe['close'])) + + # TRIGGERS + if 'trigger' in params: + + if params['trigger'] == 'ao_cross': + conditions.append(qtpylib.crossed_below( + dataframe['ao'], 0 + )) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_below( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'])) + if params['trigger'] == 'cci_30': + conditions.append(qtpylib.crossed_above( + dataframe['cci_30'], -50)) + if params['trigger'] == 'cci_45': + conditions.append(qtpylib.crossed_above( + dataframe['cci_45'], -50)) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(0.0, 4.2, name='natr-value_sell'), + Integer(-139, 105, name='trend_line-value_sell'), + Real(-1, 1, name='correl_h_l_3-value_sell'), + Real(-1, 1, name='correl_h_l_30-value_sell'), + Real(-1, 1, name='correl_h_l_10-value_sell'), + Integer(-200, 200, name='cci_30-value_sell'), + Integer(-200, 200, name='cci_45-value_sell'), + Categorical([True, False], name='correl_h_l_3-enabled'), + Categorical([True, False], name='correl_h_l_30-enabled'), + Categorical([True, False], name='correl_h_l_10-enabled'), + Categorical([True, False], name='cci_30-enabled'), + Categorical([True, False], name='cci_45-enabled'), + Categorical([True, False], name='trend_line-enabled'), + Categorical([True, False], name='natr-enabled'), + + Categorical( + ['sar', 'macd_cross_signal', 'correl_h_l_10' 'cci_45', 'cci_30'], + name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_ltcusdt_1h.py b/.env/bin/user_data/hyperopts/hyper_ltcusdt_1h.py new file mode 100644 index 000000000..dd4037130 --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_ltcusdt_1h.py @@ -0,0 +1,240 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_ltcusdt_1h(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value']) + conditions.append(dataframe['ao'] < params['ao2-value']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] < params['angle_tsf_mid-value']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value'] < dataframe['rsi']) + conditions.append(params['rsi2-value'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_below( + dataframe['sar'], dataframe['close'] + )) + if params['trigger'] == 'sine': + conditions.append(qtpylib.crossed_above( + dataframe['leadsine'], dataframe['sine'] + )) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value'), + Integer(-50, 50, name='ao2-value'), + Integer(-87, 85, name='angle_tsf_mid-value'), + Integer(8, 92, name='rsi1-value'), + Integer(8, 92, name='rsi2-value'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['sar', 'sine'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value_sell']) + conditions.append(dataframe['ao'] < params['ao2-value_sell']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] > params['angle_tsf_mid-value_sell']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value_sell'] < dataframe['rsi']) + conditions.append(params['rsi2-value_sell'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'sar': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + if params['trigger'] == 'sine': + conditions.append(qtpylib.crossed_below( + dataframe['leadsine'], dataframe['sine'] + )) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value_sell'), + Integer(-50, 50, name='ao2-value_sell'), + Integer(-87, 85, name='angle_tsf_mid-value_sell'), + Integer(8, 92, name='rsi1-value_sell'), + Integer(8, 92, name='rsi2-value_sell'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['sar', 'sine'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(60, 600, name='roi_t1'), + Integer(300, 1000, name='roi_t2'), + Integer(500, 1500, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/hyper_ltcusdt_1hpy b/.env/bin/user_data/hyperopts/hyper_ltcusdt_1hpy new file mode 100644 index 000000000..7a95c8d4f --- /dev/null +++ b/.env/bin/user_data/hyperopts/hyper_ltcusdt_1hpy @@ -0,0 +1,240 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class hyper_ethusdt2(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value']) + conditions.append(dataframe['ao'] < params['ao2-value']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] < params['angle_tsf_mid-value']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value'] < dataframe['rsi']) + conditions.append(params['rsi2-value'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'ao_cross': + conditions.append(qtpylib.crossed_above( + dataframe['ao'], 0 + )) + if params['trigger'] == 'angle_tsf_mid_cross_up': + conditions.append(qtpylib.crossed_above( + dataframe['angle_tsf_mid'], -50 + )) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value'), + Integer(-50, 50, name='ao2-value'), + Integer(-87, 85, name='angle_tsf_mid-value'), + Integer(8, 92, name='rsi1-value'), + Integer(8, 92, name='rsi2-value'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['ao_cross', 'angle_tsf_mid_cross_up'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('ao-enabled'): + conditions.append(dataframe['ao'] > params['ao1-value_sell']) + conditions.append(dataframe['ao'] < params['ao2-value_sell']) + if params.get('angle_tsf_mid-enabled'): + conditions.append(dataframe['angle_tsf_mid'] > params['angle_tsf_mid-value_sell']) + if params.get('rsi-enabled'): + conditions.append(params['rsi1-value_sell'] < dataframe['rsi']) + conditions.append(params['rsi2-value_sell'] > dataframe['rsi']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'ao_cross_dw': + conditions.append(qtpylib.crossed_below( + dataframe['ao'], 0 + )) + if params['trigger'] == 'angle_tsf_mid_cross_dw': + conditions.append(qtpylib.crossed_below( + dataframe['angle_tsf_mid'], 50 + )) + + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(-50, 50, name='ao1-value_sell'), + Integer(-50, 50, name='ao2-value_sell'), + Integer(-87, 85, name='angle_tsf_mid-value_sell'), + Integer(8, 92, name='rsi1-value_sell'), + Integer(8, 92, name='rsi2-value_sell'), + Categorical([True, False], name='ao-enabled'), + Categorical([True, False], name='angle_tsf_mid-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['angle_tsf_mid_cross_dw', 'ao_cross_dw'], name='trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(60, 600, name='roi_t1'), + Integer(300, 1000, name='roi_t2'), + Integer(500, 1500, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.25, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] diff --git a/.env/bin/user_data/hyperopts/macd_hyper.py b/.env/bin/user_data/hyperopts/macd_hyper.py new file mode 100644 index 000000000..170a20183 --- /dev/null +++ b/.env/bin/user_data/hyperopts/macd_hyper.py @@ -0,0 +1,173 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class macd(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('mfi-enabled'): + conditions.append((dataframe['macdhist']) > params['macd_diff']) + conditions.append((dataframe['macdhist']) > params['macd_diff']) + if params.get('fastd-enabled'): + conditions.append(dataframe['fastd'] < params['fastd-value']) + if params.get('adx-enabled'): + conditions.append(dataframe['adx'] > params['adx-value']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'sr': + conditions.append(qtpylib.crossed_above(dataframe['sr_fastk'], dataframe['sr_fastd'])) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) + if params['trigger'] == 'macd_histogram': + conditions.append(dataframe['macdhist'] - dataframe['macdhist'].shift(1)) + if params['trigger'] == 'slow': + conditions.append(qtpylib.crossed_above(dataframe['slowk'], dataframe['slowd'])) + if params['trigger'] == 'sf_fast': + conditions.append(qtpylib.crossed_above(dataframe['sf_fastk'], dataframe['sf_fastd'])) + if params['trigger'] == 'tema': + conditions.append(qtpylib.crossed_above(dataframe['close'], dataframe['tema'])) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['sr', 'macd_cross_signal', 'macd_histogram', 'slow', 'sf_fast', 'tema'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('sell-mfi-enabled'): + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if params.get('sell-fastd-enabled'): + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if params.get('sell-adx-enabled'): + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if params.get('sell-rsi-enabled'): + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] diff --git a/.env/bin/user_data/hyperopts/quick_ethusdt_1m_hyper.py b/.env/bin/user_data/hyperopts/quick_ethusdt_1m_hyper.py new file mode 100644 index 000000000..fc6a54c95 --- /dev/null +++ b/.env/bin/user_data/hyperopts/quick_ethusdt_1m_hyper.py @@ -0,0 +1,219 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class quick_ethusdt_1m_hyper(IHyperOpt): + """ + This is a Hyperopt template to get you started. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('macd-enabled'): + conditions.append((dataframe['macdhist']) > params['macdhist_diff_buy']) + if params.get('macd_angle-enabled'): + conditions.append((dataframe['macd_angle']) > params['macd_angle_buy']) + if params.get('tema-enabled'): + conditions.append(dataframe['tema'] < params['tema_value_buy']) + if params.get('sr_fastd-enabled'): + conditions.append(dataframe['sr_fastd'] > params['sr_fastd_value_buy']) + if params.get('sr_fastd_angle-enabled'): + conditions.append(dataframe['sr_fastd_angle'] > params['sr_fastd_angle_value_buy']) + if params.get('slowk-enabled'): + conditions.append(dataframe['slowk'] > params['slowk_value_buy']) + if params.get('slowd_angle-enabled'): + conditions.append(dataframe['slowd_angle'] > params['slowd_angle_value_buy']) + if params.get('sf_fastk-enabled'): + conditions.append(dataframe['sf_fastk'] > params['sf_fastk_value_buy']) + if params.get('sf_fastd_angle-enabled'): + conditions.append(dataframe['sf_fastd_angle'] > params['sf_fastd_angle_value_buy']) + if params.get('rsi-enabled'): + conditions.append(dataframe['rsi'] > params['rsi_value_buy']) + if params.get('rsi_angle-enabled'): + conditions.append(dataframe['rsi_angle'] > params['rsi_angle_value_buy']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'sr': + conditions.append(qtpylib.crossed_above(dataframe['sr_fastk'], dataframe['sr_fastd'])) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) + if params['trigger'] == 'macd_histogram': + conditions.append((dataframe['macdhist'] - dataframe['macdhist'].shift(1)) > 0) + if params['trigger'] == 'slow': + conditions.append(qtpylib.crossed_above(dataframe['slowk'], dataframe['slowd'])) + if params['trigger'] == 'sf_fast': + conditions.append(qtpylib.crossed_above(dataframe['sf_fastk'], dataframe['sf_fastd'])) + if params['trigger'] == 'tema': + conditions.append(qtpylib.crossed_above(dataframe['close'], dataframe['tema'])) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Real(-0.00072, 0.0008, name='macdhist_diff_buy'), + Real(-0.019, 0.018, name='macd_angle_buy'), + Real(0.016, 0.13, name='tema_value_buy'), + Integer(0, 100, name='sr_fastd_value_buy'), + Integer(-90, 90, name='sr_fastd_angle_value_buy'), + Integer(0, 100, name='slowk_value_buy'), + Integer(-90, 90, name='slowd_angle_value_buy'), + Integer(0, 100, name='sf_fastk_value_buy'), + Integer(-90, 90, name='sf_fastd_angle_value_buy'), + Integer(0, 100, name='rsi_value_buy'), + Integer(-90, 90, name='rsi_angle_value_buy'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='macd_angle-enabled'), + Categorical([True, False], name='tema-enabled'), + Categorical([True, False], name='sr_fastd-enabled'), + Categorical([True, False], name='sr_fastd_angle-enabled'), + Categorical([True, False], name='slowk-enabled'), + Categorical([True, False], name='slowd_angle-enabled'), + Categorical([True, False], name='sf_fastk-enabled'), + Categorical([True, False], name='sf_fastk_angle-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical([True, False], name='rsi_angle-enabled'), + Categorical(['sr', 'macd_cross_signal', 'macd_histogram', 'slow', 'sf_fast', 'tema'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if params.get('macd-enabled'): + conditions.append((dataframe['macdhist']) < params['macdhist_diff_sell']) + if params.get('macd_angle-enabled'): + conditions.append((dataframe['macd_angle']) < params['macd_angle_sell']) + if params.get('tema-enabled'): + conditions.append(dataframe['tema'] < params['tema_value_sell']) + if params.get('sr_fastd-enabled'): + conditions.append(dataframe['sr_fastd'] < params['sr_fastd_value_sell']) + if params.get('sr_fastd_angle-enabled'): + conditions.append(dataframe['sr_fastd_angle'] > params['sr_fastd_angle_value_sell']) + if params.get('slowk-enabled'): + conditions.append(dataframe['slowk'] < params['slowk_value_sell']) + if params.get('slowd_angle-enabled'): + conditions.append(dataframe['slowd_angle'] < params['slowd_angle_value_sell']) + if params.get('sf_fastk-enabled'): + conditions.append(dataframe['sf_fastk'] > params['sf_fastk_value_sell']) + if params.get('sf_fastd_angle-enabled'): + conditions.append(dataframe['sf_fastd_angle'] < params['sf_fastd_angle_value_sell']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['trigger'] == 'sr': + conditions.append(qtpylib.crossed_below(dataframe['sr_fastk'], dataframe['sr_fastd'])) + if params['trigger'] == 'macd_histogram': + conditions.append((dataframe['macdhist'] - dataframe['macdhist'].shift(1)) < 0) + if params['trigger'] == 'slow': + conditions.append(qtpylib.crossed_below(dataframe['slowk'], dataframe['slowd'])) + if params['trigger'] == 'sf_fast': + conditions.append(qtpylib.crossed_below(dataframe['sf_fastk'], dataframe['sf_fastd'])) + if params['trigger'] == 'tema': + conditions.append(qtpylib.crossed_below(dataframe['close'], dataframe['tema'])) + + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Real(-0.00072, 0.0008, name='macdhist_diff_sell'), + Real(-0.019, 0.018, name='macd_angle_sell'), + Real(0.016, 0.13, name='tema_value_sell'), + Integer(0, 100, name='sr_fastd_value_sell'), + Integer(-90, 90, name='sr_fastd_angle_value_sell'), + Integer(0, 100, name='slowk_value_sell'), + Integer(-90, 90, name='slowd_angle_value_sell'), + Integer(0, 100, name='sf_fastk_value_sell'), + Integer(-90, 90, name='sf_fastd_angle_value_sell'), + Categorical([True, False], name='macd-enabled'), + Categorical([True, False], name='macd_angle-enabled'), + Categorical([True, False], name='tema-enabled'), + Categorical([True, False], name='sr_fastd-enabled'), + Categorical([True, False], name='sr_fastd_angle-enabled'), + Categorical([True, False], name='slowk-enabled'), + Categorical([True, False], name='slowd_angle-enabled'), + Categorical([True, False], name='sf_fastk-enabled'), + Categorical([True, False], name='sf_fastk_angle-enabled'), + Categorical(['sr', 'macd_histogram', 'slow', 'sf_fast', 'tema'], name='trigger') + + ] diff --git a/.env/bin/user_data/logs/.gitkeep b/.env/bin/user_data/logs/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.env/bin/user_data/notebooks/.gitkeep b/.env/bin/user_data/notebooks/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.env/bin/user_data/strategies/.gitkeep b/.env/bin/user_data/strategies/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/.env/bin/user_data/strategies/__init__.py b/.env/bin/user_data/strategies/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/.env/bin/user_data/strategies/data_eth_usdt_1m.py b/.env/bin/user_data/strategies/data_eth_usdt_1m.py new file mode 100644 index 000000000..51a51fce4 --- /dev/null +++ b/.env/bin/user_data/strategies/data_eth_usdt_1m.py @@ -0,0 +1,216 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class data_ETHUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.24724, + "30": 0.1, + "46": 0.05, + "151": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.1 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.02 + trailing_stop_positive_offset = 0.14 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 14) & + (0.5263534368259521 < dataframe['correl_h_l']) & + (0.0728048430667152 < dataframe['correl_tsf_mid_close']) & + (-0.02402596125126566 < dataframe['correl_angle_short_close']) & + (0.2842166347875669 < dataframe['correl_angle_long_close']) & + (-0.6552565064627378 < dataframe['correl_mfi_close']) & + (-0.4853276710303872 < dataframe['correl_hist_close']) & + (0.442188534531633 < dataframe['mfi']) & + (0.6714488827895353 < dataframe['ema']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 68) & + (-0.6225944943311145 < dataframe['correl_h_l']) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (0.771988603840956 < dataframe['correl_angle_short_close']) & + (0.33471662411500236 < dataframe['correl_angle_long_close']) & + (-0.9562413964921457 < dataframe['correl_hist_close']) & + (-0.43268559077377733 < dataframe['correl_mfi_close']) & + (-0.25207265197064166 < dataframe['mfi']) & + (-0.00739011415527302 < dataframe['ema']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/ethusdt2_safe_prod1.py b/.env/bin/user_data/strategies/ethusdt2_safe_prod1.py new file mode 100644 index 000000000..65f396266 --- /dev/null +++ b/.env/bin/user_data/strategies/ethusdt2_safe_prod1.py @@ -0,0 +1,208 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, MAX, MIN, SAR, CCI, \ + HT_TRENDLINE, HT_DCPERIOD, HT_TRENDMODE, HT_SINE, RSI + +from freqtrade.strategy import merge_informative_pair +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ETHUSDT_1h_prod1(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.07371, + "9817": 0.0461, + "14487": 0.0254, + "15960": 0 + } + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.23371 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.11193 + trailing_stop_positive_offset = 0.20381 + trailing_only_offset_is_reached = True + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1d")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + # dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + # slowperiod=26, signalperiod=7) + + # dataframe['cci'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['ao'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=34) + # dataframe['vwap'] = qtpylib.vwap(dataframe) + # dataframe['vwap'] = qtpylib.rolling_vwap(dataframe) + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + # dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=200) + # dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=7) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=50) + + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_mid'], timeperiod=10) + # dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=50) + + # dataframe['tsf_max'] = MAX(dataframe['tsf_mid'], timeperiod=30) + # dataframe['tsf_min'] = MIN(dataframe['tsf_mid'], timeperiod=30) + # dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + # dataframe['sine'], dataframe['leadsine'] = HT_SINE(dataframe['close']) + # dataframe['trend'] = HT_TRENDLINE(dataframe['close']) + # dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + # timeperiod=5) + # dataframe['angle_trend_mid'] = LINEARREG_ANGLE(dataframe['trend'], timeperiod=10) + + # dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + # timeperiod=30, nbdevup=2, + # nbdevdn=2, matype=0) + # if not self.dp: + # # Don't do anything if DataProvider is not available. + # return dataframe + # # Get the informative pair + # informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d') + # informative['trend'] = HT_TRENDLINE(informative['close']) + # informative['period'] = HT_DCPERIOD(informative['close']) + # informative['mode'] = HT_TRENDMODE(informative['close']) + # # informative['sine'], informative['leadsine'] = HT_SINE(informative['close']) + # informative['angle_trend'] = LINEARREG_ANGLE(informative['trend'], timeperiod=5) + # # informative['sar'] = SAR(informative['high'], informative['low']) + # dataframe = merge_informative_pair(dataframe, informative, self.timeframe, '1d', ffill=True) + # return dataframe.set_index('date')['2021-01-01':].reset_index() + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['angle_tsf_mid'], -50)) & + + # (dataframe['sine_1h'] < dataframe['leadsine_1h']) & + # (dataframe['tsf_mid'] > dataframe['close']) & + # (dataframe['ao'] > -5) & + # (dataframe['rsi'] < 36) & + (dataframe['rsi'] > 14) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['angle_tsf_mid'], 50)) & + # (dataframe['sine_1h'] > dataframe['leadsine_1h']) & + # (dataframe['sar_1d'] < dataframe['close']) & + # (dataframe['tsf_mid'] < dataframe['close']) & + (dataframe['rsi'] > 50) & + (dataframe['ao'] < -10) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/ethusdt_high_risk.py b/.env/bin/user_data/strategies/ethusdt_high_risk.py new file mode 100644 index 000000000..94cb25a02 --- /dev/null +++ b/.env/bin/user_data/strategies/ethusdt_high_risk.py @@ -0,0 +1,214 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, MAX, MIN, SAR, CCI, \ + HT_TRENDLINE, HT_DCPERIOD, HT_TRENDMODE, HT_SINE, RSI, NATR, STOCH, STOCHF, STOCHRSI + +from freqtrade.strategy import merge_informative_pair +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class ETHUSDT_1m_high_risk(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.22703036349783817, + "30": 0.09085576426119433, + "82": 0.029443202051755248, + "164": 0 + } + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.22515 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.03428 + trailing_stop_positive_offset = 0.05094 + trailing_only_offset_is_reached = True + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/BTC", "1h")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + dataframe['trend'] = HT_TRENDLINE(dataframe['close']) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=12) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=48) + + dataframe['vwap_short'] = qtpylib.rolling_vwap(dataframe, window=5) + dataframe['vwap_mid'] = qtpylib.rolling_vwap(dataframe, window=90) + dataframe['vwap_long'] = qtpylib.rolling_vwap(dataframe, window=1440) + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=7) + dataframe['ao_mid'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=36) + dataframe['ao_short'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=15) + + dataframe['cci'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + dataframe['slowk'], dataframe['slowd'] = STOCH(dataframe['high'], dataframe['low'], dataframe['close'], + fastk_period=5, slowk_period=3, + slowk_matype=0, slowd_period=3, + slowd_matype=0) + dataframe['fastk'], dataframe['fastd'] = STOCHF(dataframe['high'], dataframe['low'], dataframe['close'], + fastk_period=5, fastd_period=3, fastd_matype=0) + dataframe['fastk'], dataframe['fastd'] = STOCHRSI(dataframe['close'], timeperiod=14, fastk_period=5, + fastd_period=3, fastd_matype=0) + + + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + + dataframe['min_high'] = MIN(dataframe['high'], timeperiod=5) + dataframe['max_low'] = MAX(dataframe['low'], timeperiod=5) + dataframe['max_low_min_high_ratio'] = dataframe['max_low'] - dataframe['min_high'].shift(15) + dataframe['correl_h_l_30'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + + + dataframe['angle_tsf_short'] = LINEARREG_ANGLE(dataframe['tsf_short'], timeperiod=5) + dataframe['angle_close'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=5) + dataframe['sine'], dataframe['leadsine'] = HT_SINE(dataframe['close']) + dataframe['mode'] = HT_TRENDMODE(dataframe['close']) + dataframe['corel_mode'] = CORREL(dataframe['mode'], dataframe['close'], timeperiod=30) + + dataframe = dataframe.reset_index().dropna() + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (dataframe['angle_trend'] > 0) & + (dataframe['angle_tsf_mid'] > 0) & + (0.75227 < dataframe['correl_h_l_30']) & + (0.4 < dataframe['correl_h_l_30']) & + + # (dataframe['sine_1h'] < dataframe['leadsine_1h']) & + # (dataframe['tsf_mid'] > dataframe['close']) & + # (dataframe['angle'] > 0) & + # (dataframe['rsi'] <50) & + # (dataframe['natr'] > 1.1) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['sar'], dataframe['close'])) & + + (dataframe['max_low'] - dataframe['min_high'].shift(15) < 0) & + (dataframe['angle_trend'] < 2) & + (dataframe['angle_tsf_mid'] < 2) & + (dataframe['mode'] == 1) & + # (dataframe['close'] < dataframe['vwap']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/ltcusdt_1h.py b/.env/bin/user_data/strategies/ltcusdt_1h.py new file mode 100644 index 000000000..5d848eb05 --- /dev/null +++ b/.env/bin/user_data/strategies/ltcusdt_1h.py @@ -0,0 +1,189 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, MAX, MIN, SAR, CCI, \ + HT_TRENDLINE, HT_DCPERIOD, HT_TRENDMODE, HT_SINE, RSI, NATR, HT_PHASOR + +from freqtrade.strategy import merge_informative_pair +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class ltcusdt_1h(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.04371, + "300": 0.0461, + "14487": 0.0254, + "15960": 0 + } + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.23 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.11193 + trailing_stop_positive_offset = 0.20381 + trailing_only_offset_is_reached = True + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1d")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=7) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['ao'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=34) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=48) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['natr'] = NATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=14) + + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_mid'], timeperiod=10) + dataframe['sine'], dataframe['leadsine'] = HT_SINE(dataframe['close']) + dataframe['sine'] = dataframe['sine'].multiply(10) + dataframe['leadsine'] = dataframe['leadsine'].multiply(10) + dataframe['trend'] = HT_TRENDLINE(dataframe['close']) + dataframe['mode'] = HT_TRENDMODE(dataframe['close']) + dataframe['inphase'], dataframe['quadrature'] = HT_PHASOR(dataframe['close']) + + dataframe['angle_trend_mid'] = LINEARREG_ANGLE(dataframe['trend'], timeperiod=10) + + dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=12) + dataframe['angle_macdsignal'] = LINEARREG_ANGLE(dataframe['macdsignal'], timeperiod=15) + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['leadsine'], dataframe['sine'])) & + + # (dataframe['sine_1h'] < dataframe['leadsine_1h']) & + # (dataframe['tsf_mid'] > dataframe['close']) & + (dataframe['ao'] > -5) & + (dataframe['angle_tsf_mid'] > -3) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['leadsine'], dataframe['sine'])) & + # (dataframe['sine_1h'] > dataframe['leadsine_1h']) & + # (dataframe['sar_1d'] < dataframe['close']) & + # (dataframe['tsf_mid'] < dataframe['close']) & + # (dataframe['natr'] > 2.5) & + (dataframe['angle_tsf_mid'] < 5) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/macd_strg.py b/.env/bin/user_data/strategies/macd_strg.py new file mode 100644 index 000000000..633166ade --- /dev/null +++ b/.env/bin/user_data/strategies/macd_strg.py @@ -0,0 +1,301 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, SAR, LINEARREG_ANGLE, TEMA, STOCHRSI, STOCH, STOCHF, RSI + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +# This class is a sample. Feel free to customize it. +class macd_ethbtc_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 1 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.04025819697656752, + "7": 0.015188707936204564, + "18": 0.005472487470606337, + "41": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.33515742514178193 + + # Trailing stoploss + trailing_stop = False + trailing_stop_positive = 0.34089 + trailing_stop_positive_offset = 0.43254 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'close': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "OU": { + 'ou': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/BTC", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + # MACD + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=9) + dataframe['macd_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + dataframe['macdhist_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + + + # Parabolic SAR + dataframe['sar'] = SAR(dataframe['high'], dataframe['low'], acceleration=0, maximum=0) + dataframe['sar_angle'] = LINEARREG_ANGLE(dataframe['sar'], timeperiod=3) + + # Linear angle + dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=14) + + dataframe['tema'] = TEMA(dataframe['close'], timeperiod=30) + dataframe['sr_fastk'], dataframe['sr_fastd'] = STOCHRSI(dataframe['close'], timeperiod=14, fastk_period=5, + fastd_period=3, fastd_matype=0) + dataframe['sr_fastd_angle'] = LINEARREG_ANGLE(dataframe['sr_fastd'], timeperiod=4) + + dataframe['slowk'], dataframe['slowd'] = STOCH(dataframe['high'], dataframe['low'], dataframe['close'], + fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, + slowd_matype=0) + dataframe['slowd_angle'] = LINEARREG_ANGLE(dataframe['slowd'], timeperiod=3) + dataframe['sf_fastk'], dataframe['sf_fastd'] = STOCHF(dataframe['high'], dataframe['low'], dataframe['close'], fastk_period=5, fastd_period=3, fastd_matype=0) + dataframe['sf_fastd_angle'] = LINEARREG_ANGLE(dataframe['sf_fastd'], timeperiod=3) + + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + dataframe['rsi_angle'] = LINEARREG_ANGLE(dataframe['rsi'], timeperiod=5) + + + # # first check if dataprovider is available + # if self.dp: + # if self.dp.runmode in ('live', 'dry_run'): + # ob = self.dp.orderbook(metadata['pair'], 1) + # dataframe['best_bid'] = ob['bids'][0][0] + # dataframe['best_ask'] = ob['asks'][0][0] + # + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['sar'])) & + (0 > (dataframe['sar'] - dataframe['close'])) & + (1 > (dataframe['sar'] - dataframe['sar'].shift(3))) & + (1 > dataframe['macd']) & + (1 > dataframe['macdhist']) & + (0 < (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) & + (0 < dataframe['angle']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (dataframe['uo'] < 69) & + (0 > (dataframe['sar'] - dataframe['close'])) & + (1 > (dataframe['sar'] - dataframe['sar'].shift(3))) & + (0 < dataframe['macd']) & + (1 < dataframe['macdhist']) & + (0 > (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) & + (0 > dataframe['angle']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe + + +""" +buy1: +trigger = macd cross above macdsignal +guard = sar < close +guard = 70 > ou > 50 +guard = lenear_angle > 0 + +buy2: +trigger = sar < close +guard = macd > macdsignal +guard = 70 > ou > 50 +buy3: +trigger = ou cross below 30 & close > max(close) + +sell1: +trigger = macd cross below macdsignal +guard = sar > close +guard = 50 > ou > 20 +sell2: +trigger = sar > close +guard = macd < macdsignal +guard = 50 > ou > 20 +""" + +""" ++--------+---------+----------+------------------+--------------+------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+------------------------------+----------------+-------------| +| * Best | 3/500 | 1194 | 523 654 17 | -0.12% | -0.06906927 BTC (-138.00%) | 1,559.8 m | 2.71708 | +| * Best | 6/500 | 100 | 20 0 80 | -0.07% | -0.00352831 BTC (-7.05%) | 11.5 m | 1.87067 | +| Best | 37/500 | 12 | 6 0 6 | 0.49% | 0.00294367 BTC (5.88%) | 18.2 m | 1.86009 | +| Best | 67/500 | 10 | 6 0 4 | 0.89% | 0.00443786 BTC (8.87%) | 19.5 m | 1.85245 | +| Best | 91/500 | 73 | 21 5 47 | 0.00% | 0.00007645 BTC (0.15%) | 10.2 m | 1.85215 | +| Best | 92/500 | 48 | 17 2 29 | 0.05% | 0.00116911 BTC (2.34%) | 10.4 m | 1.85189 | +| Best | 94/500 | 12 | 6 0 6 | 0.69% | 0.00416071 BTC (8.31%) | 17.8 m | 1.85143 | +| Best | 110/500 | 18 | 6 1 11 | 0.36% | 0.00327838 BTC (6.55%) | 14.3 m | 1.85113 | +| Best | 257/500 | 48 | 16 0 32 | 0.06% | 0.00154456 BTC (3.09%) | 11.3 m | 1.8505 | +| Best | 388/500 | 74 | 23 14 37 | 0.01% | 0.00045826 BTC (0.92%) | 8.2 m | 1.84665 | + [Epoch 500 of 500 (100%)] || | [Time: 1:04:49, Elapsed Time: 1:04:49] +2021-01-31 01:14:47,851 - freqtrade.optimize.hyperopt - INFO - 500 epochs saved to '/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/hyperopt_results/hyperopt_results_2021-01-31_00-07-23.pickle'. + +Best result: + + 388/500: 74 trades. 23/14/37 Wins/Draws/Losses. Avg profit 0.01%. Median profit -0.02%. Total profit 0.00045826 BTC ( 0.92Σ%). Avg duration 8.2 min. Objective: 1.84665 + + + # Buy hyperspace params: + buy_params = { + 'angle-enabled': False, + 'macd-enabled': False, + 'macd_value': 0.73579, + 'macdhist_shift': 0.87895, + 'macdhist_value': 0.29935, + 'sar-enabled': False, + 'sar_ratio': 0.43819, + 'sar_shift': 0.98992, + 'trigger': 'sell-macd_cross_signal' + } + + # Sell hyperspace params: + sell_params = { + 'angle_h_s': 0.07105, + 'macd_value_s': 0.08408, + 'macdhist_shift_s': -0.72567, + 'macdhist_value_s': 0.77324, + 'sar_ratio_s': 0.58347, + 'sar_shift_s': 0.81212, + 'sell-angle-enabled': True, + 'sell-macd-enabled': False, + 'sell-sar-enabled': False, + 'sell-uo-enabled': True, + 'trigger': 'sell-macd_cross_signal', + 'uo_l_s': 14 + } + + # ROI table: + minimal_roi = { + "0": 0.07193, + "3": 0.0382, + "5": 0.01183, + "7": 0 + } + + # Stoploss: + stoploss = -0.25471 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.04697 + trailing_stop_positive_offset = 0.05329 + trailing_only_offset_is_reached = True + +""" diff --git a/.env/bin/user_data/strategies/quick_btcusdt_1m.py b/.env/bin/user_data/strategies/quick_btcusdt_1m.py new file mode 100644 index 000000000..6bdb20cdd --- /dev/null +++ b/.env/bin/user_data/strategies/quick_btcusdt_1m.py @@ -0,0 +1,196 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, SAR, LINEARREG_ANGLE, TEMA, STOCHRSI, STOCH, STOCHF, RSI + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +# This class is a sample. Feel free to customize it. +class quick_btcusdt_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 1 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.07186329732926479, + "6": 0.03610260437996321, + "14": 0.014117594921808408, + "23": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.073946396013718 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.11645094244761 + trailing_stop_positive_offset = 0.20201226976340847 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'close': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "OU": { + 'ou': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("BTC/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + # MACD + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=9) + dataframe['macd_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + dataframe['macdhist_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + + # Linear angle + dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=14) + + dataframe['tema'] = TEMA(dataframe['close'], timeperiod=30) + dataframe['sr_fastk'], dataframe['sr_fastd'] = STOCHRSI(dataframe['close'], timeperiod=14, fastk_period=5, + fastd_period=3, fastd_matype=0) + dataframe['sr_fastd_angle'] = LINEARREG_ANGLE(dataframe['sr_fastd'], timeperiod=4) + + dataframe['slowk'], dataframe['slowd'] = STOCH(dataframe['high'], dataframe['low'], dataframe['close'], + fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, + slowd_matype=0) + dataframe['slowd_angle'] = LINEARREG_ANGLE(dataframe['slowd'], timeperiod=3) + dataframe['sf_fastk'], dataframe['sf_fastd'] = STOCHF(dataframe['high'], dataframe['low'], dataframe['close'], fastk_period=5, fastd_period=3, fastd_matype=0) + dataframe['sf_fastd_angle'] = LINEARREG_ANGLE(dataframe['sf_fastd'], timeperiod=3) + + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + dataframe['rsi_angle'] = LINEARREG_ANGLE(dataframe['rsi'], timeperiod=5) + + + # # first check if dataprovider is available + # if self.dp: + # if self.dp.runmode in ('live', 'dry_run'): + # ob = self.dp.orderbook(metadata['pair'], 1) + # dataframe['best_bid'] = ob['bids'][0][0] + # dataframe['best_ask'] = ob['asks'][0][0] + # + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) & + (dataframe['sr_fastd_angle'] > -39) & + (dataframe['sf_fastk'] > 33) & + (dataframe['sf_fastd_angle'] > -80) & + (dataframe['rsi_angle'] > 24) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + ((dataframe['macdhist']) < 0.000241872676925719) & + (dataframe['sr_fastd_angle'] > 71) & + (dataframe['sf_fastd_angle'] < 21) & + (dataframe['rsi_angle'] < 1) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe + diff --git a/.env/bin/user_data/strategies/quick_ethusdt_1m.py b/.env/bin/user_data/strategies/quick_ethusdt_1m.py new file mode 100644 index 000000000..c3b023ad1 --- /dev/null +++ b/.env/bin/user_data/strategies/quick_ethusdt_1m.py @@ -0,0 +1,197 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, SAR, LINEARREG_ANGLE, TEMA, STOCHRSI, STOCH, STOCHF, RSI + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +# This class is a sample. Feel free to customize it. +class quick_ethusdt_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 1 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.07186329732926479, + "6": 0.03610260437996321, + "14": 0.014117594921808408, + "23": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.073946396013718 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.11645094244761 + trailing_stop_positive_offset = 0.20201226976340847 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'close': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "OU": { + 'ou': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + # MACD + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=9) + dataframe['macd_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + dataframe['macdhist_angle'] = LINEARREG_ANGLE(dataframe['macd'], timeperiod=3) + + # Linear angle + dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=14) + + dataframe['tema'] = TEMA(dataframe['close'], timeperiod=30) + dataframe['sr_fastk'], dataframe['sr_fastd'] = STOCHRSI(dataframe['close'], timeperiod=14, fastk_period=5, + fastd_period=3, fastd_matype=0) + dataframe['sr_fastd_angle'] = LINEARREG_ANGLE(dataframe['sr_fastd'], timeperiod=4) + + dataframe['slowk'], dataframe['slowd'] = STOCH(dataframe['high'], dataframe['low'], dataframe['close'], + fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, + slowd_matype=0) + dataframe['slowd_angle'] = LINEARREG_ANGLE(dataframe['slowd'], timeperiod=3) + dataframe['sf_fastk'], dataframe['sf_fastd'] = STOCHF(dataframe['high'], dataframe['low'], dataframe['close'], fastk_period=5, fastd_period=3, fastd_matype=0) + dataframe['sf_fastd_angle'] = LINEARREG_ANGLE(dataframe['sf_fastd'], timeperiod=3) + + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + dataframe['rsi_angle'] = LINEARREG_ANGLE(dataframe['rsi'], timeperiod=5) + + + # # first check if dataprovider is available + # if self.dp: + # if self.dp.runmode in ('live', 'dry_run'): + # ob = self.dp.orderbook(metadata['pair'], 1) + # dataframe['best_bid'] = ob['bids'][0][0] + # dataframe['best_ask'] = ob['asks'][0][0] + # + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal'])) & + ((dataframe['macd_angle']) > -0.007579827857282747) & + (dataframe['tema'] < 0.124417394428206) & + (dataframe['sr_fastd_angle'] > -39) & + (dataframe['sf_fastk'] > 33) & + (dataframe['rsi_angle'] > 24) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + ((dataframe['macdhist']) < 0.000241872676925719) & + (dataframe['sr_fastd_angle'] > 71) & + (dataframe['sf_fastd_angle'] < 21) & + (dataframe['rsi_angle'] < 1) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe + diff --git a/.env/bin/user_data/strategies/strg1_ada_usdt_1m.py b/.env/bin/user_data/strategies/strg1_ada_usdt_1m.py new file mode 100644 index 000000000..d58178dde --- /dev/null +++ b/.env/bin/user_data/strategies/strg1_ada_usdt_1m.py @@ -0,0 +1,205 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, SAR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg1_ADAUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.16408611153968805, + "18": 0.07786509535022122, + "76": 0.01087364896379109, + "193": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.14772112352872754 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.13192197532670782 + trailing_stop_positive_offset = 0.19046200322926082 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ADA/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + ((dataframe['close'] - dataframe['tsf_mid']) > 0.6037118990957886) & + ((dataframe['close'] - dataframe['tsf_short']) > 0.280886393803766) & + (0.7374370242135467 < dataframe['correl_h_l']) & + (0.598218893737078 < dataframe['correl_tsf_short_close']) & + (-0.5081118861877524 < dataframe['correl_mfi_close']) & + (-0.00808699162233981 < (dataframe['ema'] - dataframe['middleband'])) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + ((dataframe['tsf_mid'] - dataframe['close']) < 0.44785474790276225) & + ((dataframe['tsf_short'] - dataframe['close']) < 0.17576899126417125) & + (0.030726048199457463 < dataframe['correl_h_l']) & + (0.4328953914289484 < dataframe['correl_tsf_short_close']) & + (0.09562688208375203 < dataframe['correl_mfi_close']) & + (-0.00892438828151425 < (dataframe['ema'] - dataframe['middleband'])) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg1_btc_usdt_1m.py b/.env/bin/user_data/strategies/strg1_btc_usdt_1m.py new file mode 100644 index 000000000..d6b5b96f8 --- /dev/null +++ b/.env/bin/user_data/strategies/strg1_btc_usdt_1m.py @@ -0,0 +1,199 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg1_BTCUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.24724, + "14": 0.05512, + "46": 0.01805, + "151": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.02231 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.34089 + trailing_stop_positive_offset = 0.43254 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("BTC/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['middleband'])) & + (dataframe['mfi'] < 16) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['macdsignal'], dataframe['macd'])) & + (dataframe['correl_hist_close'] < 0.9) & + (dataframe['mfi'] > 98) & + (dataframe['middleband'] < 87) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg1_doge_usdt_1m.py b/.env/bin/user_data/strategies/strg1_doge_usdt_1m.py new file mode 100644 index 000000000..7b53e69a3 --- /dev/null +++ b/.env/bin/user_data/strategies/strg1_doge_usdt_1m.py @@ -0,0 +1,216 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, SAR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg1_DOGEUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.24724, + "30": 0.1, + "46": 0.05, + "151": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.1 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.04 + trailing_stop_positive_offset = 0.14 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("DOGE/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 14) & + (0.5263534368259521 < dataframe['correl_h_l']) & + (0.0728048430667152 < dataframe['correl_tsf_mid_close']) & + (-0.02402596125126566 < dataframe['correl_angle_short_close']) & + (0.2842166347875669 < dataframe['correl_angle_long_close']) & + (-0.6552565064627378 < dataframe['correl_mfi_close']) & + (-0.4853276710303872 < dataframe['correl_hist_close']) & + (0.442188534531633 < dataframe['mfi']) & + (0.6714488827895353 < dataframe['ema']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 68) & + (-0.6225944943311145 < dataframe['correl_h_l']) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (0.771988603840956 < dataframe['correl_angle_short_close']) & + (0.33471662411500236 < dataframe['correl_angle_long_close']) & + (-0.9562413964921457 < dataframe['correl_hist_close']) & + (-0.43268559077377733 < dataframe['correl_mfi_close']) & + (-0.25207265197064166 < dataframe['mfi']) & + (-0.00739011415527302 < dataframe['ema']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg1_eth_usdt_1m.py b/.env/bin/user_data/strategies/strg1_eth_usdt_1m.py new file mode 100644 index 000000000..31d228629 --- /dev/null +++ b/.env/bin/user_data/strategies/strg1_eth_usdt_1m.py @@ -0,0 +1,233 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg1_ETHUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.24724, + "30": 0.1, + "46": 0.05, + "151": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.2 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.19 + trailing_stop_positive_offset = 0.21 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 14) & + (0.5263534368259521 < dataframe['correl_h_l']) & + (0.0728048430667152 < dataframe['correl_tsf_mid_close']) & + (-0.02402596125126566 < dataframe['correl_angle_short_close']) & + (0.2842166347875669 < dataframe['correl_angle_long_close']) & + (-0.6552565064627378 < dataframe['correl_mfi_close']) & + (-0.4853276710303872 < dataframe['correl_hist_close']) & + (0.442188534531633 < dataframe['mfi']) & + (0.6714488827895353 < dataframe['ema']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 68) & + (-0.6225944943311145 < dataframe['correl_h_l']) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (0.771988603840956 < dataframe['correl_angle_short_close']) & + (0.33471662411500236 < dataframe['correl_angle_long_close']) & + (-0.9562413964921457 < dataframe['correl_hist_close']) & + (-0.43268559077377733 < dataframe['correl_mfi_close']) & + (-0.25207265197064166 < dataframe['mfi']) & + (-0.00739011415527302 < dataframe['ema']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg1_eth_usdt_1m_prod.py b/.env/bin/user_data/strategies/strg1_eth_usdt_1m_prod.py new file mode 100644 index 000000000..a0eb2b384 --- /dev/null +++ b/.env/bin/user_data/strategies/strg1_eth_usdt_1m_prod.py @@ -0,0 +1,216 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg1_ETHUSDT_1m_prod(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.24724, + "30": 0.1, + "46": 0.05, + "151": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.1 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.04 + trailing_stop_positive_offset = 0.14 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=144) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=288) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=288) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=144) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=288) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=144) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=288) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=24) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=14) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=8) + dataframe['ma'] = MA(dataframe['close'], timeperiod=8, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=20, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 14) & + (0.5263534368259521 < dataframe['correl_h_l']) & + (0.0728048430667152 < dataframe['correl_tsf_mid_close']) & + (-0.02402596125126566 < dataframe['correl_angle_short_close']) & + (0.2842166347875669 < dataframe['correl_angle_long_close']) & + (-0.6552565064627378 < dataframe['correl_mfi_close']) & + (-0.4853276710303872 < dataframe['correl_hist_close']) & + (0.442188534531633 < dataframe['mfi']) & + (0.6714488827895353 < dataframe['ema']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['lowerband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 68) & + (-0.6225944943311145 < dataframe['correl_h_l']) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (0.771988603840956 < dataframe['correl_angle_short_close']) & + (0.33471662411500236 < dataframe['correl_angle_long_close']) & + (-0.9562413964921457 < dataframe['correl_hist_close']) & + (-0.43268559077377733 < dataframe['correl_mfi_close']) & + (-0.25207265197064166 < dataframe['mfi']) & + (-0.00739011415527302 < dataframe['ema']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_ada_usdt_1m.py b/.env/bin/user_data/strategies/strg2_ada_usdt_1m.py new file mode 100644 index 000000000..3ccec75d5 --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_ada_usdt_1m.py @@ -0,0 +1,189 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, SAR, HT_TRENDLINE, RSI, NATR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ADAUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.0816, + "30": 0.04762, + "60": 0.01142, + "150": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.20102 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.10581 + trailing_stop_positive_offset = 0.11224 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'correl_h_l': {'color': 'black'}, + 'upperband': {'color': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "mfi": { + 'mfi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ADA/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=5) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=30) + dataframe['ao'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=34) + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + + + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_mid'], timeperiod=5) + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_short'], timeperiod=5) + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (60 > dataframe['mfi']) & + # (0.15 < dataframe['natr']) & + (dataframe['angle_tsf_mid'] > 0) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['sar'], dataframe['close'])) & + # (-0.00354 > dataframe['macdhist']) & + (50.23156 > dataframe['mfi']) & + (dataframe['angle_tsf_mid'] < 0) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_ada_usdt_1m_prod.py b/.env/bin/user_data/strategies/strg2_ada_usdt_1m_prod.py new file mode 100644 index 000000000..3ccec75d5 --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_ada_usdt_1m_prod.py @@ -0,0 +1,189 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, SAR, HT_TRENDLINE, RSI, NATR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ADAUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.0816, + "30": 0.04762, + "60": 0.01142, + "150": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.20102 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.10581 + trailing_stop_positive_offset = 0.11224 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'market', + 'sell': 'market', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'correl_h_l': {'color': 'black'}, + 'upperband': {'color': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "mfi": { + 'mfi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ADA/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=5) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=30) + dataframe['ao'] = qtpylib.awesome_oscillator(dataframe, weighted=False, fast=5, slow=34) + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=14) + + + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_mid'], timeperiod=5) + dataframe['angle_tsf_mid'] = LINEARREG_ANGLE(dataframe['tsf_short'], timeperiod=5) + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=14) + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (60 > dataframe['mfi']) & + # (0.15 < dataframe['natr']) & + (dataframe['angle_tsf_mid'] > 0) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['sar'], dataframe['close'])) & + # (-0.00354 > dataframe['macdhist']) & + (50.23156 > dataframe['mfi']) & + (dataframe['angle_tsf_mid'] < 0) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_ada_usdt_1m_sharpe.py b/.env/bin/user_data/strategies/strg2_ada_usdt_1m_sharpe.py new file mode 100644 index 000000000..db4bf5ea2 --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_ada_usdt_1m_sharpe.py @@ -0,0 +1,178 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, SAR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ADAUSDT_1m_sharpe(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.17440164714028486, + "38": 0.09394715625863974, + "98": 0.027323845707844324, + "170": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.2399087254823858 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.10717125716853501 + trailing_stop_positive_offset = 0.13807946709133387 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = True + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'correl_h_l': {'color': 'black'}, + 'upperband': {'color': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "mfi": { + 'mfi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ADA/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=10, + slowperiod=24, signalperiod=7) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low']) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=60) + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=60) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=35, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['middleband'])) & + (0.6452515141186865 < dataframe['correl_h_l']) & + (18 < dataframe['mfi']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['close'], dataframe['middleband'])) & + (0.1 < dataframe['correl_h_l']) & + (17 > dataframe['mfi']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_eth_usdt_1m.py b/.env/bin/user_data/strategies/strg2_eth_usdt_1m.py new file mode 100644 index 000000000..7c1ff98be --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_eth_usdt_1m.py @@ -0,0 +1,231 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ETHUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.14918562374415067, + "34": 0.058385372968253246, + "81": 0.02650295809826818, + "164": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.22617753002701768 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.32322177120674106 + trailing_stop_positive_offset = 0.3600439363018107 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=30) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=30) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=720) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=1440) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=1440) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=720) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=30) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=1440) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=720) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=720) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=1440) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=30) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=30) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=15) + dataframe['ma'] = MA(dataframe['close'], timeperiod=15, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['middleband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 10) & + ((dataframe['tsf_mid'] - dataframe['close']) > -23) & + (dataframe['angle_mid'] > -31) & + (0.6120614546605481 < dataframe['correl_angle_short_close']) & + (0.4128274947005438 < dataframe['correl_angle_mid_close']) & + (18 < dataframe['mfi']) & + (-18 < (dataframe['ema'] - dataframe['middleband'])) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['close'], dataframe['middleband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 29) & + ((dataframe['tsf_short'] - dataframe['close']) > -94) & + (dataframe['angle_mid'] > -10) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (-0.8240439026300765 < dataframe['correl_angle_short_close']) & + (-0.9736515042784262 < dataframe['correl_angle_mid_close']) & + (80 < dataframe['mfi']) & + (26 < (dataframe['middleband'] - dataframe['ema'])) & + (18 > dataframe['macdhist']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_eth_usdt_1m_360_30_15.py b/.env/bin/user_data/strategies/strg2_eth_usdt_1m_360_30_15.py new file mode 100644 index 000000000..b17a85d7a --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_eth_usdt_1m_360_30_15.py @@ -0,0 +1,212 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import MACD, LINEARREG_ANGLE, TSF, MFI, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ETHUSDT_1m_360(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.14689, + "23": 0.07987, + "40": 0.03243, + "136": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.18934 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.02891 + trailing_stop_positive_offset = 0.05001 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = False + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=30) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=15) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=360) + + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=360) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=15) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=15) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=15) + + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=15) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=15) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=15) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=15) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=15) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=15) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['middleband'])) & + (0.42804 < dataframe['correl_h_l']) & + (dataframe['angle_short'] > -40) & + (-0.23132 < dataframe['correl_angle_short_close']) & + (0.5 < dataframe['macdhist']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['close'], dataframe['upperband'])) & + (36 < dataframe['angle_short']) & + (0.72362 < dataframe['correl_angle_short_close']) & + (0.40219 < dataframe['correl_h_l']) & + (0 > dataframe['macdhist']) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg2_eth_usdt_1m_safe_prod.py b/.env/bin/user_data/strategies/strg2_eth_usdt_1m_safe_prod.py new file mode 100644 index 000000000..a967044ee --- /dev/null +++ b/.env/bin/user_data/strategies/strg2_eth_usdt_1m_safe_prod.py @@ -0,0 +1,231 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg2_ETHUSDT_1m_prod(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.14918562374415067, + "34": 0.058385372968253246, + "81": 0.02650295809826818, + "164": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.22617753002701768 + + # Trailing stoploss + trailing_stop = True + trailing_stop_positive = 0.32322177120674106 + trailing_stop_positive_offset = 0.3600439363018107 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'upperband': {'upperband': 'green'}, + 'middleband': {'color': 'green'}, + 'lowerband': {'color': 'green'}, + 'tsf_mid': {'color': 'white'}, + 'ema': {'color': 'white'}, + }, + 'subplots': { + "corr": { + 'correl_h_l': {'color': 'black'}, + }, + "correl_tsf_mid_close": { + 'correl_tsf_mid_close': {'color': 'grey'}, + }, + "correl_angle_short_close": { + 'correl_angle_short_close': {'color': 'blue'}, + }, + "correl_angle_long_close": { + 'correl_angle_long_close': {'color': 'red'}, + }, + "correl_mfi_close": { + 'correl_mfi_close': {'color': 'black'}, + }, + "correl_hist_close": { + 'correl_tsf_mid_close': {'color': 'red'}, + }, + "mfi": { + 'mfi': {'color': 'yellow'}, + }, + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, + slowperiod=26, signalperiod=7) + + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=30) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=30) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=720) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=1440) + + dataframe['tsf_long'] = TSF(dataframe['close'], timeperiod=1440) + dataframe['tsf_mid'] = TSF(dataframe['close'], timeperiod=720) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=30) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + + dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=1440) + dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=720) + dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=30) + + dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=30) + dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=720) + dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=1440) + + dataframe['correl_hist_close'] = CORREL(dataframe['macdhist'], dataframe['close'], timeperiod=30) + dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=30) + + + + + dataframe['ema'] = EMA(dataframe['close'], timeperiod=15) + dataframe['ma'] = MA(dataframe['close'], timeperiod=15, matype=0) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['middleband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 10) & + ((dataframe['tsf_mid'] - dataframe['close']) > -23) & + (dataframe['angle_mid'] > -31) & + (0.6120614546605481 < dataframe['correl_angle_short_close']) & + (0.4128274947005438 < dataframe['correl_angle_mid_close']) & + (18 < dataframe['mfi']) & + (-18 < (dataframe['ema'] - dataframe['middleband'])) & + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['close'], dataframe['middleband'])) & + ((dataframe['tsf_mid'] - dataframe['close']) > 29) & + ((dataframe['tsf_short'] - dataframe['close']) > -94) & + (dataframe['angle_mid'] > -10) & + (0.2602396802858502 < dataframe['correl_tsf_mid_close']) & + (-0.8240439026300765 < dataframe['correl_angle_short_close']) & + (-0.9736515042784262 < dataframe['correl_angle_mid_close']) & + (80 < dataframe['mfi']) & + (26 < (dataframe['middleband'] - dataframe['ema'])) & + (18 > dataframe['macdhist']) & + + + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg3_ada_usdt_1m.py b/.env/bin/user_data/strategies/strg3_ada_usdt_1m.py new file mode 100644 index 000000000..eda1994c2 --- /dev/null +++ b/.env/bin/user_data/strategies/strg3_ada_usdt_1m.py @@ -0,0 +1,199 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, BBANDS, CORREL, MAX, AROON, HT_PHASOR, HT_SINE, HT_DCPHASE, HT_TRENDMODE, \ + HT_TRENDLINE, CCI, AROONOSC, \ + RSI, MFI, LINEARREG_ANGLE, TSF + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg3_ADAUSDT_1m_test(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.2, + "18": 0.07762, + "65": 0.02142, + "158": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + # Stoploss: + stoploss = -0.17 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.01 + trailing_stop_positive_offset = 0.05 + trailing_only_offset_is_reached = True + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 130 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + }, + 'subplots': { + "sine": { + 'leadsine': {'color': 'green'}, + 'ht_sine': {'color': 'orange'}, + }, + "aroon": { + 'aroon_down': {'color': 'brown'}, + 'aroon_up': {'color': 'blue'}, + }, + "cci": { + 'cci': {'color': 'yellow'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ADA/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + dataframe['aroon_down'], dataframe['aroon_up'] = AROON(dataframe['high'], dataframe['low'], timeperiod=120) + dataframe['aroonosc'] = AROONOSC(dataframe['high'], dataframe['low'], timeperiod=120) + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=30, + slowperiod=60, signalperiod=15) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=30, nbdevup=2, + nbdevdn=2, matype=0) + dataframe['rsi'] = RSI(dataframe['close'], timeperiod=30) + dataframe['ul'] = ULTOSC(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod1=5, timeperiod2=15, + timeperiod3=30) + # dataframe['slowk'], dataframe['slowd'] = STOCH(dataframe['high'], dataframe['low'], dataframe['close'], + # fastk_period=15, slowk_period=7, slowk_matype=0, slowd_period=7, + # slowd_matype=0) + dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + timeperiod=30) + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=30) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=10) + + dataframe['correl_h_l'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['ht_phase'] = HT_DCPHASE(dataframe['close']) + dataframe['ht_trendmode'] = HT_TRENDMODE(dataframe['close']) + dataframe['ht_trendline'] = HT_TRENDLINE(dataframe['close']) + dataframe['inphase'], dataframe['quadrature'] = HT_PHASOR(dataframe['close']) + dataframe['ht_sine'], dataframe['leadsine'] = HT_SINE(dataframe['close']) + dataframe['correl_sine_trend'] = CORREL(dataframe['leadsine'], dataframe['ht_trendmode'], timeperiod=10) + dataframe['correl_ht_sine_trend'] = CORREL(dataframe['ht_sine'], dataframe['ht_trendmode'], timeperiod=10) + dataframe['correl_ht_sine_close'] = CORREL(dataframe['ht_sine'], dataframe['close'], timeperiod=10) + dataframe['cci'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=120) + # dataframe['ht_phase_min'] = MIN(dataframe['ht_phase'], timeperiod=30) + # dataframe['ht_phase_max'] = MAX(dataframe['ht_phase'], timeperiod=60) + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['leadsine'], dataframe['ht_sine'])) & + (dataframe['cci'] < 0) & + (dataframe['angle_short'] > 0) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['aroon_up'], 83)) & + (dataframe['angle_short'] < 0) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg3_eth_usdt_1m.py b/.env/bin/user_data/strategies/strg3_eth_usdt_1m.py new file mode 100644 index 000000000..c3ab6a55e --- /dev/null +++ b/.env/bin/user_data/strategies/strg3_eth_usdt_1m.py @@ -0,0 +1,237 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, CCI, HT_DCPHASE, \ + HT_TRENDMODE, HT_TRENDLINE, MIN, MAX, HT_PHASOR, HT_SINE, LINEARREG, ATR, NATR, SAR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg3_ETHUSDT_1m(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.22703036349783817, + "30": 0.1085576426119433, + "82": 0.029443202051755248, + "164": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.1963679962572551 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.2294395227514193 + trailing_stop_positive_offset = 0.3040424465654783 + trailing_only_offset_is_reached = False + + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'lr': {'color': 'green'}, + # 'angle_mid': {'color': 'blue'}, + 'tsf_mid': {'color': 'orange'}, + }, + 'subplots': { + "correl_h_l": { + 'correl_h_l': {'color': 'black'} + }, + "cci": { + 'cci': {'color': 'red'} + }, + "natr": { + 'natr': {'color': 'red'} + }, + "ht_phase": { + 'ht_phase': {'color': 'red'} + }, + "ht_trendmode": { + 'ht_trendmode': {'color': 'red'} + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + + # dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + # timeperiod=15) + dataframe['cci_30'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['cci_45'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=45) + dataframe['trend_line'] = HT_TRENDLINE(dataframe['close']) + + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=5) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=30) + dataframe['angle_trend_45'] = LINEARREG_ANGLE(dataframe['trend_line'], timeperiod=45) + dataframe['angle_trend_30'] = LINEARREG_ANGLE(dataframe['trend_line'], timeperiod=30) + # dataframe['atr'] = ATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['natr'] = NATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=14) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=30) + + dataframe['correl_h_l_30'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_h_l_3'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=3) + dataframe['correl_h_l_10'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=10) + # dataframe['correl_close_last_close'] = CORREL(dataframe['close'].shift(1), dataframe['close'], timeperiod=30) + # + # dataframe['correl_tsf_long_close'] = CORREL(dataframe['tsf_long'], dataframe['close'], timeperiod=45) + # dataframe['correl_tsf_mid_close'] = CORREL(dataframe['tsf_mid'], dataframe['close'], timeperiod=45) + # dataframe['correl_tsf_short_close'] = CORREL(dataframe['tsf_short'], dataframe['close'], timeperiod=5) + # + # dataframe['correl_angle_short_close'] = CORREL(dataframe['angle_short'], dataframe['close'], timeperiod=45) + # dataframe['correl_angle_mid_close'] = CORREL(dataframe['angle_mid'], dataframe['close'], timeperiod=45) + # dataframe['correl_angle_long_close'] = CORREL(dataframe['angle_long'], dataframe['close'], timeperiod=45) + # + # dataframe['correl_mfi_close'] = CORREL(dataframe['mfi'], dataframe['close'], timeperiod=45) + # + # dataframe['ema'] = EMA(dataframe['close'], timeperiod=7) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=28, nbdevup=2, + nbdevdn=2, matype=0) + + # dataframe['correl_ht_sine_close'] = CORREL(dataframe['ht_sine'], dataframe['close'], timeperiod=30) + dataframe['sar'] = SAR(dataframe['high'], dataframe['low'], acceleration=0.02, maximum=0.2) + + + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (0 > dataframe['cci_30']) & + (0.15 < dataframe['natr']) & + (0 < (dataframe['trend_line'] - dataframe['close'])) & + (0.75227 < dataframe['correl_h_l_30']) & + # (dataframe['angle_long'] > 0) & + # (0.44494 < dataframe['correl_angle_mid_close']) & + # (-0.97597 < dataframe['correl_mfi_close']) & # + # (57 > dataframe['mfi']) & + # ((dataframe['close'] - dataframe['tsf_long']) > -3) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['sar'], dataframe['close'])) & + (50 > dataframe['cci_30']) & + # (100 < dataframe['cci_30']) & + (0 < (dataframe['close'] - dataframe['trend_line'])) & + (0.2 < dataframe['natr']) & + (0.4 < dataframe['correl_h_l_30']) & + + # (1 == dataframe['ht_trendmode']) & + # ((dataframe['tsf_long'] - dataframe['close']) < -3) & + # (dataframe['angle_mid'] < 50) & + # (dataframe['angle_long'] < 0) & + # (dataframe['angle_short'] > -9) & + # (dataframe['correl_mfi_close'] > -0.4065) & # + # (0.2552 < dataframe['correl_angle_long_close']) & + # (0.46789 < dataframe['correl_angle_mid_close']) & + # (57 < dataframe['mfi']) & + # (0.00585 < (dataframe['quadrature'] - dataframe['inphase'])) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strg3_eth_usdt_1m_sellonlyprofit.py b/.env/bin/user_data/strategies/strg3_eth_usdt_1m_sellonlyprofit.py new file mode 100644 index 000000000..a0977578a --- /dev/null +++ b/.env/bin/user_data/strategies/strg3_eth_usdt_1m_sellonlyprofit.py @@ -0,0 +1,219 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, LINEARREG_ANGLE, TSF, MFI, EMA, MA, BBANDS, CORREL, CCI, HT_DCPHASE, \ + HT_TRENDMODE, HT_TRENDLINE, MIN, MAX, HT_PHASOR, HT_SINE, LINEARREG, ATR, NATR, SAR + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import freqtrade.vendor.qtpylib.indicators as qtpylib + +""" + +""" + + +# This class is a sample. Feel free to customize it. +class strg3_ETHUSDT_1m_sellonlyprofit_prod(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.22703036349783817, + "30": 0.09085576426119433, + "82": 0.029443202051755248, + "164": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.2263679962572551 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.1294395227514193 + trailing_stop_positive_offset = 0.13040424465654783 + trailing_only_offset_is_reached = False + + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = True + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'lr': {'color': 'green'}, + # 'angle_mid': {'color': 'blue'}, + 'tsf_mid': {'color': 'orange'}, + }, + 'subplots': { + "correl_h_l": { + 'correl_h_l': {'color': 'black'} + }, + "cci": { + 'cci': {'color': 'red'} + }, + "natr": { + 'natr': {'color': 'red'} + }, + "ht_phase": { + 'ht_phase': {'color': 'red'} + }, + "ht_trendmode": { + 'ht_trendmode': {'color': 'red'} + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/USDT", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + + # dataframe['mfi'] = MFI(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], + # timeperiod=15) + dataframe['cci_30'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['cci_45'] = CCI(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=45) + dataframe['trend_line'] = HT_TRENDLINE(dataframe['close']) + + dataframe['angle_short'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=5) + dataframe['angle_mid'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=10) + dataframe['angle_long'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=30) + dataframe['angle_trend_45'] = LINEARREG_ANGLE(dataframe['trend_line'], timeperiod=45) + dataframe['angle_trend_30'] = LINEARREG_ANGLE(dataframe['trend_line'], timeperiod=30) + # dataframe['atr'] = ATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=30) + dataframe['natr'] = NATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=14) + dataframe['tsf_short'] = TSF(dataframe['close'], timeperiod=30) + + dataframe['correl_h_l_30'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=30) + dataframe['correl_h_l_3'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=3) + dataframe['correl_h_l_10'] = CORREL(dataframe['high'], dataframe['low'], timeperiod=10) + dataframe['upperband'], dataframe['middleband'], dataframe['lowerband'] = BBANDS(dataframe['close'], + timeperiod=28, nbdevup=2, + nbdevdn=2, matype=0) + + dataframe['sar'] = SAR(dataframe['high'], dataframe['low'], acceleration=0.02, maximum=0.2) + dataframe['angle_trend_fast'] = LINEARREG_ANGLE(dataframe['trend_line'], timeperiod=5) + + + + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (50 > dataframe['cci_30']) & + (0.15 < dataframe['natr']) & + (dataframe['angle_trend_fast'] > 0) & + (0.75227 < dataframe['correl_h_l_30']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['sar'], dataframe['close'])) & + (50 > dataframe['cci_30']) & + (0.25 < dataframe['natr']) & + (dataframe['angle_trend_fast'] < 0) & + (0.4 < dataframe['correl_h_l_30']) & + + # (1 == dataframe['ht_trendmode']) & + # ((dataframe['tsf_long'] - dataframe['close']) < -3) & + # (dataframe['angle_mid'] < 50) & + # (dataframe['angle_long'] < 0) & + # (dataframe['angle_short'] > -9) & + # (dataframe['correl_mfi_close'] > -0.4065) & # + # (0.2552 < dataframe['correl_angle_long_close']) & + # (0.46789 < dataframe['correl_angle_mid_close']) & + # (57 < dataframe['mfi']) & + # (0.00585 < (dataframe['quadrature'] - dataframe['inphase'])) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/.env/bin/user_data/strategies/strtg2.py b/.env/bin/user_data/strategies/strtg2.py new file mode 100644 index 000000000..62aa57b02 --- /dev/null +++ b/.env/bin/user_data/strategies/strtg2.py @@ -0,0 +1,281 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from talib._ta_lib import ULTOSC, MACD, SAR, LINEARREG_ANGLE + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +# This class is a sample. Feel free to customize it. +class strg_ETHBTC_1m2(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "0": 0.04025819697656752, + "7": 0.015188707936204564, + "18": 0.005472487470606337, + "41": 0 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.33515742514178193 + + # Trailing stoploss + trailing_stop = False + trailing_stop_positive = 0.34089 + trailing_stop_positive_offset = 0.43254 + trailing_only_offset_is_reached = False + + # Optimal ticker interval for the strategy. + timeframe = '1m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'close': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "OU": { + 'ou': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [("ETH/BTC", "1m")] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + # # Ultimate Oscillator + dataframe['uo'] = ULTOSC(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod1=7, timeperiod2=14, timeperiod3=28) + + # MACD + dataframe['macd'], dataframe['macdsignal'], dataframe['macdhist'] = MACD(dataframe['close'], fastperiod=12, slowperiod=26, signalperiod=9) + + # Parabolic SAR + dataframe['sar'] = SAR(dataframe['high'], dataframe['low'], acceleration=0, maximum=0) + + # Linear angle + dataframe['angle'] = LINEARREG_ANGLE(dataframe['close'], timeperiod=14) + + # first check if dataprovider is available + if self.dp: + if self.dp.runmode in ('live', 'dry_run'): + ob = self.dp.orderbook(metadata['pair'], 1) + dataframe['best_bid'] = ob['bids'][0][0] + dataframe['best_ask'] = ob['asks'][0][0] + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['close'], dataframe['sar'])) & + (0 > (dataframe['sar'] - dataframe['close'])) & + (1 > (dataframe['sar'] - dataframe['sar'].shift(3))) & + (1 > dataframe['macd']) & + (1 > dataframe['macdhist']) & + (0 < (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) & + (0 < dataframe['angle']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_below(dataframe['sar'], dataframe['close'])) & + (dataframe['uo'] < 69) & + (0 > (dataframe['sar'] - dataframe['close'])) & + (1 > (dataframe['sar'] - dataframe['sar'].shift(3))) & + (0 < dataframe['macd']) & + (1 < dataframe['macdhist']) & + (0 > (dataframe['macdhist'] - dataframe['macdhist'].shift(3))) & + (0 > dataframe['angle']) & + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe +""" +buy1: +trigger = macd cross above macdsignal +guard = sar < close +guard = 70 > ou > 50 +guard = lenear_angle > 0 + +buy2: +trigger = sar < close +guard = macd > macdsignal +guard = 70 > ou > 50 +buy3: +trigger = ou cross below 30 & close > max(close) + +sell1: +trigger = macd cross below macdsignal +guard = sar > close +guard = 50 > ou > 20 +sell2: +trigger = sar > close +guard = macd < macdsignal +guard = 50 > ou > 20 +""" + + +""" ++--------+---------+----------+------------------+--------------+------------------------------+----------------+-------------+ +| Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective | +|--------+---------+----------+------------------+--------------+------------------------------+----------------+-------------| +| * Best | 3/500 | 1194 | 523 654 17 | -0.12% | -0.06906927 BTC (-138.00%) | 1,559.8 m | 2.71708 | +| * Best | 6/500 | 100 | 20 0 80 | -0.07% | -0.00352831 BTC (-7.05%) | 11.5 m | 1.87067 | +| Best | 37/500 | 12 | 6 0 6 | 0.49% | 0.00294367 BTC (5.88%) | 18.2 m | 1.86009 | +| Best | 67/500 | 10 | 6 0 4 | 0.89% | 0.00443786 BTC (8.87%) | 19.5 m | 1.85245 | +| Best | 91/500 | 73 | 21 5 47 | 0.00% | 0.00007645 BTC (0.15%) | 10.2 m | 1.85215 | +| Best | 92/500 | 48 | 17 2 29 | 0.05% | 0.00116911 BTC (2.34%) | 10.4 m | 1.85189 | +| Best | 94/500 | 12 | 6 0 6 | 0.69% | 0.00416071 BTC (8.31%) | 17.8 m | 1.85143 | +| Best | 110/500 | 18 | 6 1 11 | 0.36% | 0.00327838 BTC (6.55%) | 14.3 m | 1.85113 | +| Best | 257/500 | 48 | 16 0 32 | 0.06% | 0.00154456 BTC (3.09%) | 11.3 m | 1.8505 | +| Best | 388/500 | 74 | 23 14 37 | 0.01% | 0.00045826 BTC (0.92%) | 8.2 m | 1.84665 | + [Epoch 500 of 500 (100%)] || | [Time: 1:04:49, Elapsed Time: 1:04:49] +2021-01-31 01:14:47,851 - freqtrade.optimize.hyperopt - INFO - 500 epochs saved to '/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/hyperopt_results/hyperopt_results_2021-01-31_00-07-23.pickle'. + +Best result: + + 388/500: 74 trades. 23/14/37 Wins/Draws/Losses. Avg profit 0.01%. Median profit -0.02%. Total profit 0.00045826 BTC ( 0.92Σ%). Avg duration 8.2 min. Objective: 1.84665 + + + # Buy hyperspace params: + buy_params = { + 'angle-enabled': False, + 'macd-enabled': False, + 'macd_value': 0.73579, + 'macdhist_shift': 0.87895, + 'macdhist_value': 0.29935, + 'sar-enabled': False, + 'sar_ratio': 0.43819, + 'sar_shift': 0.98992, + 'trigger': 'sell-macd_cross_signal' + } + + # Sell hyperspace params: + sell_params = { + 'angle_h_s': 0.07105, + 'macd_value_s': 0.08408, + 'macdhist_shift_s': -0.72567, + 'macdhist_value_s': 0.77324, + 'sar_ratio_s': 0.58347, + 'sar_shift_s': 0.81212, + 'sell-angle-enabled': True, + 'sell-macd-enabled': False, + 'sell-sar-enabled': False, + 'sell-uo-enabled': True, + 'trigger': 'sell-macd_cross_signal', + 'uo_l_s': 14 + } + + # ROI table: + minimal_roi = { + "0": 0.07193, + "3": 0.0382, + "5": 0.01183, + "7": 0 + } + + # Stoploss: + stoploss = -0.25471 + + # Trailing stop: + trailing_stop = True + trailing_stop_positive = 0.04697 + trailing_stop_positive_offset = 0.05329 + trailing_only_offset_is_reached = True + +""" \ No newline at end of file diff --git a/.env/bin/uvicorn b/.env/bin/uvicorn new file mode 100755 index 000000000..1e2fdea80 --- /dev/null +++ b/.env/bin/uvicorn @@ -0,0 +1,8 @@ +#!/home/yakov/PycharmProjects/freqtrade/.env/bin/python3.8 +# -*- coding: utf-8 -*- +import re +import sys +from uvicorn.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.gitignore b/.gitignore index 4720ff5cb..86fa457ce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,10 @@ config*.json *.sqlite logfile.txt -user_data/* -!user_data/strategy/sample_strategy.py -!user_data/notebooks -user_data/notebooks/* +freqtrade/user_data/* +!freqtrade/user_data/strategy/sample_strategy.py +!freqtrade/user_data/notebooks +freqtrade/user_data/notebooks/* freqtrade-plot.html freqtrade-profit-plot.html freqtrade/rpc/api_server/ui/* diff --git a/extract_features.py b/extract_features.py new file mode 100644 index 000000000..ce9133451 --- /dev/null +++ b/extract_features.py @@ -0,0 +1,8 @@ +from pandas import read_csv +from tsfresh import extract_relevant_features + + +dataframe = read_csv('/home/yakov/PycharmProjects/freqtrade/.env/bin/eth_1h_safe_features.csv').reset_index().dropna() +features_filtered_direct = extract_relevant_features(dataframe, dataframe['close'], + column_id='index', column_sort='date') +print(features_filtered_direct) \ No newline at end of file diff --git a/freqtrade/hyperopts/sample_hyperopt.py b/freqtrade/hyperopts/sample_hyperopt.py new file mode 100644 index 000000000..10743e911 --- /dev/null +++ b/freqtrade/hyperopts/sample_hyperopt.py @@ -0,0 +1,208 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file + +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class SampleHyperOpt(IHyperOpt): + """ + This is a sample Hyperopt to inspire you. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Rename the class name to some unique name. + - Add any methods you want to build your hyperopt. + - Add any lib you need to build your hyperopt. + + An easier way to get a new hyperopt file is by using + `freqtrade new-hyperopt --hyperopt MyCoolHyperopt`. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. + """ + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by Hyperopt. + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if 'mfi-enabled' in params and params['mfi-enabled']: + conditions.append(dataframe['mfi'] < params['mfi-value']) + if 'fastd-enabled' in params and params['fastd-enabled']: + conditions.append(dataframe['fastd'] < params['fastd-value']) + if 'adx-enabled' in params and params['adx-enabled']: + conditions.append(dataframe['adx'] > params['adx-value']) + if 'rsi-enabled' in params and params['rsi-enabled']: + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'bb_lower': + conditions.append(dataframe['close'] < dataframe['bb_lowerband']) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['sar'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching buy strategy parameters. + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by Hyperopt. + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use. + """ + conditions = [] + + # GUARDS AND TRENDS + if 'sell-mfi-enabled' in params and params['sell-mfi-enabled']: + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if 'sell-fastd-enabled' in params and params['sell-fastd-enabled']: + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if 'sell-adx-enabled' in params and params['sell-adx-enabled']: + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if 'sell-rsi-enabled' in params and params['sell-rsi-enabled']: + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters. + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. Should be a copy of same method from strategy. + Must align to populate_indicators in this file. + Only used when --spaces does not include buy space. + """ + dataframe.loc[ + ( + (dataframe['close'] < dataframe['bb_lowerband']) & + (dataframe['mfi'] < 16) & + (dataframe['adx'] > 25) & + (dataframe['rsi'] < 21) + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. Should be a copy of same method from strategy. + Must align to populate_indicators in this file. + Only used when --spaces does not include sell space. + """ + dataframe.loc[ + ( + (qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) & + (dataframe['fastd'] > 54) + ), + 'sell'] = 1 + + return dataframe diff --git a/freqtrade/hyperopts/sample_hyperopt_advanced.py b/freqtrade/hyperopts/sample_hyperopt_advanced.py new file mode 100644 index 000000000..52e397466 --- /dev/null +++ b/freqtrade/hyperopts/sample_hyperopt_advanced.py @@ -0,0 +1,306 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +from functools import reduce +from typing import Any, Callable, Dict, List + +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame +from skopt.space import Categorical, Dimension, Integer, Real # noqa + +from freqtrade.optimize.hyperopt_interface import IHyperOpt + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta # noqa +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +class AdvancedSampleHyperOpt(IHyperOpt): + """ + This is a sample hyperopt to inspire you. + Feel free to customize it. + + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ + + You should: + - Rename the class name to some unique name. + - Add any methods you want to build your hyperopt. + - Add any lib you need to build your hyperopt. + + You must keep: + - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. + + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need the + 'roi' and the 'stoploss' spaces that differ from the defaults offered by Freqtrade. + + This sample illustrates how to override these methods. + """ + @staticmethod + def populate_indicators(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + This method can also be loaded from the strategy, if it doesn't exist in the hyperopt class. + """ + dataframe['adx'] = ta.ADX(dataframe) + macd = ta.MACD(dataframe) + dataframe['macd'] = macd['macd'] + dataframe['macdsignal'] = macd['macdsignal'] + dataframe['mfi'] = ta.MFI(dataframe) + dataframe['rsi'] = ta.RSI(dataframe) + stoch_fast = ta.STOCHF(dataframe) + dataframe['fastd'] = stoch_fast['fastd'] + dataframe['minus_di'] = ta.MINUS_DI(dataframe) + # Bollinger bands + bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) + dataframe['bb_lowerband'] = bollinger['lower'] + dataframe['bb_upperband'] = bollinger['upper'] + dataframe['sar'] = ta.SAR(dataframe) + return dataframe + + @staticmethod + def buy_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the buy strategy parameters to be used by hyperopt + """ + def populate_buy_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Buy strategy Hyperopt will build and use + """ + conditions = [] + # GUARDS AND TRENDS + if 'mfi-enabled' in params and params['mfi-enabled']: + conditions.append(dataframe['mfi'] < params['mfi-value']) + if 'fastd-enabled' in params and params['fastd-enabled']: + conditions.append(dataframe['fastd'] < params['fastd-value']) + if 'adx-enabled' in params and params['adx-enabled']: + conditions.append(dataframe['adx'] > params['adx-value']) + if 'rsi-enabled' in params and params['rsi-enabled']: + conditions.append(dataframe['rsi'] < params['rsi-value']) + + # TRIGGERS + if 'trigger' in params: + if params['trigger'] == 'bb_lower': + conditions.append(dataframe['close'] < dataframe['bb_lowerband']) + if params['trigger'] == 'macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macd'], dataframe['macdsignal'] + )) + if params['trigger'] == 'sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['close'], dataframe['sar'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'buy'] = 1 + + return dataframe + + return populate_buy_trend + + @staticmethod + def indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching strategy parameters + """ + return [ + Integer(10, 25, name='mfi-value'), + Integer(15, 45, name='fastd-value'), + Integer(20, 50, name='adx-value'), + Integer(20, 40, name='rsi-value'), + Categorical([True, False], name='mfi-enabled'), + Categorical([True, False], name='fastd-enabled'), + Categorical([True, False], name='adx-enabled'), + Categorical([True, False], name='rsi-enabled'), + Categorical(['bb_lower', 'macd_cross_signal', 'sar_reversal'], name='trigger') + ] + + @staticmethod + def sell_strategy_generator(params: Dict[str, Any]) -> Callable: + """ + Define the sell strategy parameters to be used by hyperopt + """ + def populate_sell_trend(dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Sell strategy Hyperopt will build and use + """ + # print(params) + conditions = [] + # GUARDS AND TRENDS + if 'sell-mfi-enabled' in params and params['sell-mfi-enabled']: + conditions.append(dataframe['mfi'] > params['sell-mfi-value']) + if 'sell-fastd-enabled' in params and params['sell-fastd-enabled']: + conditions.append(dataframe['fastd'] > params['sell-fastd-value']) + if 'sell-adx-enabled' in params and params['sell-adx-enabled']: + conditions.append(dataframe['adx'] < params['sell-adx-value']) + if 'sell-rsi-enabled' in params and params['sell-rsi-enabled']: + conditions.append(dataframe['rsi'] > params['sell-rsi-value']) + + # TRIGGERS + if 'sell-trigger' in params: + if params['sell-trigger'] == 'sell-bb_upper': + conditions.append(dataframe['close'] > dataframe['bb_upperband']) + if params['sell-trigger'] == 'sell-macd_cross_signal': + conditions.append(qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) + if params['sell-trigger'] == 'sell-sar_reversal': + conditions.append(qtpylib.crossed_above( + dataframe['sar'], dataframe['close'] + )) + + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + + if conditions: + dataframe.loc[ + reduce(lambda x, y: x & y, conditions), + 'sell'] = 1 + + return dataframe + + return populate_sell_trend + + @staticmethod + def sell_indicator_space() -> List[Dimension]: + """ + Define your Hyperopt space for searching sell strategy parameters + """ + return [ + Integer(75, 100, name='sell-mfi-value'), + Integer(50, 100, name='sell-fastd-value'), + Integer(50, 100, name='sell-adx-value'), + Integer(60, 100, name='sell-rsi-value'), + Categorical([True, False], name='sell-mfi-enabled'), + Categorical([True, False], name='sell-fastd-enabled'), + Categorical([True, False], name='sell-adx-enabled'), + Categorical([True, False], name='sell-rsi-enabled'), + Categorical(['sell-bb_upper', + 'sell-macd_cross_signal', + 'sell-sar_reversal'], name='sell-trigger') + ] + + @staticmethod + def generate_roi_table(params: Dict) -> Dict[int, float]: + """ + Generate the ROI table that will be used by Hyperopt + + This implementation generates the default legacy Freqtrade ROI tables. + + Change it if you need different number of steps in the generated + ROI tables or other structure of the ROI tables. + + Please keep it aligned with parameters in the 'roi' optimization + hyperspace defined by the roi_space method. + """ + roi_table = {} + roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3'] + roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2'] + roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1'] + roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0 + + return roi_table + + @staticmethod + def roi_space() -> List[Dimension]: + """ + Values to search for each ROI steps + + Override it if you need some different ranges for the parameters in the + 'roi' optimization hyperspace. + + Please keep it aligned with the implementation of the + generate_roi_table method. + """ + return [ + Integer(10, 120, name='roi_t1'), + Integer(10, 60, name='roi_t2'), + Integer(10, 40, name='roi_t3'), + Real(0.01, 0.04, name='roi_p1'), + Real(0.01, 0.07, name='roi_p2'), + Real(0.01, 0.20, name='roi_p3'), + ] + + @staticmethod + def stoploss_space() -> List[Dimension]: + """ + Stoploss Value to search + + Override it if you need some different range for the parameter in the + 'stoploss' optimization hyperspace. + """ + return [ + Real(-0.35, -0.02, name='stoploss'), + ] + + @staticmethod + def trailing_space() -> List[Dimension]: + """ + Create a trailing stoploss space. + + You may override it in your custom Hyperopt class. + """ + return [ + # It was decided to always set trailing_stop is to True if the 'trailing' hyperspace + # is used. Otherwise hyperopt will vary other parameters that won't have effect if + # trailing_stop is set False. + # This parameter is included into the hyperspace dimensions rather than assigning + # it explicitly in the code in order to have it printed in the results along with + # other 'trailing' hyperspace parameters. + Categorical([True], name='trailing_stop'), + + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + + Categorical([True, False], name='trailing_only_offset_is_reached'), + ] + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. + Can be a copy of the corresponding method from the strategy, + or will be loaded from the strategy. + Must align to populate_indicators used (either from this File, or from the strategy) + Only used when --spaces does not include buy + """ + dataframe.loc[ + ( + (dataframe['close'] < dataframe['bb_lowerband']) & + (dataframe['mfi'] < 16) & + (dataframe['adx'] > 25) & + (dataframe['rsi'] < 21) + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators. + Can be a copy of the corresponding method from the strategy, + or will be loaded from the strategy. + Must align to populate_indicators used (either from this File, or from the strategy) + Only used when --spaces does not include sell + """ + dataframe.loc[ + ( + (qtpylib.crossed_above( + dataframe['macdsignal'], dataframe['macd'] + )) & + (dataframe['fastd'] > 54) + ), + 'sell'] = 1 + return dataframe diff --git a/freqtrade/hyperopts/sample_hyperopt_loss.py b/freqtrade/hyperopts/sample_hyperopt_loss.py new file mode 100644 index 000000000..a2b28f948 --- /dev/null +++ b/freqtrade/hyperopts/sample_hyperopt_loss.py @@ -0,0 +1,49 @@ +from datetime import datetime +from math import exp + +from pandas import DataFrame + +from freqtrade.optimize.hyperopt import IHyperOptLoss + + +# Define some constants: + +# set TARGET_TRADES to suit your number concurrent trades so its realistic +# to the number of days +TARGET_TRADES = 600 +# This is assumed to be expected avg profit * expected trade count. +# For example, for 0.35% avg per trade (or 0.0035 as ratio) and 1100 trades, +# self.expected_max_profit = 3.85 +# Check that the reported Σ% values do not exceed this! +# Note, this is ratio. 3.85 stated above means 385Σ%. +EXPECTED_MAX_PROFIT = 3.0 + +# max average trade duration in minutes +# if eval ends with higher value, we consider it a failed eval +MAX_ACCEPTED_TRADE_DURATION = 300 + + +class SampleHyperOptLoss(IHyperOptLoss): + """ + Defines the default loss function for hyperopt + This is intended to give you some inspiration for your own loss function. + + The Function needs to return a number (float) - which becomes smaller for better backtest + results. + """ + + @staticmethod + def hyperopt_loss_function(results: DataFrame, trade_count: int, + min_date: datetime, max_date: datetime, + *args, **kwargs) -> float: + """ + Objective function, returns smaller number for better results + """ + total_profit = results['profit_ratio'].sum() + trade_duration = results['trade_duration'].mean() + + trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8) + profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT) + duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1) + result = trade_loss + profit_loss + duration_loss + return result diff --git a/freqtrade/notebooks/strategy_analysis_example.ipynb b/freqtrade/notebooks/strategy_analysis_example.ipynb new file mode 100644 index 000000000..c6e64c74e --- /dev/null +++ b/freqtrade/notebooks/strategy_analysis_example.ipynb @@ -0,0 +1,360 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Strategy analysis example\n", + "\n", + "Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data.\n", + "The following assumes you work with SampleStrategy, data for 5m timeframe from Binance and have downloaded them into the data directory in the default location." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from freqtrade.configuration import Configuration\n", + "\n", + "# Customize these according to your needs.\n", + "\n", + "# Initialize empty configuration object\n", + "config = Configuration.from_files([])\n", + "# Optionally, use existing configuration file\n", + "# config = Configuration.from_files([\"config.json\"])\n", + "\n", + "# Define some constants\n", + "config[\"timeframe\"] = \"5m\"\n", + "# Name of the strategy class\n", + "config[\"strategy\"] = \"SampleStrategy\"\n", + "# Location of the data\n", + "data_location = Path(config['user_data_dir'], 'data', 'binance')\n", + "# Pair to analyze - Only use one pair here\n", + "pair = \"BTC_USDT\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load data using values set above\n", + "from freqtrade.data.history import load_pair_history\n", + "\n", + "candles = load_pair_history(datadir=data_location,\n", + " timeframe=config[\"timeframe\"],\n", + " pair=pair)\n", + "\n", + "# Confirm success\n", + "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {data_location}\")\n", + "candles.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load and run strategy\n", + "* Rerun each time the strategy file is changed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load strategy using values set above\n", + "from freqtrade.resolvers import StrategyResolver\n", + "strategy = StrategyResolver.load_strategy(config)\n", + "\n", + "# Generate buy/sell signals using strategy\n", + "df = strategy.analyze_ticker(candles, {'pair': pair})\n", + "df.tail()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Display the trade details\n", + "\n", + "* Note that using `data.head()` would also work, however most indicators have some \"startup\" data at the top of the dataframe.\n", + "* Some possible problems\n", + " * Columns with NaN values at the end of the dataframe\n", + " * Columns used in `crossed*()` functions with completely different units\n", + "* Comparison with full backtest\n", + " * having 200 buy signals as output for one pair from `analyze_ticker()` does not necessarily mean that 200 trades will be made during backtesting.\n", + " * Assuming you use only one condition such as, `df['rsi'] < 30` as buy condition, this will generate multiple \"buy\" signals for each pair in sequence (until rsi returns > 29). The bot will only buy on the first of these signals (and also only if a trade-slot (\"max_open_trades\") is still available), or on one of the middle signals, as soon as a \"slot\" becomes available. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Report results\n", + "print(f\"Generated {df['buy'].sum()} buy signals\")\n", + "data = df.set_index('date', drop=False)\n", + "data.tail()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load existing objects into a Jupyter notebook\n", + "\n", + "The following cells assume that you have already generated data using the cli. \n", + "They will allow you to drill deeper into your results, and perform analysis which otherwise would make the output very difficult to digest due to information overload." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load backtest results to pandas dataframe\n", + "\n", + "Analyze a trades dataframe (also used below for plotting)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats\n", + "\n", + "# if backtest_dir points to a directory, it'll automatically load the last backtest file.\n", + "backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n", + "# backtest_dir can also point to a specific file \n", + "# backtest_dir = config[\"user_data_dir\"] / \"backtest_results/backtest-result-2020-07-01_20-04-22.json\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# You can get the full backtest statistics by using the following command.\n", + "# This contains all information used to generate the backtest result.\n", + "stats = load_backtest_stats(backtest_dir)\n", + "\n", + "strategy = 'SampleStrategy'\n", + "# All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well.\n", + "# Example usages:\n", + "print(stats['strategy'][strategy]['results_per_pair'])\n", + "# Get pairlist used for this backtest\n", + "print(stats['strategy'][strategy]['pairlist'])\n", + "# Get market change (average change of all pairs from start to end of the backtest period)\n", + "print(stats['strategy'][strategy]['market_change'])\n", + "# Maximum drawdown ()\n", + "print(stats['strategy'][strategy]['max_drawdown'])\n", + "# Maximum drawdown start and end\n", + "print(stats['strategy'][strategy]['drawdown_start'])\n", + "print(stats['strategy'][strategy]['drawdown_end'])\n", + "\n", + "\n", + "# Get strategy comparison (only relevant if multiple strategies were compared)\n", + "print(stats['strategy_comparison'])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load backtested trades as dataframe\n", + "trades = load_backtest_data(backtest_dir)\n", + "\n", + "# Show value-counts per pair\n", + "trades.groupby(\"pair\")[\"sell_reason\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load live trading results into a pandas dataframe\n", + "\n", + "In case you did already some trading and want to analyze your performance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from freqtrade.data.btanalysis import load_trades_from_db\n", + "\n", + "# Fetch trades from database\n", + "trades = load_trades_from_db(\"sqlite:///tradesv3.sqlite\")\n", + "\n", + "# Display results\n", + "trades.groupby(\"pair\")[\"sell_reason\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Analyze the loaded trades for trade parallelism\n", + "This can be useful to find the best `max_open_trades` parameter, when used with backtesting in conjunction with `--disable-max-market-positions`.\n", + "\n", + "`analyze_trade_parallelism()` returns a timeseries dataframe with an \"open_trades\" column, specifying the number of open trades for each candle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from freqtrade.data.btanalysis import analyze_trade_parallelism\n", + "\n", + "# Analyze the above\n", + "parallel_trades = analyze_trade_parallelism(trades, '5m')\n", + "\n", + "parallel_trades.plot()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plot results\n", + "\n", + "Freqtrade offers interactive plotting capabilities based on plotly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from freqtrade.plot.plotting import generate_candlestick_graph\n", + "# Limit graph period to keep plotly quick and reactive\n", + "\n", + "# Filter trades to one pair\n", + "trades_red = trades.loc[trades['pair'] == pair]\n", + "\n", + "data_red = data['2019-06-01':'2019-06-10']\n", + "# Generate candlestick graph\n", + "graph = generate_candlestick_graph(pair=pair,\n", + " data=data_red,\n", + " trades=trades_red,\n", + " indicators1=['sma20', 'ema50', 'ema55'],\n", + " indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']\n", + " )\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Show graph inline\n", + "# graph.show()\n", + "\n", + "# Render graph in a seperate window\n", + "graph.show(renderer=\"browser\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data." + ] + } + ], + "metadata": { + "file_extension": ".py", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "mimetype": "text/x-python", + "name": "python", + "npconvert_exporter": "python", + "pygments_lexer": "ipython3", + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + }, + "version": 3 + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 4325e537e..2670e4215 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -179,6 +179,8 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: # Create description for sell summarizing the trade trades['desc'] = trades.apply(lambda row: f"{round(row['profit_ratio'] * 100, 1)}%, " f"{row['sell_reason']}, " + f"open:{row['open_date']}, " + f"close:{row['close_date']}, " f"{row['trade_duration']} min", axis=1) trade_buys = go.Scatter( diff --git a/freqtrade/strategies/sample_strategy.py b/freqtrade/strategies/sample_strategy.py new file mode 100644 index 000000000..b3f9fef07 --- /dev/null +++ b/freqtrade/strategies/sample_strategy.py @@ -0,0 +1,366 @@ +# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement +# isort: skip_file +# --- Do not remove these libs --- +import numpy as np # noqa +import pandas as pd # noqa +from pandas import DataFrame + +from freqtrade.strategy.interface import IStrategy + +# -------------------------------- +# Add your lib to import here +import talib.abstract as ta +import freqtrade.vendor.qtpylib.indicators as qtpylib + + +# This class is a sample. Feel free to customize it. +class SampleStrategy(IStrategy): + """ + This is a sample strategy to inspire you. + More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md + + You can: + :return: a Dataframe with all mandatory indicators for the strategies + - Rename the class name (Do not forget to update class_name) + - Add any methods you want to build your strategy + - Add any lib you need to build your strategy + + You must keep: + - the lib in the section "Do not remove these libs" + - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, + populate_sell_trend, hyperopt_space, buy_strategy_generator + """ + # Strategy interface version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + INTERFACE_VERSION = 2 + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi". + minimal_roi = { + "60": 0.01, + "30": 0.02, + "0": 0.04 + } + + # Optimal stoploss designed for the strategy. + # This attribute will be overridden if the config file contains "stoploss". + stoploss = -0.10 + + # Trailing stoploss + trailing_stop = False + # trailing_only_offset_is_reached = False + # trailing_stop_positive = 0.01 + # trailing_stop_positive_offset = 0.0 # Disabled / not configured + + # Optimal ticker interval for the strategy. + timeframe = '5m' + + # Run "populate_indicators()" only for new candle. + process_only_new_candles = False + + # These values can be overridden in the "ask_strategy" section in the config. + use_sell_signal = True + sell_profit_only = False + ignore_roi_if_buy_signal = False + + # Number of candles the strategy requires before producing valid signals + startup_candle_count: int = 30 + + # Optional order type mapping. + order_types = { + 'buy': 'limit', + 'sell': 'limit', + 'stoploss': 'market', + 'stoploss_on_exchange': False + } + + # Optional order time in force. + order_time_in_force = { + 'buy': 'gtc', + 'sell': 'gtc' + } + + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + + def informative_pairs(self): + """ + Define additional, informative pair/interval combinations to be cached from the exchange. + These pair/interval combinations are non-tradeable, unless they are part + of the whitelist as well. + For more information, please consult the documentation + :return: List of tuples in the format (pair, interval) + Sample: return [("ETH/USDT", "5m"), + ("BTC/USDT", "15m"), + ] + """ + return [] + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Adds several different TA indicators to the given DataFrame + + Performance Note: For the best performance be frugal on the number of indicators + you are using. Let uncomment only the indicator you are using in your strategies + or your hyperopt configuration, otherwise you will waste your memory and CPU usage. + :param dataframe: Dataframe with data from the exchange + :param metadata: Additional information, like the currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + + # Momentum Indicators + # ------------------------------------ + + # ADX + dataframe['adx'] = ta.ADX(dataframe) + + # # Plus Directional Indicator / Movement + # dataframe['plus_dm'] = ta.PLUS_DM(dataframe) + # dataframe['plus_di'] = ta.PLUS_DI(dataframe) + + # # Minus Directional Indicator / Movement + # dataframe['minus_dm'] = ta.MINUS_DM(dataframe) + # dataframe['minus_di'] = ta.MINUS_DI(dataframe) + + # # Aroon, Aroon Oscillator + # aroon = ta.AROON(dataframe) + # dataframe['aroonup'] = aroon['aroonup'] + # dataframe['aroondown'] = aroon['aroondown'] + # dataframe['aroonosc'] = ta.AROONOSC(dataframe) + + # # Awesome Oscillator + # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) + + # # Keltner Channel + # keltner = qtpylib.keltner_channel(dataframe) + # dataframe["kc_upperband"] = keltner["upper"] + # dataframe["kc_lowerband"] = keltner["lower"] + # dataframe["kc_middleband"] = keltner["mid"] + # dataframe["kc_percent"] = ( + # (dataframe["close"] - dataframe["kc_lowerband"]) / + # (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) + # ) + # dataframe["kc_width"] = ( + # (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) / dataframe["kc_middleband"] + # ) + + # # Ultimate Oscillator + # dataframe['uo'] = ta.ULTOSC(dataframe) + + # # Commodity Channel Index: values [Oversold:-100, Overbought:100] + # dataframe['cci'] = ta.CCI(dataframe) + + # RSI + dataframe['rsi'] = ta.RSI(dataframe) + + # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy) + # rsi = 0.1 * (dataframe['rsi'] - 50) + # dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) + + # # Inverse Fisher transform on RSI normalized: values [0.0, 100.0] (https://goo.gl/2JGGoy) + # dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1) + + # # Stochastic Slow + # stoch = ta.STOCH(dataframe) + # dataframe['slowd'] = stoch['slowd'] + # dataframe['slowk'] = stoch['slowk'] + + # Stochastic Fast + stoch_fast = ta.STOCHF(dataframe) + dataframe['fastd'] = stoch_fast['fastd'] + dataframe['fastk'] = stoch_fast['fastk'] + + # # Stochastic RSI + # Please read https://github.com/freqtrade/freqtrade/issues/2961 before using this. + # STOCHRSI is NOT aligned with tradingview, which may result in non-expected results. + # stoch_rsi = ta.STOCHRSI(dataframe) + # dataframe['fastd_rsi'] = stoch_rsi['fastd'] + # dataframe['fastk_rsi'] = stoch_rsi['fastk'] + + # MACD + macd = ta.MACD(dataframe) + dataframe['macd'] = macd['macd'] + dataframe['macdsignal'] = macd['macdsignal'] + dataframe['macdhist'] = macd['macdhist'] + + # MFI + dataframe['mfi'] = ta.MFI(dataframe) + + # # ROC + # dataframe['roc'] = ta.ROC(dataframe) + + # Overlap Studies + # ------------------------------------ + + # Bollinger Bands + bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) + dataframe['bb_lowerband'] = bollinger['lower'] + dataframe['bb_middleband'] = bollinger['mid'] + dataframe['bb_upperband'] = bollinger['upper'] + dataframe["bb_percent"] = ( + (dataframe["close"] - dataframe["bb_lowerband"]) / + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) + ) + dataframe["bb_width"] = ( + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] + ) + + # Bollinger Bands - Weighted (EMA based instead of SMA) + # weighted_bollinger = qtpylib.weighted_bollinger_bands( + # qtpylib.typical_price(dataframe), window=20, stds=2 + # ) + # dataframe["wbb_upperband"] = weighted_bollinger["upper"] + # dataframe["wbb_lowerband"] = weighted_bollinger["lower"] + # dataframe["wbb_middleband"] = weighted_bollinger["mid"] + # dataframe["wbb_percent"] = ( + # (dataframe["close"] - dataframe["wbb_lowerband"]) / + # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) + # ) + # dataframe["wbb_width"] = ( + # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) / + # dataframe["wbb_middleband"] + # ) + + # # EMA - Exponential Moving Average + # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3) + # dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) + # dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) + # dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21) + # dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) + # dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) + + # # SMA - Simple Moving Average + # dataframe['sma3'] = ta.SMA(dataframe, timeperiod=3) + # dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5) + # dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10) + # dataframe['sma21'] = ta.SMA(dataframe, timeperiod=21) + # dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50) + # dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) + + # Parabolic SAR + dataframe['sar'] = ta.SAR(dataframe) + + # TEMA - Triple Exponential Moving Average + dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + + # Cycle Indicator + # ------------------------------------ + # Hilbert Transform Indicator - SineWave + hilbert = ta.HT_SINE(dataframe) + dataframe['htsine'] = hilbert['sine'] + dataframe['htleadsine'] = hilbert['leadsine'] + + # Pattern Recognition - Bullish candlestick patterns + # ------------------------------------ + # # Hammer: values [0, 100] + # dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe) + # # Inverted Hammer: values [0, 100] + # dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe) + # # Dragonfly Doji: values [0, 100] + # dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe) + # # Piercing Line: values [0, 100] + # dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe) # values [0, 100] + # # Morningstar: values [0, 100] + # dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe) # values [0, 100] + # # Three White Soldiers: values [0, 100] + # dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe) # values [0, 100] + + # Pattern Recognition - Bearish candlestick patterns + # ------------------------------------ + # # Hanging Man: values [0, 100] + # dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe) + # # Shooting Star: values [0, 100] + # dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe) + # # Gravestone Doji: values [0, 100] + # dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe) + # # Dark Cloud Cover: values [0, 100] + # dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe) + # # Evening Doji Star: values [0, 100] + # dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe) + # # Evening Star: values [0, 100] + # dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe) + + # Pattern Recognition - Bullish/Bearish candlestick patterns + # ------------------------------------ + # # Three Line Strike: values [0, -100, 100] + # dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe) + # # Spinning Top: values [0, -100, 100] + # dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe) # values [0, -100, 100] + # # Engulfing: values [0, -100, 100] + # dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe) # values [0, -100, 100] + # # Harami: values [0, -100, 100] + # dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe) # values [0, -100, 100] + # # Three Outside Up/Down: values [0, -100, 100] + # dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe) # values [0, -100, 100] + # # Three Inside Up/Down: values [0, -100, 100] + # dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe) # values [0, -100, 100] + + # # Chart type + # # ------------------------------------ + # # Heikin Ashi Strategy + # heikinashi = qtpylib.heikinashi(dataframe) + # dataframe['ha_open'] = heikinashi['open'] + # dataframe['ha_close'] = heikinashi['close'] + # dataframe['ha_high'] = heikinashi['high'] + # dataframe['ha_low'] = heikinashi['low'] + + # Retrieve best bid and best ask from the orderbook + # ------------------------------------ + """ + # first check if dataprovider is available + if self.dp: + if self.dp.runmode in ('live', 'dry_run'): + ob = self.dp.orderbook(metadata['pair'], 1) + dataframe['best_bid'] = ob['bids'][0][0] + dataframe['best_ask'] = ob['asks'][0][0] + """ + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30 + (dataframe['tema'] <= dataframe['bb_middleband']) & # Guard: tema below BB middle + (dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame populated with indicators + :param metadata: Additional information, like the currently traded pair + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70 + (dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle + (dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling + (dataframe['volume'] > 0) # Make sure Volume is not 0 + ), + 'sell'] = 1 + return dataframe diff --git a/freqtrade/user_data/backtest_results/.gitkeep b/freqtrade/user_data/backtest_results/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/user_data/data/.gitkeep b/freqtrade/user_data/data/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/user_data/hyperopts/.gitkeep b/freqtrade/user_data/hyperopts/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/user_data/logs/.gitkeep b/freqtrade/user_data/logs/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/user_data/notebooks/.gitkeep b/freqtrade/user_data/notebooks/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/user_data/strategies/.gitkeep b/freqtrade/user_data/strategies/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/hyper_parser.py b/hyper_parser.py new file mode 100644 index 000000000..6be6bd79f --- /dev/null +++ b/hyper_parser.py @@ -0,0 +1,15 @@ +import ast + + +class HyperParser(ast.NodeTransformer): + def __init__(self, obj, *args, **kwargs): + super().__init__(*args, **kwargs) + self.obj = obj + + @property + def class_def(self): + return [cl.body for cl in self.obj.body if isinstance(cl, ast.ClassDef)][0] + + @property + def indicators(self): + return [ind for ind in self.class_def] \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 000000000..0199c452f --- /dev/null +++ b/utils.py @@ -0,0 +1,92 @@ + +import sqlite3 + +import pandas as pd + + +#Pivot Points, Supports and Resistances +def PPSR(df): + PP = pd.Series((df['high'] + df['low'] + df['close']) / 3) + R1 = pd.Series(2 * PP - df['low']) + S1 = pd.Series(2 * PP - df['high']) + R2 = pd.Series(PP + df['high'] - df['low']) + S2 = pd.Series(PP - df['high'] + df['low']) + R3 = pd.Series(df['high'] + 2 * (PP - df['low'])) + S3 = pd.Series(df['low'] - 2 * (df['high'] - PP)) + psr = {'PP':PP, 'R1':R1, 'S1':S1, 'R2':R2, 'S2':S2, 'R3':R3, 'S3':S3} + PSR = pd.DataFrame(psr) + df = df.join(PSR) + return df + +#Camarilla Pivot Points +def camarilla_pp(df): + PP = pd.Series((df['high'] + df['low'] + df['close']) / 3) + R1 = pd.Series(2 * PP - df['low']) + S1 = pd.Series(2 * PP - df['high']) + R2 = pd.Series(PP + df['high'] - df['low']) + S2 = pd.Series(PP - df['high'] + df['low']) + R3 = pd.Series(df['high'] + 2 * (PP - df['low'])) + S3 = pd.Series(df['low'] - 2 * (df['high'] - PP)) + psr = {'PP':PP, 'R1':R1, 'S1':S1, 'R2':R2, 'S2':S2, 'R3':R3, 'S3':S3} + PSR = pd.DataFrame(psr) + df = df.join(PSR) + return df + + +def get_best_run_by_total_profit(pkl_path): + df = pd.read_pickle(pkl_path) + + total_profit = 0 + i = 0 + best = None + for res in df: + i += 1 + if res['loss'] >= 5: + continue + if total_profit < res['results_metrics']['total_profit']: + total_profit = res['results_metrics']['total_profit'] + if res['results_metrics']['trade_count'] < 100: + continue + best = res + return best + +def get_best_from_pkl(pkl_path): + df = pd.read_pickle(pkl_path) + return [strg for strg in df if strg['is_best']][0] + + +def get_most_trades(pkl_path): + # "/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/hyperopt_results/hyperopt_results_2021-01-30_13-15-48.pickle" + + df = pd.read_pickle(pkl_path) + + total_trades = 0 + i = 0 + best = None + for res in df: + i += 1 + if res['loss'] >= 5: + continue + if res['results_metrics']['trade_count'] < 100: + continue + if total_trades < res['results_metrics']['trade_count']: + total_trades = res['results_metrics']['trade_count'] + + best = res + return best + + +def get_trade_from_db(): + # Read sqlite query results into a pandas DataFrame + con = sqlite3.connect("/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/ethusdt_19022020.sqlite") + df = pd.read_sql_query("SELECT * from trades", con) + # Verify that result of SQL query is stored in the dataframe + con.close() + + + + + +b = get_best_run_by_total_profit( + pkl_path="/home/yakov/PycharmProjects/freqtrade/.env/bin/user_data/hyperopt_results/ethusdt2_safe_sharpe_2021-02-28_20-54-24.pickle") +print(b) \ No newline at end of file