下载盘中历史股票数据
Download intraday historical stock data
我想下载历史盘中股票数据。我发现 AlphaVantage 提供了两年的数据。这是我免费找到的历史最长的数据。
我正在制作一个脚本来下载他们提供的所有股票代码在所有时间范围内的完整两年数据。他们提供从当天(或最后一个交易日,我不确定)起每隔 30 天划分的数据。行从最新到最旧的时间日期。我想反转数据出现的顺序,并将所有月份与仅出现一次的 headers 列连接起来。所以我会有一个 csv
文件,其中包含每只股票和时间范围的两年数据。数据行将从最旧到最新的时间日期。
我遇到的问题是我还想使用脚本来更新数据,但我不知道如何仅附加尚未出现在我的文件中的数据。我下载的数据以 15 分钟为间隔从 2020-09-28 07:15:00
变为 2020-10-26 20:00:00
(当它们存在时,会丢失一些)。当我再次使用脚本时,我想更新数据。我想以某种方式删除已经出现的行并仅附加其余行。因此,如果出现的最后一个日期时间是例如 2020-10-26 20:00:00
,它将继续从 2020-10-26 2020-10-26 20:15:00
追加(如果它存在)。如何正确更新数据?
此外,更新时,如果文件已经存在,它会复制 headers 列,这是我不想做的事情。编辑:我已经用 header=(not os.path.exists(file))
解决了这个问题,但是在每次迭代中检查文件是否存在似乎效率很低。
我还必须使脚本符合 API 的每分钟 5 次调用和每天 500 次调用的规则。有没有办法让脚本在达到每日限制时停止并在下次运行时继续?或者我应该在 API 次通话之间增加 173 秒的睡眠时间?
import os
import glob
import pandas as pd
from typing import List
from requests import get
from pathlib import Path
import os.path
import sys
BASE_URL= 'https://www.alphavantage.co/'
def download_previous_data(
file: str,
ticker: str,
timeframe: str,
slices: List,
):
for _slice in slices:
url = f'{BASE_URL}query?function=TIME_SERIES_INTRADAY_EXTENDED&symbol={ticker}&interval={timeframe}&slice={_slice}&apikey=demo&datatype=csv'
pd.read_csv(url).iloc[::-1].to_csv(file, mode='a', index=False, encoding='utf-8-sig')
def main():
# Get a list of all ticker symbols
print('Downloading ticker symbols:')
#df = pd.read_csv('https://www.alphavantage.co/query?function=LISTING_STATUS&apikey=demo')
#tickers = df['symbol'].tolist()
tickers = ['IBM']
timeframes = ['1min', '5min', '15min', '30min', '60min']
# To download the data in a subdirectory where the script is located
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# Make sure the download folders exists
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
#download_path = f'/media/user/Portable Drive/Trading/data/{timeframe}'
Path(download_path).mkdir(parents=True, exist_ok=True)
# For each ticker symbol download all data available for each timeframe
# except for the last month which would be incomplete.
# Each download iteration has to be in a 'try except' in case the ticker symbol isn't available on alphavantage
for ticker in tickers:
print(f'Downloading data for {ticker}...')
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
filepath = f'{download_path}/{ticker}.csv'
# NOTE:
# To ensure optimal API response speed, the trailing 2 years of intraday data is evenly divided into 24 "slices" - year1month1, year1month2,
# year1month3, ..., year1month11, year1month12, year2month1, year2month2, year2month3, ..., year2month11, year2month12.
# Each slice is a 30-day window, with year1month1 being the most recent and year2month12 being the farthest from today.
# By default, slice=year1month1
if Path(filepath).is_file(): # if the file already exists
# download the previous to last month
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
else: # if the file doesn't exist
# download the two previous years
#slices = ['year2month12', 'year2month11', 'year2month10', 'year2month9', 'year2month8', 'year2month7', 'year2month6', 'year2month5', 'year2month4', 'year2month3', 'year2month2', 'year2month1', 'year1month12', 'year1month11', 'year1month10', 'year1month9', 'year1month8', 'year1month7', 'year1month6', 'year1month5', 'year1month4', 'year1month3', 'year1month2']
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
if __name__ == '__main__':
main()
你的问题里有很多问题!
这些是供您尝试的建议,但我无法测试它们的有效性:
- 将所有文件名读入列表,检查文件名是否存在于列表中,而不是每次都 ping os
- 从现有文件中读取数据并追加 pandas 中的所有内容并写入新文件。无法确定您是否正在追加 csv 文件,但如果您遇到困难,只需读取数据并追加新数据 - 直到您弄清楚如何正确追加 excel。或者将新的迭代保存到他们自己的文件中并稍后合并文件。
- 如果您担心有重复项,请查看 drop_duplicates()
- 在你的 for 循环中查看 time.sleep() 的时间模块以减少调用
- 如果您有 1 分钟的数据,您可以查看 resample() 到 5 分钟、15 分钟,而不是在所有 os 时间范围内导入
我想下载历史盘中股票数据。我发现 AlphaVantage 提供了两年的数据。这是我免费找到的历史最长的数据。
我正在制作一个脚本来下载他们提供的所有股票代码在所有时间范围内的完整两年数据。他们提供从当天(或最后一个交易日,我不确定)起每隔 30 天划分的数据。行从最新到最旧的时间日期。我想反转数据出现的顺序,并将所有月份与仅出现一次的 headers 列连接起来。所以我会有一个 csv
文件,其中包含每只股票和时间范围的两年数据。数据行将从最旧到最新的时间日期。
我遇到的问题是我还想使用脚本来更新数据,但我不知道如何仅附加尚未出现在我的文件中的数据。我下载的数据以 15 分钟为间隔从 2020-09-28 07:15:00
变为 2020-10-26 20:00:00
(当它们存在时,会丢失一些)。当我再次使用脚本时,我想更新数据。我想以某种方式删除已经出现的行并仅附加其余行。因此,如果出现的最后一个日期时间是例如 2020-10-26 20:00:00
,它将继续从 2020-10-26 2020-10-26 20:15:00
追加(如果它存在)。如何正确更新数据?
此外,更新时,如果文件已经存在,它会复制 headers 列,这是我不想做的事情。编辑:我已经用 header=(not os.path.exists(file))
解决了这个问题,但是在每次迭代中检查文件是否存在似乎效率很低。
我还必须使脚本符合 API 的每分钟 5 次调用和每天 500 次调用的规则。有没有办法让脚本在达到每日限制时停止并在下次运行时继续?或者我应该在 API 次通话之间增加 173 秒的睡眠时间?
import os
import glob
import pandas as pd
from typing import List
from requests import get
from pathlib import Path
import os.path
import sys
BASE_URL= 'https://www.alphavantage.co/'
def download_previous_data(
file: str,
ticker: str,
timeframe: str,
slices: List,
):
for _slice in slices:
url = f'{BASE_URL}query?function=TIME_SERIES_INTRADAY_EXTENDED&symbol={ticker}&interval={timeframe}&slice={_slice}&apikey=demo&datatype=csv'
pd.read_csv(url).iloc[::-1].to_csv(file, mode='a', index=False, encoding='utf-8-sig')
def main():
# Get a list of all ticker symbols
print('Downloading ticker symbols:')
#df = pd.read_csv('https://www.alphavantage.co/query?function=LISTING_STATUS&apikey=demo')
#tickers = df['symbol'].tolist()
tickers = ['IBM']
timeframes = ['1min', '5min', '15min', '30min', '60min']
# To download the data in a subdirectory where the script is located
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# Make sure the download folders exists
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
#download_path = f'/media/user/Portable Drive/Trading/data/{timeframe}'
Path(download_path).mkdir(parents=True, exist_ok=True)
# For each ticker symbol download all data available for each timeframe
# except for the last month which would be incomplete.
# Each download iteration has to be in a 'try except' in case the ticker symbol isn't available on alphavantage
for ticker in tickers:
print(f'Downloading data for {ticker}...')
for timeframe in timeframes:
download_path = f'{modpath}/{timeframe}'
filepath = f'{download_path}/{ticker}.csv'
# NOTE:
# To ensure optimal API response speed, the trailing 2 years of intraday data is evenly divided into 24 "slices" - year1month1, year1month2,
# year1month3, ..., year1month11, year1month12, year2month1, year2month2, year2month3, ..., year2month11, year2month12.
# Each slice is a 30-day window, with year1month1 being the most recent and year2month12 being the farthest from today.
# By default, slice=year1month1
if Path(filepath).is_file(): # if the file already exists
# download the previous to last month
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
else: # if the file doesn't exist
# download the two previous years
#slices = ['year2month12', 'year2month11', 'year2month10', 'year2month9', 'year2month8', 'year2month7', 'year2month6', 'year2month5', 'year2month4', 'year2month3', 'year2month2', 'year2month1', 'year1month12', 'year1month11', 'year1month10', 'year1month9', 'year1month8', 'year1month7', 'year1month6', 'year1month5', 'year1month4', 'year1month3', 'year1month2']
slices = ['year1month2']
download_previous_data(filepath, ticker, timeframe, slices)
if __name__ == '__main__':
main()
你的问题里有很多问题! 这些是供您尝试的建议,但我无法测试它们的有效性:
- 将所有文件名读入列表,检查文件名是否存在于列表中,而不是每次都 ping os
- 从现有文件中读取数据并追加 pandas 中的所有内容并写入新文件。无法确定您是否正在追加 csv 文件,但如果您遇到困难,只需读取数据并追加新数据 - 直到您弄清楚如何正确追加 excel。或者将新的迭代保存到他们自己的文件中并稍后合并文件。
- 如果您担心有重复项,请查看 drop_duplicates()
- 在你的 for 循环中查看 time.sleep() 的时间模块以减少调用
- 如果您有 1 分钟的数据,您可以查看 resample() 到 5 分钟、15 分钟,而不是在所有 os 时间范围内导入