Search code examples
python-3.xpandasfunctioniterationalpha-vantage

How do I iterate through combinations of two lists and perform a function each time?


Doing an Alphavantage API pull for historic stock data. I'm pulling one of their indicators. Instead of writing 36 separate functions and manually pulling, I'd like to iterate through the 36 possible combinations and do the pull each time with different variables (the variables being each of the combinations). Below is my code. It currently returns "NONE". What am I doing wrong?

Also, is there a way to combine these two functions into one?

Thanks!

def get_ppo_series(matype, series_type):
    pull_parameters = {
        'function': 'PPO',
        'symbol': stock,
        'interval': interval,
        'series_type': series_type,
        'fastperiod': 12,
        'slowperiod': 26,
        'matype': matype,
        'datatype': 'json',
        'apikey': key
    }
    column = 0
    pull = rq.get(url, params=pull_parameters)
    data = pull.json()
    df = pd.DataFrame.from_dict(data['Technical Analysis: PPO'], orient='index', dtype=float)
    df.reset_index(level=0, inplace=True)
    df.columns = ['Date', 'PPO Series ' + str(column)]
    df.insert(0, 'Stock', stock)
    column += 1
    return df.tail(past_years * annual_trading_days)

def run_ppo_series():
    matype = list(range(8))
    series_type = ['open', 'high', 'low', 'close']
    combinations = product(matype, series_type)
    for matype, series_type in combinations:
        get_ppo_series(matype, series_type)

print(run_ppo_series())

I also tried the following. This version at least ran one iteration and returned data. But it stops there ???

def get_ppo_series():
    column = 0
    matype = list(range(8))
    series_type = ['open', 'high', 'low', 'close']
    combinations = product(matype, series_type)
    for matype, series_type in combinations:
        pull_parameters = {
            'function': 'PPO',
            'symbol': stock,
            'interval': interval,
            'series_type': series_type,
            'fastperiod': 12,
            'slowperiod': 26,
            'matype': matype,
            'datatype': 'json',
            'apikey': key
        }
        pull = rq.get(url, params=pull_parameters)
        data = pull.json()
        df = pd.DataFrame.from_dict(data['Technical Analysis: PPO'], orient='index', dtype=float)
        df.reset_index(level=0, inplace=True)
        df.columns = ['Date', 'PPO Series ' + str(column)]
        df.insert(0, 'Stock', stock)
        column += 1
        return df.tail(past_years * annual_trading_days)

print(get_ppo_series())

Solution

  • import requests as rq
    import itertools
    
    url = 'https://www.alphavantage.co/query?'
    key = 'get your own key'
    
    def get_ppo_series(matype, series_type):
        pull_parameters = {
            'function': 'PPO',
            'symbol': 'msft',
            'interval': '60min',
            'series_type': series_type,
            'fastperiod': 12,
            'slowperiod': 26,
            'matype': matype,
            'datatype': 'json',
            'apikey': key
        }
        column = 0
        pull = rq.get(url, params=pull_parameters)
        data = pull.json()
        print('*' * 50)
        print(f'MAType: {matype}, Series: {series_type}')
        print(data)
    
    def run_ppo_series():
        matype = list(range(8))
        series_type = ['open', 'high', 'low', 'close']
        combinations = itertools.product(matype, series_type)
        for matype, series_type in combinations:
            get_ppo_series(matype, series_type)
    
    run_ppo_series()
    
    1. The code above works without issue once symbol and interval values are supplied.
    2. Thank you for using Alpha Vantage! Our standard API call frequency is 5 calls per minute and 500 calls per day
    3. I didn't bother with the DataFrame portion of get_ppo_series because it's not relevant for receiving the data
    4. I would leave the functions separate, it looks cleaner and I think it's standard for a function to do 1 thing.
    5. A counter can be added to the code and time.sleep(60) after every 5 iterations unless you have a different API call frequency

    Function with 60 second wait after every 5 api calls

    import time
    
    def run_ppo_series():
        matype = list(range(8))
        series_type = ['open', 'high', 'low', 'close']
        combinations = itertools.product(matype, series_type)
        count = 0
        for matype, series_type in combinations:
            if (count%5 == 0) & (count != 0):
                time.sleep(60)
            get_ppo_series(matype, series_type)
            count+=1