股票价格是否是随机的是一个一直处于争论中的话题。我曾经和身边的朋友就这个问题谈过看法,多数倾向于股票价格中有某种规律可循,不是随机的,但我的观点可能稍有不同。我的看法是,就股票价格,即开高收低这四个价格本身的分布而言,特征是随机的,但股票的长期趋势有内生规律可循,而所谓的规律,并不是价格这个简单的因子能够解释的,而是基于一些更宏观的因素,比如经济周期,企业基本面,以及地缘或其他周期性因素的影响。
在交易策略算法的研究中,经常会使用蒙特卡洛式的算法进行大量的数据生成,模拟与回归。就这个问题,我曾经写过一个简单的模拟股票价格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[bars] = [
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[bars, "close"]
i += 1
bars += 1
return df
该函数返回一个收益率序列符合均值为mean,标准差为std_dev的K线数据帧。我们以均值为0,标准差为0.03即3%为默认参数,生成5000根K线,其对应的图表如下图所示:
上面的图表看起来是不是和真实的股票走势非常像?如果告诉您这就是一只股票的真实走势,我想多数人并不会怀疑吧,而这的的确确是用随机数生成的假数据。
在fake_klines函数的参数中,mean参数和std_dev参数决定了所生成K线图表的趋势与波动程度,这很好理解,均值mean为正,那么走势一定是长期向上的,为负则为长期下跌趋势;std_dev参数是数据的离散参数,标准差越高,数据的波动就越大。在实际使用这个函数的时候,可以根据需要调整参数设置。下面贴几张上涨趋势和下跌趋势的参数图表:
上面的图表演示了函数生成的上涨和下跌趋势图表,一个需要说明的是,下跌趋势的图表K线根数是2000根,之所以不生成更多的根数,是因为在长期下跌的趋势中,价格将慢慢趋近于0,而价格越趋近于0,每日涨跌幅的直方分布图上的峰度就会越高,最终趋于失真。
在上面随机生成的K线图表中,我们如果用传统的技术指标工具去分析,可以发现走势出现中枢,前高前低形成的阻力与支撑,技术指标出现顶底背离后价格开始改变运动趋势,几乎你所有的技术指标工具都有用武之地,而这一切的基础,仅仅是随机生成的假数据。
那么问题来了,真实世界的股票价格?到底是不是随机游走的呢?欢迎评论区留下您的观点与看法:)
文章评论