0
\$\begingroup\$

How can I rework the code up that ema(x, 5) returns the data now in emaout? I'm trying to enclose everything in one def.

Right now its in a for loop and a def.

x = [32.47, 32.70, 32.77, 33.11, 33.25, 33.23, 33.23, 33.0, 33.04, 33.21]

def ema(series, period, prevma):
    smoothing = 2.0 / (period + 1.0)                
    return prevma + smoothing * (series[bar] - prevma)

prevema = x[0] 
emaout =[]

for bar, close in enumerate(x):
    curema = ema(x, 5, prevema) 
    prevema = curema
    emaout.append(curema)

print 
print emaout

x could be a NumPy array.

\$\endgroup\$
2
\$\begingroup\$
  1. ema uses series in one place, where it references series[bar]. But bar is a global variable which is frowned upon. Let's pass series[bar] instead of series to ema.
  2. That would be series[bar] in the for loop, but series[bar] is the same thing as close, so let's pass that instead.
  3. ema's period is only used to calculate smoothing. Let's calculate smoothing outside and pass it in.
  4. But now ema's a single line, so let's inline it
  5. Let's put all of that logic inside a function
  6. We use enumerate in the for loop, but we don't use bar

Result:

x = [32.47, 32.70, 32.77, 33.11, 33.25, 33.23, 33.23, 33.0, 33.04, 33.21]

def function(x, period):
    prevema = x[0] 
    emaout =[]

    smoothing = 2.0 / (period + 1.0)                
    for close in x:
        curema = prevma + smoothing * (close - prevma) 
        prevema = curema
        emaout.append(curema)

    return prevema
print 
print function(x, 5)

We can better by using numpy.

def function(x, period):
    smoothing = 2.0 / (period + 1.0)                
    current = numpy.array(x) # take the current value as a numpy array

    previous = numpy.roll(x,1) # create a new array with all the values shifted forward
    previous[0] = x[0] # start with this exact value
    # roll will have moved the end into the beginning not what we want

    return previous + smoothing * (current - previous)
\$\endgroup\$
  • \$\begingroup\$ @ winston the answers dont match. \$\endgroup\$ – Merlin Sep 11 '11 at 15:42
  • \$\begingroup\$ @Merlin, I didn't test what I wrote. But hopefully it gives you some idea of how to improve your existing code. \$\endgroup\$ – Winston Ewert Sep 11 '11 at 17:38
  • \$\begingroup\$ @merlin, numpy.roll([1,2,3,4], 1) == numpy.array(4,1,2,3) It shifts all of the elements in the array by one. That way when I subtract the original and rolled arrays I get the difference from one to the next. \$\endgroup\$ – Winston Ewert Sep 11 '11 at 18:15
  • \$\begingroup\$ @merlin, you are supposed to @ username of person you are talking to, not @ yourself. You don't need to when commenting on my questions because I am automatically alerted about those \$\endgroup\$ – Winston Ewert Sep 11 '11 at 18:16
  • \$\begingroup\$ @winston...the on numpy.roll, how can you 'roll' only one column in array? tIA \$\endgroup\$ – Merlin Sep 11 '11 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.