1
votes

Comment importer plusieurs cours d'actions avec des pandas via Yahoo?

J'essaie donc d'obtenir plusieurs cours boursiers en utilisant des pandas et des panadas datareader. Si j'essaie d'importer un seul ticker, cela fonctionnera bien, mais si j'en utilise plus d'un, une erreur se produit. Le code est:

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

Bien que j'obtienne l'erreur:

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

Alors, comment puis-je le contourner en ne laissant passer qu'une action. Jusqu'à présent, j'ai essayé d'utiliser à la place quandl et google, qui ne fonctionnent pas non plus. J'ai aussi essayé pdr.get_data_yahoo mais j'obtiens le même résultat. J'ai également essayé yf.download () et j'ai toujours le même problème. Quelqu'un a-t-il des idées pour contourner ce problème? Merci.

MODIFIER: Code complet:

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) 


3 commentaires

Est-ce que cela répond à votre question? Téléchargement simultané de plusieurs actions à partir de python Yahoo Finance


@Trenton McKinney Merci d'avoir répondu, j'ai déjà vu cette page et j'ai essayé mais j'ai quand même reçu la même erreur que je ne pouvais pas passer 2 objets.


Désolé, je ne comprends pas la question - ne passez-vous pas 2 actions ['BA', 'AMD'] et ce code ne fonctionne-t-il pas?


3 Réponses :


0
votes

J'ai essayé 3 actions dans votre code et il renvoie des données pour les 3, pas sûr d'avoir compris le problème auquel vous êtes confronté?

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

Résultat:

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)


7 commentaires

J'ai essayé le code ci-dessus et j'ai reçu la même erreur. L'erreur que j'ai reçue a été ajoutée à la question en tant que modification.


Pouvez-vous essayer pip install pandas_datareader --upgrade et la même chose pour les pandas. Quelle version de python et de pandas utilisez-vous?


J'ai déjà essayé de faire cela, et mes pandas et ma version de pandas datareader sont 1.14.0. J'utilise python 3.7


Où exécutez-vous ce code? Pouvez-vous essayer de l'exécuter ailleurs? Comme le terminal python ou Jupyter?


Je l'exécute dans Jupyter


Essayez de l'exécuter sur un terminal vscode ou python et voyez si vous obtenez la même erreur


Il semble donc que lorsque je demande simplement les données, il imprime la sortie que vous avez ci-dessus. Mais ensuite, cela donne l'erreur que je ne peux pas passer 3 arguments en 1 lorsque je l'exécute avec le code complet (il est imprimé ci-dessus). J'ai exécuté le code complet avec une seule entreprise et cela fonctionne très bien. Mais quand je passe 2 ou plus, cela me donne l'erreur. Avez-vous des idées sur la raison de cette situation?



0
votes

Je pense que l'erreur vient de votre moyenne mobile et de la ligne d ['sma50'] = np.round (d ['Close']. rolling (window = 2) .mean (), décimals = 2) car d représente 3 actions, je pense qu'il faut séparer chaque action et calculer la moyenne mobile séparément

EDIT: j'ai essayé quelque chose pour deux actions uniquement (BA et AMD) mais ce n'est pas la meilleure solution car je répète toujours moi-même pour chaque ligne. Je ne suis qu'un débutant en Python mais peut-être que cela vous aidera à trouver une solution à votre problème PS: La dernière ligne ne fonctionne pas vraiment bien (qui est l'impression du P&L et du Retour)

"

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 commentaires

Merci d'avoir répondu. Je pensais à cela aussi, mais comment pourrais-je ajuster le code pour les moyennes mobiles pour qu'ils soient espérés.


Dois-je réécrire l'intégralité du code pour chaque action?


J'ai ajouté une modification. J'ai essayé d'exécuter votre code avec un seul stock mais j'ajoute des erreurs, vous pouvez consulter mon code et si jamais vous trouvez une solution, pourriez-vous s'il vous plaît poster le code ici? Cela aidera à améliorer mes compétences en codage. Merci



0
votes

Il semble qu'il y ait un bogue dans le lecteur de données pandas. Je contourne ce problème en initialisant avec un symbole, puis en définissant la propriété symbol sur l'objet instancié. Après cela, cela fonctionne bien pour appeler read () sur tmp ci-dessous.

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()


0 commentaires