日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

股票因子擴(kuò)展1(漲停因子計算)

 常熟老李jlr5mr 2022-05-25 發(fā)布于江蘇

前文介紹了股票日線數(shù)據(jù)下載,從本文起開始記錄一些股票因子的計算方法,這些因子將用于后續(xù)策略的編寫。

我們將實現(xiàn)雙神穿多線策略,策略的選股條件是,股票當(dāng)日形成雙神(間隔的2個漲停),K線同時上穿5、10、20、30日均線,30日線在60日線上方,把當(dāng)日漲停收盤價格定義為買點buy_point。買入價格為后續(xù)日期開盤價與buy_point的較小值,賣出止盈價格為buy_point*(1+6.18%),止損價格為buy_point*(1-16.18%)。

在寫本系列文章之前,尚未對該策略進(jìn)行參數(shù)調(diào)整、勝率統(tǒng)計、回測分析,就目前觀察的幾只個股來看,都有不錯的漲幅。讀者可以參與一起實現(xiàn)和優(yōu)化,共同打造成一個實盤策略。

該策略在2018年至2020年3年周期回測后,年化收益為41.7%,最大回撤為25.8%。

本文首先計算漲停因子。

主要代碼分析

新建源文件,命名為data_center_v3.py,全部內(nèi)容見文末,v3主要涉及3個方面的改動:

新增計算漲停因子函數(shù)

def zt(df):

該函數(shù)用于計算漲停因子,其中:

  • 參數(shù)df為待計算擴(kuò)展因子的DataFrame
  • 返回值為包含擴(kuò)展因子的DataFrame

這里以當(dāng)日收盤價較前一日收盤價上漲9.8%及以上作為漲停判斷標(biāo)準(zhǔn)。若漲停,則因子為True,否則為False。

    df['zt'] = np.where((df['close'].values >= 1.098 * df['preclose'].values), True, False)

計算漲停因子,考慮到復(fù)權(quán)以及創(chuàng)業(yè)板和科創(chuàng)板漲停為漲幅20%,這里把當(dāng)日收盤價較前一日收盤價上漲9.8%及以上都作為漲停。

    return df

返回包含擴(kuò)展因子的DataFrame

新增計算擴(kuò)展因子

def extend_factor(df):

該函數(shù)用于計算擴(kuò)展因子,其中:

  • 參數(shù)df為待計算擴(kuò)展因子的DataFrame
  • 返回值為包含擴(kuò)展因子的DataFrame

在v3中只計算漲停因子,后續(xù)會添加雙神等因子的計算。

    df = df.pipe(zt)

使用pipe調(diào)用函數(shù)zt,計算漲停因子

    return df

返回包含擴(kuò)展因子的DataFrame。

修改創(chuàng)建數(shù)據(jù)函數(shù)

def create_data(stock_codes, from_date='1990-12-19', to_date=datetime.date.today().strftime('%Y-%m-%d'), adjustflag='2'):
    """
    下載指定日期內(nèi),指定股票的日線數(shù)據(jù),計算擴(kuò)展因子

    :param stock_codes: 待下載數(shù)據(jù)的股票代碼
    :param from_date: 日線開始日期
    :param to_date: 日線結(jié)束日期
    :param adjustflag: 復(fù)權(quán)選項 1:后復(fù)權(quán)  2:前復(fù)權(quán)  3:不復(fù)權(quán)  默認(rèn)為前復(fù)權(quán)
    :return: None
    """

    # 下載股票循環(huán)
    for code in stock_codes:
        print('正在下載{}...'.format(code))

        # 登錄BaoStock
        bs.login()

        # 下載日線數(shù)據(jù)
        out_df = bs.query_history_k_data_plus(code, g_baostock_data_fields, start_date=from_date, end_date=to_date,
                                              frequency='d', adjustflag=adjustflag).get_data()

        # 注銷登錄
        bs.logout()

        # 剔除停盤數(shù)據(jù)
        if out_df.shape[0]:
            out_df = out_df[(out_df['volume'] != '0') & (out_df['volume'] != '')]

以上內(nèi)容與v2相同,可參考v2分析內(nèi)容。

        if not out_df.shape[0]:
            continue

如果數(shù)據(jù)為空,則不進(jìn)行后續(xù)過濾及擴(kuò)展因子計算。

        out_df.drop_duplicates(['date'], inplace=True)

曾遇到過出現(xiàn)重復(fù)數(shù)據(jù)的情況,加一道去重過濾。

        if out_df.shape[0] < g_available_days_limit:
            continue

這里設(shè)置只處理已有多于等于g_available_days_limit根日線數(shù)據(jù)的股票,如果可用的日線數(shù)據(jù)少于g_available_days_limit根,則不創(chuàng)建數(shù)據(jù),來確保后續(xù)可以有效計算擴(kuò)展因子。
在文件開頭我們設(shè)置了全局變量:

g_available_days_limit = 250
        convert_list = ['open', 'high', 'low', 'close', 'preclose', 'volume', 'amount', 'turn', 'pctChg']
        out_df[convert_list] = out_df[convert_list].astype(float)

把相關(guān)字段類型轉(zhuǎn)化為float類型,BaoStock下載得到的這些字段默認(rèn)為str類型,需要轉(zhuǎn)化為float類型,才能用于后續(xù)指標(biāo)計算。

        out_df.reset_index(drop=True, inplace=True)

重置索引,由于我們進(jìn)行了去重、剔除停盤數(shù)據(jù)等操作,需要對索引進(jìn)行重置,來保持索引的連續(xù)性。

        out_df = extend_factor(out_df)

調(diào)用函數(shù)extend_factor計算擴(kuò)展因子。

        print(out_df)

打印數(shù)據(jù)創(chuàng)建結(jié)果,我們來看一下三美股份sh.603379的打印結(jié)果:

           date       open       high  ...   pcfNcfTTM  isST     zt
0    2019-04-02  32.652593  32.652593  ...   76.815822     0   True
1    2019-04-03  35.917853  35.917853  ...   84.497404     0   True
2    2019-04-04  39.511735  39.511735  ...   92.952079     0   True
3    2019-04-08  43.462210  43.462210  ...  102.245642     0   True
4    2019-04-09  47.755292  47.755292  ...   97.278109     0  False
..          ...        ...        ...  ...         ...   ...    ...
598  2021-09-13  31.580000  33.380000  ...  -70.841885     0  False
599  2021-09-14  32.520000  35.000000  ...  -71.822773     0  False
600  2021-09-15  33.020000  36.250000  ...  -79.015949     0   True
601  2021-09-16  37.900000  38.000000  ...  -77.381136     0  False
602  2021-09-17  35.510000  39.050000  ...  -85.119250     0   True

[603 rows x 18 columns]

倒數(shù)第三行和最后一行顯示2021年9月15日和17日為漲停,對應(yīng)看一下K線圖:

也可以看到2021年9月15日和17日均為漲停,計算結(jié)果正確。

小結(jié)

本文主要介紹了要實現(xiàn)的策略的思路,完成了漲停因子的計算,后續(xù)繼續(xù)介紹策略所需的其他因子的實現(xiàn)方式。

到目前為止,創(chuàng)建的數(shù)據(jù)只是用于打印,未實現(xiàn)存儲。因此只要確保程序能正常運行即可,不需要等待程序運行結(jié)束。等后續(xù)文章所有因子都介紹完成后,我們會進(jìn)行多線程計算,并將結(jié)果保存到MySQL中。


data_center_v3.py的全部代碼如下:

import baostock as bs
import datetime
import sys
import numpy as np

# 可用日線數(shù)量約束
g_available_days_limit = 250

# BaoStock日線數(shù)據(jù)字段
g_baostock_data_fields = 'date,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ, psTTM,pcfNcfTTM,isST'


def get_stock_codes(date=None):
    """
    獲取指定日期的A股代碼列表

    若參數(shù)date為空,則返回最近1個交易日的A股代碼列表
    若參數(shù)date不為空,且為交易日,則返回date當(dāng)日的A股代碼列表
    若參數(shù)date不為空,但不為交易日,則打印提示非交易日信息,程序退出

    :param date: 日期
    :return: A股代碼的列表
    """

    # 登錄baostock
    bs.login()

    # 從BaoStock查詢股票數(shù)據(jù)
    stock_df = bs.query_all_stock(date).get_data()

    # 如果獲取數(shù)據(jù)長度為0,表示日期date非交易日
    if 0 == len(stock_df):

        # 如果設(shè)置了參數(shù)date,則打印信息提示date為非交易日
        if date is not None:
            print('當(dāng)前選擇日期為非交易日或尚無交易數(shù)據(jù),請設(shè)置date為歷史某交易日日期')
            sys.exit(0)

        # 未設(shè)置參數(shù)date,則向歷史查找最近的交易日,當(dāng)獲取股票數(shù)據(jù)長度非0時,即找到最近交易日
        delta = 1
        while 0 == len(stock_df):
            stock_df = bs.query_all_stock(datetime.date.today() - datetime.timedelta(days=delta)).get_data()
            delta += 1

    # 注銷登錄
    bs.logout()

    # 篩選股票數(shù)據(jù),上證和深證股票代碼在sh.600000與sz.39900之間
    stock_df = stock_df[(stock_df['code'] >= 'sh.600000') & (stock_df['code'] < 'sz.399000')]

    # 返回股票列表
    return stock_df['code'].tolist()


def create_data(stock_codes, from_date='1990-12-19', to_date=datetime.date.today().strftime('%Y-%m-%d'),
                adjustflag='2'):
    """
    下載指定日期內(nèi),指定股票的日線數(shù)據(jù),計算擴(kuò)展因子

    :param stock_codes: 待下載數(shù)據(jù)的股票代碼
    :param from_date: 日線開始日期
    :param to_date: 日線結(jié)束日期
    :param adjustflag: 復(fù)權(quán)選項 1:后復(fù)權(quán)  2:前復(fù)權(quán)  3:不復(fù)權(quán)  默認(rèn)為前復(fù)權(quán)
    :return: None
    """

    # 下載股票循環(huán)
    for code in stock_codes:
        print('正在下載{}...'.format(code))

        # 登錄BaoStock
        bs.login()

        # 下載日線數(shù)據(jù)
        out_df = bs.query_history_k_data_plus(code, g_baostock_data_fields, start_date=from_date, end_date=to_date,
                                              frequency='d', adjustflag=adjustflag).get_data()

        # 注銷登錄
        bs.logout()

        # 剔除停盤數(shù)據(jù)
        if out_df.shape[0]:
            out_df = out_df[(out_df['volume'] != '0') & (out_df['volume'] != '')]

        # 如果數(shù)據(jù)為空,則不創(chuàng)建
        if not out_df.shape[0]:
            continue

        # 刪除重復(fù)數(shù)據(jù)
        out_df.drop_duplicates(['date'], inplace=True)

        # 日線數(shù)據(jù)少于g_available_days_limit,則不創(chuàng)建
        if out_df.shape[0] < g_available_days_limit:
            continue

        # 將數(shù)值數(shù)據(jù)轉(zhuǎn)為float型,便于后續(xù)處理
        convert_list = ['open', 'high', 'low', 'close', 'preclose', 'volume', 'amount', 'turn', 'pctChg']
        out_df[convert_list] = out_df[convert_list].astype(float)

        # 重置索引
        out_df.reset_index(drop=True, inplace=True)

        # 計算擴(kuò)展因子
        out_df = extend_factor(out_df)

        print(out_df)


def extend_factor(df):
    """
    計算擴(kuò)展因子

    :param df: 待計算擴(kuò)展因子的DataFrame
    :return: 包含擴(kuò)展因子的DataFrame
    """

    # 使用pipe計算漲停因子
    df = df.pipe(zt)

    return df


def zt(df):
    """
    計算漲停因子

    若漲停,則因子為True,否則為False
    以當(dāng)日收盤價較前一日收盤價上漲9.8%及以上作為漲停判斷標(biāo)準(zhǔn)

    :param df: 待計算擴(kuò)展因子的DataFrame
    :return: 包含擴(kuò)展因子的DataFrame
    """

    df['zt'] = np.where((df['close'].values >= 1.098 * df['preclose'].values), True, False)

    return df


if __name__ == '__main__':
    stock_codes = get_stock_codes()
    create_data(stock_codes)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多