IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    股票价格是随机漫步游走的吗?

    QThinker发表于 2024-02-12 13:52:29
    love 0

    股票价格是否是随机的是一个一直处于争论中的话题。我曾经和身边的朋友就这个问题谈过看法,多数倾向于股票价格中有某种规律可循,不是随机的,但我的观点可能稍有不同。我的看法是,就股票价格,即开高收低这四个价格本身的分布而言,特征是随机的,但股票的长期趋势有内生规律可循,而所谓的规律,并不是价格这个简单的因子能够解释的,而是基于一些更宏观的因素,比如经济周期,企业基本面,以及地缘或其他周期性因素的影响。

    在交易策略算法的研究中,经常会使用蒙特卡洛式的算法进行大量的数据生成,模拟与回归。就这个问题,我曾经写过一个简单的模拟股票价格K线的工具函数,在这里分享一下。

    贴代码之前,首先说明一下这个函数的实现逻辑:

    从对股票市场的长期统计数据来看,收益率这个序列符合正态分布。基于此,我们定义一个初始价格,设定一些约束参数,比如需要考虑张跌停板的限制,后续生成符合正态分布的收益率序列以反算对应的K线价格。下面是代码实现:

    import numpy as np
    import random
    from pandas import DataFrame
    from datetime import datetime, timedelta
    
    def fake_klines(
        initial_date: datetime,
        initial_close: float,
        num: int,
        precision: int = 2,
        constraint: float = 0.1,
        mean: float = 0,
        std_dev: float = 0.03,
        volume_range: tuple[float, float] = (8000, 10000),
        drop_weekend: bool = True,
    ) -> DataFrame:
        """
        随机K线生成器
    
        Args:
        -----
            - initial_date (datetime): 初始日期
            - initial_close (float): 初始收盘价格
            - num (int): 需要生成的K线根数
            - precision (int, optional): 价格精度. Defaults to 2.
            - constraint (float, optional): 涨跌停约束条件. Defaults to 0.1.
            - mean (float, optional): 收益序列均值. Defaults to 0.
            - std_dev (float, optional): 收益率序列标准差. Defaults to 0.03.
            - volume_range (tuple[float, float], optional): 成交量取值范围. Defaults to (8000, 10000).
            - drop_weekend (bool, optional): 日期生成是否包含周六周日. Defaults to True.
    
        Returns:
        --------
            DataFrame: K线数据帧
        """
    
        close = initial_close
        df = DataFrame(columns=["datetime", "open", "high", "low", "close", "volume"])
        i = 0
        bars = 0
    
        while bars < num:
            today = initial_date + timedelta(days=i)
    
            if drop_weekend and (today.weekday() == 5 or today.weekday() == 6):
                i += 1
                continue
    
            random_pcts = np.clip(
                np.random.normal(
                    mean, std_dev, 4
                ),
                -1 * constraint,
                constraint
            ).tolist()
    
            high_pct = max(random_pcts)
            low_pct = min(random_pcts)
            random_pcts.remove(high_pct)
            random_pcts.remove(low_pct)
    
            df.loc[i] = [
                today,
                round(close * (1 + random_pcts[0]), precision),
                round(close * (1 + high_pct), precision),
                round(close * (1 + low_pct), precision),
                round(close * (1 + random_pcts[1]), precision),
                random.randint(volume_range[0], volume_range[1]),
            ]
            close = df.loc[i, "close"]
    
            i += 1
            bars += 1
    
        return df

    该函数返回一个收益率序列符合均值为mean,标准差为std_dev的K线数据帧。我们以均值为0,标准差为0.03即3%为默认参数,生成5000根K线,其对应的图表如下图所示:

    均值为0,标准差为3%,随机5000根K线图表
    均值为0,标准差为3%,随机5000根K线的收益率分布直方图

    上面的图表看起来是不是和真实的股票走势非常像?如果告诉您这就是一只股票的真实走势,我想多数人并不会怀疑吧,而这的的确确是用随机数生成的假数据。

    在fake_klines函数的参数中,mean参数和std_dev参数决定了所生成K线图表的趋势与波动程度,这很好理解,均值mean为正,那么走势一定是长期向上的,为负则为长期下跌趋势;std_dev参数是数据的离散参数,标准差越高,数据的波动就越大。在实际使用这个函数的时候,可以根据需要调整参数设置。下面贴几张上涨趋势和下跌趋势的参数图表:

    均值为0.1%,标准差为5%,随机5000根上升趋势的K线图表
    均值为0.1%,标准差为5%,随机5000根上升趋势的收益率分布直方图
    均值为-0.1%,标准差为5%,随机2000根下跌趋势的K线图表
    均值为-0.1%,标准差为5%,随机2000根下跌趋势的收益率分布直方图

    上面的图表演示了函数生成的上涨和下跌趋势图表,一个需要说明的是,下跌趋势的图表K线根数是2000根,之所以不生成更多的根数,是因为在长期下跌的趋势中,价格将慢慢趋近于0,而价格越趋近于0,每日涨跌幅的直方分布图上的峰度就会越高,最终趋于失真。

    在上面随机生成的K线图表中,我们如果用传统的技术指标工具去分析,可以发现走势出现中枢,前高前低形成的阻力与支撑,技术指标出现顶底背离后价格开始改变运动趋势,几乎你所有的技术指标工具都有用武之地,而这一切的基础,仅仅是随机生成的假数据。

    那么问题来了,真实世界的股票价格?到底是不是随机游走的呢?欢迎评论区留下您的观点与看法:)



沪ICP备19023445号-2号
友情链接