EMA(EMA) and DEMA: How to calculate using python and spreadsheetssteemCreated with Sketch.

in #trading6 years ago

This is the second in a series of posts about trading indicators, in which I talk about indicators that can be used to trade crypto (or anything else, actually) and offer a spreadsheet and python code to calculate them. Read more about the series at the bottom of this post.


emaema-dema.png

Shortcuts for the lazy

Intro

Moving Averages (MAs) are among the simplest indicators used for trading, but they are used everywhere. Traders can use MAs directly or can use other indicators that are based on MAs (there are many).

On this post I'll focus on the variations of moving averages called EMA(EMA) and DEMA. To know more about the basic MAs that are a requirement to understand this post, read my previous post first.

EMA(EMA) is just an EMA (Exponential Moving Average) calculated over the EMA values. So you calculate EMA once using a given type of input (usually the closing values of candles) and then you calculate the EMA again using the previously calculated EMA as input. Might sound complex at first, but it really isn't. The EMA(EMA) is not really used by itself, it's mostly calculated so that other indicators can be calculated based on it.

DEMA is the Double Exponential Moving Average, which is calculated based on the EMA and on the EMA(EMA). It is a more aggressive type of MA, that reacts to price changes even faster than the EMA. In other words, it's a moving average with less lag than the EMA.

Main features and how to use EMA(EMA) and DEMA

I won't go into all the details in this post since I already wrote about MAs in the previous one and since there's already a lot of content on it available on the internet (check the references below). So let's focus on the most important points to remind us of how MAs, and specially DEMA, can be used:

  • MAs indicate trend. They are the averages of prices, so they respond slower to prices than the actual prices themselves -- they are lagging indicators. DEMA is a variant that responds faster than the EMA and the SMA.
  • They can be used in pairs to detect crossovers that can represent trend changes. As the DEMA moves faster, it allows for trend changes to be detected faster, with the caveat that it might trigger more false alarms.
  • There are indicators that use MAs as a building block, such as the MACD. These indicators allow traders to select the type of MA they want to use, DEMA usually being one of the options.
  • There are trading strategies that use MAs to detect buy or sell signals, such as the Open Close Cross Strategy (OCC). These strategies also allow traders to select the type of MA to be used, including the DEMA.
  • MAs can become resistance or support lines.

btcusdt-sma-ema-dema.png
(You can see in this example how the DEMA, in yellow, moves much faster than both the SMA and the EMA, in blue and purple. In the section where the dashed lines cross, the DEMA is almost $2k below the other indicators.)

How to calculate

In the previous post we saw how to calculate SMA and EMA. Both are used to calculate the target MAs of this post, the EMA(EMA) and the DEMA.

Spreadsheet

If you like to learn by example, check the spreadsheet showing how this indicator is calculated with real examples. Look at the cells in the spreadsheet and you will see the formulas used to get to those values.

EMA(EMA)

To calculate the EMA of an EMA, apply the same formula of a "standard" EMA over the pre-calculated EMA values.

So, going step by step, you first calculate the EMA using the price as the input:

  1. Calculate the multiplier:
    • Multiplier = (2 / (length + 1))
    • Where length is the length of the EMA you want (e.g. for the EMA(20), length is 20)
  2. Calculate the first EMA:
    • First EMA = SUM(prices) / length
    • Where prices is an array with the closing price of the first length candles
  3. Calculate all other EMAs:
    • EMA = (price * multiplier) + (EMAp * (1 - multiplier))
    • Where price is the closing price of the current candle
    • Where EMAp is the EMA calculated for the previous candle

Now, having the EMA for each candle, use them as the input for the same calculation done above. Just replace the price by the ema:

  1. Calculate the multiplier as before:
    • Multiplier = (2 / (length + 1))
  2. Calculate the first EMA(EMA):
    • First EMA(EMA) = SUM(EMAs) / length
    • Where EMAs is an array with the EMAs of the first length candles
  3. Calculate all other EMA(EMA)s:
    • EMA(EMA) = (EMA * multiplier) + (EMA(EMA)p * (1 - multiplier))
    • Where EMA is the EMA of the current candle
    • Where EMA(EMA)p is the EMA(EMA) calculated for the previous candle

DEMA

Here things get a lot simpler, because once you have the EMA(EMA) calculated you've already done 90% of the work. The DEMA is calculated with:

DEMA = 2*EMA – EMA(EMA)

Putting it in words, just multiply the current EMA by two and subtract the current EMA(EMA). Easy, right?

Note that, since the DEMA is based on the EMA(EMA) and the latter is calculated based on the EMA, the first DEMA you will be able to calculate is for the candle number 2 * length. For example, the first EMA(5) you can calculate is for the 5th candle, since you need 5 values to calculate it. For EMA(EMA(5)) you need 5 EMA(5) values, which you will only get in the 10th candle. This usually doesn't matter much because in the long term you will always have enough candles, but it's nice to know.

Show me the code

The code should be ran using python 3. It reads the candles from the file input.csv that you can download here. It contains daily candles for the symbol BTCUSDT on Binance.

You can change the parameters at the top of the file, that by default will calculate the EMA(EMA(5)) and DEMA(5) of the candles in the input file using the closing price of the candles. Edit the file accordingly, save it as dema.py and simply run it with python3 dema.py. You need to have the input.csv file in the same directory.

You can then double check the results with the values in the spreadsheet to confirm everything is correct!

import csv
import re
from functools import reduce
from dateutil import parser

CSV_FILE = 'input.csv'
EMA_LENGTH = 5
EMA_SOURCE = 'close'

candles = []

# Reads the input file and saves to `candles` all the candles found. Each candle is
# a dict with the timestamp and the OHLC values.
def read_candles():
    with open(CSV_FILE, 'r') as csvfile:
        reader = csv.reader(csvfile, delimiter=',')
        for row in reader:
            try:
                candles.append({
                    'ts': parser.parse(row[0]),
                    'low': float(re.sub(",", "", row[1])),
                    'high': float(re.sub(",", "", row[2])),
                    'open': float(re.sub(",", "", row[3])),
                    'close': float(re.sub(",", "", row[4]))
                })
            except:
                print('Error parsing {}'.format(row))

# Calculates the SMA of an array of candles using the `source` price.
def calculate_sma(candles, source):
    length = len(candles)
    sum = reduce((lambda last, x: { source: last[source] + x[source] }), candles)
    sma = sum[source] / length
    return sma

# Calculates the EMA of an array of candles using the `source` price.
def calculate_ema(candles, source):
    length = len(candles)
    target = candles[0]
    previous = candles[1]

    # if there is no previous EMA calculated, then EMA=SMA
    if 'ema' not in previous or previous['ema'] == None:
        return calculate_sma(candles, source)

    else:
        # multiplier: (2 / (length + 1))
        # EMA: (close * multiplier) + ((1 - multiplier) * EMA(previous))
        multiplier = 2 / (length + 1)
        ema = (target[source] * multiplier) + (previous['ema'] * (1 - multiplier))

        return ema

# Calculates the EMA(EMA) of an array of candles.
def calculate_ema_ema(candles):
    length = len(candles)
    target = candles[0]
    previous = candles[1]

    # all previous candles need to have an EMA already, otherwise we can't calculate EMA(EMA)
    have_ema = list(filter(lambda a: 'ema' in a and a['ema'] != None, candles[1:]))
    if len(have_ema) >= length - 1:

        # if there is no previous EMA(EMA) calculated yet, then EMA(EMA)=SMA(EMA)
        if 'ema_ema' not in previous or previous['ema_ema'] == None:
            return calculate_sma(candles, 'ema')

        # if there is a previous EMA(EMA), it is used
        else:
            # multiplier: (2 / (length + 1))
            # EMA(EMA): (EMA * multiplier) + ((1 - multiplier) * EMA(EMA, previous))
            multiplier = 2 / (length + 1)
            ema_ema = (target['ema'] * multiplier) + (previous['ema_ema'] * (1 - multiplier))

            return ema_ema

    else:
        return None

# Calculates the DEMA of an array of candles.
def calculate_dema(candles):
    target = candles[0]

    # can only calculate the DEMA if we have the EMA and the EMA(EMA) if the target candle
    if 'ema' not in target or 'ema_ema' not in target or target['ema'] == None or target['ema_ema'] == None:
        return None

    else:
        # DEMA = 2*EMA – EMA(EMA)
        dema = (2 * target['ema']) - target['ema_ema']
        return dema

def calculate(candles, source):
    candles[0]['sma'] = calculate_sma(candles, source)
    candles[0]['ema'] = calculate_ema(candles, source)
    candles[0]['ema_ema'] = calculate_ema_ema(candles)
    candles[0]['dema'] = calculate_dema(candles)

if __name__ == '__main__':
    read_candles()

    # progress through the array of candles to calculate the indicators for each
    # block of candles
    position = 0
    while position + EMA_LENGTH <= len(candles):
        current_candles = candles[position:(position+EMA_LENGTH)]
        current_candles = list(reversed(current_candles))
        calculate(current_candles, EMA_SOURCE)
        position += 1

    for candle in candles:
        if 'sma' in candle:
            print('{}: sma={} ema={} ema(ema)={} dema={}'.format(candle['ts'], candle['sma'], candle['ema'], candle['ema_ema'], candle['dema']))

(Script also available as a gist)

References


About the series

This is a series of posts about trading indicators, in which I talk about indicators that can be used to trade crypto (or anything else, actually). You can already find extensive information about most of these indicators on the internet, but it isn't always easy to find reliable and detailed information on how to calculate them. So I show a very concise explanation of how they work and then focus on explaining their formulas, including a spreadsheet and code snippets in all the posts so you can calculate the indicators yourself!

Some indicators are extremely simple to calculate (SMA is one of them), but some are kinda tricky. You might spend hours trying to adjust parameters and formulas to get them right (I know that I did). Or you can just get the code here and use it smile

The code is usually written in python and validated against TradingView, a reliable source of price information and indicator values.

Read the previous posts at:


Disclaimer: This is not financial advice, I write for informational and educational purposes only. This article expresses solely my opinion, make of it what you wish.

Sort:  

hey, this post resteemed by @manikchandsk to over 7600 followers and voted. good luck
thanks for using our service.
send 0.300 sbd or steem to @manikchandsk and keep post link in memo that you want resteem + 40 upvote +@manikchandsk 100%upvote.
click for details..https://steemit.com/manikchandsk/@manikchandsk/post-resteem-upvote-service

Resteemed to over 18900 followers and 100% upvoted. Thank you for using my service!

Send 0.200 Steem or 0.200 Steem Dollars and the URL in the memo to use the bot.
Read here how the bot from Berlin works.

#resteembot #bestofresteembot #winwithresteembot

@resteem.bot

Feel free to join our partner crypto exchange: https://www.binance.com/?ref=10230705.

@resteem.bot

@resteemator is a new bot casting votes for its followers. Follow @resteemator and vote this comment to increase your chance to be voted in the future!

Coin Marketplace

STEEM 0.30
TRX 0.40
JST 0.061
BTC 95809.07
ETH 3681.84
SBD 4.03