不用深厚的数学功底也不用深厚的金融知识,用python也能炒股?
不用深厚的数学功底也不用深厚的金融知识, 本文中也不会引用各种高深的投资模型或数学模型。这不用,那不用的,到底怎么用python炒股?往下看
交易系统
在交易之前,我们应该首先有一个交易系统用于指导我们自己交易,不一定有什么规范,但是可以作为一个交易的依据,至于这个依据可不可行,科不科学那就见仁见智了。
当然了,这里的交易系统不一定是程序,只是指你自己的交易原则或者遵守的一些技巧或者方法,你可以手动执行也可以借助编程语言,编程语言不就是一套用来使用的工具么.
这里参考海龟交易法则里面的交易体系(这里只是参考大方向).
建立一个完善的交易体系,我们至少应该思考一下六个方面。
1、市场----买卖什么
2、头寸规模----买卖多少
3、入市----何时买入
4、止损----何时退出亏损的头寸
5、止盈----何时退出盈利的头寸
6、离市----何时离市
简单的示例
买卖A股
全仓
当日涨幅超过3%买入。
当持有头寸亏损超过3%,平仓
当日跌幅大于3%或者三个连续阴线
分析: 这个交易策略其实只有在行情以波浪形状向上的行情时候才能获利,如果是盘整的情况下,怕是会亏的很惨。这里之所以写的这么简单粗暴是为了后面策略测试撸代码简单。
数据获取及处理
因为这里说的是用python炒股,所以应该采用程序的方式去获取数据,如果人工炒股,下载任何股票行情软件都是可以的,但是人工的执行是需要花费比较多的精力的。
而python语言中用于获取股票行情数据的库,最有名莫过于tushare了。
这里以上证乐视的股票为例吧。
python环境安装
获取行情数据
import pandas as pd
import tushare as ts
通过股票代码获取股票数据,这里没有指定开始及结束日期
df = ts.get_k_data("300104")
查看前十条数据
df.head()
查看后十条数据
df.tail()
将数据的index转换成date字段对应的日期
df.index = pd.to_datetime(df.date)
将多余的date字段删除
df.drop("date", inplace=True, axis=1)
计算常用指标
# 计算5,15,50日的移动平均线, MA5, MA15, MA50
days = [5, 15, 50]
for ma in days:column_name = "MA{}".format(ma)df[column_name] = pd.rolling_mean(df.close, ma)# 计算浮动比例
df["pchange"] = df.close.pct_change()
# 计算浮动点数
df["change"] = df.close.diff()
最终处理完成后的结果如下:
df.head()
Out[13]: open close high low volume code MA5 MA15 MA50 \
date
2013-11-29 9.396 9.741 9.870 9.389 146587.0 300104 NaN NaN NaN
2013-12-02 9.298 8.768 9.344 8.768 177127.0 300104 NaN NaN NaN
2013-12-03 8.142 8.414 8.546 7.890 176305.0 300104 NaN NaN NaN
2013-12-04 8.391 8.072 8.607 8.053 120115.0 300104 NaN NaN NaN
2013-12-05 7.983 7.366 8.108 7.280 253764.0 300104 8.4722 NaN NaN pchange change
date
2013-11-29 NaN NaN
2013-12-02 -0.099887 -0.973
2013-12-03 -0.040374 -0.354
2013-12-04 -0.040647 -0.342
可视化
走势图
所谓一图胜前言,将数据可视化可以非常直观的感受到股票的走势。
个人觉得,如果用程序炒股还是应该一切都量化的,不应该有过多的主观观点,如果过于依赖直觉或者当时心情,那么实在没必要用程序分析了。
df[["close", "MA5", "MA15", "MA50"]].plot(figsiz=(10,18))
效果如下:
k线图
import matplotplib.pyplot as plt
from matplotlib.daet import DateFormatter
from matplotlib.finance import date2num, candlestick_ohlcdef candlePlot(data, title=""):data["date"] = [date2num(pd.to_datetime(x)) for x in data.index]dataList = [tuple(x) for x in data[["date", "open", "high", "low", "close"]].values]ax = plt.subplot()ax.set_title(title)ax.xaxis.set_major_formatter(DateFormatter("%y-%m-%d"))candlestick_ohlc(ax, dataList, width=0.7, colorup="r", colordown="g")plt.setp(plt.gca().get_xticklabels(), rotation=50,horizontalalignment="center")fig = plt.gcf()fig.set_size_inches(20, 15)plt.grid(True)candlePlot(df)
效果如下:
策略测试
手动撸代码 京东方A(000725)。
在学习过程中有什么不懂得可以加我的
python学习交流扣扣qun,784758214
群里有不错的学习视频教程、开发工具与电子书籍。
与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容
# 导入相关模块
import tushare as ts
import pandas as pd# 获取数据
df = ts.get_k_data("000725")# 处理数据
df.index = pd.to_datetime(df.date)
df.drop("date", axis=1, inplace=True)# 计算浮动比例
df["pchange"] = df.close.pct_change()
# 计算浮动点数
df["change"] = df.close.diff()# 查看当前数据数据前五行open close high low volume code pchange change
date
2015-07-20 4.264 4.234 4.342 4.165 13036186.0 000725 NaN NaN
2015-07-21 4.136 4.195 4.274 4.096 8776773.0 000725 -0.009211 -0.039
2015-07-22 4.175 4.146 4.214 4.067 9083703.0 000725 -0.011681 -0.049
2015-07-23 4.136 4.254 4.283 4.096 12792734.0 000725 0.026049 0.108
2015-07-24 4.224 4.136 4.254 4.106 13009620.0 000725 -0.027739 -0.118# 设定回撤值
withdraw = 0.03
# 设定突破值
breakthrough = 0.03
# 设定账户资金
account = 10000
# 持有仓位手数
position = 0def buy(bar):global account, positionprint("{}: buy {}".format(bar.date, bar.close))# 一手价格one = bar.close * 100position = account // oneaccount = account - (position * one)def sell(bar):global account, position# 一手价格print("{}: sell {}".format(bar.date, bar.close))one = bar.close * 100account += position * oneposition = 0print("开始时间投资时间: ", df.iloc[0].date)
for date in df.index:bar = df.loc[date]if bar.pchange and bar.pchange > breakthrough and position == 0:buy(bar)elif bar.pchange and bar.pchange < withdraw and position > 0:sell(bar)print("最终可有现金: ", account)
print("最终持有市值: ", position * df.iloc[-1].close * 100)
输出如下:
开始时间投资时间: 2015-07-20
2015-07-29: buy 3.83
2015-07-30: sell 3.653
2015-08-04: buy 3.752
…
2018-02-27: sell 5.71
2018-03-06: buy 5.79
最终可有现金: 333.3
最终持有市值: 7527.0
结论: 通过上面的测试发现资亏了两千多…
借助测试框架
借助测试框架才是正确的回撤姿势,因为框架包含了更多的功能。这里使用pyalgotrade。
简单使用
from pyalgotrade import strategy
from pyalgotrade import technical
from pyalgotrade.barfeed import yahoofeed# 自定义事件窗口类
class DiffEventWindow(technical.EventWindow):def __init__(self, period):assert(period > 0)super(DiffEventWindow, self).__init__(period)self.__value = Nonedef onNewValue(self, dateTime, value):super(DiffEventWindow, self).onNewValue(dateTime, value)if self.windowFull():lastValue = self.getValues()[0]nowValue = self.getValues()[1]self.__value = (nowValue - lastValue) / lastValuedef getValue(self):return self.__value# 自定义指标
``
class Diff(technical.EventBasedFilter):def __init__(self, dataSeries, period, maxLen=None):super(Diff, self).__init__(dataSeries, DiffEventWindow(period), maxLen)# 定义自己的策略class MyStrategy(strategy.BacktestingStrategy):def __init__(self, feed, instrument, diffPeriod=2):# 传入feed及初始账户资金super(MyStrategy, self).__init__(feed, 10000)self.__instrument = instrumentself.__position = Noneself.setUseAdjustedValues(True)self.__prices = feed[instrument].getPriceDataSeries()self.__diff = Diff(self.__prices, diffPeriod)self.__break = 0.03self.__withdown = -0.03def getDiff(self):return self.__diffdef onEnterCanceled(self, position):self.__position = Nonedef onEnterOk(self, position):execInfo = position.getEntryOrder().getExecutionInfo()self.info("BUY at $%.2f" % (execInfo.getPrice()))def onExitOk(self, position):execInfo = position.getExitOrder().getExecutionInfo()self.info("SELL at $%.2f" % (execInfo.getPrice()))self.__position = Nonedef onExitCanceled(self, position):# If the exit was canceled, re-submit it.self.__position.exitMarket()def onBars(self, bars):account = self.getBroker().getCash()bar = bars[self.__instrument]if self.__position is None:one = bar.getPrice() * 100oneUnit = account // oneif oneUnit > 0 and self.__diff[-1] > self.__break:self.__position = self.enterLong(self.__instrument, oneUnit * 100, True)elif self.__diff[-1] < self.__withdown and not self.__position.exitActive():self.__position.exitMarket()def runStrategy():# 下载数据jdf = ts.get_k_data("000725")# 新建Adj Close字段jdf["Adj Close"] =jdf.close# 将tushare下的数据的字段保存为pyalgotrade所要求的数据格式jdf.columns = ["Date", "Open", "Close", "High", "Low", "Volume", "code", "Adj Close"]# 将数据保存成本地csv文件jdf.to_csv("jdf.csv", index=False)feed = yahoofeed.Feed()feed.addBarsFromCSV("jdf", "jdf.csv")myStrategy = MyStrategy(feed, "jdf")myStrategy.run()print("Final portfolio value: $%.2f" % myStrategy.getResult())runStrategy()
输出如下
2015-07-30 00:00:00 strategy [INFO] BUY at $3.78
2015-07-31 00:00:00 strategy [INFO] SELL at $3.57
2015-08-05 00:00:00 strategy [INFO] BUY at $3.73
2015-08-06 00:00:00 strategy [INFO] SELL at $3.56
…
2018-02-13 00:00:00 strategy [INFO] BUY at $5.45
Final portfolio value: $7877.30
猛地一看会发现,用框架似乎写了更多的代码,但是框架内置了更多分析工具。
下面简单介绍。
策略可视化
from pyalgotrade import strategy
from pyalgotrade import technical
from pyalgotrade.barfeed import yahoofeed
from pyalgotrade import plotter
from pyalgotrade.stratanalyzer import returnsclass DiffEventWindow(technical.EventWindow):def __init__(self, period):assert(period > 0)super(DiffEventWindow, self).__init__(period)self.__value = Nonedef onNewValue(self, dateTime, value):super(DiffEventWindow, self).onNewValue(dateTime, value)if self.windowFull():lastValue = self.getValues()[0]nowValue = self.getValues()[1]self.__value = (nowValue - lastValue) / lastValuedef getValue(self):return self.__valueclass Diff(technical.EventBasedFilter):def __init__(self, dataSeries, period, maxLen=None):super(Diff, self).__init__(dataSeries, DiffEventWindow(period), maxLen)class MyStrategy(strategy.BacktestingStrategy):def __init__(self, feed, instrument, diffPeriod=2):super(MyStrategy, self).__init__(feed, 10000)self.__instrument = instrumentself.__position = Noneself.setUseAdjustedValues(True)self.__prices = feed[instrument].getPriceDataSeries()self.__diff = Diff(self.__prices, diffPeriod)self.__break = 0.03self.__withdown = -0.03def getDiff(self):return self.__diffdef onEnterCanceled(self, position):self.__position = Nonedef onEnterOk(self, position):execInfo = position.getEntryOrder().getExecutionInfo()self.info("BUY at $%.2f" % (execInfo.getPrice()))def onExitOk(self, position):execInfo = position.getExitOrder().getExecutionInfo()self.info("SELL at $%.2f" % (execInfo.getPrice()))self.__position = Nonedef onExitCanceled(self, position):# If the exit was canceled, re-submit it.self.__position.exitMarket()def onBars(self, bars):account = self.getBroker().getCash()bar = bars[self.__instrument]if self.__position is None:one = bar.getPrice() * 100oneUnit = account // oneif oneUnit > 0 and self.__diff[-1] > self.__break:self.__position = self.enterLong(self.__instrument, oneUnit * 100, True)elif self.__diff[-1] < self.__withdown and not self.__position.exitActive():self.__position.exitMarket()def runStrategy():# 下载数据jdf = ts.get_k_data("000725")# 新建Adj Close字段jdf["Adj Close"] =jdf.close# 将tushare下的数据的字段保存为pyalgotrade所要求的数据格式jdf.columns = ["Date", "Open", "Close", "High", "Low", "Volume", "code", "Adj Close"]# 将数据保存成本地csv文件jdf.to_csv("jdf.csv", index=False)feed = yahoofeed.Feed()feed.addBarsFromCSV("jdf", "jdf.csv")myStrategy = MyStrategy(feed, "jdf")returnsAnalyzer = returns.Returns()myStrategy.attachAnalyzer(returnsAnalyzer)plt = plotter.StrategyPlotter(myStrategy)plt.getInstrumentSubplot("jdf")plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())myStrategy.run()print("Final portfolio value: $%.2f" % myStrategy.getResult())plt.plot()runStrategy()
图片输出如下
股价监控
根据这个需求写了一个股价监控的半成品,通过邮箱监控。
项目参考: https://github.com/youerning/UserPyScript/tree/master/monitor
技巧:在微信的辅助功能里面启用QQ邮箱提醒的功能,那么股价变动的通知就会很及时了,因为微信几乎等同于短信了。
这里简单说一下各个配置项及使用方法。
default段落
breakthrough代表突破的比例,需要传入两个值,项目里面的突破比例依次是3%,5%.
withdraw代表回撤,也需要两个值,示例为3%,5%.
attention代表关注的股票列表,填入关注的股票代码,用空格隔开
注:这里暂时没有考虑关注股票的情况,所以很多的关注股票也许有性能上的问题。
mail段落
依次输入用户名及密码以及收件人的邮箱
position段落
当前持仓的股票以及其持仓成本。
如持有京东方A(000725)以5.76的股价。
000725 = 5.76
如果多个持仓就多个如上的相应的键值对。
使用方法参考该脚本的readme
https://github.com/youerning/UserPyScript/blob/master/monitor/README.md
PS:很难过的是英文水平不好还用因为注释,以及用英文词汇做变量名,如果词不达意请见谅。
如果你依然在编程的世界里迷茫,可以加入我们的Python学习扣qun:784758214,看看前辈们是如何学习的。交流经验。从基础的python脚本到web开发、爬虫、django、数据挖掘等,零基础到项目实战的资料都有整理。送给每一位python的小伙伴!分享一些学习的方法和需要注意的小细节,点击加入我们的 python学习者聚集地
下单
这一部分本人暂时没有让程序自动执行,因为暂时还没有打磨出来一套适合自己并相信的体系,所以依靠股价监控的通知,根据不断修正的体系在手动执行交易。
不用深厚的数学功底也不用深厚的金融知识,用python也能炒股?相关推荐
- weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件、不用jar...
2019独角兽企业重金招聘Python工程师标准>>> weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件.不用jar ...
- 硬件工程师需要数学功底吗_您不需要数学就可以成为软件工程师
硬件工程师需要数学功底吗 When people start looking into software engineering as a career path, a typical first q ...
- MySQL索引为什么不用跳表,Redis为什么不用B+树
MySQL索引为什么不用跳表,Redis为什么不用B+树 知识引入 在讲述问题之前,我相信来到这里的朋友一定都是事先了解过 B+ 树.跳表这两种数据结构了的. 所以下面介绍这两种数据结构的时候,只是整 ...
- 数学建模——智能优化之模拟退火模型详解Python代码
数学建模--智能优化之模拟退火模型详解Python代码 #本功能实现最小值的求解#from matplotlib import pyplot as plt import numpy as np imp ...
- 数学建模_随机森林分类模型详解Python代码
数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...
- python数学知识_【数学知识】高一的集合知识的Python编程实现
[数学知识]高一的集合知识的Python编程实现Python3 集合概念集合与元素的关系集合与集合的关系集合与集合的运算 本博客适合高中学生入门编程知识学习,从高中的数学概念转换到其python实现, ...
- 金融数学和计算机科学哪个专业好,金融数学专业属于什么类型学科
金融数学专业属于经济学类.全国本科专业基本专业分为12大类:哲学.经济学.法学.教育学.文学.历史学.理学.工学.农学.医学.管理学.艺术学. 金融数学专业属于什么类专业学历层次门类科目 金融数学本科 ...
- 【数学知识】高一的集合知识的Python编程实现
[数学知识]高一的集合知识的Python编程实现 Python3 集合概念 集合与元素的关系 集合与集合的关系 集合与集合的运算 本博客适合高中学生入门编程知识学习,从高中的数学概念转换到其pytho ...
- 数学奥赛用不用计算机,报考自招必看!五大学科竞赛利弊详解,到底哪科最适合你?...
原标题:报考自招必看!五大学科竞赛利弊详解,到底哪科最适合你? 关注 学科竞赛的奖项越来越成为进入清北华五等名校最直接的敲门砖,同时参加学科竞赛对平时学习也有着很大的帮助,建议平时成绩中上游的学生都要 ...
- CLI or GUI --- 要高效还是要易用? (该文作者的功底真的很深厚啊)
目录(?) [+] 这篇文章很棒 转载过来欣赏地址httpwwwcnitblogcomaddonearchive2008010838581html 要高效还是要易用谈CLI与GUI 前言 定义 ...
最新文章
- cygwin是一个在windows平台上运行的unix模拟环境,下载与安装
- 提示计算机未安装flash,大师应对安装了flash,但浏览器提示没安装,如何解决...
- 的源码管理器中有感叹图标_玄说前端面试层层解析—关于 redux 的源码
- cocos2d-x开发之动作游戏实战--5
- 5 高可靠,构建RabbitMQ集群架构
- 本地项目添加到远程仓库
- Postresql初始安装后用户的创建
- Python非本地语句
- 犀牛keyshot插件_keyshot 对接 犀牛各版本插件集合
- 教程 Re:Zero ROS (五)—— 导入模型,关节控制器
- windows10安装双系统后,删除linux,开机进入grub怎么办
- 【元宵节】中国人民大学与加拿大女王大学金融硕士项目与你的那份“缘”
- 【PM】产品需求文档PRD的一般格式
- oracle 甩手 java ee_Eclipse正式代替Oracle接管Java EE
- 阿里云视频上传到抖音服务器
- 开发框架-.Net:Learun(力软敏捷开发)
- Android JNI --函数调用大全
- 成功的背后--原CSDN国服排名第一大神逆袭之路
- Mosquitto安装及使用
- canvas实现地图放大缩小拖拽
热门文章
- 用VC++5.0播放AVI文件的两种方法
- 计算机开机反复启动,电脑开机一直无限重启怎么解决
- dkp管理系统 php,RB!DKP v3.1.8 Build
- Lab4 Architecture Lab
- 生物信息学|miRNA-疾病关联预测的图形自动编码模型
- 深度学习方法实现红外图片中人物动作识别
- django mysql 时区_Django 中关于时间、时区的用法
- Android常用的开源库收集(持续更新中)
- 电脑插入耳机后没反应怎么办?
- Urchin.exe使用说明