freqtrade / freqtrade

Free, open source crypto trading bot
https://www.freqtrade.io
GNU General Public License v3.0
28.13k stars 6.03k forks source link

Building the strategy with EMA crossovers? #3700

Closed kiandp closed 4 years ago

kiandp commented 4 years ago

Describe your environment

Your question

Ask the question you have not been able to find an answer in our Documentation

kiandp commented 4 years ago

Hi dear fellows, I am trying to build a strategy with EMA cross-overs. I am using these code for my buy and sell signals and I don't get any error and its looks fine, however, when I run the strategy , the bot will buy and sell differently as I programmed it. My objection is to buy when ema8_corsses above ema-30 and sell when ema3_crosses below ema-8. it's pretty simple code but I couldn't find concept for a cross above and cross below in TA_LIB for ema-crossovers functions. when I use :

dataframe.loc[

        (
                (qtpylib.crossed_above(dataframe['ema8'], dataframe['ema30'])) &

        'buy'] = 1

& dataframe.loc[ ( (qtpylib.crossed_below(dataframe['ema3'], dataframe['ema8']))

        ),
        'sell'] = 1
    return dataframe

# when i use this command "(qtpylib.crossed_above(dataframe['ema8'], dataframe['ema30'])) " does it mean it will buy when ema-8 crosses above ema30 from below. I don't want to use price I want to use ema integrations with each other. please help me to understand and evolve this strategy. thanks

xmatthias commented 4 years ago

I'm not sure where the question is.

This seems like okish code - and it'll do exactly what it says - it'll buy when EMA8 crosses EMA30 from below (so EMA8 was below EMA30 on the previous candle, and is now above EMA30).

We would recommend to also include volume in the mix, mainly to ensure that backtesting is not buying on "empty" candles - but that's about it.

kiandp commented 4 years ago

Thanks for your fast response. I really appreciate your help and thanks again for sharing your knowledge. I added volume as you said thanks for the tip. With this code:

(dataframe['mean-volume'] > 0.75)

The problem is ema30 cross-above works as it Supposed to but the problem is it doesn't buy right of the bat, it will buy after price moved up and has already crossed ema30. I am trying to buy at the exact moment when ema8 crosses ema30. I suspected this problem occured becuase order book and pair spread but after carefull investigation i noticed , bot will buy after it already crossed over ema8 over ema30,not exactly at the exact moment. & Another problem i encountred with is the bot will buy in sideways market whenever all ema values are the same,when ema8 is equal ema30. Its shouldn't be this way,i think i am missing something here 2-This is my another question?! Since there is no range for "EMA" ,we have to define each ema individually in python. So in optimization with hyperopt i can't give a range to it and i am little bit confused about what value should i put in guards section if i want to check with ema cross overs works better for that dataset. Thanks for your time.

kiandp commented 4 years ago

This is how the code looks like:

pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement

import talib.abstract as ta from pandas import DataFrame

import freqtrade.vendor.qtpylib.indicators as qtpylib from freqtrade.strategy.interface import IStrategy

class EMA(IStrategy): """ Default Strategy provided by freqtrade bot. You can override it with your own strategy """

# Minimal ROI designed for the strategy
minimal_roi = {
    "40": 0.0,
    "30": 0.01,
    "20": 0.02,
    "0": 0.04
}

# Optimal stoploss designed for the strategy
stoploss = -0.10

# Optimal ticker interval for the strategy
ticker_interval = '4h'

# Optional order type mapping
order_types = {
    'buy': 'limit',
    'sell': 'limit',
    'stoploss': 'limit',
    'stoploss_on_exchange': False
}

# Optional time in force for orders
order_time_in_force = {
    'buy': 'gtc',
    'sell': 'gtc',
}

def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame

    Performance Note: For the best performance be frugal on the number of indicators
    you are using. Let uncomment only the indicator you are using in your strategies
    or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
    :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
    :param metadata: Additional information, like the currently traded pair
    :return: a Dataframe with all mandatory indicators for the strategies
    """

            # EMA - Exponential Moving Average
    dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
    dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
    dataframe['ema8'] = ta.EMA(dataframe, timeperiod=8)
    dataframe['ema30'] = ta.EMA(dataframe, timeperiod=30)
    dataframe['ema25'] = ta.EMA(dataframe, timeperiod=25)
    dataframe['mean-volume'] = dataframe['volume'].mean()

    return dataframe

def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    """
    Based on TA indicators, populates the buy signal for the given dataframe
    :param dataframe: DataFrame
    :param metadata: Additional information, like the currently traded pair
    :return: DataFrame with buy column
    """
    dataframe.loc[
        (
                (qtpylib.crossed_above(dataframe['ema8'], dataframe['ema30'])) &
                (dataframe['mean-volume'] > 0.75)

        ),
        'buy'] = 1

    return dataframe

def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    """
    Based on TA indicators, populates the sell signal for the given dataframe
    :param dataframe: DataFrame
    :param metadata: Additional information, like the currently traded pair
    :return: DataFrame with buy column
    """
    dataframe.loc[
        (
                (qtpylib.crossed_below(dataframe['ema3'], dataframe['ema8'])) &
                ((dataframe['ema5']> dataframe['ema8']))
        ),
        'sell'] = 1
    return dataframe
xmatthias commented 4 years ago

dataframe['mean-volume'] = dataframe['volume'].mean() Please don't do this - it's one of the pitfals mentioned in the documentation.

Freqtrade will never buy right "at the cross" - but will buy at open of the subsequent candle.

However, also manually, you can't buy right "at the cross" - as that would mean that you rely on incomplete candle. This could however mean that halfway through the candle, there happens the cross - but price drops afterwards - and at candle's close, the cross is not happening anymore. This behaviour is called repainting - and is something dangerous, as it can create buys which are unexplicable.

I would recommend to read through the documentation to get a full understanding on how freqtrade works, and so you are aware of the pitfalls that there are (like the volume-trap above).

Please note that issues here should be used for technical problems, not for "please write a strategy for me". Feel free to join our slack channel to discuss questions around stratgies, where our community can help in case of questions.

xmatthias commented 4 years ago

Going to close this as i think the initial question was answered - and questions in the form of "help me get my strategy idea to code" should not be made in the issue-tracker, but rather asked in the slack community.