量化交易之回测篇 - Tushare股票接口

from datetime import datetime
from typing import List

from public_module.object import BarData
from public_module.constant import Exchange
from public_module.tqz_extern.tools.pandas_operator.pandas_operator import TQZPandas  # noqa

import tushare
from public_module.tqz_extern.tqz_constant import TQZEquitExchangeType, TQZStockIntervalType

class TQZTushareClient:

    __api = tushare.pro_api()

    # --- api part ---
    @classmethod
    def query_multi_stocks_history_bars(cls, stock_list: list, start: datetime, end: datetime, interval: TQZStockIntervalType = TQZStockIntervalType.DAILY) -> dict:
        """
        Api of query history bars(multi stocks) with (stock_list, start_date, end_date).
        """
        # stock_list = cls.__api.stock_basic(exchange='', list_status='L', fields='ts_code')['ts_code'].values.tolist()

        stock_bars_map = {}
        for stock_name in stock_list:
            stock_code, stock_exchange = stock_name.split('.')[0], stock_name.split('.')[1]
            if stock_exchange in [TQZEquitExchangeType.SZ.value]:
                stock_exchange = Exchange.SZ
            elif stock_exchange in [TQZEquitExchangeType.SH.value]:
                stock_exchange = Exchange.SH
            elif stock_exchange in [TQZEquitExchangeType.BJ.value]:
                stock_exchange = Exchange.BJ
            else:
                assert False, f'bad stock_exchange: {stock_exchange}'

            if interval not in [TQZStockIntervalType.DAILY, TQZStockIntervalType.WEEKLY, TQZStockIntervalType.MONTHLY]:
                assert False, f'bad interval: {interval}'

            stock_bars_map[stock_name] = cls.query_history_bars(ts_symbol=stock_name, exchange=stock_exchange, start_date=start, end_date=end, interval=interval)

        return stock_bars_map


    @classmethod
    def query_history_bars(cls, ts_symbol: str, exchange: Exchange, start_date: datetime, end_date: datetime, interval: TQZStockIntervalType = TQZStockIntervalType.DAILY):
        """
        Api of query history bars(single stock) with (start_date, end_date).
        """

        bars_dataframe = cls.__load_stock_history_dataframe(
            ts_symbol=ts_symbol,
            start_date=start_date.strftime('%Y%m%d'),
            end_date=end_date.strftime('%Y%m%d'),
            interval=interval
        )

        bar_list: List[BarData] = []
        if bars_dataframe is not None:
            for ix, row in bars_dataframe.iterrows():
                bar = BarData(
                    symbol=ts_symbol.split('.')[0],  # noqa
                    exchange=exchange,  # noqa
                    interval=interval,  # noqa
                    datetime=datetime.strptime(row["trade_date"], "%Y%m%d"),  # noqa
                    open_price=row["open"],  # noqa
                    high_price=row["high"],  # noqa
                    low_price=row["low"],  # noqa
                    close_price=row["close"],  # noqa
                    volume=row["vol"],  # noqa
                    open_interest=row["amount"],  # noqa
                    gateway_name="TQZTushare",   # noqa
                )
                bar_list.append(bar)

        return bar_list


    # --- private part ---
    @classmethod
    def __load_stock_dataframe(cls, ts_symbol: str, offset: int, interval: TQZStockIntervalType = TQZStockIntervalType.DAILY):
        """
        Get data of single stock with ts_symbol and offset_days(from today).
        """

        if interval in [TQZStockIntervalType.WEEKLY]:
            source_dataframe = cls.__api.weekly(
                ts_code=ts_symbol,
                fields='ts_code,trade_date,open,high,low,close,vol,amount'
            )
        elif interval in [TQZStockIntervalType.MONTHLY]:
            source_dataframe = cls.__api.monthly(
                ts_code=ts_symbol,
                fields='ts_code,trade_date,open,high,low,close,vol,amount'
            )
        elif interval in [TQZStockIntervalType.DAILY]:
            source_dataframe = cls.__api.daily(ts_code=ts_symbol)
        else:
            assert False, f'bad interval {interval}'

        stock_dataframe = source_dataframe[:offset].iloc[::-1]
        stock_dataframe.reset_index(inplace=True)
        del stock_dataframe['index']

        return stock_dataframe

    @classmethod
    def __load_stock_history_dataframe(cls, ts_symbol: str, start_date: str, end_date: str, interval: TQZStockIntervalType = TQZStockIntervalType.DAILY):
        """
        Get data of single stock with ts_symbol、start_date and end_date.
        """

        if interval in [TQZStockIntervalType.WEEKLY]:
            source_dataframe = cls.__api.weekly(
                ts_code=ts_symbol,
                start_date=start_date,
                end_date=end_date,
                fields='ts_code,trade_date,open,high,low,close,vol,amount'
            )
        elif interval in [TQZStockIntervalType.MONTHLY]:
            source_dataframe = cls.__api.monthly(
                ts_code=ts_symbol,
                start_date=start_date,
                end_date=end_date,
                fields='ts_code,trade_date,open,high,low,close,vol,amount'
            )
        elif interval in [TQZStockIntervalType.DAILY]:
            source_dataframe = cls.__api.daily(
                ts_code=ts_symbol,
                start_date=start_date,
                end_date=end_date
            )
        else:
            assert False, f'bad interval {interval}'

        stock_dataframe = source_dataframe.iloc[::-1]
        stock_dataframe.reset_index(inplace=True)
        del stock_dataframe['index']

        return stock_dataframe


if __name__ == '__main__':
    # double_stocks_dataframes = api.daily(ts_code='000001.SZ,600000.SH', start_date='20180701', end_date='20180718')

    start_test = datetime.strptime('2022-02-15', '%Y-%m-%d')
    end_test = datetime.strptime('2022-02-18', '%Y-%m-%d')
    bars_map = TQZTushareClient.query_multi_stocks_history_bars(
        stock_list=['871981.BJ', '872925.BJ', '689009.SH'],
        start=start_test,
        end=end_test
    )

    print("bars_map: " + str(bars_map))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
股票量化交易中非常重要的一环,它可以通过历史数据对交易策略进行模拟和评估,从而评估策略的可行性和优劣性。在Python中,有很多开源的量化交易框架可以用来进行股票,如zipline、backtrader等。 下面是一个使用zipline框架进行简单交易策略的例子: 1. 安装zipline ```python pip install zipline ``` 2. 编写交易策略代码 ```python from zipline.api import order_target_percent, record, symbol def initialize(context): context.asset = symbol('AAPL') def handle_data(context, data): # 获取过去10天的收盘价 prices = data.history(context.asset, 'price', 10, '1d') # 计算平均价 mean_price = prices.mean() # 如果当前价格低于平均价,则买入 if data.current(context.asset, 'price') < mean_price: # 调整持仓比例至100% order_target_percent(context.asset, 1.0) # 否则卖出 else: # 调整持仓比例至0% order_target_percent(context.asset, 0.0) # 记录当前持仓比例 record(position=context.portfolio.positions[context.asset].amount) ``` 3. 运行 ```python from zipline import run_algorithm from zipline.api import symbol from datetime import datetime start = datetime(2016, 1, 1) end = datetime(2017, 1, 1) result = run_algorithm( start=start, end=end, initialize=initialize, capital_base=10000, handle_data=handle_data, bundle='quandl' ) ``` 在上述代码中,我们定义了一个简单的交易策略,即如果当前价格低于过去10天的平均价,则买入,否则卖出。然后我们使用zipline框架进行,设定开始和结束时间、初始资本、数据来源等参数,最终得到结果。 需要注意的是,这只是一个简单的例子,实际的交易策略可能会更加复杂,需要考虑更多的因素。另外,在进行股票时,也需要注意避免过度拟合或过度优化,以免出现虚高的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值