【问题标题】:How to import multiple stock prices with pandas through yahoo?如何通过yahoo用pandas导入多个股票价格?
【发布时间】:2020-09-12 11:16:55
【问题描述】:

所以我尝试使用 pandas 和 panadas 数据阅读器获取多个股票价格。如果我只尝试导入一个代码,它将运行良好,但如果我使用多个,则会出现错误。代码是:

import pandas as pd
import pandas_datareader as web
import datetime as dt
stocks = ['BA', 'AMD']
start = dt.datetime(2018, 1, 1)
end = dt.datetime(2020, 1, 1)
d = web.DataReader(stocks, 'yahoo', start, end) 

虽然我得到了错误:

ValueError: Wrong number of items passed 2, placement implies 1

那么我该如何绕过它只允许通过 1 只股票。 到目前为止,我已经尝试使用 quandl 和 google,但它们也不起作用。我也尝试过pdr.get_data_yahoo,但我得到了相同的结果。我也尝试过yf.download(),但仍然遇到同样的问题。有没有人有任何想法来解决这个问题?谢谢。

编辑:完整代码:

import pandas as pd
import pandas_datareader as web
import datetime as dt
import yfinance as yf
import numpy as np
stocks = ['BA', 'AMD', 'AAPL']
start = dt.datetime(2018, 1, 1)
end = dt.datetime(2020, 1, 1)
d = web.DataReader(stocks, 'yahoo', start, end)
d['sma50'] = np.round(d['Close'].rolling(window=2).mean(), decimals=2)
d['sma200'] = np.round(d['Close'].rolling(window=14).mean(), decimals=2)
d['200-50'] = d['sma200'] - d['sma50']
_buy = -2
d['Crossover_Long'] = np.where(d['200-50'] < _buy, 1, 0)
d['Crossover_Long_Change']=d.Crossover_Long.diff()
d['buy'] = np.where(d['Crossover_Long_Change'] == 1, 'buy', 'n/a')
d['sell'] = np.where(d['Crossover_Long_Change'] == -1, 'sell', 'n/a')
pd.set_option('display.max_rows', 5093)
d.drop(['High', 'Low', 'Close', 'Volume', 'Open'], axis=1, inplace=True)
d.dropna(inplace=True)
#make 2 dataframe
d.set_index(d['Adj Close'], inplace=True)
buy_price = d.index[d['Crossover_Long_Change']==1]
sell_price = d.index[d['Crossover_Long_Change']==-1]
d['Crossover_Long_Change'].value_counts()
profit_loss = (sell_price - buy_price)*10
commision = buy_price*.01
position_value = (buy_price + commision)*10
percent_return = (profit_loss/position_value)*100
percent_rounded = np.round(percent_return, decimals=2)
prices = { 
    "Buy Price" : buy_price,
    "Sell Price" : sell_price,
    "P/L" : profit_loss,
    "Return": percent_rounded
}
df = pd.DataFrame(prices)
print('The return was {}%, and profit or loss was ${} '.format(np.round(df['Return'].sum(), decimals=2), 
                                                               np.round(df['P/L'].sum(), decimals=2)))
d

【问题讨论】:

  • @Trenton McKinney 感谢您的回复,我已经看过该页面并尝试过,但我仍然收到无法传递 2 个对象的相同错误。
  • 对不起,我不明白这个问题 - 你不是通过了 2 只股票 ['BA', 'AMD'] 并且这段代码不工作吗?

标签: python pandas yahoo-finance pandas-datareader


【解决方案1】:

我在您的代码中尝试了 3 只股票,它返回所有 3 只股票的数据,不确定我是否理解您面临的问题?

import pandas as pd
import pandas_datareader as web
import datetime as dt
stocks = ['BA', 'AMD', 'AAPL']
start = dt.datetime(2018, 1, 1)
end = dt.datetime(2020, 1, 1)
d = web.DataReader(stocks, 'yahoo', start, end)
print(d)

输出:

Attributes   Adj Close                              Close                         ...        Open                            Volume
Symbols             BA        AMD        AAPL          BA        AMD        AAPL  ...          BA        AMD        AAPL         BA          AMD        AAPL
Date                                                                              ...
2018-01-02  282.886383  10.980000  166.353714  296.839996  10.980000  172.259995  ...  295.750000  10.420000  170.160004  2978900.0   44146300.0  25555900.0
2018-01-03  283.801239  11.550000  166.324722  297.799988  11.550000  172.229996  ...  295.940002  11.610000  172.529999  3211200.0  154066700.0  29517900.0
2018-01-04  282.724396  12.120000  167.097290  296.670013  12.120000  173.029999  ...  297.940002  12.100000  172.539993  4171700.0  109503000.0  22434600.0
2018-01-05  294.322296  11.880000  168.999741  308.839996  11.880000  175.000000  ...  296.769989  12.190000  173.440002  6177700.0   63808900.0  23660000.0
2018-01-08  295.570740  12.280000  168.372040  310.149994  12.280000  174.350006  ...  308.660004  12.010000  174.350006  4124900.0   63346000.0  20567800.0
...                ...        ...         ...         ...        ...         ...  ...         ...        ...         ...        ...          ...         ...
2019-12-24  331.030457  46.540001  282.831299  333.000000  46.540001  284.269989  ...  339.510010  46.099998  284.690002  4120100.0   44432200.0  12119700.0
2019-12-26  327.968689  46.630001  288.442780  329.920013  46.630001  289.910004  ...  332.700012  46.990002  284.820007  4593400.0   57562800.0  23280300.0
2019-12-27  328.187408  46.180000  288.333313  330.140015  46.180000  289.799988  ...  330.200012  46.849998  291.119995  4124000.0   36581300.0  36566500.0
2019-12-30  324.469513  45.520000  290.044617  326.399994  45.520000  291.519989  ...  330.500000  46.139999  289.459991  4525500.0   41149700.0  36028600.0
2019-12-31  323.833313  45.860001  292.163818  325.760010  45.860001  293.649994  ...  325.410004  45.070000  289.929993  4958800.0   31673200.0  25201400.0

【讨论】:

  • 我尝试了上面的代码并收到了同样的错误。我收到的错误已作为编辑添加到问题中。
  • 你可以试试pip install pandas_datareader --upgrade 和熊猫一样。你用的是什么版本的 python 和 pandas?
  • 我已经尝试过这样做,我的 pandas 和我的 pandas datareader 版本是 1.14.0 。我正在使用 python 3.7
  • 你在哪里运行这段代码?您可以尝试在其他地方运行它吗?喜欢 python 终端还是 Jupyter?
  • 所以似乎当我只是请求数据时,它会打印您上面的输出。但是它给出了错误,当我使用完整代码运行它时,我无法在 1 中传递 3 个参数(它打印在上面)。我只与一家公司运行了完整的代码,并且运行良好。但是当我通过 2 或更多时,它会给我错误。您对这是为什么有任何想法吗?
【解决方案2】:

我认为错误来自您的移动平均线和线 d['sma50'] = np.round(d['Close'].rolling(window=2).mean(), decimals=2) 因为 d 代表 3 只股票,我认为你必须将每只股票分开并分别计算移动平均线

编辑:我只尝试了两只股票(BA 和 AMD),但这不是最好的解决方案,因为我总是在每一行都重复自己。 我只是 Python 的初学者,但也许这会帮助您找到解决问题的方法 PS:最后一行不太好用(就是打印损益表和退货)

"

import pandas as pd
import pandas_datareader as web
import datetime as dt
stock1 = ['BA']
stock2=['AMD']
start = dt.datetime(2018, 1, 1)
end = dt.datetime(2020, 1, 1)
d1 = web.DataReader(stock1, 'yahoo', start, end)
d2 = web.DataReader(stock2, 'yahoo', start, end)
d1['sma50'] = np.round(d1['Close'].rolling(window=2).mean(), decimals=2)
d2['sma50'] = np.round(d2['Close'].rolling(window=2).mean(), decimals=2)
d1['sma200'] = np.round(d1['Close'].rolling(window=14).mean(), decimals=2)
d2['sma200'] = np.round(d2['Close'].rolling(window=14).mean(), decimals=2)
d1['200-50'] = d1['sma200'] - d1['sma50']
d2['200-50'] = d2['sma200'] - d2['sma50']
_buy = -2
d1['Crossover_Long'] = np.where(d1['200-50'] < _buy, 1, 0)
d2['Crossover_Long'] = np.where(d2['200-50'] < _buy, 1, 0)
d1['Crossover_Long_Change']=d1.Crossover_Long.diff()
d2['Crossover_Long_Change']=d2.Crossover_Long.diff()
d1['buy'] = np.where(d1['Crossover_Long_Change'] == 1, 'buy', 'n/a')
d2['buy'] = np.where(d2['Crossover_Long_Change'] == 1, 'buy', 'n/a')
d1['sell_BA'] = np.where(d1['Crossover_Long_Change'] == -1, 'sell', 'n/a')
d2['sell_AMD'] = np.where(d2['Crossover_Long_Change'] == -1, 'sell', 'n/a')
pd.set_option('display.max_rows', 5093)
d1.drop(['High', 'Low', 'Close', 'Volume', 'Open'], axis=1, inplace=True)
d2.drop(['High', 'Low', 'Close', 'Volume', 'Open'], axis=1, inplace=True)
d2.dropna(inplace=True)
d1.dropna(inplace=True)
d1.set_index("Adj Close",inplace=True)
d2.set_index("Adj Close",inplace=True)
buy_price_BA = np.array(d1.index[d1['Crossover_Long_Change']==1])
buy_price_AMD = np.array(d2.index[d2['Crossover_Long_Change']==1])
sell_price_BA = np.array(d1.index[d1['Crossover_Long_Change']==-1])
sell_price_AMD = np.array(d2.index[d2['Crossover_Long_Change']==-1])
d1['Crossover_Long_Change'].value_counts()
d2['Crossover_Long_Change'].value_counts()
profit_loss_BA = (sell_price_BA - buy_price_BA)*10
profit_loss_AMD = (sell_price_AMD - buy_price_AMD)*10
commision_BA = buy_price_BA*.01
commision_AMD = buy_price_AMD*.01
position_value_BA = (buy_price_BA + commision_BA)*10
position_value_AMD = (buy_price_AMD + commision_AMD)*10
percent_return_BA = np.round(((profit_loss_BA/position_value_BA)*100),decimals=2)
percent_return_AMD = np.round(((profit_loss_AMD/position_value_AMD)*100),decimals=2)
prices_BA = { 
    "Buy Price BA" : [buy_price_BA],
    "Sell Price BA" : [sell_price_BA],
    "P/L BA" : [profit_loss_BA],
    "Return BA": [percent_return_BA]}
df = pd.DataFrame(prices_BA)
print('The return was {}%, and profit or loss was ${} '.format(np.round(df['Return BA'].sum(), decimals=2), 
                                                           np.round(df['P/L BA'].sum(), decimals=2)))
prices_AMD = { 
    "Buy Price AMD" : [buy_price_AMD],
    "Sell Price AMD" : [sell_price_AMD],
    "P/L AMD" : [profit_loss_AMD],
    "Return AMD": [percent_return_AMD]}
df = pd.DataFrame(prices_AMD)
print('The return was {}%, and profit or loss was ${} '.format(np.round(df['Return AMD'].sum(), decimals=2), 
                                                               np.round(df['P/L AMD'].sum(), decimals=2)))

【讨论】:

  • 感谢您的回复。我也在考虑这个问题,但是我将如何调整移动平均线的代码以使其分散。
  • 我是否必须为每只股票重写整个代码?
  • 我添加了一个编辑。我试图只用一只股票来运行你的代码,但我添加了错误,你可以查看我的代码,如果你找到解决方案,你可以在这里发布代码吗?这将有助于提高我的编码技能。谢谢
【解决方案3】:

熊猫数据阅读器中似乎存在错误。我通过使用一个符号初始化然后在实例化对象上设置符号属性来解决它。完成之后,在下面的 tmp 上调用 read() 就可以了。

import pandas_datareader as pdr
all_symbols = ['ibb', 'xly', 'fb', 'exx1.de']

tmp = pdr.yahoo.daily.YahooDailyReader(symbols=all_symbols[0])
# this is a work-around, pdr is broken...
tmp.symbols = all_symbols
data = tmp.read()

【讨论】:

    猜你喜欢
    • 2018-01-02
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多