freqtrade_origin/en/2021.11/strategy-advanced/index.html

1342 lines
36 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://www.freqtrade.io/2021.11/strategy-advanced/">
<link rel="icon" href="../images/logo.png">
<meta name="generator" content="mkdocs-1.2.3, mkdocs-material-7.3.6">
<title>Advanced Strategy - Freqtrade</title>
<link rel="stylesheet" href="../assets/stylesheets/main.a57b2b03.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.3f5d1f46.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<link rel="stylesheet" href="../stylesheets/ft.extra.css">
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="blue-grey" data-md-color-accent="tear">
<script>function __prefix(e){return new URL("..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<script>var palette=__get("__palette");if(null!==palette&&"object"==typeof palette.color)for(var key in palette.color)document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<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="#advanced-strategies" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" 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">
Advanced Strategy
</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_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" 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_2">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" 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>
<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">
<button type="reset" class="md-search__icon md-icon" 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" 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"></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"><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 id="widget-wrapper">
</div>
<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"><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">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../docker_quickstart/" class="md-nav__link">
Quickstart with Docker
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3">
Installation
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Installation" data-md-level="1">
<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">
Linux/MacOS/Raspberry
</a>
</li>
<li class="md-nav__item">
<a href="../windows_installation/" class="md-nav__link">
Windows
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../bot-basics/" class="md-nav__link">
Freqtrade Basics
</a>
</li>
<li class="md-nav__item">
<a href="../configuration/" class="md-nav__link">
Configuration
</a>
</li>
<li class="md-nav__item">
<a href="../strategy-customization/" class="md-nav__link">
Strategy Customization
</a>
</li>
<li class="md-nav__item">
<a href="../strategy-callbacks/" class="md-nav__link">
Strategy Callbacks
</a>
</li>
<li class="md-nav__item">
<a href="../stoploss/" class="md-nav__link">
Stoploss
</a>
</li>
<li class="md-nav__item">
<a href="../plugins/" class="md-nav__link">
Plugins
</a>
</li>
<li class="md-nav__item">
<a href="../bot-usage/" class="md-nav__link">
Start the bot
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_11" type="checkbox" id="__nav_11" >
<label class="md-nav__link" for="__nav_11">
Control the bot
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Control the bot" data-md-level="1">
<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">
Telegram
</a>
</li>
<li class="md-nav__item">
<a href="../rest-api/" class="md-nav__link">
REST API & FreqUI
</a>
</li>
<li class="md-nav__item">
<a href="../webhook-config/" class="md-nav__link">
Web Hook
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../data-download/" class="md-nav__link">
Data Downloading
</a>
</li>
<li class="md-nav__item">
<a href="../backtesting/" class="md-nav__link">
Backtesting
</a>
</li>
<li class="md-nav__item">
<a href="../hyperopt/" class="md-nav__link">
Hyperopt
</a>
</li>
<li class="md-nav__item">
<a href="../utils/" class="md-nav__link">
Utility Sub-commands
</a>
</li>
<li class="md-nav__item">
<a href="../plotting/" class="md-nav__link">
Plotting
</a>
</li>
<li class="md-nav__item">
<a href="../exchanges/" class="md-nav__link">
Exchange-specific Notes
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_18" type="checkbox" id="__nav_18" >
<label class="md-nav__link" for="__nav_18">
Data Analysis
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Data Analysis" data-md-level="1">
<label class="md-nav__title" for="__nav_18">
<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">
Jupyter Notebooks
</a>
</li>
<li class="md-nav__item">
<a href="../strategy_analysis_example/" class="md-nav__link">
Strategy analysis
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_19" type="checkbox" id="__nav_19" checked>
<label class="md-nav__link" for="__nav_19">
Advanced Topics
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Advanced Topics" data-md-level="1">
<label class="md-nav__title" for="__nav_19">
<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">
Advanced Post-installation Tasks
</a>
</li>
<li class="md-nav__item">
<a href="../edge/" class="md-nav__link">
Edge Positioning
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Advanced Strategy
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Advanced Strategy
</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="#storing-information" class="md-nav__link">
Storing information
</a>
</li>
<li class="md-nav__item">
<a href="#dataframe-access" class="md-nav__link">
Dataframe access
</a>
</li>
<li class="md-nav__item">
<a href="#buy-tag" class="md-nav__link">
Buy Tag
</a>
</li>
<li class="md-nav__item">
<a href="#exit-tag" class="md-nav__link">
Exit tag
</a>
</li>
<li class="md-nav__item">
<a href="#derived-strategies" class="md-nav__link">
Derived strategies
</a>
</li>
<li class="md-nav__item">
<a href="#embedding-strategies" class="md-nav__link">
Embedding Strategies
</a>
<nav class="md-nav" aria-label="Embedding Strategies">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#encoding-a-string-as-base64" class="md-nav__link">
Encoding a string as BASE64
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#performance-warning" class="md-nav__link">
Performance warning
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../advanced-hyperopt/" class="md-nav__link">
Advanced Hyperopt
</a>
</li>
<li class="md-nav__item">
<a href="../sandbox-testing/" class="md-nav__link">
Sandbox Testing
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../faq/" class="md-nav__link">
FAQ
</a>
</li>
<li class="md-nav__item">
<a href="../sql_cheatsheet/" class="md-nav__link">
SQL Cheat-sheet
</a>
</li>
<li class="md-nav__item">
<a href="../updating/" class="md-nav__link">
Updating Freqtrade
</a>
</li>
<li class="md-nav__item">
<a href="../deprecated/" class="md-nav__link">
Deprecated Features
</a>
</li>
<li class="md-nav__item">
<a href="../developer/" class="md-nav__link">
Contributors Guide
</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="#storing-information" class="md-nav__link">
Storing information
</a>
</li>
<li class="md-nav__item">
<a href="#dataframe-access" class="md-nav__link">
Dataframe access
</a>
</li>
<li class="md-nav__item">
<a href="#buy-tag" class="md-nav__link">
Buy Tag
</a>
</li>
<li class="md-nav__item">
<a href="#exit-tag" class="md-nav__link">
Exit tag
</a>
</li>
<li class="md-nav__item">
<a href="#derived-strategies" class="md-nav__link">
Derived strategies
</a>
</li>
<li class="md-nav__item">
<a href="#embedding-strategies" class="md-nav__link">
Embedding Strategies
</a>
<nav class="md-nav" aria-label="Embedding Strategies">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#encoding-a-string-as-base64" class="md-nav__link">
Encoding a string as BASE64
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#performance-warning" class="md-nav__link">
Performance warning
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/freqtrade/freqtrade/edit/master/docs/strategy-advanced.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
</a>
<h1 id="advanced-strategies">Advanced Strategies<a class="headerlink" href="#advanced-strategies" title="Permanent link">&para;</a></h1>
<p>This page explains some advanced concepts available for strategies.
If you're just getting started, please be familiar with the methods described in the <a href="../strategy-customization/">Strategy Customization</a> documentation and with the <a href="../bot-basics/">Freqtrade basics</a> first.</p>
<p><a href="../bot-basics/">Freqtrade basics</a> describes in which sequence each method described below is called, which can be helpful to understand which method to use for your custom needs.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>All callback methods described below should only be implemented in a strategy if they are actually used.</p>
</div>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>You can get a strategy template containing all below methods by running <code>freqtrade new-strategy --strategy MyAwesomeStrategy --template advanced</code></p>
</div>
<h2 id="storing-information">Storing information<a class="headerlink" href="#storing-information" title="Permanent link">&para;</a></h2>
<p>Storing information can be accomplished by creating a new dictionary within the strategy class.</p>
<p>The name of the variable can be chosen at will, but should be prefixed with <code>cust_</code> to avoid naming collisions with predefined strategy variables.</p>
<p>```python
class AwesomeStrategy(IStrategy):
# Create custom dictionary
custom_info = {}</p>
<div class="codehilite"><pre><span></span><code>def populate_indicators(self, dataframe: DataFrame, metadata: dict) -&gt; DataFrame:
# Check if the entry already exists
if not metadata[&quot;pair&quot;] in self.custom_info:
# Create empty entry for this pair
self.custom_info[metadata[&quot;pair&quot;]] = {}
if &quot;crosstime&quot; in self.custom_info[metadata[&quot;pair&quot;]]:
self.custom_info[metadata[&quot;pair&quot;]][&quot;crosstime&quot;] += 1
else:
self.custom_info[metadata[&quot;pair&quot;]][&quot;crosstime&quot;] = 1
</code></pre></div>
<p>```</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash.</p>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If the data is pair-specific, make sure to use pair as one of the keys in the dictionary.</p>
</div>
<h2 id="dataframe-access">Dataframe access<a class="headerlink" href="#dataframe-access" title="Permanent link">&para;</a></h2>
<p>You may access dataframe in various strategy functions by querying it from dataprovider.</p>
<p>``` python
from freqtrade.exchange import timeframe_to_prev_date</p>
<p>class AwesomeStrategy(IStrategy):
def confirm_trade_exit(self, pair: str, trade: 'Trade', order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str,
current_time: 'datetime', **kwargs) -&gt; bool:
# Obtain pair dataframe.
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)</p>
<div class="codehilite"><pre><span></span><code> # Obtain last available candle. Do not use current_time to look up latest candle, because
# current_time points to current incomplete candle whose data is not available.
last_candle = dataframe.iloc[-1].squeeze()
# &lt;...&gt;
# In dry/live runs trade open date will not match candle open date therefore it must be
# rounded.
trade_date = timeframe_to_prev_date(self.timeframe, trade.open_date_utc)
# Look up trade candle.
trade_candle = dataframe.loc[dataframe[&#39;date&#39;] == trade_date]
# trade_candle may be empty for trades that just opened as it is still incomplete.
if not trade_candle.empty:
trade_candle = trade_candle.squeeze()
# &lt;...&gt;
</code></pre></div>
<p>```</p>
<div class="admonition warning">
<p class="admonition-title">Using .iloc[-1]</p>
<p>You can use <code>.iloc[-1]</code> here because <code>get_analyzed_dataframe()</code> only returns candles that backtesting is allowed to see.
This will not work in <code>populate_*</code> methods, so make sure to not use <code>.iloc[]</code> in that area.
Also, this will only work starting with version 2021.5.</p>
</div>
<hr />
<h2 id="buy-tag">Buy Tag<a class="headerlink" href="#buy-tag" title="Permanent link">&para;</a></h2>
<p>When your strategy has multiple buy signals, you can name the signal that triggered.
Then you can access you buy signal on <code>custom_sell</code></p>
<p>```python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -&gt; DataFrame:
dataframe.loc[
(
(dataframe['rsi'] &lt; 35) &amp;
(dataframe['volume'] &gt; 0)
),
['buy', 'buy_tag']] = (1, 'buy_signal_rsi')</p>
<div class="codehilite"><pre><span></span><code>return dataframe
</code></pre></div>
<p>def custom_sell(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
current_profit: float, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
if trade.buy_tag == 'buy_signal_rsi' and last_candle['rsi'] &gt; 80:
return 'sell_signal_rsi'
return None</p>
<p>```</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code>buy_tag</code> is limited to 100 characters, remaining data will be truncated.</p>
</div>
<h2 id="exit-tag">Exit tag<a class="headerlink" href="#exit-tag" title="Permanent link">&para;</a></h2>
<p>Similar to <a href="#buy-tag">Buy Tagging</a>, you can also specify a sell tag.</p>
<p>``` python
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -&gt; DataFrame:
dataframe.loc[
(
(dataframe['rsi'] &gt; 70) &amp;
(dataframe['volume'] &gt; 0)
),
['sell', 'exit_tag']] = (1, 'exit_rsi')</p>
<div class="codehilite"><pre><span></span><code>return dataframe
</code></pre></div>
<p>```</p>
<p>The provided exit-tag is then used as sell-reason - and shown as such in backtest results.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code>sell_reason</code> is limited to 100 characters, remaining data will be truncated.</p>
</div>
<h2 id="derived-strategies">Derived strategies<a class="headerlink" href="#derived-strategies" title="Permanent link">&para;</a></h2>
<p>The strategies can be derived from other strategies. This avoids duplication of your custom strategy code. You can use this technique to override small parts of your main strategy, leaving the rest untouched:</p>
<p>``` python
class MyAwesomeStrategy(IStrategy):
...
stoploss = 0.13
trailing_stop = False
# All other attributes and methods are here as they
# should be in any custom strategy...
...</p>
<p>class MyAwesomeStrategy2(MyAwesomeStrategy):
# Override something
stoploss = 0.08
trailing_stop = True
```</p>
<p>Both attributes and methods may be overridden, altering behavior of the original strategy in a way you need.</p>
<div class="admonition note">
<p class="admonition-title">Parent-strategy in different files</p>
<p>If you have the parent-strategy in a different file, you'll need to add the following to the top of your "child"-file to ensure proper loading, otherwise freqtrade may not be able to load the parent strategy correctly.</p>
<p>``` python
import sys
from pathlib import Path
sys.path.append(str(Path(<strong>file</strong>).parent))</p>
<p>from myawesomestrategy import MyAwesomeStrategy
```</p>
</div>
<h2 id="embedding-strategies">Embedding Strategies<a class="headerlink" href="#embedding-strategies" title="Permanent link">&para;</a></h2>
<p>Freqtrade provides you with an easy way to embed the strategy into your configuration file.
This is done by utilizing BASE64 encoding and providing this string at the strategy configuration field,
in your chosen config file.</p>
<h3 id="encoding-a-string-as-base64">Encoding a string as BASE64<a class="headerlink" href="#encoding-a-string-as-base64" title="Permanent link">&para;</a></h3>
<p>This is a quick example, how to generate the BASE64 string in python</p>
<p>```python
from base64 import urlsafe_b64encode</p>
<p>with open(file, 'r') as f:
content = f.read()
content = urlsafe_b64encode(content.encode('utf-8'))
```</p>
<p>The variable 'content', will contain the strategy file in a BASE64 encoded form. Which can now be set in your configurations file as following</p>
<p><code>json
"strategy": "NameOfStrategy:BASE64String"</code></p>
<p>Please ensure that 'NameOfStrategy' is identical to the strategy name!</p>
<h2 id="performance-warning">Performance warning<a class="headerlink" href="#performance-warning" title="Permanent link">&para;</a></h2>
<p>When executing a strategy, one can sometimes be greeted by the following in the logs</p>
<blockquote>
<p>PerformanceWarning: DataFrame is highly fragmented.</p>
</blockquote>
<p>This is a warning from <a href="https://github.com/pandas-dev/pandas"><code>pandas</code></a> and as the warning continues to say:
use <code>pd.concat(axis=1)</code>.
This can have slight performance implications, which are usually only visible during hyperopt (when optimizing an indicator).</p>
<p>For example:</p>
<p><code>python
for val in self.buy_ema_short.range:
dataframe[f'ema_short_{val}'] = ta.EMA(dataframe, timeperiod=val)</code></p>
<p>should be rewritten to</p>
<p>```python
frames = [dataframe]
for val in self.buy_ema_short.range:
frames.append({
f'ema_short_{val}': ta.EMA(dataframe, timeperiod=val)
})</p>
<h1 id="append-columns-to-existing-dataframe">Append columns to existing dataframe<a class="headerlink" href="#append-columns-to-existing-dataframe" title="Permanent link">&para;</a></h1>
<p>merged_frame = pd.concat(frames, axis=1)
```</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer">
<a href="../edge/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Edge Positioning" rel="prev">
<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">
<div class="md-ellipsis">
<span class="md-footer__direction">
Previous
</span>
Edge Positioning
</div>
</div>
</a>
<a href="../advanced-hyperopt/" class="md-footer__link md-footer__link--next" aria-label="Next: Advanced Hyperopt" rel="next">
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
Next
</span>
Advanced Hyperopt
</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-footer-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>
<!-- Load binance SDK -->
<script async defer src="https://public.bnbstatic.com/static/js/broker-sdk/broker-sdk@1.0.0.min.js"></script>
<script>
window.onload = function () {
var sidebar = document.getElementById('widget-wrapper')
var newDiv = document.createElement("div");
newDiv.id = "widget";
try {
sidebar.prepend(newDiv);
window.binanceBrokerPortalSdk.initBrokerSDK('#widget', {
apiHost: 'https://www.binance.com',
brokerId: 'R4BD3S82',
slideTime: 4e4,
});
} catch(err) {
console.log(err)
}
}
</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": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "search": "../assets/javascripts/workers/search.fcfe8b6d.min.js", "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.b1047164.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>