一,mysql创建vnpy数据库
1,使用vnpy配置创建数据库
2,用sql创建数据库
-- vnpy.dbbardata definition
CREATE TABLE `dbbardata` (
`id` int NOT NULL AUTO_INCREMENT,
`symbol` varchar(255) NOT NULL,
`exchange` varchar(255) NOT NULL,
`datetime` datetime NOT NULL,
`interval` varchar(255) NOT NULL,
`volume` double NOT NULL,
`turnover` double NOT NULL,
`open_interest` double NOT NULL,
`open_price` double NOT NULL,
`high_price` double NOT NULL,
`low_price` double NOT NULL,
`close_price` double NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `dbbardata_symbol_exchange_interval_datetime` (`symbol`,`exchange`,`interval`,`datetime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- vnpy.dbbaroverview definition
CREATE TABLE `dbbaroverview` (
`id` int NOT NULL AUTO_INCREMENT,
`symbol` varchar(255) NOT NULL,
`exchange` varchar(255) NOT NULL,
`interval` varchar(255) NOT NULL,
`count` int NOT NULL,
`start` datetime NOT NULL,
`end` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `dbbaroverview_symbol_exchange_interval` (`symbol`,`exchange`,`interval`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
二,代码
objects.py
from dataclasses import field
from datetime import datetime
from enum import Enum
class Exchange(Enum):
"""
Exchange.
"""
# Chinese
CFFEX = "CFFEX" # China Financial Futures Exchange
SHFE = "SHFE" # Shanghai Futures Exchange
CZCE = "CZCE" # Zhengzhou Commodity Exchange
DCE = "DCE" # Dalian Commodity Exchange
INE = "INE" # Shanghai International Energy Exchange
GFEX = "GFEX" # Guangzhou Futures Exchange
SSE = "SSE" # Shanghai Stock Exchange
SZSE = "SZSE" # Shenzhen Stock Exchange
BSE = "BSE" # Beijing Stock Exchange
SHHK = "SHHK" # Shanghai-HK Stock Connect
SZHK = "SZHK" # Shenzhen-HK Stock Connect
SGE = "SGE" # Shanghai Gold Exchange
WXE = "WXE" # Wuxi Steel Exchange
CFETS = "CFETS" # CFETS Bond Market Maker Trading System
XBOND = "XBOND" # CFETS X-Bond Anonymous Trading System
class Interval(Enum):
"""
Interval of bar data.
"""
MINUTE = "1m"
HOUR = "1h"
DAILY = "d"
WEEKLY = "w"
TICK = "tick"
class BarData():
"""
Candlestick bar data of a certain trading period.
"""
symbol: str
exchange: Exchange
datetime: datetime
interval: Interval = None
volume: float = 0
turnover: float = 0
open_interest: float = 0
open_price: float = 0
high_price: float = 0
low_price: float = 0
close_price: float = 0
def __str__(self):
return f"{self.symbol} {self.exchange} {self.datetime} {self.interval} {self.volume} \
{self.turnover} {self.open_interest} {self.open_price} {self.high_price} {self.low_price} {self.close_price}"
def __post_init__(self) -> None:
""""""
self.vt_symbol: str = f"{self.symbol}.{self.exchange.value}"
mysql_database.py
from peewee import *
from datetime import *
# 连接 MySQL 数据库
db = MySQLDatabase('vnpy', user='root', password='xxxxxx', host='localhost', port=3306)
class DbBarData(Model):
"""K线数据表映射对象"""
id: AutoField = AutoField()
symbol: str = CharField()
exchange: str = CharField()
datetime: datetime = DateTimeField()
interval: str = CharField()
volume: float = FloatField()
turnover: float = FloatField()
open_interest: float = FloatField()
open_price: float = FloatField()
high_price: float = FloatField()
low_price: float = FloatField()
close_price: float = FloatField()
class Meta:
database = db
indexes: tuple = ((("symbol", "exchange", "interval", "datetime"), True),)
class DbBarOverview(Model):
"""K线汇总数据表映射对象"""
id: AutoField = AutoField()
symbol: str = CharField()
exchange: str = CharField()
interval: str = CharField()
count: int = IntegerField()
start: datetime = DateTimeField()
end: datetime = DateTimeField()
class Meta:
database = db
indexes: tuple = ((("symbol", "exchange", "interval"), True),)
main.py
import re
from datetime import datetime, time
from typing import List
import akshare as ak
from mysql_database import db
import pandas as pd
from akshare import futures_zh_daily_sina, futures_zh_minute_sina
from peewee import chunked, ModelSelect
from db.objects import BarData, Exchange, Interval
from db.mysql_database import DbBarData, DbBarOverview
def save_bar_data(bars: List[BarData], stream: bool = False) -> bool:
"""保存K线数据"""
# 读取主键参数
bar: BarData = bars[0]
symbol: str = bar.symbol
exchange: Exchange = bar.exchange
interval: Interval = bar.interval
# 将BarData数据转换为字典,并调整时区
data: list = []
for bar in bars:
# bar.datetime = convert_tz(bar.datetime)
d: dict = bar.__dict__
d["exchange"] = d["exchange"].value
d["interval"] = d["interval"].value
# d.pop("gateway_name")
# d.pop("vt_symbol")
data.append(d)
# 使用upsert操作将数据更新到数据库中
with db.atomic():
for c in chunked(data, 50):
DbBarData.insert_many(c).on_conflict_replace().execute()
# 更新K线汇总数据
overview: DbBarOverview = DbBarOverview.get_or_none(
DbBarOverview.symbol == symbol,
DbBarOverview.exchange == exchange.value,
DbBarOverview.interval == interval.value,
)
index_end = len(bars) - 1
if not overview:
overview: DbBarOverview = DbBarOverview()
overview.symbol = symbol
overview.exchange = exchange.value
overview.interval = interval.value
overview.start = bars[0].datetime
overview.end = bars[index_end].datetime
overview.count = len(bars)
elif stream:
overview.end = bars[index_end].datetime
overview.count += len(bars)
else:
overview.start = min(bars[0].datetime, overview.start)
overview.end = max(bars[index_end].datetime, overview.end)
s: ModelSelect = DbBarData.select().where(
(DbBarData.symbol == symbol)
& (DbBarData.exchange == exchange.value)
& (DbBarData.interval == interval.value)
)
overview.count = s.count()
overview.save()
return True
def convert_to_bardata(row):
"""Convert a row of Pandas DataFrame to BarData object."""
bar = BarData()
bar.symbol = row['symbol']
bar.exchange = Exchange(row['exchange'])
bar.datetime = datetime.strptime(row['datetime'], '%Y-%m-%d %H:%M:%S')
bar.interval = row['interval']
bar.volume = row['volume'] # 成交量
bar.turnover = None # 成交额
bar.open_interest = row['hold'] # 持仓量
bar.open_price = row['open']
bar.high_price = row['high']
bar.low_price = row['low']
bar.close_price = row['close']
return bar
interval_dict = {
'1': Interval.MINUTE,
'60': Interval.HOUR
}
# 交易所上市品种简称
d = {
Exchange.DCE: ('A', 'C', 'Y', 'FB', 'L', 'J', 'PG', 'PP', 'RR', 'EG', 'M', 'CS', 'B', 'EB', 'I', 'JD', 'P', 'V', 'JM', 'LH'),
Exchange.CZCE: ('CJ', 'PF', 'SA', 'TA', 'SR', 'CF', 'FG', 'UR', 'AP', 'PK', 'OI', 'RM', 'SF', 'CY', 'RS', 'MA', 'SM'),
Exchange.SHFE: ('WR', 'BU', 'HC', 'AU', 'NI', 'SN', 'RU', 'CU', 'AL', 'ZN', 'PB', 'SP', 'AG', 'RB', 'SS', 'FU'),
Exchange.INE: ('LU', 'BC', 'SC', 'NR')
}
def get_exchange(symbol:str):
p = re.match(r'^[A-Za-z]+', symbol).group().upper()
for exchange in d.keys():
for s in d.get(exchange):
# 打印每个值
if p == s:
return exchange.value
def get_data(symbol: str, interval: str):
df = pd.DataFrame()
if interval in ['1', '60']:
df = futures_zh_minute_sina(symbol, interval)
df['interval'] = interval_dict.get(interval)
elif interval == Interval.DAILY.value:
df = futures_zh_daily_sina(symbol)
df['interval'] = Interval.DAILY
df['datetime'] = df['date'] + ' 00:00:00'
df['symbol'] = symbol.upper()
df['exchange'] = get_exchange(symbol)
return df
if __name__ == '__main__':
symbol = 'cu2409'
interval = 'd' # 可以是 '1' ,'60' ,'d' 代表1分钟,1小时,1天
df = get_data(symbol, interval)
list = []
list = df.apply(convert_to_bardata, axis=1)
save_bar_data(list)
print(list)
运行结果
三,查看数据
dbbardata 表 dbbarovervice表