0

Minimal Question:

def smooth(indicator, aggregation, tick):
    storage.ZZZ = []
    storage.ZZZZ = []

is the pertinent part of my definition, when I call that definition I'm using:

MA_now_smooth = smooth(MA, IN, I)[-1]

where MA is an input array, IN and I are constants; the definition is further defined below but ultimately returns the last input to storage.ZZZZ. What I want is to create custom storage objects that are named according to the "indicator" input so that the persistent variables don't overlap when calling upon this definition for myriad array inputs.

ie

smooth(MA, IN, I)[-1]

should create:

storage.ZZZ_MA
storage.ZZZZ_MA

but

smooth(MA2, IN, I)[-1]

should create:

storage.ZZZ_MA2
storage.ZZZZ_MA2

In Depth Question:

I'm creating an Simple Moving Average smoothing definition for TA-lib indicators at tradewave.net; TA-lib is a library of black box functions that give "Financial Technical Analysis" array outputs for things like "moving average" "exponential moving average" "stochastic" etc. My definition is a secondary simple smoothing of these TA-lib functions.

I'm having to do this because when "aggregating" candles counting backwards from current, I'm getting "wiggly" outputs; you can read more about that here if you need background: https://discuss.tradewave.net/t/aggregating-candles-some-thoughts

My definition code works well to create a list of smoothed values when smoothing a single indicator "MA"; a TA-lib array:

import talib

def smooth(indicator, aggregation, tick):
    import math
    A = int(math.ceil(aggregation/tick))
    if info.tick == 0:
        storage.ZZZ = []
        storage.ZZZZ = []
    storage.ZZZ.append(indicator[-1])
    storage.ZZZ = storage.ZZZ[-A:]
    ZZZ = sum(storage.ZZZ) / len(storage.ZZZ)
    storage.ZZZZ.append(ZZZ)
    storage.ZZZZ = storage.ZZZZ[-250:]
    return storage.ZZZZ


def tick():

    I               = info.interval
    period          = 10
    IN              = 3600
    instrument      = pairs.btc_usd
    C               = data(interval=IN)[instrument].warmup_period('close')

    MA              = talib.MA(C, timeperiod=period, matype=0)  

    MA_now = MA[-1]
    MA_now_smooth = smooth(MA, IN, I)[-1]

    plot('MA', MA_now)
    plot('MA_smooth', MA_now_smooth)

However, when I attempt to smooth more than one indicator with the same definition, it fails because the persistent variables in the definition are the same for both MA and MA2. This does not work:

import talib

def smooth(indicator, aggregation, tick):
    import math
    A = int(math.ceil(aggregation/tick))
    if info.tick == 0:
        storage.ZZZ = []
        storage.ZZZZ = []
    storage.ZZZ.append(indicator[-1])
    storage.ZZZ = storage.ZZZ[-A:]
    ZZZ = sum(storage.ZZZ) / len(storage.ZZZ)
    storage.ZZZZ.append(ZZZ)
    storage.ZZZZ = storage.ZZZZ[-250:]
    return storage.ZZZZ

def tick():

    I               = info.interval
    period          = 10
    IN              = 3600
    instrument      = pairs.btc_usd
    C               = data(interval=IN)[instrument].warmup_period('close')

    MA              = talib.MA(C, timeperiod=period, matype=0)  
    MA2             = talib.MA(C, timeperiod=2*period, matype=0)  

    MA_now = MA[-1]
    MA2_now = MA2[-1]
    MA_now_smooth = smooth(MA, IN, I)[-1]
    MA2_now_smooth = smooth(MA2, IN, I)[-1]

    plot('MA', MA_now)
    plot('MA2', MA2_now)    
    plot('MA_smooth', MA_now_smooth)
    plot('MA2_smooth', MA2_now_smooth)    

What I would like to do... and don't understand how to do:

I'd like for the definition to create a new persistent storage object for each new input and I'd like for the names of my objects to detect the name of the "indicator" input, ie:

storage.ZZZ_MA
storage.ZZZZ_MA
ZZZ_MA

for the "MA" smoothing and

storage.ZZZ_MA2
storage.ZZZZ_MA2
ZZZ_MA2

for "MA2" smoothing

I would like to be able to reuse this definition with many different array inputs for "indicator" and for each instance use the name of the indicator array appended to the persistent object names used in the definition. For example:

storage.ZZZ_MA3
storage.ZZZ_MA4
etc.

In the instances below info.interval is my tick size of 15 minutes (900 sec) and my aggregation was 1 hour (3600 sec)

With the single output of "MA" and correct smoothing

With dual outputs of "MA" and "MA2" I'm getting incorrect smoothing

In the second image I'm looking for a two "smooth" lines one in the middle of the wiggly red plot and the other in the middle of wiggly blue plot. Instead I'm getting two identical wiggly lines (purple & orange) that split the difference. I understand why, but I don't know how to fix it.

1) please show me how

2) please tell me what I'm looking to do is "called" and point me to some tags/posts where I can learn more.

Thanks for your help!

LP

litepresence
  • 3,109
  • 1
  • 27
  • 35
  • 1
    I'm new here and I've done my best to write a "well received question" per the rules here: https://stackoverflow.com/help/on-topic If you're going to downvote my thread at least let me know why. – litepresence Jul 02 '14 at 23:02
  • Although I didn't downvote the question it is long-winded, and as far as I can see conflates two entirely separate issues. – holdenweb Jul 02 '14 at 23:43
  • My only question is how to create custom names for persistent variables within a definition with input from the first variable name. If you understand my question could you pose it in a more clear way? – litepresence Jul 02 '14 at 23:50
  • I'm also open to any alternative solutions to my dilemma... this is just the only way I could come up with to solve the problem. I included the "long-winded" stuff so you could understand the context of my circumstance and why I needed this solution. – litepresence Jul 02 '14 at 23:53
  • I understand why you _think_ you needed this solution, but using a dict is much preferable. Dynamically creating variables always runs risks (what happens if you are using a name that is overwritten by dynamic creation code?). I appreciate you tried to give as much context as possible. – holdenweb Jul 03 '14 at 00:02
  • The wiggly data issue is experienced by a large number of users for a large variety of array outputs. I was the individual that devised this smoothing method. The method has been well received as best way to deal with the issue by the community. It works very well if a new definition is written with new persistent variables in each definition. However, it just seems really redundant to clutter one's scripts with a bunch of nearly identical definitions. I'm looking to create a "universal" definition that anyone else can use to smooth multiple financial indicator arrays within one script. – litepresence Jul 03 '14 at 00:06
  • "what happens if you are using a name that is overwritten by dynamic creation code?" I was hoping to overcome this issue by using "ZZZ_" and "ZZZZ_" as prefixes. – litepresence Jul 03 '14 at 00:07

2 Answers2

1

Make storage a dict, and use string keys rather than trying to create and access dynamic variables?

holdenweb
  • 33,305
  • 7
  • 57
  • 77
0

Well I've arrived at an interim solution.

While I like this solution as its doing everything I need. I would like to eliminate the redundant "label" input. Is there any way for me to reference the name of my input parameter/argument "indicator" instead of its object so that I could return to my original 3 input parameters rather than 4?

I tried this:

def smooth(indicator, aggregation, tick):
    import math
    A = int(math.ceil(aggregation/tick))
    ZZZ = 'ZZZ_%s' % dict([(t.__name__, t) for t in indicator])
    ZZZZ = 'ZZZZ_%s' %  dict([(t.__name__, t) for t in indicator])
    if info.tick == 0:
        storage[ZZZ] = []
        storage[ZZZZ] = []
    storage[ZZZ].append(indicator[-1])
    storage[ZZZ] = storage[ZZZ][-A:]
    ZZZZZ = sum(storage[ZZZ]) / len(storage[ZZZ])
    storage[ZZZZ].append(ZZZZZ)
    storage[ZZZZ] = storage[ZZZZ][-250:]
    return storage[ZZZZ]

but I get:

File "", line 259, in File "", line 31, in tick File "", line 6, in smooth AttributeError: 'numpy.float64' object has no attribute 'name'

Here is my current 4 argument definition smoothing 4 different TA-lib moving averages. This same definition can be used with many other aggregated TA-lib indicators. It should work with ANY aggregate/tick size ratio including 1:1.

import talib

def smooth(indicator, aggregation, tick, label):

    import math
    A = int(math.ceil(aggregation/tick))
    ZZZ = 'ZZZ_%s' % label
    ZZZZ = 'ZZZZ_%s' % label
    if info.tick == 0:
        storage[ZZZ] = []
        storage[ZZZZ] = []
    storage[ZZZ].append(indicator[-1])
    storage[ZZZ] = storage[ZZZ][-A:]
    ZZZZZ = sum(storage[ZZZ]) / len(storage[ZZZ])
    storage[ZZZZ].append(ZZZZZ)
    storage[ZZZZ] = storage[ZZZZ][-250:]
    return storage[ZZZZ]

def tick():

    I               = info.interval
    period          = 10
    IN              = 3600
    instrument      = pairs.btc_usd
    C               = data(interval=IN)[instrument].warmup_period('close')

    MA1             = talib.MA(C, timeperiod=period, matype=0)  
    MA2             = talib.MA(C, timeperiod=2*period, matype=0)  
    MA3             = talib.MA(C, timeperiod=3*period, matype=0)  
    MA4             = talib.MA(C, timeperiod=4*period, matype=0)      

    MA1_now = MA1[-1]
    MA2_now = MA2[-1]
    MA3_now = MA3[-1]
    MA4_now = MA4[-1]    
    MA1_now_smooth = smooth(MA1, IN, I, 'MA1')[-1]
    MA2_now_smooth = smooth(MA2, IN, I, 'MA2')[-1]
    MA3_now_smooth = smooth(MA3, IN, I, 'MA3')[-1]
    MA4_now_smooth = smooth(MA4, IN, I, 'MA4')[-1]    

    plot('MA1', MA1_now)
    plot('MA2', MA2_now)  
    plot('MA3', MA3_now)
    plot('MA4', MA4_now)              
    plot('MA1_smooth', MA1_now_smooth)
    plot('MA2_smooth', MA2_now_smooth)    
    plot('MA3_smooth', MA3_now_smooth)
    plot('MA4_smooth', MA4_now_smooth)       

http://i.imgur.com/nVThZ3s.png

h/t james for collaboration

litepresence
  • 3,109
  • 1
  • 27
  • 35