0
votes

I'm running this python 3 code code:

import os
import csv
import glob
import numpy as np
import collections


Prices = collections.namedtuple('Prices', field_names=['time', 'open', 'high', 'low', 'close', 'volume'])


def read_csv(file_name, sep=',', filter_data=True, fix_open_price=False):
    print("Reading", file_name)                 
    with open(file_name, 'rt', encoding='utf-8') as fd:
        reader = csv.reader(fd, delimiter=sep)
        x = next(reader)                      
        if '<OPEN>' not in x and sep == ',':  
            return read_csv(file_name, ';') 
        indices = [x.index(s) for s in ('<TIME>', '<OPEN>', '<HIGH>', '<LOW>', '<CLOSE>', '<VOL>')]
        t, o, h, l, c, v = [], [], [], [], [], []
        count_out = 0
        count_filter = 0
        count_fixed = 0
        prev_vals = None
        for row in reader:
            vals = list(map(float, [row[idx] for idx in indices]))
            if filter_data and all(map(lambda v: abs(v-vals[0]) < 1e-8, vals[:-1])):
                count_filter += 1
                continue

            to, po, ph, pl, pc, pv = vals

            # fix open price for current bar to match close price for the previous bar
            if fix_open_price and prev_vals is not None:
                ppo, pph, ppl, ppc, ppv = prev_vals
                if abs(po - ppc) > 1e-8:
                    count_fixed += 1
                    po = ppc
                    pl = min(pl, po)
                    ph = max(ph, po)
            count_out += 1
            t.append(to)
            o.append(po)
            c.append(pc)
            h.append(ph)
            l.append(pl)
            v.append(pv)
            prev_vals = vals
    print("Read done, got %d rows, %d filtered, %d open prices adjusted" % (count_filter + count_out, count_filter, count_fixed))
    return Prices(time=np.array(t, dtype=np.int),
                  open=np.array(o, dtype=np.float32),
                  high=np.array(h, dtype=np.float32),
                  low=np.array(l, dtype=np.float32),
                  close=np.array(c, dtype=np.float32),
                  volume=np.array(v, dtype=np.float32))

def prices_to_relative(prices):
    """   
    Convert prices to relative in respect to open price
    :param ochl: tuple with open, close, high, low     
    :return: tuple with open, rel_close, rel_high, rel_low
    """   
    assert isinstance(prices, Prices)            
    rh = (prices.high - prices.open) / prices.open
    rl = (prices.low - prices.open) / prices.open
    rc = (prices.close - prices.open) / prices.open
    tm = prices.time
    return Prices(time=tm, open=prices.open, high=rh, low=rl, close=rc, volume=prices.volume)


def load_relative(csv_file):
    return prices_to_relative(read_csv(csv_file))


def price_files(dir_name):
    result = []
    for path in glob.glob(os.path.join(dir_name, "*.csv")):
        result.append(path)
    return result


def load_year_data(year, basedir='data'):
    y = str(year)[-2:] 
    result = {}        
    for path in glob.glob(os.path.join(basedir, "*_%s*.csv" % y)):
        result[path] = load_relative(path)
    return result      


load_relative(read_csv('/home/darfeder/Downloads/9781838826994_Code/Chapter10/data/YNDX_150101_151231.csv'))

And I'm getting this error:

TypeError: expected str, bytes or os.PathLike object, not Prices

The csv file loaded is like this:

20150105 100100 1064 1064 1064 1064 0
20150105 100200 1064 1064 1064 1064 0
20150105 100300 1064 1064 1064 1064 0
20150105 100400 1064 1064 1064 1064 0

The error is in the "prices_to_relative" function

Stack trace:

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) in 87 88 ---> 89 load_relative(read_csv('/home/darfeder/Downloads/9781838826994_Code/Chapter10/data/YNDX_150101_151231.csv'))

in load_relative(csv_file) 69 70 def load_relative(csv_file): ---> 71 return prices_to_relative(read_csv(csv_file)) 72 73

in read_csv(file_name, sep, filter_data, fix_open_price) 11 def read_csv(file_name, sep=',', filter_data=True, fix_open_price=False): 12 print("Reading", file_name) ---> 13 with open(file_name, 'rt', encoding='utf-8') as fd: 14 reader = csv.reader(fd, delimiter=sep) 15 x = next(reader)

TypeError: expected str, bytes or os.PathLike object, not Prices

1
You should give a stacktrace and indicate at what line in your code the error is raised. - Serge Ballesta
error shows you in which line you have problem and you could use print(...), print(type(...)) to see what you have in variables. - furas
load_relative needs only path like load_relative( '/home/darfeder/...' ) but you use collection from read_csv() in load_relative( read_csv(...) ) - furas

1 Answers

2
votes

Your code seems odd - there are several calls to read_csv when I'd have epxected to see only one, e.g.:

in main:

load_relative(read_csv('/home/darfeder/Downloads/9781838826994_Code/Chapter10/data/YNDX_150101_151231.csv'))

in load_relative:

return prices_to_relative(read_csv(csv_file))

in read_csv, a recursive call? (I guess this is probably OK, adapts to using ; as CSV separator):

return read_csv(file_name, ';') 

I'd say the problem is the first of those: pass the filename not the result of reading the file, so change it to:

load_relative('/home/darfeder/Downloads/9781838826994_Code/Chapter10/data/YNDX_150101_151231.csv')

Also you should open the csv file without specifying 'rt' and specify newline='' as per documentation examples https://docs.python.org/3/library/csv.html, so change:

with open(file_name, 'rt', encoding='utf-8') as fd:

to:

with open(file_name, newline='', encoding='utf-8') as fd:

As you don't provide sample data I don't have a way to test this - hopefully these suggestions resolve the problem.