Micro-sheep / Micro-sheep/efinance

如何在盘中设定定时任务更新行情数据,制作1分钟K线数据?

Open
#63 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
4.1k
Forks
755
PR merge metrics
No merged PRs in 30d

Description

示例代码如下
```python
import numpy as np
from datetime import datetime
from threading import Thread
import time
from typing import Deque
import efinance as ef
from collections import deque
import pandas as pd
from dataclasses import dataclass

@dataclass()
class QuoteSnapshotOneMinute:
update_time: datetime
df: pd.DataFrame

quote_queue: Deque[QuoteSnapshotOneMinute] = deque(maxlen=10000)
pre_start_time = '09:15:00'
pre_end_time = '11:30:05'
after_start_time = '13:00:00'
after_end_time = '15:00:05'

def make_latest_kline_minute(quote_queue: Deque[QuoteSnapshotOneMinute]) -> pd.DataFrame:
if len(quote_queue) < 2:
return None
o = quote_queue[-2].df
c = quote_queue[-1].df
df = pd.DataFrame(columns=['股票代码', '股票名称', '时间',
'今开', '昨收', '开盘', '收盘', '最高', '最低'], index=o.index)
df['时间'] = quote_queue[-1].update_time.strftime('%Y-%m-%d %H:%M')
df['今开'] = o['今开']
df['昨收'] = o['昨日收盘']
df['开盘'] = o['最新价']
df['收盘'] = c['最新价']
df['最高'] = np.select(
[o['分钟最高'] > c['分钟最高']],
[o['分钟最高']], c['分钟最高'])
df['最低'] = np.select(
[o['分钟最低'] < c['分钟最低']],
[o['分钟最低']], c['分钟最低'])
df['成交额'] = c['成交额'] - o['成交额']
df['成交量'] = c['成交量'] - o['成交量']
df['累计成交额'] = c['成交额']
df['累计成交量'] = c['成交量']
df['股票代码'] = o.index
df['股票名称'] = o['股票名称']
return df

def update_snapshot(interval: float = 1):
"""
按一定时间间隔更新行情快照

Parameters
----------
interval : float, optional
更新间隔,默认 1 秒

Notes
-----
需要保证更新间隔秒数小于 3 秒
"""
# 记录最新一分钟内最高价
high_minute: pd.Series = None
# 记录最新一分钟内最低价
low_minute: pd.Series = None
# 记录当前 1 分钟K线是否已经完成
finished = False
while 1:
now = datetime.now()
# 大盘数据更新时间
update_time = datetime.strptime(ef.stock.get_latest_quote('上证指数')[
'更新时间'].iloc[0], '%Y-%m-%d %H:%M:%S')
# 非交易日
if update_time.date() != now.date():
break
t = now.strftime('%H:%M:%S')
# 非交易时间段
if t >= after_end_time or t <= pre_start_time:
print('不在交易时间段')
break

# 交易时间段
if pre_start_time <= t <= pre_end_time or after_start_time <= t <= after_end_time:
df = ef.stock.get_realtime_quotes()
df = df.set_index('股票代码', drop=False).sort_index()
df['成交额'] = pd.to_numeric(df['成交额'], errors='coerce')
df['成交量'] = pd.to_numeric(df['成交量'], errors='coerce')
df['最新价'] = pd.to_numeric(df['最新价'], errors='coerce')
sn = QuoteSnapshotOneMinute(update_time, df)

# 分钟开始
if len(quote_queue) == 0 or quote_queue[-1].update_time.strftime('%H:%M') != sn.update_time.strftime('%H:%M'):
if update_time.second < 5:
sn.df['分钟最高'] = sn.df['最新价']
sn.df['分钟最低'] = sn.df['最新价']

high_minute = sn.df['分钟最高']
low_minute = sn.df['分钟最低']

quote_queue.append(sn)
finished = False

print(f'{update_time} 记录 1 分钟开始行情快照')
# 分钟末尾
elif not finished and quote_queue[-1].update_time.strftime('%H:%M') == sn.update_time.strftime('%H:%M') and sn.update_time.second > 56:
sn.df['分钟最高'] = high_minute
sn.df['分钟最低'] = low_minute

quote_queue.append(sn)
finished = True
kline = make_latest_kline_minute(quote_queue)

# 下一分钟准备开始了 所以把分钟内最高最低价清空
high_minute = None
low_minute = None

print(f'{update_time} 记录 1 分钟结束行情快照')
print(kline)

# 非分钟末尾 更新最低、最高价
else:
high_minute = np.select(
[sn.df['最新价'] > high_minute],
[sn.df['最新价']], high_minute)
low_minute = np.select(
[sn.df['最新价'] < low_minute],
[sn.df['最新价']], low_minute)

else:
print(f'{now} 非盘中')
time.sleep(interval)

print('启动新线程记录行情')
t = Thread(target=update_snapshot, daemon=True)
t.start()
t.join()

```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running the supplied Python example and inspect the efinance entry points ef.stock.get_latest_quote and ef.stock.get_realtime_quotes, along with update_snapshot and make_latest_kline_minute. The issue does not define a repository change or acceptance criteria; clarify whether the expected outcome is usage documentation, an example, or a library feature before proceeding.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, pandas, python
Domain
data, documentation
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.