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.