Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
232 views
in Technique[技术] by (71.8m points)

pandas datareader - Declaring an instance of a class in a for loop: Python

I have been working on a project involving the stock market, and created my own class for it, however when I run this code I get an error

import stock_class as st

for i in names:
    string = str(i)
    stonk = st.stock(string, datetime.datetime(2016,12,31),datetime.datetime.now())
    wSTD = stonk.standard_deviation() * weight[0]

When I run this same code outside of the loop it works just fine, so I think it may be a weird python thing where you can't declare an instance class with an iterated variable. However weird it may seem. here is the error I get in response to the following code running:

pandas_datareader._utils.RemoteDataError: No data fetched for symbol CHOLF using YahooDailyReader

let me know if anyone needs further information, thank you.

Here is the library I made and called:

import numpy as np
import pandas as pd
import yfinance as yf
import datetime as datetime
import pandas_datareader.data as web
import os
import math

class stock:

    def __init__(self, name, start, end):
        self.name = name #string
        self.start = start
        self.end = end # datetime funtion
        
    
    def history_data(self):
        hist = web.DataReader(self.name,'yahoo',self.start, self.end)
        return hist
        
        
    def returnP(self):
        stonk = self.history_data()
        close = stonk['Close']
        returnlist = []
        for i in range(len(close)):
            if i != 0:
                returnVal = (close[i]/close[i-1])-1
                returnlist.append(returnVal)
            else:
                returnlist.append(0)
        stonk['Return'] = returnlist  #hopefully places a new column for the return rate
        return stonk
    
    def standard_deviation(self):
        stonk = self.returnP()
        array = []
        mean = sum(stonk['Return'])/stonk.count()['Return']
        for i in range(stonk.count()['Return']):
            array.append((stonk['Return'][i] - mean)**2)
        std = math.sqrt(sum(array)/len(array))
        return std
    
    def cum_return(self):
        stonk = self.returnP()
        stonk['Cumreturn'] = (stonk['Return']+1).cumprod()
        return stonk
    
    def yfticker(self): #should not be called by user
        stonk = yf.Ticker(self.name)
        info = stonk.info
        return info
    
    def PEG(self):
        info = self.yfticker()
        PEG = info['pegRatio']
        return PEG
    
    def FPE(self):
        info = self.yfticker()
        FPE = info['forwardPE']
        return FPE
    
    def price_book(self):
        info = self.yfticker()
        priceToBook = info['priceToBook']
        return priceToBook 

as previously aforementioned, this code works by itself, here is the code where the error takes place in the buy() function

import stock_class as st
import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import datetime
import time
class descision:

    def __init__(self, names, money): # takes an array of stocks so we can value
        self.names = names           # dem bitches ['tsla', 'fb', 'aapl', ... ]
        self.money = money

    def buy(self):
        weight = [.5, .25, .25] # weights for STD, FPE, and PEG
        money = self.money
        split = money/10
        names = self.names
        pair = {}
        buying = [] #going into dataframe
        FPE = []
        PEG = []
        STD = []
        price = [] # going into dataframe
        date = []
        amtBought = []
        for i in names:
            string = str(i)
            print(i)
            
            stonk = st.stock(string, datetime.datetime(2016,12,31),datetime.datetime.now())
            print('1')
            wSTD = stonk.standard_deviation() * weight[0]
            print(wSTD)
            wFPE = stonk.FPE() * weight[1]
            wPEG = stonk.PEG() * weight[2]
            heafty = (wSTD + wFPE + wPEG)
            pair[i] = heafty
        for i in range(10):
            buying.append(max(pair))
            pair.pop(max(pair))
        for i in buying:
            stock = yf.Ticker(i)
            hist = stock/history('1d')
            buyPrice = hist['Close'][-1]
            price.append(buyPrice)
            date.append(datetime.datetime.now())
            amtBought.append(split/buyPrice)
        tuples = list(zip(buying, price, date, amtBought))
        df = pd.DataFrame(tuples, columns = ['Names', 'Buy Price',
                                             'Date Purchased' ,' Amount'])
        return df
                          
        
        
        # buy from the stocks in the growers with the least volitility,
        # PE, and PEG

    #def sell(self):
        

file = open('growers.txt','r')
names = []
money = 1000
for i in file:
    names.append(str(i))
y = descision(names, money)
y.buy()

I hope my edit provides enough information

question from:https://stackoverflow.com/questions/65649523/declaring-an-instance-of-a-class-in-a-for-loop-python

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It seems there's nothing wrong with creating an object of that class on each iteration of the for loop... It's more likely to be about the stock market return value than the objects.

Just to show you that you can create the objects inside the loop:

class Kid:
def __init__(self, age, name, city):
    self.age = age
    self.name = name
    self.city = city

def AgeIn5Years(self):
    return self.age + 5


kids = [Kid(i, f'Jhon {i}', 'London') for i in range(11, 16)]

[print(kid.AgeIn5Years()) for kid in kids]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...