1
\$\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.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Sep 9, 2011 at 2:24
\$\endgroup\$

1 Answer 1

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)
answered Sep 9, 2011 at 3:29
\$\endgroup\$
8
  • \$\begingroup\$ @ winston the answers dont match. \$\endgroup\$ Commented Sep 11, 2011 at 15:42
  • 1
    \$\begingroup\$ @Merlin, I didn't test what I wrote. But hopefully it gives you some idea of how to improve your existing code. \$\endgroup\$ Commented Sep 11, 2011 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\$ Commented Sep 11, 2011 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\$ Commented Sep 11, 2011 at 18:16
  • \$\begingroup\$ @winston...the on numpy.roll, how can you 'roll' only one column in array? tIA \$\endgroup\$ Commented Sep 11, 2011 at 18:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.