FSD – Create moving average cross strategy

DISCLAIMER
The codes in this post is just for educational purpose, and not to be used on live trading

Let’s create a new strategy together. For this time, we create a strategy based of moving average crossover. First step, we need to calculate the moving averages. We need to import library needed to do the calculation. For this example, we need to import talib and qtpylib.

import freqtrade.vendor.qtpylib.indicators as qtpylib
import talib.abstract as ta

Then we set minimal roi and stoploss. FOr this example, we tell the bot to exit the trade whenever the bot reach 5% profit or -5% loss.

minimal_roi = {
    "0": 0.05
}
stoploss = -0.05

Then we calculate the fast and slow moving averages in populate_indicators

def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
	dataframe['ema_9'] = ta.EMA(dataframe['close'], 9)
	dataframe['ema_20'] = ta.EMA(dataframe['close'], 20)
	return dataframe

Now we need to create the entry logic. The logic is simple, ema_9 crossed above ema_20. We add (dataframe['volume'] > 0) in the logic to make sure we don’t buy idle coins.

def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        qtpylib.crossed_above(dataframe['ema_9'], dataframe['ema_20'])
        &
        (dataframe['volume'] > 0)
        , ['enter_long', 'enter_tag']
    ] = (1, 'golden cross')
    
    return dataframe

Next, we set the exit logic, which is when ema_9 crossed below ema_20

def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        qtpylib.crossed_below(dataframe['ema_9'], dataframe['ema_20'])
        &
        (dataframe['volume'] > 0)
        , ['exit_long', 'exit_tag']
    ] = (1, 'death cross')
    return dataframe

The complete file will look like this

from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib

class ma_cross (IStrategy):
	def version(self) -> str:
		return "ma-cross-v1"
	
	INTERFACE_VERSION = 3
	
	minimal_roi = {
		"0": 0.05
	}
	
	stoploss = -0.05
	timeframe = '15m'
	process_only_new_candles = True
	startup_candle_count = 999
	
	def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
		dataframe['ema_9'] = ta.EMA(dataframe['close'], 9)
		dataframe['ema_20'] = ta.EMA(dataframe['close'], 20)
		return dataframe
	
	def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
		dataframe['enter_long'] = 0
		
		dataframe.loc[
			qtpylib.crossed_above(dataframe['ema_9'], dataframe['ema_20'])
			&
			(dataframe['volume'] > 0)
			, ['enter_long', 'enter_tag']
		] = (1, 'golden cross')

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

		dataframe.loc[
			qtpylib.crossed_below(dataframe['ema_9'], dataframe['ema_20'])
			&
			(dataframe['volume'] > 0)
			, ['exit_long', 'exit_tag']
		] = (1, 'death cross')
			
		return dataframe

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *