1-4移动均线交叉策略3

第一阶段、一个简单策略入门量化投资

1-4移动均线交叉策略3

上一文1-3移动均线交叉策略2中,我们得到的结果是令人失望的。但我们的探索还要继续。
我们知道,使用投资组合的方式进行分散投资是降低风险的好办法。尽管移动均线交叉策略的表现并不理想,我们还是在此策略基础上进行修改,添加采用投资组合进行投资的代码,重新进行回测。
修改后的代码,你只需提前设置你想要购买股票的公司代码列表,例如:

# the list of listed companies that we are concerned about
listed_company_list = ["AAPL","MSFT","GOOG","FB","TWTR","NFLX","AMZN","SNY","NTDOY","IBM","HPQ"]

假设初始资金仍为100万,在使用上面给出的投资组合的情况下,资产的变化情况如下图所示:
这里写图片描述
这时,我们策略的收益率为93.5%
平均年化收益率为9.138%
显然,使用投资组合后,收益进一步减少了,但是我们也清楚其中的积极意义,这样的策略分摊了风险。我们都知道,风险越大,收益越高的现象是普遍存在的,如何权衡呢?
于是我们看到,同样是均线交叉策略,使用和不使用投资组合两种情况,在回测后判断策略优劣时就已经针对风险与收益的权衡出现了问题。
因此,如何更合理的在回测时评价策略的优劣是一个需要探索的有意义工作,未完待续…


完整代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetimeimport stockdata_preProcess as preProcess##### the first step: get the listed companies's stock data that we concerned about# the time interval of the data we want to get(from start to end)
start = datetime.datetime(2010, 1, 1)
end = datetime.date.today()# the list of listed companies that we are concerned about
listed_company_list = ["AAPL","MSFT","GOOG","FB","TWTR","NFLX","AMZN","SNY","NTDOY","IBM","HPQ"]
# *trouble*: I can't get "YHOO" 's data, and I have't find# download data (we do not need to repeat this work)
#preProcess.downloadAndSaveData(listed_company_list, start, end)# use moving average crossover strategy to build the trading signal dataframe
#   stocks: the data, e.g: [("AAPL", apple_adjust_data),("MSFT", microsoft_adjust_data),("GOOG", google_adjust_data)]
#   fast: the span of short-term moving average
#   slow: the span of long-term moving average
def ma_crossover_orders(stocks, fast, slow):fast_str = str(fast) + 'd'slow_str = str(slow) + 'd'ma_diff_str = fast_str + '-' + slow_strtrades = pd.DataFrame({"Price": [], "Regime": [], "Signal": []})for s in stocks:s[1][fast_str] = np.round(s[1]["Close"].rolling(window = fast, center = False).mean(), 2)s[1][slow_str] = np.round(s[1]["Close"].rolling(window = slow, center = False).mean(), 2)s[1][ma_diff_str] = s[1][fast_str] - s[1][slow_str]s[1]["Regime"] = np.where(s[1][ma_diff_str] > 0, 1, 0)s[1]["Regime"] = np.where(s[1][ma_diff_str] < 0, -1, s[1]["Regime"])regime_orig = s[1].ix[-1, "Regime"]s[1].ix[-1, "Regime"] = 0s[1]["Signal"] = np.sign(s[1]["Regime"] - s[1]["Regime"].shift(1))s[1].ix[-1, "Regime"] = regime_origsignals = pd.concat([pd.DataFrame({"Price": s[1].loc[s[1]["Signal"] == 1, "Close"],"Regime": s[1].loc[s[1]["Signal"] == 1, "Regime"],"Signal": "Buy"}),pd.DataFrame({"Price": s[1].loc[s[1]["Signal"] == -1, "Close"],"Regime": s[1].loc[s[1]["Signal"] == -1, "Regime"],"Signal": "Sell"}),])signals.index = pd.MultiIndex.from_product([signals.index, [s[0]]], names = ["Date", "Symbol"])trades = trades.append(signals)trades.sort_index(inplace = True)trades.index = pd.MultiIndex.from_tuples(trades.index, names = ["Date", "Symbol"])return trades# do the backtest
#   signals: the dataframe recording the trading signal
#   cash: the initial cash flow
#   port_value: the largest proportion of single transaction to total assets
#   batch: the smallest unit of the number of shares traded
def backtest(signals, cash, port_value = .1, batch = 100):SYMBOL = 1portfolio = dict()    # denote: all the stock asset allocationport_prices = dict()  # denote: all the stock price correspond to the asset allocationresults = pd.DataFrame({"Start Cash": [],"End Cash": [],"Portfolio Value": [],"Type": [],"Shares": [],"Share Price": [],"Trade Value": [],"Profit per Share": [],"Total Profit": []})for index, row in signals.iterrows():# index[SYMBOL] denote the listed company's name, e.g APPLshares = portfolio.setdefault(index[SYMBOL], 0)trade_val = 0batches = 0# step 1 : sell current stock(if we hold current stock)# if shares>0, means we already hold the stock of the company# so it is a sell signal here, we sell all the shares held nowcash_change = row["Price"] * sharesportfolio[index[SYMBOL]] = 0old_price = port_prices.setdefault(index[SYMBOL], row["Price"]) # get the price when we buy the stock before# step 2 : compute portfolio's value( the value after sell current stock)portfolio_val = 0for key, val in portfolio.items():portfolio_val += val * port_prices[key]# step 3 : buy current stock( if it is a buy singnal here )if row["Signal"] == "Buy" and row["Regime"] == 1:batches = np.floor((portfolio_val + cash) * port_value) // np.ceil(batch * row["Price"])trade_val = batches * batch * row["Price"]cash_change -= trade_valportfolio[index[SYMBOL]] = batches * batchport_prices[index[SYMBOL]] = row["Price"]old_price = row["Price"]elif row["Signal"] == "Sell" and row["Regime"] == -1:passpprofit = row["Price"] - old_priceresults = results.append(pd.DataFrame({"Start Cash": cash,"End Cash": cash + cash_change,"Portfolio Value": cash + cash_change + portfolio_val + trade_val,"Type": row["Signal"],"Shares": batch * batches,"Share Price": row["Price"],"Trade Value": abs(cash_change),"Profit per Share": pprofit,"Total Profit": batches * batch * pprofit}, index = [index]))cash += cash_changeresults.sort_index(inplace = True)results.index = pd.MultiIndex.from_tuples(results.index, names = ["Date", "Symbol"])return results##### get the data we save in .csv file and then return the repaired data to the user
DataSetList = preProcess.repairAndGetData(listed_company_list)##### use moving average crossover strategy to build the trading signal dataframe
# build the data format requied by the function ma_crossover_orders
# ( combine the stock name and the corresponding data )
stock_NameDataTuple_List = []
for i in range(len(listed_company_list)):cur_stock = DataSetList[i];cur_company = listed_company_list[i]stock_NameDataTuple_List.append((cur_company,cur_stock))signals = ma_crossover_orders(stock_NameDataTuple_List, fast = 20, slow = 50)
# these codes are the same as below: (use Ctrl+/ to batch annotation code)
# apple = DataSetList[0]
# microsoft = DataSetList[1]
# google = DataSetList[2]
# facebook = DataSetList[3]
# twitter = DataSetList[4]
# netflix = DataSetList[5]
# amazon = DataSetList[6]
# sony = DataSetList[7]
# nintendo = DataSetList[8]
# ibm = DataSetList[9]
# hp = DataSetList[10]
# signals = ma_crossover_orders([("AAPL", preProcess.ohlc_adjust(apple)),
#                               ("MSFT",  preProcess.ohlc_adjust(microsoft)),
#                               ("GOOG",  preProcess.ohlc_adjust(google)),
#                               ("FB",    preProcess.ohlc_adjust(facebook)),
#                               ("TWTR",  preProcess.ohlc_adjust(twitter)),
#                               ("NFLX",  preProcess.ohlc_adjust(netflix)),
#                               ("AMZN",  preProcess.ohlc_adjust(amazon)),
#                               ("SNY",   preProcess.ohlc_adjust(sony)),
#                               ("NTDOY", preProcess.ohlc_adjust(nintendo)),
#                               ("IBM",   preProcess.ohlc_adjust(ibm)),
#                               ("HPQ",   preProcess.ohlc_adjust(hp))],
#                             fast = 20, slow = 50)
print(signals)##### do the back test
bk = backtest(signals, 1000000)
print(bk)##### show the changes in portfolio value
#bk["Portfolio Value"].groupby(level = 0).apply(lambda x: x[-1]).plot()
portfolio_ValueList = bk["Portfolio Value"].groupby(level = 0).apply(lambda x: x[-1])
portfolio_ValueList.plot()
#print(portfolio_ValueList)##### compute annualized rate of return
initial_value = portfolio_ValueList[0]
deadline_value = portfolio_ValueList[-1]initial_date = portfolio_ValueList.index[0]
deadline_date = portfolio_ValueList.index[-1]
holding_interval = (deadline_date - initial_date).days / 365AnnualReturnRate = ( pow(deadline_value/initial_value,1/holding_interval) - 1 )*100
print('平均年化收益率: ',AnnualReturnRate,"%")
print((deadline_value-initial_value)/initial_value)plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32学习及应用笔记一:SysTick定时器学习及应用

&#xfeff;&#xfeff; 这几年一直使用STM32的MCU&#xff0c;对ARM内核的SysTick计时器也经常使用&#xff0c;但几乎没有仔细了解过。最近正好要在移植一个新的操作系统时接触到了这块&#xff0c;据比较深入的了解了一下。 1、SysTick究竟是什么&#xff1f; 关于SysT…

使用Atom快速打造好用的Markdown编辑器

使用Atom快速打造好用的Markdown编辑器 Atom当前主流的跨平台的三大编辑器(Atom,sublime,vscode)之一 今天尝试了使用Atom来打造Markdown编辑器&#xff0c;快速上手且易用&#xff0c;墙裂推荐&#xff01; 下面直接进入正题&#xff0c;一步步介绍如何使用Atom快速打造好用…

PID控制器开发笔记之一:PID算法原理及基本实现

&#xfeff;&#xfeff; 在自动控制中&#xff0c;PID及其衍生出来的算法是应用最广的算法之一。各个做自动控制的厂家基本都有会实现这一经典算法。我们在做项目的过程中&#xff0c;也时常会遇到类似的需求&#xff0c;所以就想实现这一算法以适用于更多的应用场景。…

十分钟能学会的简单python爬虫

简单爬虫三步走&#xff0c;So easy~ 本文介绍一个使用python实现爬虫的超简单方法&#xff0c;精通爬虫挺难&#xff0c;但学会实现一个能满足简单需求的爬虫&#xff0c;只需10分钟&#xff0c;往下读吧~ 该方法不能用于带有反爬机制的页面&#xff0c;但对于我这样的非专业…

PID控制器开发笔记之二:积分分离PID控制器的实现

前面的文章中&#xff0c;我们已经讲述了PID控制器的实现&#xff0c;包括位置型PID控制器和增量型PID控制器。但这个实现只是最基本的实现&#xff0c;并没有考虑任何的干扰情况。在本节及后续的一些章节&#xff0c;我们就来讨论一下经典PID控制器的优化与改进。这一节我们首…

利用python实现短信和电话提醒功能

有时候&#xff0c;我们需要程序帮我们自动检测某些事件的发生 这个需求是广泛存在的 因此&#xff0c;这里整理了利用python实现短信和电话提醒功能的方法 主要需要完成以下4个步骤&#xff1a; - 安装核心库&#xff1a;twilio - 注册账号及配置 - 发送短信示例 - 电话…

PID控制器开发笔记之三:抗积分饱和PID控制器的实现

积分作用的引入是为了消除系统的静差&#xff0c;提高控制精度。但是如果一个系统总是存在统一个方向的偏差&#xff0c;就可能无限累加而进而饱和&#xff0c;极大影响系统性能。抗积分饱和就是用以解决这一问题的方法之一。这一节我们就来实现抗积分饱和的PID算法。 1、抗积…

如何获取STM32 MCU的唯一ID

前段时间由于应用需要对产品授权进行限制&#xff0c;所以研究了一下有关STM32 MCU的唯一ID的资料&#xff0c;并最终利用它实现了我们的目标。 1、基本描述 在STM32的全系列MCU中均有一个96位的唯一设备标识符。在ST的相关资料中&#xff0c;对其功能的描述有3各方面&#x…

SHA256算法原理详解

1. SHA256简介 SHA256是SHA-2下细分出的一种算法 SHA-2&#xff0c;名称来自于安全散列算法2&#xff08;英语&#xff1a;Secure Hash Algorithm 2&#xff09;的缩写&#xff0c;一种密码散列函数算法标准&#xff0c;由美国国家安全局研发&#xff0c;属于SHA算法之一&…

学习笔记:区块链概念入门

本文是100天区块链学习计划的第二篇学习笔记&#xff0c;其实就是按照阮一峰的网络日志-区块链入门教程的讲解进行的简单梳理。也是时间有点紧张的原因&#xff0c;相比于上一篇SHA256算法原理详解&#xff0c;个人感觉质量和原创程度明显下降。待对区块链有了更深的理解后&…

PID控制器开发笔记之四:梯形积分PID控制器的实现

从微积分的基本原理看&#xff0c;积分的实现是在无限细分的情况下进行的矩形加和计算。但是在离散状态下&#xff0c;时间间隔已经足够大&#xff0c;矩形积分在某些时候显得精度要低了一些&#xff0c;于是梯形积分被提出来以提升积分精度。 1、梯形积分基本思路 在PID控制…

SHA256 的C语言实现

前几天总结了SHA256的算法原理一文 SHA2系列的原理并不复杂&#xff0c;但是需要注意细节还是挺多的。不少中文博客贴出的代码都有错&#xff0c;这两天也踩了几个坑。 代码在这里&#xff01;&#xff01;&#xff01;SHA256的C Code 代码实现主要依照的这个git仓库crypto-…

信息摘要算法之一:MD5算法分析及实现

MD5即Message-DigestAlgorithm 5&#xff08;信息-摘要算法5&#xff09;&#xff0c;用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一&#xff08;又译摘要算法、哈希算法&#xff09;&#xff0c;主流编程语言普遍已有MD5实现。 1、MD5算法简介 MD5在90年代初由…

非对称加密概述

非对称加密概述 前言 在阅读《精通比特币》的过程中&#xff0c;我发现比特币系统中有两个重要的概念需要利用非对称加密技术&#xff1a; 比特币地址的生成 交易合法性的验证 因此&#xff0c;我用了几天时间学习了密码学基础知识&#xff0c;尤其是非对称加密技术的原理…

信息摘要算法之二:SHA1算法分析及实现

SHA算法&#xff0c;即安全散列算法&#xff08;Secure Hash Algorithm&#xff09;是一种与MD5同源的数据加密算法&#xff0c;该算法经过加密专家多年来的发展和改进已日益完善&#xff0c;现在已成为公认的最安全的散列算法之一&#xff0c;并被广泛使用。 1、概述 SHA算法…

2018数学建模A题的简单指导

之前写过一篇博客&#xff0c;介绍如何使用差分格式求解热传导方程 今天打开博客&#xff0c;突然发现评论区被这篇文章霸屏了 询问实验室的小伙伴才知&#xff0c;原来是被可爱的建模学子们攻占了 经过简单的了解&#xff0c;发现今年建模的A题的核心就是求解一个热传导方程…

PID控制器开发笔记之五:变积分PID控制器的实现

在普通的PID控制算法中&#xff0c;由于积分系数Ki是常数&#xff0c;所以在整个控制过程中&#xff0c;积分增量是不变的。然而&#xff0c;系统对于积分项的要求是&#xff0c;系统偏差大时&#xff0c;积分作用应该减弱甚至是全无&#xff0c;而在偏差小时&#xff0c;则应该…

使用SIFT匹配金馆长表情包

python使用opencv计算SIFT特征点的示例前言潜在的问题记录demo1&#xff1a;计算并绘制特征点demo2&#xff1a;使用SIFT匹配两幅图像参考文章地址前言 SIFT&#xff08;Scale-invariant feature transform&#xff09;是2004年提出的&#xff0c;至今已经经受住各种考验&…

PID控制器开发笔记之六:不完全微分PID控制器的实现

从PID控制的基本原理我们知道&#xff0c;微分信号的引入可改善系统的动态特性&#xff0c;但也存在一个问题&#xff0c;那就是容易引进高频干扰&#xff0c;在偏差扰动突变时尤其显出微分项的不足。为了解决这个问题人们引入低通滤波方式来解决这一问题。 1、不完全微分的基…

使用Python实现简易的数据标注工具

使用Python实现简易的数据标注工具 以增加工作效率为目的&#xff0c;最近一直在着手构建一个AI ToolBox 这两天&#xff0c;我为其中的预处理工具目录添加了数据标注模块&#xff0c;本文所介绍内容的代码见这里 该数据标注模块包含以下几个demo gui_tkinter_exercise.py …