PyalgoTrade 优化(六)
满足优化器组件。这个想法很简单:
有一个服务器负责:
提供数据来运行策略。
提供运行策略的参数。
记录每个工作线程的策略结果。
有多名工作人员负责:
- 使用服务器提供的数据和参数运行策略。
为了说明这一点,我们将使用一种称为相对强弱指标RSI2的策略,
它需要以下参数:
- SMA期间用于趋势识别。我们称这个entrySMA为150到250。
- 退出点的SMA周期较小。我们称这个exitSMA为5到15之间。
- 进入短期/长仓的RSI期间。我们称之为rsiPeriod,范围介于2到10之间。
- 长期进仓的RSI超卖阈值。我们称此overSoldThreshold为5到25之间。
- RSI超买买入门槛。我们称之为OverBoughtThreshold,范围为75到95。
如果我的数学是好的,那些是4409559不同的组合。
测试这个策略为一组参数花了大约0.16秒。如果我连续执行所有组合,我需要大约8.5天的时间来评估所有组合,并找到最佳参数。那是很长一段时间,但是如果我能够拿到10台8核电脑来完成这项工作,总时间将会下降到大约2.5个小时。
长话短说,我们需要平行
我们先从“道琼斯工业平均水平”下载3年的每日k线数据:
python -c "from pyalgotrade.tools import yahoofinance; yahoofinance.download_daily_bars('dia', 2009, 'dia-2009.csv')"
python -c "from pyalgotrade.tools import yahoofinance; yahoofinance.download_daily_bars('dia', 2010, 'dia-2010.csv')"
python -c "from pyalgotrade.tools import yahoofinance; yahoofinance.download_daily_bars('dia', 2011, 'dia-2011.csv')"
from pyalgotrade import strategy
from pyalgotrade.technical import ma
from pyalgotrade.technical import rsi
from pyalgotrade.technical import cross
class RSI2(strategy.BacktestingStrategy):
def __init__(self, feed, instrument, entrySMA, exitSMA, rsiPeriod, overBoughtThreshold, overSoldThreshold):
super(RSI2, self).__init__(feed)
self.__instrument = instrument
# We'll use adjusted close values, if available, instead of regular close values.
if feed.barsHaveAdjClose():
self.setUseAdjustedValues(True)
self.__priceDS = feed[instrument].getPriceDataSeries()
self.__entrySMA = ma.SMA(self.__priceDS, entrySMA)
self.__exitSMA = ma.SMA(self.__priceDS, exitSMA)
self.__rsi = rsi.RSI(self.__priceDS, rsiPeriod)
self.__overBoughtThreshold = overBoughtThreshold
self.__overSoldThreshold = overSoldThreshold
self.__longPos = None
self.__shortPos = None
def getEntrySMA(self):
return self.__entrySMA
def getExitSMA(self):
return self.__exitSMA
def getRSI(self):
return self.__rsi
def onEnterCanceled(self, position):
if self.__longPos == position:
self.__longPos = None
elif self.__shortPos == position:
self.__shortPos = None
else:
assert(False)
def onExitOk(self, position):
if self.__longPos == position:
self.__longPos = None
elif self.__shortPos == position:
self.__shortPos = None
else:
assert(False)
def onExitCanceled(self, position):
# If the exit was canceled, re-submit it.
position.exitMarket()
def onBars(self, bars):
# Wait for enough bars to be available to calculate SMA and RSI.
if self.__exitSMA[-1] is None or self.__entrySMA[-1] is None or self.__rsi[-1] is None:
return
bar = bars[self.__instrument]
if self.__longPos is not None:
if self.exitLongSignal():
self.__longPos.exitMarket()
elif self.__shortPos is not None:
if self.exitShortSignal():
self.__shortPos.exitMarket()
else:
if self.enterLongSignal(bar):
shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
self.__longPos = self.enterLong(self.__instrument, shares, True)
elif self.enterShortSignal(bar):
shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
self.__shortPos = self.enterShort(self.__instrument, shares, True)
def enterLongSignal(self, bar):
return bar.getPrice() > self.__entrySMA[-1] and self.__rsi[-1] <= self.__overSoldThreshold
def exitLongSignal(self):
return cross.cross_above(self.__priceDS, self.__exitSMA) and not self.__longPos.exitActive()
def enterShortSignal(self, bar):
return bar.getPrice() < self.__entrySMA[-1] and self.__rsi[-1] >= self.__overBoughtThreshold
def exitShortSignal(self):
return cross.cross_below(self.__priceDS, self.__exitSMA) and not self.__shortPos.exitActive()
服务器脚本
import itertools
from pyalgotrade.barfeed import yahoofeed
from pyalgotrade.optimizer import server
def parameters_generator():
instrument = ["dia"]
entrySMA = range(150, 251)
exitSMA = range(5, 16)
rsiPeriod = range(2, 11)
overBoughtThreshold = range(75, 96)
overSoldThreshold = range(5, 26)
return itertools.product(instrument, entrySMA, exitSMA, rsiPeriod, overBoughtThreshold, overSoldThreshold)
# The if __name__ == '__main__' part is necessary if running on Windows.
if __name__ == '__main__':
# Load the feed from the CSV files.
feed = yahoofeed.Feed()
feed.addBarsFromCSV("dia", "dia-2009.csv")
feed.addBarsFromCSV("dia", "dia-2010.csv")
feed.addBarsFromCSV("dia", "dia-2011.csv")
# Run the server.
server.serve(feed, parameters_generator(), "localhost", 5000)
服务器代码正在做3件事情:
- 声明生成函数,为该策略产生不同的参数组合。
- 使用我们下载的CSV文件加载Feed。
- 运行端口5000上等待传入连接的服务器。
这是使用pyalgotrade.optimizer.worker模块与服务器提供的数据并行运行策略的工作脚本:
from pyalgotrade.optimizer import worker
import rsi2
# The if __name__ == '__main__' part is necessary if running on Windows.
if __name__ == '__main__':
worker.run(rsi2.RSI2, "localhost", 5000, workerName="localworker")
当您运行服务器和客户端时,您将在服务器控制台上看到类似的内容:
2014-05-03 15:04:01,083 server [INFO] Loading bars
2014-05-03 15:04:01,348 server [INFO] Waiting for workers
2014-05-03 15:04:58,277 server [INFO] Partial result 1242173.28754 with parameters: ('dia', 150, 5, 2, 91, 19) from localworker
2014-05-03 15:04:58,566 server [INFO] Partial result 1203266.33502 with parameters: ('dia', 150, 5, 2, 81, 19) from localworker
2014-05-03 15:05:50,965 server [INFO] Partial result 1220763.1579 with parameters: ('dia', 150, 5, 3, 83, 24) from localworker
2014-05-03 15:05:51,325 server [INFO] Partial result 1221627.50793 with parameters: ('dia', 150, 5, 3, 80, 24) from localworker
.
.
在工作台的控制台上有这样的东西:
2014-05-03 15:02:25,360 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 84, 15)
2014-05-03 15:02:25,377 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 94, 5)
2014-05-03 15:02:25,661 localworker [INFO] Result 1090481.06342
2014-05-03 15:02:25,661 localworker [INFO] Result 1031470.23717
2014-05-03 15:02:25,662 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 93, 25)
2014-05-03 15:02:25,665 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 84, 14)
2014-05-03 15:02:25,995 localworker [INFO] Result 1135558.55667
2014-05-03 15:02:25,996 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 93, 24)
2014-05-03 15:02:26,006 localworker [INFO] Result 1083987.18174
2014-05-03 15:02:26,007 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 84, 13)
2014-05-03 15:02:26,256 localworker [INFO] Result 1093736.17175
2014-05-03 15:02:26,257 localworker [INFO] Running strategy with parameters ('dia', 150, 5, 2, 84, 12)
2014-05-03 15:02:26,280 localworker [INFO] Result 1135558.55667
.
.
请注意,您应该只运行一个服务器和一个或多个工作。
如果您只想在自己的桌面上并行运行策略,您可以利用pyalgotrade.optimizer.local 模块,如下所示:
import itertools
from pyalgotrade.optimizer import local
from pyalgotrade.barfeed import yahoofeed
import rsi2
def parameters_generator():
instrument = ["dia"]
entrySMA = range(150, 251)
exitSMA = range(5, 16)
rsiPeriod = range(2, 11)
overBoughtThreshold = range(75, 96)
overSoldThreshold = range(5, 26)
return itertools.product(instrument, entrySMA, exitSMA, rsiPeriod, overBoughtThreshold, overSoldThreshold)
# The if __name__ == '__main__' part is necessary if running on Windows.
if __name__ == '__main__':
# Load the feed from the CSV files.
feed = yahoofeed.Feed()
feed.addBarsFromCSV("dia", "dia-2009.csv")
feed.addBarsFromCSV("dia", "dia-2010.csv")
feed.addBarsFromCSV("dia", "dia-2011.csv")
local.run(rsi2.RSI2, feed, parameters_generator())
代码正在做3件事情:
1.声明生成不同参数组合的生成函数。
2.使用我们下载的CSV文件加载Feed。
3.使用pyalgotrade.optimizer.local模块并行运行策略,找到最佳结果。
当您运行此代码时,您应该看到如下:
2014-05-03 15:08:06,587 server [INFO] Loading bars
2014-05-03 15:08:06,910 server [INFO] Waiting for workers
2014-05-03 15:08:58,347 server [INFO] Partial result 1242173.28754 with parameters: ('dia', 150, 5, 2, 91, 19) from worker-95583
2014-05-03 15:08:58,967 server [INFO] Partial result 1203266.33502 with parameters: ('dia', 150, 5, 2, 81, 19) from worker-95584
2014-05-03 15:09:52,097 server [INFO] Partial result 1220763.1579 with parameters: ('dia', 150, 5, 3, 83, 24) from worker-95584
2014-05-03 15:09:52,921 server [INFO] Partial result 1221627.50793 with parameters: ('dia', 150, 5, 3, 80, 24) from worker-95583
2014-05-03 15:10:40,826 server [INFO] Partial result 1142162.23912 with parameters: ('dia', 150, 5, 4, 76, 17) from worker-95584
2014-05-03 15:10:41,318 server [INFO] Partial result 1107487.03214 with parameters: ('dia', 150, 5, 4, 83, 17) from worker-95583
.
.
为了记录,发现的最佳结果是$ 2314.40,具有以下参数:
- entrySMA:154
- exitSMA:5
- rsiPeriod:2
- overBoughtThreshold:91
- overSoldThreshold:18
作者:readilen
链接:http://www.jianshu.com/p/8c43f54cf7a1
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
PyalgoTrade 优化(六)的更多相关文章
- MySQL性能优化(六):分区
原文:MySQL性能优化(六):分区 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbi ...
- MyEclipse优化-六步攻略
1.首先是jsp的可视化页面 windows -> preferences->General-> Editors -> File Associations 在上方框内选择*. ...
- hexo next主题深度优化(六),使用hexo-neat插件压缩页面,大幅度提升页面性能和响应速度。
文章目录 隆重感谢: 背景 开始 试水 成功的案例 安装插件,执行命令. hexo _config.yml文件添加 坑 跳过压缩文件的正确配置方式 压缩html时不要跳过.md文件 压缩html时不要 ...
- Java读取Level-1行情dbf文件极致优化(3)
最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...
- PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量
2014-09-25 Created By BaoXinjian
- WPF性能优化经验总结
WPF性能优化一.Rendering Tier 1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染.下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tie ...
- PHP性能优化学习笔记--语言级性能优化--来自慕课网Pangee http://www.imooc.com/learn/205
使用ab进行压力测试 ab -n行数 -c并发数 url 重点关注下面两点: 1.Request per secend : 每秒可接收的请求数 2.Time per request : 每次请求所耗费 ...
- redis的内存优化【转】
Redis所有的数据都在内存中,而内存又是非常宝贵的资源.对于如何优化内存使用一直是Redis用户非常关注的问题.本文让我们深入到Redis细节中,学习内存优化的技巧.分为如下几个部分: 一.redi ...
- 项目四:Java秒杀系统方案优化-高性能高并发实战
技术栈 前端:Thymeleaf.Bootstrap.JQuery 后端:SpringBoot.JSR303.MyBatis 中间件:RabbitMQ.Redis.Druid 功能模块 分布式会话,商 ...
随机推荐
- (转)《SSO CAS单点系列》之 实现一个SSO认证服务器是这样的!
上篇我们引入了SSO这个话题<15分钟了解SSO是个什么鬼!>.本篇我们一步步深入分析SSO实现机理,并亲自动手实现一个线上可用的SSO认证服务器!首先,我们来分析下单Web应用系统登录登 ...
- PAT Sum of Number Segments[数学问题][一般]
1104 Sum of Number Segments(20 分) Given a sequence of positive numbers, a segment is defined to be a ...
- python中的shallow copy 与 deep copy
今天在写代码的时候遇到一个奇葩的问题,问题描述如下: 代码中声明了一个list,将list作为参数传入了function1()中,在function1()中对list进行了del()即删除了一个元素. ...
- 2018-2019-1 20189215 《Linux内核原理与分析》第四周作业
<庖丁解牛>第三章书本知识总结 计算机的三大法宝 存储程序计算机 函数调用堆栈 中断 操作系统的两把宝剑 中断上下文的切换--保存现场和恢复现场 进程上下文的切换 Linux内核源码的目录 ...
- 20145204《Java程序设计》第10周学习总结
网络编程 网络编程:在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设计 ...
- s3c2440中U-boot移植时执行cp.b提示:Flash not Erased【转】
本文转载自:https://blog.csdn.net/baiyang139/article/details/79054415 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...
- 《EMCAScript6入门》读书笔记——2.let和const命令
- 解决Github Desktop Repo publish 失败问题
参考: src refspec master does not match any when pushing commits in git Github上传项目步骤和常见问题 Trying to gi ...
- The Road to Ryu: Hi Ryu
参考: ryu入门教程 ryu ryu/ryu Structure -ryu/ryu app base cmd contrib controller lib ofproto services test ...
- Android 3.0 r1 API中文文档(108) —— ExpandableListAdapter
前言 本章内容是android.widget.ExpandableListAdapter,版本为Android 3.0 r1,翻译来自"深夜未眠",欢迎访问它的博客:" ...