Reputation: 1083
I am trying to test a Python library called Tulip dynamically. To do it I need to call the proper ti.<indicator_name>
and pass the arguments to call the method.
The problem is, each method has fixed number of parameters and I don't know how to pass it properly.
Let's say I want to test ti.sma
method that requires two arguments real and period
def sma(real, period):
"""
Simple Moving Average
"""
return lib.sma([real], [period])
So, I would need to call it as:
sma_test = ti.sma(real=[25,20,22,30,22,28,25,30,21,23,24,22], period=5)
So my question is, how do I call the method above dynamically using the json below as payload?
{
"short_name": "sma",
"data": [74.333511, 73.61084, 74.197395, 73.848442, 75.036385, 76.630219, 76.803459, 77.385063],
"period": 5
}
I have made this validator where I could get the function object but how about the parameters?
import pandas as pd
import numpy as np
import tulipy as ti
import datetime
import uuid
import inspect
def validate_indicator(payload):
data = np.array(payload.get('data'))
try:
indicator = getattr(ti, payload.get('short_name'))
validation_test = indicator(data)
If I run the code above I get the Exception TypeError
obviously because I didn't pass the required argument period
in output = indicator(data)
. I believe the way to get there is to make a new function with optional *args
validate_indicator(
{
"short_name": "sma",
"data": [74.333511, 73.61084, 74.197395, 73.848442, 75.036385, 76.630219, 76.803459, 77.385063],
"period": 5
}
)
Result:
"sma() missing 1 required positional argument: 'period'"
Another example, if I want to test ti.bbands
that requires real, period and stddev as arguments.
def bbands(real, period, stddev):
"""
Bollinger Bands
"""
return lib.bbands([real], [period, stddev])
Upvotes: 0
Views: 110
Reputation: 692
You actually can use **kwargs
:
File test.py
import test2
data = {
"short_name": "sma",
"data": [74.333511, 73.61084, 74.197395, 73.848442, 75.036385, 76.630219, 76.803459, 77.385063],
"period": 5
}
f = getattr(test2, data.pop('short_name'))
f(**data)
File test2.py
:
def sma(data, period):
print(data)
print(period)
> python3 test.py
[74.333511, 73.61084, 74.197395, 73.848442, 75.036385, 76.630219, 76.803459, 77.385063]
5
Note:
If you want to use *args
, you could call the function as:
f(*[value for value in data.values()])
This would be a function that accepts the data dict as a parameter and calls the corresponding function for you:
def validate_function(data):
f = getattr(ti, data.pop('short_name'))
f(**data)
Upvotes: 1