摘要:金融领域一向都是与数学和统计高度相关的行业,今天数学建模已经成为金融行业的发展动力和竞争力表现,人才需求旺盛。

金融领域一向都是与数学和统计高度相关的行业,今天数学建模已经成为金融行业的发展动力和竞争力表现,人才需求旺盛。特别是近年来大数据和计算机技术的发展,算法成为投资领域的重要决策手段之一,算法交易也成为重要的股票交易技术,特别是高频交易(HFT),量化投资等依赖机器算法的模型越来越流行。

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

恰巧看到一篇国外博客介绍Python在股票投资的应用,俺模仿看看如何玩玩股票投资组合的模型建模方法。第一讲先讲讲如何获取数据和可视化。后面一篇文章讲如何进行投资组合建模。

第一部分先介绍如何获取股票数据和可视化分析,移动平均的分析。

第一步:获取股票数据

我们需要安装一个python包:pip install pandas_datareader

包的相关说明:https://pandas-datareader.readthedocs.io/en/latest/

包可用通过API直接获取yahoo财经,Google 财经,world bank等数据接口提供的股票数据,这里我们用雅虎财经——yahoo finance的股票接口数据。

假设我们要获得沪市贵州茅台(600519.SS)——才有股票代码加沪深SS或SZ。

定义了股票开始日期和截止日期(系统今日时间)后

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
这样就获得了2010-1-1至2016-12-13日(今天)的贵州茅台股票基本数据。

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
可用看到很快就得到了沪市A股贵州茅台的近7年的股价数据。

接下来我们进行一系列可视化图表分析

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
这里用到了标准的matplotlib库,将输出结果呈现在Jupther上。

对于股票类型数据,High、Low、Open、Close、Adj Close如何在一张图上表现,最常用的叫阴阳烛图candlestick_ohlc。

为了阅读方便,画阴阳烛图的Python函数代码在文章最后...

pandas_candlestick_ohlc(maotai)

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
如果是多只股票的可视化如何表现呢?我们再多抓几只股票数据(同一周期)

我们增加同仁堂600085.SS和全聚德002186.SZ两只股票

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
看看走势图

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网我们发现因为三只股票的股价不同,坐标尺度不统一造成可视化不清晰。考量不同股票的股价不同,坐标标度有显著尺度差异,可用考虑用双轴标度可视化。

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
坐标尺度考虑是一方面,我们也可以考虑采用基期2010-1-4日股价作为基点进行对标或标准化股票指数化。

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
可视化趋势图

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
从趋势上看,从2010年第一个交易日开始,这三只股票基本上都是增长趋势,特别是同仁堂股价增长变动较大。

我们还可以计算各种股价的增长或变化,用:

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
或者:

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

我先展示用log变化:

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

最后,在可视化部分我们来看移动平均的趋势图。

在Python中实现q-day的移动平均(moving average)是比较方便的

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

我们下面分别指定20d、50d和200d的窗口期分析移动平均的走势图

股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网
股票分析 | 用Python玩玩A股股票数据分析-可视化部分-数据分析网

至此我们完成了沪市或深市A股选择的股票交易数据下载,并采用各种可视化和标准化方法,以及给出了移动平均的趋势图的可视化。

当然这不是我玩的目的,只是告诉大家获取数据的方便性,以及Python的各种包的易用性,如果将股票数据下载后导入Tableau或其他软件也可以进行各种分析,特别是R语言有很多股票分析模型。

其实本篇文章的重点是接下来我要描述如何在固定投资金额比如100万,预期收益率10%,止损率20%的条件下如何进行多只股票组合投资的buy-sell模型。

如果您也在玩的话,可以先看看移动平均曲线,以及不同周期移动平均的交叉点的含义。

说实话,俺对股票也是一窍不通的,多头和空头,长线和短线,看空看多的投资策略都影响模型的建立和落实。

大家可以拷贝这段代码:pandas_candlestick_ohlc(maotai)

from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY

from matplotlib.finance import candlestick_ohlc

def pandas_candlestick_ohlc(dat, stick = "day", otherseries = None):

"""

:param dat: pandas DataFrame object with datetime64 index, and float columns "Open", "High", "Low", and "Close", likely created via DataReader from "yahoo"

:param stick: A string or number indicating the period of time covered by a single candlestick. Valid string inputs include "day", "week", "month", and "year", ("day" default), and any numeric input indicates the number of trading days included in a period

:param otherseries: An iterable that will be coerced into a list, containing the columns of dat that hold other series to be plotted as lines

This will show a Japanese candlestick plot for stock data stored in dat, also plotting other series if passed.

"""

mondays = WeekdayLocator(MONDAY)        # major ticks on the mondays

alldays = DayLocator()              # minor ticks on the days

dayFormatter = DateFormatter('%d')      # e.g., 12

# Create a new DataFrame which includes OHLC data for each period specified by stick input

transdat = dat.loc[:,["Open", "High", "Low", "Close"]]

if (type(stick) == str):

if stick == "day":

plotdat = transdat

stick = 1 # Used for plotting

elif stick in ["week", "month", "year"]:

if stick == "week":

transdat["week"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[1]) # Identify weeks

elif stick == "month":

transdat["month"] = pd.to_datetime(transdat.index).map(lambda x: x.month) # Identify months

transdat["year"] = pd.to_datetime(transdat.index).map(lambda x: x.isocalendar()[0]) # Identify years

grouped = transdat.groupby(list(set(["year",stick]))) # Group by year and other appropriate variable

plotdat = pd.DataFrame({"Open": [], "High": [], "Low": [], "Close": []}) # Create empty data frame containing what will be plotted

for name, group in grouped:

plotdat = plotdat.append(pd.DataFrame({"Open": group.iloc[0,0],

"High": max(group.High),

"Low": min(group.Low),

"Close": group.iloc[-1,3]},

index = [group.index[0]]))

if stick == "week": stick = 5

elif stick == "month": stick = 30

elif stick == "year": stick = 365

elif (type(stick) == int and stick >= 1):

transdat["stick"] = [np.floor(i / stick) for i in range(len(transdat.index))]

grouped = transdat.groupby("stick")

plotdat = pd.DataFrame({"Open": [], "High": [], "Low": [], "Close": []}) # Create empty data frame containing what will be plotted

for name, group in grouped:

plotdat = plotdat.append(pd.DataFrame({"Open": group.iloc[0,0],

"High": max(group.High),

"Low": min(group.Low),

"Close": group.iloc[-1,3]},

index = [group.index[0]]))

else:

raise ValueError('Valid inputs to argument "stick" include the strings "day", "week", "month", "year", or a positive integer')

# Set plot parameters, including the axis object ax used for plotting

fig, ax = plt.subplots()

fig.subplots_adjust(bottom=0.2)

if plotdat.index[-1] - plotdat.index[0] < pd.Timedelta('730 days'):

weekFormatter = DateFormatter('%b %d')  # e.g., Jan 12

ax.xaxis.set_major_locator(mondays)

ax.xaxis.set_minor_locator(alldays)

else:

weekFormatter = DateFormatter('%b %d, %Y')

ax.xaxis.set_major_formatter(weekFormatter)

ax.grid(True)

# Create the candelstick chart

candlestick_ohlc(ax, list(zip(list(date2num(plotdat.index.tolist())), plotdat["Open"].tolist(), plotdat["High"].tolist(),

plotdat["Low"].tolist(), plotdat["Close"].tolist())),

colorup = "black", colordown = "red", width = stick * .4)

# Plot other series (such as moving averages) as lines

if otherseries != None:

if type(otherseries) != list:

otherseries = [otherseries]

dat.loc[:,otherseries].plot(ax = ax, lw = 1.3, grid = True)

ax.xaxis_date()

ax.autoscale_view()

plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')

plt.show()

pandas_candlestick_ohlc(maotai)

来源:沈浩老师(微信公众号:artofdata)