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 Réponses :
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)
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?
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)))
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
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()
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?