数据分析之A股市场技术分析是否可行

前言

这里并不是为了说明技术分析可行,也不是为了说明技术分析不可行,仅是以我浅薄的知识验证一些事情,测试方法及测试结果都会公布如下.

至于测试方法是否严谨, 就请读者自行判断吧。

数据获取

这里随机选择300支股票,并下载最近七年的日内行情数据.

导入必要库

import tushare as ts
import random
import os
import json
import datetime

筛选股票

num = 300
code_lis = []

# 获取中小板数据
zxb_df = ts.get_gem_classified()
zxb_lis = list(zxb_df.code)

# 获取沪深三百
hs300_df = ts.get_hs300s()
hs300_lis = list(hs300_df.code)

# 依次从中小板,沪深300中随机选取 num/2支股票代码
zxb_rand = random.sample(zxb_lis, int(num / 2))
hs300_rand = random.sample(hs300_lis, int(num / 2))

# 保存到code_lis并保存
code_lis.extend(zxb_rand)
code_lis.extend(hs300_rand)
with open(code_file, "w") as wf:
    json.dump(code_lis, wf)

return code_lis

筛选说明: 随机从中小板以及沪深300里面随机各选择150支股票用于此次测试。

下载数据

download_path = "download"
now = datetime.datetime.now()
start_time = now - datetime.timedelta(days=years * 365)
start = start_time.strftime("%Y-%m-%d")

try:
    print("{} 正在下载".format(code))
    df = ts.get_k_data(code, start=start)
    print("{} 下载完成".format(code))
except Exception as e:
    print("{} 下载失败".format(code))
    return

# 新建Adj Close字段
df["Adj Close"] = df.close

# 将tushare下的数据的字段保存为pyalgotrade所要求的数据格式
df.columns = ["Date", "Open", "Close", "High", "Low", "Volume", "code", "Adj Close"]

# 将数据保存成本地csv文件
df.to_csv(save_path, index=False)

可直接执行源代码 里面的downloader.py文件

执行结果如下

最后数据文件结构如下:

Date,Open,Close,High,Low,Volume,code,Adj Close
2011-03-10,5.606,5.488,5.606,5.477,308493.0,000001,5.488
2011-03-11,5.464,5.42,5.501,5.413,230166.0,000001,5.42
2011-03-14,5.403,5.461,5.467,5.4,217999.0,000001,5.461
2011-03-15,5.41,5.349,5.437,5.302,284381.0,000001,5.349
2011-03-16,5.356,5.386,5.403,5.315,242075.0,000001,5.386
2011-03-17,5.342,5.305,5.369,5.295,207262.0,000001,5.305
2011-03-18,5.366,5.346,5.366,5.319,145243.0,000001,5.346
2011-03-21,5.336,5.326,5.366,5.309,160157.0,000001,5.326

注: 这里下载每只股票最近七年的日内行情数据,但是并不是所有的公司都上市了七年。
源代码参考:donwloader.py

策略选取

策略的选择原则是不会涵盖大量的计算。单纯通过开收高低、前复权收盘价、交易量这些基本数据用于决策买入卖出。

注: 关于策略的选择以及其参数这里有很大的主观成分。

选择策略如下

双均线策略

双均线策略应该是最简单的策略了,主要原理是,选择一条短期的移动平均线,一条长期的移动平均线,当短期移动平均线向上突破长期移动平均线则买入,反之,则卖出。

这里选择10日的短期移动平均线,25日的长期移动平均线。

随机策略

这个策略用来随机选择买入时间点,然后20个交易日后卖出.

瞧瞧随机的力量。

海龟交易策略

  • 市场: A股市场
  • 仓位: 通过市场波动性调整及管理仓位.具体计算流程如下。
    1. True Range

      True Range = Maximum(H ? L, H ? PDC, PDC ? L)

      公式中, True Range代表一天内的波动量,H为当日最高价, L为当日最低价, PDC为前一日收盘价.

    2. N

      N= (19 * PDN + TR) / 20

      公式中:TR为True Range,即一天波动量,PDN为前一日N值。如果没有PDN则取TR的二十日平均值.

    3. Doller Volatility

      Dollar Volatility =N ?DollarsPerPoint

      公式中, Dollar Volatility指的是波动的价格,Dollars per Point指的是标的股票每波动一个最小单位,1手股票的总价格变化量。在国内最小变化量是0.01元,1手是100股。所以Dollars per Point就是0.01×100=1

    4. Unit

      Unit = (1 % of AccountMarketDollar) / Volatility

      公式中, Unit即为我们买卖的单位,1% of Account是总资产的1%,Market Dollar Volatility就是我们之前算出的Dollar Volatility,通过此公式计算出的Unit就是我们要买入的单位数量。此公式的意义是在一般情况下(市场波动率不大的时候),如果买入1Unit单位的资产,当天震幅使得总资产的变化不超过1%

  • 入市: 海龟有两个交易系统,可以自由选择,这里只选择系统一。

    系统一

    1.若当前价格高于过去20日的最高价,则买入一个Unit(注意是分钟回测)

    2.加仓:若股价在上一次买入(或加仓)的基础上上涨了0.5N,则加仓一个Unit

    系统二

    与系统一相一致,但当如破55日最高价时才购买

    1.若当前价格高于过去55日的最高价,则买入一个Unit.

    1.加仓:若股价在上一次买入(或加仓)的基础上上涨了0.5N,则加仓一个Unit

    Example:若某只股票A的N为2,20日最高价为100,则当股价突破100时买入一个Unit,当股价突破100+0.5×2=101时加仓一个Unit,当股价突破101+0.5×2=102时加仓一个Unit。

  • 止盈:

    系统一

    当股价跌破10日内最低价时(10日唐奇安通道下沿),清空头寸结束本次交易

    系统二

    当股价跌破20日内最低价时(20日唐奇安通道下沿),清空头寸结束本次交易

  • 技巧: 资金的调整。

    开始时设定两个比例:Loss和Adjust。若交易结束后损失的资金占总资金比例大于Loss,则今后只用现有投资资金的Adjust比例。

    Example:若初始资金为100万,设定Loss=80%,Adjust=90%。则当总资产低于100×80%=80万时,进行一次资金调整,以后只使用80×90%=72万的资金用于投资行为

参考链接:https://www.joinquant.com/post/c1747eae8096b5028e471892bef0cf1d?f=stydy&m=algorithm

Dual Thrust交易策略

  • 计算触发值

    1)N日High的最高价HH, N日Close的最低价LC;

    (2)N日Close的最高价HC,N日Low的最低价LL;

    (3)Range = Max(HH-LC,HC-LL)

    (4)BuyLine = Open + K * Range

    (5)SellLine = Open + K * Range

策略模型参考下图

  • 入市

    (1)当价格向上突破上轨时,如果当时持有空仓,则先平仓,再开多仓;如果没有仓位,则直接开多仓;

    (2)当价格向下突破下轨时,如果当时持有多仓,则先平仓,再开空仓;如果没有仓位,则直接开空仓;

    用于A股只能做过所以不用卖空策略卖空策略用于离市.K值使用0.3, 由于这个k值没有参数调优过,完全是随便想的值,所以可能让dual thrust策略的效果没有发挥到最大。

  • 止损: 无

这里N日的值取15天。

参考链接: https://www.joinquant.com/post/274

源代码

由于代码段并非几十行, 会占据文章很大篇幅,请参考GitHub链接:stock-analysis

测试结果分析

分析说明: 由于个人水平有限,所以只能以我浅薄的知识来解释我看到的,如果你有兴趣做出自己的解读,可以翻看源代码,自行测试。就不用说我业余了,我的确是业余玩家^_^

再者这里的测试至少是存在以下问题的

  1. 实际交易中,在涨停板或跌停板不一定能买得进去或卖的出去.
  2. 实际交易中买入或卖出的价格并没有回测中那么理想
  3. 实际交易中,不会只买一只股票。

我关注的测试结果主要如下:

  • 该策略是否适用于所有股票,即测试的所有股票都能盈利么,如果不是,那么盈利的概率如何。
  • 回撤比例。

所以选择以下指标用于分析结果

  • 最终收益情况
  • 最大回测比例
  • 交易次数

最终产生数据格式如下

code,cum return,end,max drawdown,start,trade count
000008,99.6340721572,2018-03-12,37.6096792448,2011-03-22,24
000060,-34.5886186243,2018-03-12,49.0665092914,2011-03-15,35
000063,36.5405019876,2018-03-12,44.1047335728,2011-03-15,38
000069,-61.6228879039,2018-03-12,64.7843454103,2011-03-15,41
000100,88.7160620486,2018-03-12,44.7998410399,2011-03-15,29

这里的cum return指累计收益,max drawdown指最大回撤比例,单位都是%

上证指数走势图

首先瞧瞧上证指数走势图
执行以下命令

python index_data.py

这里选择近七年的数据,我觉得还是可以的,因为有横盘期,上涨期,下跌期,所以可以检验策略是否能够逃过下跌期,以及能不能在横盘期有所作为。因为本文可能更注重的是如何获取数据,及编写策略,最后数据分析

以下输出通过执行以下命令:

python strategy_sma.py index
python strategy_random.py index
python strategy_dual_trust.py index

上证指数双均线策略收益图

输出如下

start at 2011-03-16
Total trades: 35
Final portfolio value: $1399434.50
Cumulative returns: 39.94 %
Max. drawdown: 31.97 %
end at 2018-03-13

收益图如下

上证指数随机策略收益图

输出如下

Total trades: 73
Final portfolio value: $1173928.61
Cumulative returns: 17.39 %
Max. drawdown: 38.10 %
end at 2018-03-13

收益图如下

上证指数daul thrust策略收益图

输出如下

start at 2011-03-16
Total trades: 32
Final portfolio value: $1860958.06
Cumulative returns: 86.10 %
Max. drawdown: 21.70 %
end at 2018-03-13

收益图如下

值得注意的是用tushare下载的上证指数的数据可能是有问题的,因为2015-03-27这天的最低价(Low)居然大于开盘价(Open)!!!

这里对上证指数的回测是基于上证指数可买,并且价格是指数值,并且可买一股。

股票双均线策略结果

# 读取双均线策略输出结果
sma = pd.read_csv("result/strategy_sma.csv")

# 查看数据前5条
sma.head()
   code  cum return         end  max drawdown       start  trade count
0     8   99.634072  2018-03-12     37.609679  2011-03-22           24
1    60  -34.588619  2018-03-12     49.066509  2011-03-15           35
2    63   36.540502  2018-03-12     44.104734  2011-03-15           38
3    69  -61.622888  2018-03-12     64.784345  2011-03-15           41
4   100   88.716062  2018-03-12     44.799841  2011-03-15           29

# 统计结果
sma.describe()
                code   cum return  max drawdown  trade count
count     299.000000   299.000000    299.000000   299.000000
mean   348897.023411    52.958878     46.737723    24.498328
std    202821.008968   127.114389     14.790231    12.048942
min         8.000000   -70.380766      4.832993     0.000000
25%    300140.500000   -16.502707     37.721394    13.000000
50%    300452.000000    20.156509     46.572972    29.000000
75%    600192.500000    73.175792     58.063121    34.000000
max    603858.000000  1236.661103     78.002843    42.000000

股票随机策略结果

rand = pd.read_csv("result/strategy_random.csv")

rand.head()
Out[120]:
   code  cum return         end  max drawdown       start  trade count
0     8   57.171853  2018-03-12     42.133326  2011-03-22           41
1    60    0.717321  2018-03-12     64.914506  2011-03-15           64
2    63   38.541158  2018-03-12     63.594804  2011-03-15           58
3    69  -13.064397  2018-03-12     48.498738  2011-03-15           70
4   100   48.973887  2018-03-12     42.911270  2011-03-15           58

rand.describe()
Out[121]:
                code  cum return  max drawdown  trade count
count     299.000000  299.000000    299.000000   299.000000
mean   348897.023411   37.561896     53.839700    40.755853
std    202821.008968   98.958464     15.073869    20.628316
min         8.000000  -78.754755      6.127005     1.000000
25%    300140.500000  -29.201594     43.073549    22.000000
50%    300452.000000    5.418000     54.826874    45.000000
75%    600192.500000   69.043188     64.120164    59.000000
max    603858.000000  651.783545     90.516418    73.000000

股票dual thrust策略结果

dual = pd.read_csv("result/strategy_dual_trust.csv")

dual.head()
Out[123]:
   code  cum return         end  max drawdown       start  trade count
0     8   -1.724564  2018-03-12     47.924826  2011-03-22           21
1    60  -15.859906  2018-03-12     48.323636  2011-03-15           30
2    63   46.218235  2018-03-12     59.273602  2011-03-15           35
3    69   22.708655  2018-03-12     33.797895  2011-03-15           34
4   100  140.985523  2018-03-12     39.504217  2011-03-15           24

dual.describe()
Out[24]:
                code  cum return  max drawdown  trade count
count     299.000000  299.000000    299.000000   299.000000
mean   348897.023411   43.451147     46.518626    21.548495
std    202821.008968   95.254409     17.610361    11.283421
min         8.000000  -71.021800      0.000000     0.000000
25%    300140.500000  -17.341418     33.842472    11.000000
50%    300452.000000   17.209486     46.212199    25.000000
75%    600192.500000   75.395195     60.644285    31.000000
max    603858.000000  838.836061     82.656125    46.000000

由于pyalgotrade框架自身的限制,我在这个交易策略中按照EventWindow的模式自行建立一个EventWindow的类。

海龟交易策略结果

以后补上

收益分析

从上面的回测结果你会发现累计收益无论是最大值还是平均值都是双均线策略.

交易频繁的是dual thrust

但是上面的分析其实是有问题的,因为这些股票中有很多的股票可能上市事件不长,所以会产生很大的误导,因为太短时间的回测有很大的随机性,这会导致,以为这个策略很好但是,其实知识恰好而已。

当然了, 我这里的测试,其实也有一个很大的随机因素的占比。

这里让我们将上市时间小于七年的股票去除,再次查看收益情况

回测股票数据如下

python strategy_sma.py
python strategy_randome.py
python strategy_dual_trust.py

双均线策略

sma[sma.start > pd.to_datetime("2011-03-15")].describe()
Out[32]:
                code  cum return  max drawdown  trade count
count     151.000000  151.000000    151.000000   151.000000
mean   332525.701987   31.358881     44.409062    15.390728
std    143561.914878  112.389358     16.168624    10.214352
min         8.000000  -70.380766      4.832993     0.000000
25%    300299.500000  -23.127234     33.424244     6.000000
50%    300470.000000    2.206130     44.971140    13.000000
75%    300637.500000   33.425479     56.288630    24.500000
max    603858.000000  828.628299     78.002843    37.000000

随机策略

rand[sma.start > pd.to_datetime("2011-03-15")].describe()
Out[33]:
                code  cum return  max drawdown  trade count
count     151.000000  151.000000    151.000000   151.000000
mean   332525.701987   17.033825     52.263797    24.821192
std    143561.914878   86.767753     16.254297    15.643140
min         8.000000  -70.347804      6.127005     1.000000
25%    300299.500000  -34.364267     42.012492    10.500000
50%    300470.000000   -4.734439     54.193410    22.000000
75%    300637.500000   40.879252     63.065449    38.500000
max    603858.000000  651.783545     88.746525    60.000000

dual thrus策略

dual[sma.start > pd.to_datetime("2011-03-15")].describe()
Out[34]:
                code  cum return  max drawdown  trade count
count     151.000000  151.000000    151.000000   151.000000
mean   332525.701987   24.231603     43.172343    13.284768
std    143561.914878   74.396766     19.763869     9.501142
min         8.000000  -65.661905      0.000000     0.000000
25%    300299.500000  -22.606043     28.152275     5.000000
50%    300470.000000   -0.466305     42.328093    11.000000
75%    300637.500000   48.149141     60.095440    21.500000
max    603858.000000  328.261149     82.357505    35.000000

最后瞧瞧获得收益的概率
这里假设最低基准是支付宝的收益,即4%,如果七年后的收益小于31%都是亏损的,计算方法如下。

from math import pow

pow(1.04, 7)
Out[38]: 1.3159317792358403

双均线策略盈利概率

len(sma[sma.start > pd.to_datetime("2011-03-15")][sma["cum return"] > 31])/len(sma[sma.start > pd.to_datetime("2011-03-15")])

Out[40]: 0.271523178807947

随机策略盈利概率

len(rand[sma.start > pd.to_datetime("2011-03-15")][rand["cum return"] > 31])/len(rand[sma.start > pd.to_datetime("2011-03-15")])

Out[42]: 0.2913907284768212

dual thrust策略盈利概率

len(dual[sma.start > pd.to_datetime("2011-03-15")][dual["cum return"] > 31])/len(dual[sma.start > pd.to_datetime("2011-03-15")])

Out[43]: 0.2847682119205298

总结

好吧,就收益分析而言居然随机策略的盈利概率居然大于其他两个策略,而且概率都小于50%.

这里的分析还是有很大的局限性,比如数据的频度,以及样本的大小。

所以就就这个不太严谨的回测分析会发现,在时间长度为七年的条件下,单纯技术分析似乎胜率不大,但是这里没有在回测之前筛选一些股票,是一个不太现实的问题,比如一些基本面的数据。再者这里没有设置调仓,且是全仓。这里当且仅当是股票分析的一篇分析层次超浅的文章吧。

后面会写pyalgotrade的源码分析以及使用说明.

最后的最后

关注以下再走吧。。。^_^

原文地址:http://blog.51cto.com/youerning/2086390

时间: 2024-11-06 09:25:11

数据分析之A股市场技术分析是否可行的相关文章

国内各大云计算厂商虚拟技术分析

最近在整理一些云计算的材料,在google和百度上搜索了一下国内各大云计算厂商使用的主要技术: 1.华为云:openstack基金会的金牌会员,所有的虚拟化产品几乎都是使用openstack技术,虚拟技术估计是KVM 2.浪潮云海:之前大部分使用的是VMware技术,2014年7月份加入openstack基金会,下一代云海估计会使用openstack. 3.腾讯云:自助开发的云平台技术,大数据分析方面比较成功,依赖hadoop.虚拟化方面主要是KVM. 4.阿里云:自主开发的云平台技术,虚拟化技

A股市场底部顶部历史数据

1. A股市场平均市盈率 大顶沪市平均市盈率:66-70倍. A股市场2次大底沪市平均市盈率:12倍-15倍. 大底时的例子. 2005年6月6日上证指数1000点时的14倍市盈率.2008年10月28日上证指数1624点时的14倍市盈率. 中国股市在历史上,大盘平均市盈率在20倍以下时,是对应的大牛市的相对底部——是属于低风险投资区域. 中国股市历史大盘平均市盈率在55倍以上应该是对应的就是大牛市的相对高位---高风险区投机区域. 2.A股平均价格 A股市场顶部平均价格:17至20元. A股市

《Spark大数据分析:核心概念、技术及实践》大数据技术一览

本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第1章,第1节,作者穆罕默德·古勒(Mohammed Guller)更多章节内容可以访问云栖社区"华章计算机"公众号查看. 大数据技术一览 我们正处在大数据时代.数据不仅是任何组织的命脉,而且在指数级增长.今天所产生的数据比过去几年所产生的数据大好几个数量级.挑战在于如何从数据中获取商业价值.这就是大数据相关技术想要解决的问题.因此,大数据已成为过去几年最热门的技术趋势之一.一些非常活跃的开源项目都

蓝牙协议分析(7)_BLE连接有关的技术分析

转自:http://www.wowotech.net/bluetooth/ble_connection.html#comments 1. 前言 了解蓝牙的人都知道,在经典蓝牙中,保持连接(Connection)是一个相当消耗资源(power和带宽)的过程.特别是当没有数据传输的时候,所消耗的资源完全被浪费了.因而,对很多蓝牙设备来说(特别是功耗敏感的设备),希望在无数可传的时候,能够断开连接.但是,由于跳频(hopping)以及物理通道(Physical Channel)划分的缘故,经典蓝牙连接

3DSMAX建模技术分析

在游戏美术中,模型的建立是很重要的,今天卡拉小编与大家分享的是3DSMAX建模技术分析1 旋转建模 用于具有中心对称的物体的造型比较简单,只需用工 具画出对称截面,加入(旋转)修改器就可以得到三维实体,有些还可以加入一些特殊变形,以增强表现的效果.2 Loft放样建模 这种建模的含义是将一个二维的交错物件转换为完整的三维物件的一个处理过程,也就是将一个二维的造型物件沿着第三轴向构建出复杂曲面的模型.也可以这样理解这个过程:将许多2D(shape)造型物件紧密且整齐地排列于一条路经(path)上,

蓝牙4.0技术分析1-广播者角色

第1章  BlueTooth Roles-Broadcaster 1.1    广播类型 广播可设置以下几种类型: 1)   Connectable Undirected Event Type(可连接无定向广播) 2)   Connectable Directed Event Type(可连接定向广播) 3)   Scannable Undirected Event Type(可扫描无定向广播) 4)   Non-connectable Undirected Event Type(不可连接无定向

PLSQL_R12 MOAC多组织底层技术实现技术分析(Oracle VPD)

  2014-05-30 BaoXinjian In Capgemini  一. 介绍 之前一直存在对Oracle R12 多组织访问的一些疑惑,所以查询了一些相关资料,并介绍实现R12 MOAC的Oracle VPD技术 Oracle VPD全称Virtual Private Database, Oracle的一种控制数据访问的其中安全策略之一 Oracle数据安全策略访问实现方法 Role-based security create role cust_role; grant select

Java三大主流开源工作流引擎技术分析

Java三大主流开源工作流引擎技术分析 首先,这个评论是我从网上,书中,搜索和整理出来的,也许有技术点上的错误点,也许理解没那么深入.但是我是秉着学习的态度加以评论,学习,希望对大家有用,进入正题! 三大主流工作流引擎:Shark,osworkflow,jbpm! Shark的靠山是Enhydra.Enhydra做过什么呢?多了!从j2ee应用服务器,到o/r mapping工具,到这个工作流引擎等等.为什么Shark的持久层采用DODS来实现?就是因为他们是一家人. Jbpm的靠山是jboss

负载均衡技术分析与测试报告

负载均衡技术分析与测试报告                 目录 负载均衡测试报告... 1 负载均衡技术概述:... 2 服务器负载均衡... 2 链路负载均衡... 3 Outbound链路负载均衡... 3 Inbound链路负载均衡... 4 常见负载均衡调度算法... 5 测试目的... 6 测试环境搭建... 7 1:原始网络环境... 7 2:测试网络环境... 7 测试设备介绍... 8 1:产品介绍... 8 2:产品操作界面... 8 出现问题... 9 最终解决方案...