
一些同学由于tushare近期无法访问,问我通达信mootdx 没法获取复权数据,怎么使用,问到复权怎么处理。
其实认真看过moodtx官方文档的同学应该知道, moodtx提到了 辅助函数。 这里摘自官方文档
可以按年份获取单只股票的复权行情数据 (自己计算复权蛋疼的不行,这个诸位先用着吧 😀)
参数说明:
"600300" 格式"00": 不复权, "01": 前复权, "02": 后复权"2021" 格式, 默认当前年份返回值:
调用方法:
from mootdx.contrib.adjust import get_adjust_year
get_adjust_year(symbol='000001', year='2021', factor='01')通过这种方式 可以获取前复权、后复权的数据。
看到开源源码的同学应该知道,其实是借助同花顺的接口, 和我之前封装全市场股票日K数据有类似的地方, 都是借助了同花顺相关数据。
对于程序员来说,我们平时可以多在github上逛逛开源项目,从中汲取灵感。 一些你想解决的一些问题在开源项目中都能找到或多或少的答案。
另外,一些同学可能不想依赖mootdx, 毕竟在苹果M芯片运行可能会有py_mini_racer报错相关问题, 那我基于这个代码改一下吧, 直接就可以在python环境就能运行。
这里贴一下完整代码,参考下思路, 具体根据自己的实际情况改造。 备注:如果发现格式有多余的特殊字符,用普通浏览器打开复制应该没问题。
import datetime
import json
import re
import time
import requests
import numpy as np
import pandas as pd
def get_adjust_year(symbol=None, year=None, factor='00'):
"""采集同花顺复权数据
# http://d.10jqka.com.cn/v2/line/hs_600036/01/2018.js
# http://d.10jqka.com.cn/v6/line/hs_600000/00/all.js
:param symbol: 股票代码
:param factor: 前后复权 before 或 01 为前复权, after 或 02为后复权
:param year: 年份
:return: DataFrame
"""
# 最大重试次数和重试间隔
max_retries = 5
retry_delay = 2
year = datetime.datetime.now().year if not year else year
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/90.0.4430.212 Safari/537.36',
'Referer': 'http://stockpage.10jqka.com.cn/',
'DNT': '1',
}
if factor == 'before':
factor = '01'
if factor == 'after':
factor = '02'
if factor not in ['01', '02']:
print('⚠️ 复权参数错误,factor 的值必须是: before, after, 01, 02')
return pd.DataFrame()
# 重试机制
for attempt in range(max_retries):
try:
url = f'http://d.10jqka.com.cn/v2/line/hs_{symbol}/{factor}/{year}.js'
response = requests.get(url, headers=headers)
response.raise_for_status()
# 处理特殊响应情况
if 'window.location.href' in response.text:
print('⚠️ 请求频繁,等待后重试...')
time.sleep(retry_delay)
continue
# 提取并解析JSON数据
text = re.findall(r'\((.*)\)', response.text)
if not text:
print('⚠️ 数据格式错误,尝试重新获取...')
time.sleep(retry_delay)
continue
data_json = json.loads(text[0])
data = data_json['data'].split(';')
data = [item.split(',')[:8] for item in data]
# 创建DataFrame
columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'amount', 'adjust']
df = pd.DataFrame(data, columns=columns)
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
# 转换数据类型
for col in ['open', 'high', 'low', 'close', 'volume', 'amount', 'adjust']:
df[col] = pd.to_numeric(df[col], errors='coerce')
return df
except requests.exceptions.RequestException as e:
print(f'⚠️ 请求失败: {e},尝试重试 ({attempt + 1}/{max_retries})...')
time.sleep(retry_delay)
except (json.JSONDecodeError, KeyError, IndexError) as e:
print(f'⚠️ 数据解析错误: {e},尝试重新获取...')
time.sleep(retry_delay)
except Exception as e:
print(f'⚠️ 未知错误: {e}')
break
return pd.DataFrame()
# 使用示例
if __name__ == "__main__":
# 获取前复权数据
df = get_adjust_year(symbol="600036", year=2023, factor="before")
if not df.empty:
print("✅ 数据获取成功!")
print(f"获取数据量: {len(df)} 条")
print(f"日期范围: {df.index.min().strftime('%Y-%m-%d')} 至 {df.index.max().strftime('%Y-%m-%d')}")
print("\n前5行数据预览:")
print(df.head())
else:
print("❌ 数据获取失败,请检查参数或稍后重试")如果我的分享对你投资有所帮助,不吝啬给个点赞关注呗。