使用akshare下载bar数据导入vnpy数据库

一,mysql创建vnpy数据库

        1,使用vnpy配置创建数据库

使用akshare下载bar数据导入vnpy数据库_第1张图片

         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)

        运行结果

使用akshare下载bar数据导入vnpy数据库_第2张图片

三,查看数据

   dbbardata 表 使用akshare下载bar数据导入vnpy数据库_第3张图片   dbbarovervice表

​​​​​​​使用akshare下载bar数据导入vnpy数据库_第4张图片

你可能感兴趣的:(数据库,python,数据分析)