freqtrade_origin/en/2024.7.1/freqai-configuration/index.html

2371 lines
104 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Freqtrade is a free and open source crypto trading bot written in Python, designed to support all major exchanges and be controlled via Telegram or builtin Web UI">
<link rel="canonical" href="https://www.freqtrade.io/en/latest/2024.7.1/freqai-configuration/">
<link rel="prev" href="../freqai/">
<link rel="next" href="../freqai-parameter-table/">
<link rel="icon" href="../images/logo.png">
<meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.29">
<title>Configuration - Freqtrade</title>
<link rel="stylesheet" href="../assets/stylesheets/main.76a95c52.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../stylesheets/ft.extra.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="tear">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#configuration" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Freqtrade" class="md-header__button md-logo" aria-label="Freqtrade" data-md-component="logo">
<img src="../images/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Freqtrade
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Configuration
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="tear" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6zm0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4zM7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="blue-grey" data-md-color-accent="tear" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3Z"/></svg>
</label>
</form>
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7 0-.24-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91 1.61 0 2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08Z"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/freqtrade/freqtrade" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<!-- Main navigation -->
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Freqtrade" class="md-nav__button md-logo" aria-label="Freqtrade" data-md-component="logo">
<img src="../images/logo.png" alt="logo">
</a>
Freqtrade
</label>
<div class="md-nav__source">
<a href="https://github.com/freqtrade/freqtrade" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../docker_quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quickstart with Docker
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Installation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../installation/" class="md-nav__link">
<span class="md-ellipsis">
Linux/MacOS/Raspberry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../windows_installation/" class="md-nav__link">
<span class="md-ellipsis">
Windows
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../bot-basics/" class="md-nav__link">
<span class="md-ellipsis">
Freqtrade Basics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../configuration/" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../strategy-customization/" class="md-nav__link">
<span class="md-ellipsis">
Strategy Customization
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../strategy-callbacks/" class="md-nav__link">
<span class="md-ellipsis">
Strategy Callbacks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../stoploss/" class="md-nav__link">
<span class="md-ellipsis">
Stoploss
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../plugins/" class="md-nav__link">
<span class="md-ellipsis">
Plugins
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../bot-usage/" class="md-nav__link">
<span class="md-ellipsis">
Start the bot
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
<label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="0">
<span class="md-ellipsis">
Control the bot
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_11">
<span class="md-nav__icon md-icon"></span>
Control the bot
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../telegram-usage/" class="md-nav__link">
<span class="md-ellipsis">
Telegram
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../freq-ui/" class="md-nav__link">
<span class="md-ellipsis">
freqUI
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../rest-api/" class="md-nav__link">
<span class="md-ellipsis">
REST API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../webhook-config/" class="md-nav__link">
<span class="md-ellipsis">
Web Hook
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../data-download/" class="md-nav__link">
<span class="md-ellipsis">
Data Downloading
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../backtesting/" class="md-nav__link">
<span class="md-ellipsis">
Backtesting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hyperopt/" class="md-nav__link">
<span class="md-ellipsis">
Hyperopt
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_15" checked>
<label class="md-nav__link" for="__nav_15" id="__nav_15_label" tabindex="0">
<span class="md-ellipsis">
FreqAI
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_15_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_15">
<span class="md-nav__icon md-icon"></span>
FreqAI
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../freqai/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Configuration
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Configuration
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#setting-up-the-configuration-file" class="md-nav__link">
<span class="md-ellipsis">
Setting up the configuration file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#building-a-freqai-strategy" class="md-nav__link">
<span class="md-ellipsis">
Building a FreqAI strategy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#important-dataframe-key-patterns" class="md-nav__link">
<span class="md-ellipsis">
Important dataframe key patterns
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#setting-the-startup_candle_count" class="md-nav__link">
<span class="md-ellipsis">
Setting the startup_candle_count
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-dynamic-target-threshold" class="md-nav__link">
<span class="md-ellipsis">
Creating a dynamic target threshold
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-different-prediction-models" class="md-nav__link">
<span class="md-ellipsis">
Using different prediction models
</span>
</a>
<nav class="md-nav" aria-label="Using different prediction models">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#setting-model-targets" class="md-nav__link">
<span class="md-ellipsis">
Setting model targets
</span>
</a>
<nav class="md-nav" aria-label="Setting model targets">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#regressors" class="md-nav__link">
<span class="md-ellipsis">
Regressors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#classifiers" class="md-nav__link">
<span class="md-ellipsis">
Classifiers
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#pytorch-module" class="md-nav__link">
<span class="md-ellipsis">
PyTorch Module
</span>
</a>
<nav class="md-nav" aria-label="PyTorch Module">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#quick-start" class="md-nav__link">
<span class="md-ellipsis">
Quick start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#structure" class="md-nav__link">
<span class="md-ellipsis">
Structure
</span>
</a>
<nav class="md-nav" aria-label="Structure">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#model" class="md-nav__link">
<span class="md-ellipsis">
Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#trainer" class="md-nav__link">
<span class="md-ellipsis">
Trainer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#integration-with-freqai-module" class="md-nav__link">
<span class="md-ellipsis">
Integration with Freqai module
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#full-example" class="md-nav__link">
<span class="md-ellipsis">
Full example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#improving-performance-with-torchcompile" class="md-nav__link">
<span class="md-ellipsis">
Improving performance with torch.compile()
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../freqai-parameter-table/" class="md-nav__link">
<span class="md-ellipsis">
Parameter table
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../freqai-feature-engineering/" class="md-nav__link">
<span class="md-ellipsis">
Feature engineering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../freqai-running/" class="md-nav__link">
<span class="md-ellipsis">
Running FreqAI
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../freqai-reinforcement-learning/" class="md-nav__link">
<span class="md-ellipsis">
Reinforcement Learning
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../freqai-developers/" class="md-nav__link">
<span class="md-ellipsis">
Developer guide
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../leverage/" class="md-nav__link">
<span class="md-ellipsis">
Short / Leverage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../utils/" class="md-nav__link">
<span class="md-ellipsis">
Utility Sub-commands
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../plotting/" class="md-nav__link">
<span class="md-ellipsis">
Plotting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../exchanges/" class="md-nav__link">
<span class="md-ellipsis">
Exchange-specific Notes
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_20" >
<label class="md-nav__link" for="__nav_20" id="__nav_20_label" tabindex="0">
<span class="md-ellipsis">
Data Analysis
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_20_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_20">
<span class="md-nav__icon md-icon"></span>
Data Analysis
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../data-analysis/" class="md-nav__link">
<span class="md-ellipsis">
Jupyter Notebooks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../strategy_analysis_example/" class="md-nav__link">
<span class="md-ellipsis">
Strategy analysis
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../advanced-backtesting/" class="md-nav__link">
<span class="md-ellipsis">
Backtest analysis
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_21" >
<label class="md-nav__link" for="__nav_21" id="__nav_21_label" tabindex="0">
<span class="md-ellipsis">
Advanced Topics
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_21_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_21">
<span class="md-nav__icon md-icon"></span>
Advanced Topics
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../advanced-setup/" class="md-nav__link">
<span class="md-ellipsis">
Advanced Post-installation Tasks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../trade-object/" class="md-nav__link">
<span class="md-ellipsis">
Trade Object
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../lookahead-analysis/" class="md-nav__link">
<span class="md-ellipsis">
Lookahead analysis
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../recursive-analysis/" class="md-nav__link">
<span class="md-ellipsis">
Recursive analysis
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../strategy-advanced/" class="md-nav__link">
<span class="md-ellipsis">
Advanced Strategy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../advanced-hyperopt/" class="md-nav__link">
<span class="md-ellipsis">
Advanced Hyperopt
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../advanced-orderflow/" class="md-nav__link">
<span class="md-ellipsis">
Orderflow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../producer-consumer/" class="md-nav__link">
<span class="md-ellipsis">
Producer/Consumer mode
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sql_cheatsheet/" class="md-nav__link">
<span class="md-ellipsis">
SQL Cheat-sheet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../edge/" class="md-nav__link">
<span class="md-ellipsis">
Edge Positioning
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../strategy_migration/" class="md-nav__link">
<span class="md-ellipsis">
Strategy migration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../updating/" class="md-nav__link">
<span class="md-ellipsis">
Updating Freqtrade
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../deprecated/" class="md-nav__link">
<span class="md-ellipsis">
Deprecated Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../developer/" class="md-nav__link">
<span class="md-ellipsis">
Contributors Guide
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<!-- Table of contents -->
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#setting-up-the-configuration-file" class="md-nav__link">
<span class="md-ellipsis">
Setting up the configuration file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#building-a-freqai-strategy" class="md-nav__link">
<span class="md-ellipsis">
Building a FreqAI strategy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#important-dataframe-key-patterns" class="md-nav__link">
<span class="md-ellipsis">
Important dataframe key patterns
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#setting-the-startup_candle_count" class="md-nav__link">
<span class="md-ellipsis">
Setting the startup_candle_count
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-dynamic-target-threshold" class="md-nav__link">
<span class="md-ellipsis">
Creating a dynamic target threshold
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-different-prediction-models" class="md-nav__link">
<span class="md-ellipsis">
Using different prediction models
</span>
</a>
<nav class="md-nav" aria-label="Using different prediction models">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#setting-model-targets" class="md-nav__link">
<span class="md-ellipsis">
Setting model targets
</span>
</a>
<nav class="md-nav" aria-label="Setting model targets">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#regressors" class="md-nav__link">
<span class="md-ellipsis">
Regressors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#classifiers" class="md-nav__link">
<span class="md-ellipsis">
Classifiers
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#pytorch-module" class="md-nav__link">
<span class="md-ellipsis">
PyTorch Module
</span>
</a>
<nav class="md-nav" aria-label="PyTorch Module">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#quick-start" class="md-nav__link">
<span class="md-ellipsis">
Quick start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#structure" class="md-nav__link">
<span class="md-ellipsis">
Structure
</span>
</a>
<nav class="md-nav" aria-label="Structure">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#model" class="md-nav__link">
<span class="md-ellipsis">
Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#trainer" class="md-nav__link">
<span class="md-ellipsis">
Trainer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#integration-with-freqai-module" class="md-nav__link">
<span class="md-ellipsis">
Integration with Freqai module
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#full-example" class="md-nav__link">
<span class="md-ellipsis">
Full example
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#improving-performance-with-torchcompile" class="md-nav__link">
<span class="md-ellipsis">
Improving performance with torch.compile()
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">&para;</a></h1>
<p>FreqAI is configured through the typical <a href="../configuration/">Freqtrade config file</a> and the standard <a href="../strategy-customization/">Freqtrade strategy</a>. Examples of FreqAI config and strategy files can be found in <code>config_examples/config_freqai.example.json</code> and <code>freqtrade/templates/FreqaiExampleStrategy.py</code>, respectively.</p>
<h2 id="setting-up-the-configuration-file">Setting up the configuration file<a class="headerlink" href="#setting-up-the-configuration-file" title="Permanent link">&para;</a></h2>
<p>Although there are plenty of additional parameters to choose from, as highlighted in the <a href="../freqai-parameter-table/#parameter-table">parameter table</a>, a FreqAI config must at minimum include the following parameters (the parameter values are only examples):</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="nt">&quot;freqai&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;enabled&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;purge_old_models&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;train_period_days&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;backtest_period_days&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;identifier&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;unique-id&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;feature_parameters&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;include_timeframes&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;5m&quot;</span><span class="p">,</span><span class="s2">&quot;15m&quot;</span><span class="p">,</span><span class="s2">&quot;4h&quot;</span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;include_corr_pairlist&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;ETH/USD&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;LINK/USD&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;BNB/USD&quot;</span>
<span class="w"> </span><span class="p">],</span>
<span class="w"> </span><span class="nt">&quot;label_period_candles&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">24</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;include_shifted_candles&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;indicator_periods_candles&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">20</span><span class="p">]</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;data_split_parameters&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;test_size&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.25</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
</code></pre></div>
<p>A full example config is available in <code>config_examples/config_freqai.example.json</code>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The <code>identifier</code> is commonly overlooked by newcomers, however, this value plays an important role in your configuration. This value is a unique ID that you choose to describe one of your runs. Keeping it the same allows you to maintain crash resilience as well as faster backtesting. As soon as you want to try a new run (new features, new model, etc.), you should change this value (or delete the <code>user_data/models/unique-id</code> folder. More details available in the <a href="../freqai-parameter-table/#feature-parameters">parameter table</a>.</p>
</div>
<h2 id="building-a-freqai-strategy">Building a FreqAI strategy<a class="headerlink" href="#building-a-freqai-strategy" title="Permanent link">&para;</a></h2>
<p>The FreqAI strategy requires including the following lines of code in the standard <a href="../strategy-customization/">Freqtrade strategy</a>:</p>
<div class="highlight"><pre><span></span><code> <span class="c1"># user should define the maximum startup candle count (the largest number of candles</span>
<span class="c1"># passed to any single indicator)</span>
<span class="n">startup_candle_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">20</span>
<span class="k">def</span> <span class="nf">populate_indicators</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="n">metadata</span><span class="p">:</span> <span class="nb">dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="c1"># the model will return all labels created by user in `set_freqai_targets()`</span>
<span class="c1"># (&amp; appended targets), an indication of whether or not the prediction should be accepted,</span>
<span class="c1"># the target mean/std values for each of the labels created by user in</span>
<span class="c1"># `set_freqai_targets()` for each training period.</span>
<span class="n">dataframe</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">freqai</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dataframe</span>
<span class="k">def</span> <span class="nf">feature_engineering_expand_all</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="n">period</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> *Only functional with FreqAI enabled strategies*</span>
<span class="sd"> This function will automatically expand the defined features on the config defined</span>
<span class="sd"> `indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and</span>
<span class="sd"> `include_corr_pairs`. In other words, a single feature defined in this function</span>
<span class="sd"> will automatically expand to a total of</span>
<span class="sd"> `indicator_periods_candles` * `include_timeframes` * `include_shifted_candles` *</span>
<span class="sd"> `include_corr_pairs` numbers of features added to the model.</span>
<span class="sd"> All features must be prepended with `%` to be recognized by FreqAI internals.</span>
<span class="sd"> :param df: strategy dataframe which will receive the features</span>
<span class="sd"> :param period: period of the indicator - usage example:</span>
<span class="sd"> dataframe[&quot;%-ema-period&quot;] = ta.EMA(dataframe, timeperiod=period)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-r</span><span class="s2">si-period&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">RSI</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="n">period</span><span class="p">)</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;%-mfi-period&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">MFI</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="n">period</span><span class="p">)</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-a</span><span class="s2">dx-period&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">ADX</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="n">period</span><span class="p">)</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-s</span><span class="s2">ma-period&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">SMA</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="n">period</span><span class="p">)</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-e</span><span class="s2">ma-period&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">EMA</span><span class="p">(</span><span class="n">dataframe</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="n">period</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dataframe</span>
<span class="k">def</span> <span class="nf">feature_engineering_expand_basic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> *Only functional with FreqAI enabled strategies*</span>
<span class="sd"> This function will automatically expand the defined features on the config defined</span>
<span class="sd"> `include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`.</span>
<span class="sd"> In other words, a single feature defined in this function</span>
<span class="sd"> will automatically expand to a total of</span>
<span class="sd"> `include_timeframes` * `include_shifted_candles` * `include_corr_pairs`</span>
<span class="sd"> numbers of features added to the model.</span>
<span class="sd"> Features defined here will *not* be automatically duplicated on user defined</span>
<span class="sd"> `indicator_periods_candles`</span>
<span class="sd"> All features must be prepended with `%` to be recognized by FreqAI internals.</span>
<span class="sd"> :param df: strategy dataframe which will receive the features</span>
<span class="sd"> dataframe[&quot;%-pct-change&quot;] = dataframe[&quot;close&quot;].pct_change()</span>
<span class="sd"> dataframe[&quot;%-ema-200&quot;] = ta.EMA(dataframe, timeperiod=200)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;%-pct-change&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">pct_change</span><span class="p">()</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-r</span><span class="s2">aw_volume&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;volume&quot;</span><span class="p">]</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-r</span><span class="s2">aw_price&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="n">dataframe</span>
<span class="k">def</span> <span class="nf">feature_engineering_standard</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> *Only functional with FreqAI enabled strategies*</span>
<span class="sd"> This optional function will be called once with the dataframe of the base timeframe.</span>
<span class="sd"> This is the final function to be called, which means that the dataframe entering this</span>
<span class="sd"> function will contain all the features and columns created by all other</span>
<span class="sd"> freqai_feature_engineering_* functions.</span>
<span class="sd"> This function is a good place to do custom exotic feature extractions (e.g. tsfresh).</span>
<span class="sd"> This function is a good place for any feature that should not be auto-expanded upon</span>
<span class="sd"> (e.g. day of the week).</span>
<span class="sd"> All features must be prepended with `%` to be recognized by FreqAI internals.</span>
<span class="sd"> :param df: strategy dataframe which will receive the features</span>
<span class="sd"> usage example: dataframe[&quot;%-day_of_week&quot;] = (dataframe[&quot;date&quot;].dt.dayofweek + 1) / 7</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-d</span><span class="s2">ay_of_week&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;date&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">dt</span><span class="o">.</span><span class="n">dayofweek</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">7</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;</span><span class="si">%-ho</span><span class="s2">ur_of_day&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;date&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">dt</span><span class="o">.</span><span class="n">hour</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">25</span>
<span class="k">return</span> <span class="n">dataframe</span>
<span class="k">def</span> <span class="nf">set_freqai_targets</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> *Only functional with FreqAI enabled strategies*</span>
<span class="sd"> Required function to set the targets for the model.</span>
<span class="sd"> All targets must be prepended with `&amp;` to be recognized by the FreqAI internals.</span>
<span class="sd"> :param df: strategy dataframe which will receive the targets</span>
<span class="sd"> usage example: dataframe[&quot;&amp;-target&quot;] = dataframe[&quot;close&quot;].shift(-1) / dataframe[&quot;close&quot;]</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;&amp;-s_close&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span>
<span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="bp">self</span><span class="o">.</span><span class="n">freqai_info</span><span class="p">[</span><span class="s2">&quot;feature_parameters&quot;</span><span class="p">][</span><span class="s2">&quot;label_period_candles&quot;</span><span class="p">])</span>
<span class="o">.</span><span class="n">rolling</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">freqai_info</span><span class="p">[</span><span class="s2">&quot;feature_parameters&quot;</span><span class="p">][</span><span class="s2">&quot;label_period_candles&quot;</span><span class="p">])</span>
<span class="o">.</span><span class="n">mean</span><span class="p">()</span>
<span class="o">/</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span>
<span class="o">-</span> <span class="mi">1</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">dataframe</span>
</code></pre></div>
<p>Notice how the <code>feature_engineering_*()</code> is where <a href="../freqai-feature-engineering/#feature-engineering">features</a> are added. Meanwhile <code>set_freqai_targets()</code> adds the labels/targets. A full example strategy is available in <code>templates/FreqaiExampleStrategy.py</code>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The <code>self.freqai.start()</code> function cannot be called outside the <code>populate_indicators()</code>.</p>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Features <strong>must</strong> be defined in <code>feature_engineering_*()</code>. Defining FreqAI features in <code>populate_indicators()</code>
will cause the algorithm to fail in live/dry mode. In order to add generalized features that are not associated with a specific pair or timeframe, you should use <code>feature_engineering_standard()</code>
(as exemplified in <code>freqtrade/templates/FreqaiExampleStrategy.py</code>).</p>
</div>
<h2 id="important-dataframe-key-patterns">Important dataframe key patterns<a class="headerlink" href="#important-dataframe-key-patterns" title="Permanent link">&para;</a></h2>
<p>Below are the values you can expect to include/use inside a typical strategy dataframe (<code>df[]</code>):</p>
<table>
<thead>
<tr>
<th>DataFrame Key</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>df['&amp;*']</code></td>
<td>Any dataframe column prepended with <code>&amp;</code> in <code>set_freqai_targets()</code> is treated as a training target (label) inside FreqAI (typically following the naming convention <code>&amp;-s*</code>). For example, to predict the close price 40 candles into the future, you would set <code>df['&amp;-s_close'] = df['close'].shift(-self.freqai_info["feature_parameters"]["label_period_candles"])</code> with <code>"label_period_candles": 40</code> in the config. FreqAI makes the predictions and gives them back under the same key (<code>df['&amp;-s_close']</code>) to be used in <code>populate_entry/exit_trend()</code>. <br> <strong>Datatype:</strong> Depends on the output of the model.</td>
</tr>
<tr>
<td><code>df['&amp;*_std/mean']</code></td>
<td>Standard deviation and mean values of the defined labels during training (or live tracking with <code>fit_live_predictions_candles</code>). Commonly used to understand the rarity of a prediction (use the z-score as shown in <code>templates/FreqaiExampleStrategy.py</code> and explained <a href="#creating-a-dynamic-target-threshold">here</a> to evaluate how often a particular prediction was observed during training or historically with <code>fit_live_predictions_candles</code>). <br> <strong>Datatype:</strong> Float.</td>
</tr>
<tr>
<td><code>df['do_predict']</code></td>
<td>Indication of an outlier data point. The return value is integer between -2 and 2, which lets you know if the prediction is trustworthy or not. <code>do_predict==1</code> means that the prediction is trustworthy. If the Dissimilarity Index (DI, see details <a href="../freqai-feature-engineering/#identifying-outliers-with-the-dissimilarity-index-di">here</a>) of the input data point is above the threshold defined in the config, FreqAI will subtract 1 from <code>do_predict</code>, resulting in <code>do_predict==0</code>. If <code>use_SVM_to_remove_outliers</code> is active, the Support Vector Machine (SVM, see details <a href="../freqai-feature-engineering/#identifying-outliers-using-a-support-vector-machine-svm">here</a>) may also detect outliers in training and prediction data. In this case, the SVM will also subtract 1 from <code>do_predict</code>. If the input data point was considered an outlier by the SVM but not by the DI, or vice versa, the result will be <code>do_predict==0</code>. If both the DI and the SVM considers the input data point to be an outlier, the result will be <code>do_predict==-1</code>. As with the SVM, if <code>use_DBSCAN_to_remove_outliers</code> is active, DBSCAN (see details <a href="../freqai-feature-engineering/#identifying-outliers-with-dbscan">here</a>) may also detect outliers and subtract 1 from <code>do_predict</code>. Hence, if both the SVM and DBSCAN are active and identify a datapoint that was above the DI threshold as an outlier, the result will be <code>do_predict==-2</code>. A particular case is when <code>do_predict == 2</code>, which means that the model has expired due to exceeding <code>expired_hours</code>. <br> <strong>Datatype:</strong> Integer between -2 and 2.</td>
</tr>
<tr>
<td><code>df['DI_values']</code></td>
<td>Dissimilarity Index (DI) values are proxies for the level of confidence FreqAI has in the prediction. A lower DI means the prediction is close to the training data, i.e., higher prediction confidence. See details about the DI <a href="../freqai-feature-engineering/#identifying-outliers-with-the-dissimilarity-index-di">here</a>. <br> <strong>Datatype:</strong> Float.</td>
</tr>
<tr>
<td><code>df['%*']</code></td>
<td>Any dataframe column prepended with <code>%</code> in <code>feature_engineering_*()</code> is treated as a training feature. For example, you can include the RSI in the training feature set (similar to in <code>templates/FreqaiExampleStrategy.py</code>) by setting <code>df['%-rsi']</code>. See more details on how this is done <a href="../freqai-feature-engineering/">here</a>. <br> <strong>Note:</strong> Since the number of features prepended with <code>%</code> can multiply very quickly (10s of thousands of features are easily engineered using the multiplictative functionality of, e.g., <code>include_shifted_candles</code> and <code>include_timeframes</code> as described in the <a href="../freqai-parameter-table/">parameter table</a>), these features are removed from the dataframe that is returned from FreqAI to the strategy. To keep a particular type of feature for plotting purposes, you would prepend it with <code>%%</code> (see details below). <br> <strong>Datatype:</strong> Depends on the feature created by the user.</td>
</tr>
<tr>
<td><code>df['%%*']</code></td>
<td>Any dataframe column prepended with <code>%%</code> in <code>feature_engineering_*()</code> is treated as a training feature, just the same as the above <code>%</code> prepend. However, in this case, the features are returned back to the strategy for FreqUI/plot-dataframe plotting and monitoring in Dry/Live/Backtesting <br> <strong>Datatype:</strong> Depends on the feature created by the user. Please note that features created in <code>feature_engineering_expand()</code> will have automatic FreqAI naming schemas depending on the expansions that you configured (i.e. <code>include_timeframes</code>, <code>include_corr_pairlist</code>, <code>indicators_periods_candles</code>, <code>include_shifted_candles</code>). So if you want to plot <code>%%-rsi</code> from <code>feature_engineering_expand_all()</code>, the final naming scheme for your plotting config would be: <code>%%-rsi-period_10_ETH/USDT:USDT_1h</code> for the <code>rsi</code> feature with <code>period=10</code>, <code>timeframe=1h</code>, and <code>pair=ETH/USDT:USDT</code> (the <code>:USDT</code> is added if you are using futures pairs). It is useful to simply add <code>print(dataframe.columns)</code> in your <code>populate_indicators()</code> after <code>self.freqai.start()</code> to see the full list of available features that are returned to the strategy for plotting purposes.</td>
</tr>
</tbody>
</table>
<h2 id="setting-the-startup_candle_count">Setting the <code>startup_candle_count</code><a class="headerlink" href="#setting-the-startup_candle_count" title="Permanent link">&para;</a></h2>
<p>The <code>startup_candle_count</code> in the FreqAI strategy needs to be set up in the same way as in the standard Freqtrade strategy (see details <a href="../strategy-customization/#strategy-startup-period">here</a>). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling the <code>dataprovider</code>, to avoid any NaNs at the beginning of the first training. You can easily set this value by identifying the longest period (in candle units) which is passed to the indicator creation functions (e.g., TA-Lib functions). In the presented example, <code>startup_candle_count</code> is 20 since this is the maximum value in <code>indicators_periods_candles</code>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>There are instances where the TA-Lib functions actually require more data than just the passed <code>period</code> or else the feature dataset gets populated with NaNs. Anecdotally, multiplying the <code>startup_candle_count</code> by 2 always leads to a fully NaN free training dataset. Hence, it is typically safest to multiply the expected <code>startup_candle_count</code> by 2. Look out for this log message to confirm that the data is clean:</p>
<div class="highlight"><pre><span></span><code>2022-08-31 15:14:04 - freqtrade.freqai.data_kitchen - INFO - dropped 0 training points due to NaNs in populated dataset 4319.
</code></pre></div>
</div>
<h2 id="creating-a-dynamic-target-threshold">Creating a dynamic target threshold<a class="headerlink" href="#creating-a-dynamic-target-threshold" title="Permanent link">&para;</a></h2>
<p>Deciding when to enter or exit a trade can be done in a dynamic way to reflect current market conditions. FreqAI allows you to return additional information from the training of a model (more info <a href="../freqai-feature-engineering/#returning-additional-info-from-training">here</a>). For example, the <code>&amp;*_std/mean</code> return values describe the statistical distribution of the target/label <em>during the most recent training</em>. Comparing a given prediction to these values allows you to know the rarity of the prediction. In <code>templates/FreqaiExampleStrategy.py</code>, the <code>target_roi</code> and <code>sell_roi</code> are defined to be 1.25 z-scores away from the mean which causes predictions that are closer to the mean to be filtered out.</p>
<div class="highlight"><pre><span></span><code><span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;target_roi&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;&amp;-s_close_mean&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;&amp;-s_close_std&quot;</span><span class="p">]</span> <span class="o">*</span> <span class="mf">1.25</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;sell_roi&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;&amp;-s_close_mean&quot;</span><span class="p">]</span> <span class="o">-</span> <span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;&amp;-s_close_std&quot;</span><span class="p">]</span> <span class="o">*</span> <span class="mf">1.25</span>
</code></pre></div>
<p>To consider the population of <em>historical predictions</em> for creating the dynamic target instead of information from the training as discussed above, you would set <code>fit_live_predictions_candles</code> in the config to the number of historical prediction candles you wish to use to generate target statistics.</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="nt">&quot;freqai&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;fit_live_predictions_candles&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
<span class="w"> </span><span class="p">}</span>
</code></pre></div>
<p>If this value is set, FreqAI will initially use the predictions from the training data and subsequently begin introducing real prediction data as it is generated. FreqAI will save this historical data to be reloaded if you stop and restart a model with the same <code>identifier</code>.</p>
<h2 id="using-different-prediction-models">Using different prediction models<a class="headerlink" href="#using-different-prediction-models" title="Permanent link">&para;</a></h2>
<p>FreqAI has multiple example prediction model libraries that are ready to be used as is via the flag <code>--freqaimodel</code>. These libraries include <code>CatBoost</code>, <code>LightGBM</code>, and <code>XGBoost</code> regression, classification, and multi-target models, and can be found in <code>freqai/prediction_models/</code>.</p>
<p>Regression and classification models differ in what targets they predict - a regression model will predict a target of continuous values, for example what price BTC will be at tomorrow, whilst a classifier will predict a target of discrete values, for example if the price of BTC will go up tomorrow or not. This means that you have to specify your targets differently depending on which model type you are using (see details <a href="#setting-model-targets">below</a>).</p>
<p>All of the aforementioned model libraries implement gradient boosted decision tree algorithms. They all work on the principle of ensemble learning, where predictions from multiple simple learners are combined to get a final prediction that is more stable and generalized. The simple learners in this case are decision trees. Gradient boosting refers to the method of learning, where each simple learner is built in sequence - the subsequent learner is used to improve on the error from the previous learner. If you want to learn more about the different model libraries you can find the information in their respective docs:</p>
<ul>
<li>CatBoost: <a href="https://catboost.ai/en/docs/">https://catboost.ai/en/docs/</a></li>
<li>LightGBM: <a href="https://lightgbm.readthedocs.io/en/v3.3.2/#">https://lightgbm.readthedocs.io/en/v3.3.2/#</a></li>
<li>XGBoost: <a href="https://xgboost.readthedocs.io/en/stable/#">https://xgboost.readthedocs.io/en/stable/#</a></li>
</ul>
<p>There are also numerous online articles describing and comparing the algorithms. Some relatively lightweight examples would be <a href="https://towardsdatascience.com/catboost-vs-lightgbm-vs-xgboost-c80f40662924#:~:text=In%20CatBoost%2C%20symmetric%20trees%2C%20or,the%20same%20depth%20can%20differ.">CatBoost vs. LightGBM vs. XGBoost — Which is the best algorithm?</a> and <a href="https://medium.com/riskified-technology/xgboost-lightgbm-or-catboost-which-boosting-algorithm-should-i-use-e7fda7bb36bc">XGBoost, LightGBM or CatBoost — which boosting algorithm should I use?</a>. Keep in mind that the performance of each model is highly dependent on the application and so any reported metrics might not be true for your particular use of the model.</p>
<p>Apart from the models already available in FreqAI, it is also possible to customize and create your own prediction models using the <code>IFreqaiModel</code> class. You are encouraged to inherit <code>fit()</code>, <code>train()</code>, and <code>predict()</code> to customize various aspects of the training procedures. You can place custom FreqAI models in <code>user_data/freqaimodels</code> - and freqtrade will pick them up from there based on the provided <code>--freqaimodel</code> name - which has to correspond to the class name of your custom model.
Make sure to use unique names to avoid overriding built-in models.</p>
<h3 id="setting-model-targets">Setting model targets<a class="headerlink" href="#setting-model-targets" title="Permanent link">&para;</a></h3>
<h4 id="regressors">Regressors<a class="headerlink" href="#regressors" title="Permanent link">&para;</a></h4>
<p>If you are using a regressor, you need to specify a target that has continuous values. FreqAI includes a variety of regressors, such as the <code>CatboostRegressor</code>via the flag <code>--freqaimodel CatboostRegressor</code>. An example of how you could set a regression target for predicting the price 100 candles into the future would be</p>
<div class="highlight"><pre><span></span><code><span class="n">df</span><span class="p">[</span><span class="s1">&#39;&amp;s-close_price&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s1">&#39;close&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="mi">100</span><span class="p">)</span>
</code></pre></div>
<p>If you want to predict multiple targets, you need to define multiple labels using the same syntax as shown above.</p>
<h4 id="classifiers">Classifiers<a class="headerlink" href="#classifiers" title="Permanent link">&para;</a></h4>
<p>If you are using a classifier, you need to specify a target that has discrete values. FreqAI includes a variety of classifiers, such as the <code>CatboostClassifier</code> via the flag <code>--freqaimodel CatboostClassifier</code>. If you elects to use a classifier, the classes need to be set using strings. For example, if you want to predict if the price 100 candles into the future goes up or down you would set</p>
<div class="highlight"><pre><span></span><code><span class="n">df</span><span class="p">[</span><span class="s1">&#39;&amp;s-up_or_down&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="mi">100</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">],</span> <span class="s1">&#39;up&#39;</span><span class="p">,</span> <span class="s1">&#39;down&#39;</span><span class="p">)</span>
</code></pre></div>
<p>If you want to predict multiple targets you must specify all labels in the same label column. You could, for example, add the label <code>same</code> to define where the price was unchanged by setting</p>
<div class="highlight"><pre><span></span><code><span class="n">df</span><span class="p">[</span><span class="s1">&#39;&amp;s-up_or_down&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="mi">100</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">],</span> <span class="s1">&#39;up&#39;</span><span class="p">,</span> <span class="s1">&#39;down&#39;</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s1">&#39;&amp;s-up_or_down&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="mi">100</span><span class="p">)</span> <span class="o">==</span> <span class="n">df</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">],</span> <span class="s1">&#39;same&#39;</span><span class="p">,</span> <span class="n">df</span><span class="p">[</span><span class="s1">&#39;&amp;s-up_or_down&#39;</span><span class="p">])</span>
</code></pre></div>
<h2 id="pytorch-module">PyTorch Module<a class="headerlink" href="#pytorch-module" title="Permanent link">&para;</a></h2>
<h3 id="quick-start">Quick start<a class="headerlink" href="#quick-start" title="Permanent link">&para;</a></h3>
<p>The easiest way to quickly run a pytorch model is with the following command (for regression task):</p>
<div class="highlight"><pre><span></span><code>freqtrade<span class="w"> </span>trade<span class="w"> </span>--config<span class="w"> </span>config_examples/config_freqai.example.json<span class="w"> </span>--strategy<span class="w"> </span>FreqaiExampleStrategy<span class="w"> </span>--freqaimodel<span class="w"> </span>PyTorchMLPRegressor<span class="w"> </span>--strategy-path<span class="w"> </span>freqtrade/templates<span class="w"> </span>
</code></pre></div>
<div class="admonition note">
<p class="admonition-title">Installation/docker</p>
<p>The PyTorch module requires large packages such as <code>torch</code>, which should be explicitly requested during <code>./setup.sh -i</code> by answering "y" to the question "Do you also want dependencies for freqai-rl or PyTorch (~700mb additional space required) [y/N]?".
Users who prefer docker should ensure they use the docker image appended with <code>_freqaitorch</code>.
We do provide an explicit docker-compose file for this in <code>docker/docker-compose-freqai.yml</code> - which can be used via <code>docker compose -f docker/docker-compose-freqai.yml run ...</code> - or can be copied to replace the original docker file.
This docker-compose file also contains a (disabled) section to enable GPU resources within docker containers. This obviously assumes the system has GPU resources available.</p>
</div>
<h3 id="structure">Structure<a class="headerlink" href="#structure" title="Permanent link">&para;</a></h3>
<h4 id="model">Model<a class="headerlink" href="#model" title="Permanent link">&para;</a></h4>
<p>You can construct your own Neural Network architecture in PyTorch by simply defining your <code>nn.Module</code> class inside your custom <a href="#using-different-prediction-models"><code>IFreqaiModel</code> file</a> and then using that class in your <code>def train()</code> function. Here is an example of logistic regression model implementation using PyTorch (should be used with nn.BCELoss criterion) for classification tasks.</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">LogisticRegression</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">input_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="c1"># Define your layers</span>
<span class="bp">self</span><span class="o">.</span><span class="n">linear</span> <span class="o">=</span> <span class="n">nn</span><span class="o">.</span><span class="n">Linear</span><span class="p">(</span><span class="n">input_size</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">activation</span> <span class="o">=</span> <span class="n">nn</span><span class="o">.</span><span class="n">Sigmoid</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="n">torch</span><span class="o">.</span><span class="n">Tensor</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">torch</span><span class="o">.</span><span class="n">Tensor</span><span class="p">:</span>
<span class="c1"># Define the forward pass</span>
<span class="n">out</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">linear</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">out</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">activation</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
<span class="k">return</span> <span class="n">out</span>
<span class="k">class</span> <span class="nc">MyCoolPyTorchClassifier</span><span class="p">(</span><span class="n">BasePyTorchClassifier</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is a custom IFreqaiModel showing how a user might setup their own </span>
<span class="sd"> custom Neural Network architecture for their training.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">data_convertor</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">PyTorchDataConvertor</span><span class="p">:</span>
<span class="k">return</span> <span class="n">DefaultPyTorchDataConvertor</span><span class="p">(</span><span class="n">target_tensor_type</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">float</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">freqai_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;model_training_parameters&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">learning_rate</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;learning_rate&quot;</span><span class="p">,</span> <span class="mf">3e-4</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">model_kwargs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;model_kwargs&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">trainer_kwargs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;trainer_kwargs&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="k">def</span> <span class="nf">fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_dictionary</span><span class="p">:</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">dk</span><span class="p">:</span> <span class="n">FreqaiDataKitchen</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Any</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> User sets up the training and test data to fit their desired model here</span>
<span class="sd"> :param data_dictionary: the dictionary holding all data for train, test,</span>
<span class="sd"> labels, weights</span>
<span class="sd"> :param dk: The datakitchen object for the current coin/model</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">class_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_class_names</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">convert_label_column_to_int</span><span class="p">(</span><span class="n">data_dictionary</span><span class="p">,</span> <span class="n">dk</span><span class="p">,</span> <span class="n">class_names</span><span class="p">)</span>
<span class="n">n_features</span> <span class="o">=</span> <span class="n">data_dictionary</span><span class="p">[</span><span class="s2">&quot;train_features&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">LogisticRegression</span><span class="p">(</span>
<span class="n">input_dim</span><span class="o">=</span><span class="n">n_features</span>
<span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">optim</span><span class="o">.</span><span class="n">AdamW</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">parameters</span><span class="p">(),</span> <span class="n">lr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">learning_rate</span><span class="p">)</span>
<span class="n">criterion</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">CrossEntropyLoss</span><span class="p">()</span>
<span class="n">init_model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_init_model</span><span class="p">(</span><span class="n">dk</span><span class="o">.</span><span class="n">pair</span><span class="p">)</span>
<span class="n">trainer</span> <span class="o">=</span> <span class="n">PyTorchModelTrainer</span><span class="p">(</span>
<span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
<span class="n">optimizer</span><span class="o">=</span><span class="n">optimizer</span><span class="p">,</span>
<span class="n">criterion</span><span class="o">=</span><span class="n">criterion</span><span class="p">,</span>
<span class="n">model_meta_data</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;class_names&quot;</span><span class="p">:</span> <span class="n">class_names</span><span class="p">},</span>
<span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span>
<span class="n">init_model</span><span class="o">=</span><span class="n">init_model</span><span class="p">,</span>
<span class="n">data_convertor</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">data_convertor</span><span class="p">,</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">trainer_kwargs</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">trainer</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">data_dictionary</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">splits</span><span class="p">)</span>
<span class="k">return</span> <span class="n">trainer</span>
</code></pre></div>
<h4 id="trainer">Trainer<a class="headerlink" href="#trainer" title="Permanent link">&para;</a></h4>
<p>The <code>PyTorchModelTrainer</code> performs the idiomatic PyTorch train loop:
Define our model, loss function, and optimizer, and then move them to the appropriate device (GPU or CPU). Inside the loop, we iterate through the batches in the dataloader, move the data to the device, compute the prediction and loss, backpropagate, and update the model parameters using the optimizer. </p>
<p>In addition, the trainer is responsible for the following:
- saving and loading the model
- converting the data from <code>pandas.DataFrame</code> to <code>torch.Tensor</code>. </p>
<h4 id="integration-with-freqai-module">Integration with Freqai module<a class="headerlink" href="#integration-with-freqai-module" title="Permanent link">&para;</a></h4>
<p>Like all freqai models, PyTorch models inherit <code>IFreqaiModel</code>. <code>IFreqaiModel</code> declares three abstract methods: <code>train</code>, <code>fit</code>, and <code>predict</code>. we implement these methods in three levels of hierarchy.
From top to bottom:</p>
<ol>
<li><code>BasePyTorchModel</code> - Implements the <code>train</code> method. all <code>BasePyTorch*</code> inherit it. responsible for general data preparation (e.g., data normalization) and calling the <code>fit</code> method. Sets <code>device</code> attribute used by children classes. Sets <code>model_type</code> attribute used by the parent class.</li>
<li><code>BasePyTorch*</code> - Implements the <code>predict</code> method. Here, the <code>*</code> represents a group of algorithms, such as classifiers or regressors. responsible for data preprocessing, predicting, and postprocessing if needed.</li>
<li><code>PyTorch*Classifier</code> / <code>PyTorch*Regressor</code> - implements the <code>fit</code> method. responsible for the main train flaw, where we initialize the trainer and model objects.</li>
</ol>
<p><img alt="image" src="../assets/freqai_pytorch-diagram.png" /></p>
<h4 id="full-example">Full example<a class="headerlink" href="#full-example" title="Permanent link">&para;</a></h4>
<p>Building a PyTorch regressor using MLP (multilayer perceptron) model, MSELoss criterion, and AdamW optimizer.</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">PyTorchMLPRegressor</span><span class="p">(</span><span class="n">BasePyTorchRegressor</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">freqai_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;model_training_parameters&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">learning_rate</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;learning_rate&quot;</span><span class="p">,</span> <span class="mf">3e-4</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">model_kwargs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;model_kwargs&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">trainer_kwargs</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;trainer_kwargs&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="k">def</span> <span class="nf">fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_dictionary</span><span class="p">:</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">dk</span><span class="p">:</span> <span class="n">FreqaiDataKitchen</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Any</span><span class="p">:</span>
<span class="n">n_features</span> <span class="o">=</span> <span class="n">data_dictionary</span><span class="p">[</span><span class="s2">&quot;train_features&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">PyTorchMLPModel</span><span class="p">(</span>
<span class="n">input_dim</span><span class="o">=</span><span class="n">n_features</span><span class="p">,</span>
<span class="n">output_dim</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">model_kwargs</span>
<span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">optim</span><span class="o">.</span><span class="n">AdamW</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">parameters</span><span class="p">(),</span> <span class="n">lr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">learning_rate</span><span class="p">)</span>
<span class="n">criterion</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">MSELoss</span><span class="p">()</span>
<span class="n">init_model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_init_model</span><span class="p">(</span><span class="n">dk</span><span class="o">.</span><span class="n">pair</span><span class="p">)</span>
<span class="n">trainer</span> <span class="o">=</span> <span class="n">PyTorchModelTrainer</span><span class="p">(</span>
<span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
<span class="n">optimizer</span><span class="o">=</span><span class="n">optimizer</span><span class="p">,</span>
<span class="n">criterion</span><span class="o">=</span><span class="n">criterion</span><span class="p">,</span>
<span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span>
<span class="n">init_model</span><span class="o">=</span><span class="n">init_model</span><span class="p">,</span>
<span class="n">target_tensor_type</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">float</span><span class="p">,</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">trainer_kwargs</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">trainer</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">data_dictionary</span><span class="p">)</span>
<span class="k">return</span> <span class="n">trainer</span>
</code></pre></div>
<p>Here we create a <code>PyTorchMLPRegressor</code> class that implements the <code>fit</code> method. The <code>fit</code> method specifies the training building blocks: model, optimizer, criterion, and trainer. We inherit both <code>BasePyTorchRegressor</code> and <code>BasePyTorchModel</code>, where the former implements the <code>predict</code> method that is suitable for our regression task, and the latter implements the train method.</p>
<details class="note">
<summary>Setting Class Names for Classifiers</summary>
<p>When using classifiers, the user must declare the class names (or targets) by overriding the <code>IFreqaiModel.class_names</code> attribute. This is achieved by setting <code>self.freqai.class_names</code> in the FreqAI strategy inside the <code>set_freqai_targets</code> method.</p>
<p>For example, if you are using a binary classifier to predict price movements as up or down, you can set the class names as follows:
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">set_freqai_targets</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span> <span class="n">metadata</span><span class="p">:</span> <span class="n">Dict</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DataFrame</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">freqai</span><span class="o">.</span><span class="n">class_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;down&quot;</span><span class="p">,</span> <span class="s2">&quot;up&quot;</span><span class="p">]</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s1">&#39;&amp;s-up_or_down&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">shift</span><span class="p">(</span><span class="o">-</span><span class="mi">100</span><span class="p">)</span> <span class="o">&gt;</span>
<span class="n">dataframe</span><span class="p">[</span><span class="s2">&quot;close&quot;</span><span class="p">],</span> <span class="s1">&#39;up&#39;</span><span class="p">,</span> <span class="s1">&#39;down&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dataframe</span>
</code></pre></div>
To see a full example, you can refer to the <a href="https://github.com/freqtrade/freqtrade/blob/develop/tests/strategy/strats/freqai_test_classifier.py">classifier test strategy class</a>.</p>
</details>
<h4 id="improving-performance-with-torchcompile">Improving performance with <code>torch.compile()</code><a class="headerlink" href="#improving-performance-with-torchcompile" title="Permanent link">&para;</a></h4>
<p>Torch provides a <code>torch.compile()</code> method that can be used to improve performance for specific GPU hardware. More details can be found <a href="https://pytorch.org/tutorials/intermediate/torch_compile_tutorial.html">here</a>. In brief, you simply wrap your <code>model</code> in <code>torch.compile()</code>:</p>
<div class="highlight"><pre><span></span><code> <span class="n">model</span> <span class="o">=</span> <span class="n">PyTorchMLPModel</span><span class="p">(</span>
<span class="n">input_dim</span><span class="o">=</span><span class="n">n_features</span><span class="p">,</span>
<span class="n">output_dim</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">model_kwargs</span>
<span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</code></pre></div>
<p>Then proceed to use the model as normal. Keep in mind that doing this will remove eager execution, which means errors and tracebacks will not be informative.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../freqai/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Introduction">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Introduction
</div>
</div>
</a>
<a href="../freqai-parameter-table/" class="md-footer__link md-footer__link--next" aria-label="Next: Parameter table">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Parameter table
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4Z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
<!-- Place this tag in your head or just before your close body tag. -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["content.code.annotate", "search.share", "content.code.copy", "navigation.top", "navigation.footer"], "search": "../assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.fe8b6f2b.min.js"></script>
<script src="../javascripts/config.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>