【量化交易笔记】12.海龟交易策略

news2024/10/2 6:35:12

引言

海龟交易法则是一种著名的趋势跟踪交易策略,适用于中长线投资者。

海龟交易策略(Turtle Trading)起源于美国,由著名的交易员理查德·丹尼斯(Richard Dennis)创立。这种交易策略属于趋势跟踪策略,适用于中长线投资者。其核心思想是捕捉市场的主要趋势,并在趋势开始时买入,趋势结束时卖出。海龟交易法则以严格的纪律和长期的跟踪为特点,旨在实现稳定的长期盈利。

原理:

海龟交易策略一套完整的交易系统,包括市场,入市,头寸规模、止损/止盈,出场,买卖策略等。

  1. 市场:海龟交易者关注全球市场,主要观察股票、债券、商品、货币等市场的趋势。
  2. 入市:海龟交易者使用一定的技术指标来判断市场趋势,并在市场价格突破一定阻力位时买入。例如,他们可能会使用移动平均线或趋势线来确定趋势。
    头寸规模:海龟交易者会根据他们的风险承受能力和市场状况来决定头寸规模。他们通常会使用一定比例的账户资金来投资,以控制风险。
  3. 止损/止盈:海龟交易者会设定止损点和止盈点,以限制损失并锁定盈利。止损点通常设置在离当前价格一定距离的位置,以减少损失。止盈点则根据市场状况和投资者的目标来设定。
  4. 出场:海龟交易者在市场价格达到止盈点或止损点时平仓。他们也会在市场趋势逆转时出场,以避免损失。
  5. 买卖策略:海龟交易者既可以做多,也可以做空。他们通常会观察市场趋势,并在趋势开始时买入,趋势结束时卖出。他们也会在市场波动较大时进行反趋势交易,以获取短线利润。

总的来说,海龟交易法则是一套以风险控制为核心的交易系统,旨在捕捉市场趋势并最大化盈利。

趋势追踪——唐奇安通道

海龟交易法则利用唐奇安通道的突破点作为买卖信号指导交易,简单而言唐奇安通道是由一条上轨线、中线和下线组成,上轨线由N1日内最高价构成,下轨线由N2日内最低价计算,当价格冲破上轨是可能的买入信号,反之,冲破下轨时是可能的卖出信号。

海龟交易系统本质上是一个趋势跟随的系统,但是最值得学习的是资金管理尤其是分批建仓及动态止损的部分。书中提到了N值仓位管理法,其中N值与技术指标平均真实波幅 ATR计算类似。ATR是真实波幅TR的20日平均值,而TR是当前交易日最高价和最低价之差 、前一交易日收盘价与当前交易日最高价之差、前一交易日收盘价与当前交易日最低价之差三者中的最大值,用公式表示为:

TR=Max(High−Low,abs(High−PreClose),abs(PreClose−Low)),技术指标库TA-Lib提供了直接计算ATR的函数。

下面使用简化版的海龟交易法则进行历史回测,即不考虑仓位管理和动态止损/止盈条件,以唐奇安通道突破作为买入卖出信号。

交易规则为:
(1)当今天的收盘价,大于过去20个交易日中的最高价时,以收盘价买入;
(2)买入后,当收盘价小于过去10个交易日中的最低价时,以收盘价卖出。

数据采集模块

import pandas as pd 
import numpy as np
import talib as ta
from datetime import datetime,timedelta
import matplotlib.pyplot as plt
%matplotlib inline 
#正常显示画图时出现的中文和负号
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
import baostock as bs



#### 登陆系统 ####
def get_k_data(code,start,end):
    lg = bs.login()
    rs = bs.query_history_k_data_plus(code,
        "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ,psTTM,pcfNcfTTM,isST",
    start_date=start, end_date=end,
        frequency="d", adjustflag="3")
    data=rs.get_data()
    data['date'] = pd.to_datetime(data['date']) 
    bs.logout()   
    return data.set_index('date')

为了与前面的文章统一,仍选sh.600000,时间区间为从2023-1-1 到 2023-10-19

hs=get_k_data('sh.600000','2023-1-1','2023-10-19')[['close','open','high','low','volume']]
#最近N1个交易日最高价
hs['up']=ta.MAX(hs.high,timeperiod=20).shift(1)
#最近N2个交易日最低价
hs['down']=ta.MIN(hs.low,timeperiod=10).shift(1)
#每日真实波动幅度
hs['ATR']=ta.ATR(hs.high,hs.low,hs.close,timeperiod=20)
hs.tail()
datecloseopenhighlowvolumeupdownATR
2023-10-137.10007.11007.15007.0800196504107.27.00.096226
2023-10-167.07007.12007.13007.0400249077337.27.00.095914
2023-10-177.09007.09007.10007.0500190291437.27.00.093619
2023-10-187.05007.07007.11007.0500214857217.27.00.091938
2023-10-196.84007.04007.05006.8300616797717.27.00.098341

设置买卖策略及相关信号

def my_strategy(data):
    x1=data.close>data.up
    x2=data.close.shift(1)<data.up.shift(1)
    x=x1&x2
    y1=data.close<data.down
    y2=data.close.shift(1)>data.down.shift(1)
    y=y1&y2
    data.loc[x,'signal']='buy'
    data.loc[y,'signal']='sell'
    buy_date=(data[data.signal=='buy'].index).strftime('%Y%m%d')
    sell_date=(data[data.signal=='sell'].index).strftime('%Y%m%d')
    buy_close=data[data.signal=='buy'].close.round(2).tolist()
    sell_close=data[data.signal=='sell'].close.round(2).tolist()
    return (buy_date,buy_close,sell_date,sell_close)

以下代码实现了回测,并加上了alpha 、 beta、年化收益、夏普比率等

相关公式

年化收益率

年化收益率=[(投资内收益 / 本金)/ 投资天数] * 365×100%
而实际上采用以下公式计算,考虑到一年的交易日 约为250日
p r = ( p e n d p s t a r ) 250 / n − 1 p_r=(\frac{p_{end}}{p_{star}})^{250/n}-1 pr=(pstarpend)250/n1

这里的alpha和beta 是指量化投资理论的 α \alpha α β \beta β

贝塔(Beta)

表示投资的系统性风险,反映了策略对大盘变化的敏感性。
例如,一个策略的Beta为1.3,则大盘涨1%的时候,策略可能涨1.3%,反之亦然;

如果一个策略的Beta为-1.3,说明大盘涨1%的时候,策略可能跌1.3%,反之亦然。
β = C o v ( p n , B n ) σ B 2 \beta=\frac{Cov(p_n,B_n)}{\sigma^2_B} β=σB2Cov(pn,Bn)
p n p_n pn:策略每日收益率
B n B_n Bn:基准每日收益率
σ B 2 \sigma^2_B σB2:基准每日收益方差
C o v ( p n , B n ) Cov(p_n,B_n) Cov(pn,Bn):策略和基准每日收益率的协方差

阿尔法(Alpha)

非系统性风险,Alpha是投资者获得与市场波动无关的回报,一般用来度量投资者的投资技艺。例如,投资者获得了12%的回报,其基准获得了10%的回报,那么Alpha或者价值增值的部分就是2%。

α = p r − r f − β ( B r − r f ) \alpha=p_r-r_f-\beta(B_r-r_f) α=prrfβ(Brrf)
p r p_r pr:策略的年化收益率
r f r_f rf:无风险收益率
B r B_r Br:基准年化收益率

收益波动率(Volatility)

用来测量资产的风险性,波动越大代表策略风险越高。
σ p = 250 n − 1 ∑ t = 1 n ( p t − p t ‾ ) 2 \sigma_p=\sqrt{\frac{250}{n-1} \sum^n_{t=1}(p_t- \overline{p_t})^2} σp=n1250t=1n(ptpt)2

夏普比率(Sharpe Ratio)

表示每承受一单位总风险,会产生多少的超额报酬,可以同时对策略的收益与风险进行综合考虑。
夏普比率为(算法交易收益-基准收益)/算法交易收益的标准差
S h a r p R a t i o = p r − r f σ p SharpRatio=\frac{p_r-r_f}{\sigma_p} SharpRatio=σpprrf
p r p_r pr:策略的年化收益率
r f r_f rf:无风险收益率
σ p \sigma_p σp策略收益率波动率

信息比率(Information Ratio)

衡量单位超额风险带来的超额收益。

信息比率越大,说明该策略单位跟踪误差所获得的超额收益越高,因此,信息比率较大的策略的表现要优于信息比率较小的策略。合理的投资目标应该是在承担适度风险下,尽可能追求高信息比率。
I n f o r m a t i o n R a t i o = p r − B r σ t InformationRatio=\frac{p_r-B_r}{\sigma_t} InformationRatio=σtprBr

最大回撤(Max Drawdown)

描述策略可能出现的最糟糕的情况。

M a x D r a w D o w n t = max ⁡ ( 1 − P j P i ) MaxDrawDown_t=\max(1-\frac{P_j}{P_i}) MaxDrawDownt=max(1PiPj)


def strategy(stock,start,end,N1=20,N2=10):
    df=get_k_data(stock,start,end)[['close','open','high','low','volume']]
    df=df.astype("float")
    df['ret']=df.close/df.close.shift(1)-1
    #最近N1个交易日最高价
    df['H_N1']=ta.MAX(df.high,timeperiod=N1)
    #最近N2个交易日最低价
    df['L_N2']=ta.MIN(df.low,timeperiod=N2)
    #当日收盘价>昨天最近N1个交易日最高点时发出信号设置为1
    buy_index=df[df.close>df['H_N1'].shift(1)].index
    df.loc[buy_index,'收盘信号']=1
    #将当日收盘价<昨天最近N2个交易日的最低点时收盘信号设置为0
    sell_index=df[df.close<df['L_N2'].shift(1)].index
    df.loc[sell_index,'收盘信号']=0
    df['当天仓位']=df['收盘信号'].shift(1)
    df['当天仓位'].fillna(method='ffill',inplace=True)
    d=df[df['当天仓位']==1].index[0]-timedelta(days=1)
    df1=df.loc[d:].copy()
    df1['ret'][0]=0
    df1['当天仓位'][0]=0
    #当仓位为1时,买入持仓,当仓位为0时,空仓,计算资金净值
    df1['策略净值']=(df1.ret.values*df1['当天仓位'].values+1.0).cumprod()
    df1['指数净值']=(df1.ret.values+1.0).cumprod()
    df1['策略收益率']=df1['策略净值']/df1['策略净值'].shift(1)-1
    df1['指数收益率']=df1.ret
    total_ret=df1[['策略净值','指数净值']].iloc[-1]-1
    annual_ret=pow(1+total_ret,250/len(df1))-1
    dd=(df1[['策略净值','指数净值']].cummax()-df1[['策略净值','指数净值']])/df1[['策略净值','指数净值']].cummax()
    d=dd.max()
    beta=df1[['策略收益率','指数收益率']].cov().iat[0,1]/df1['指数收益率'].var()
    alpha=(annual_ret['策略净值']-annual_ret['指数净值']*beta)
    exReturn=df1['策略收益率']-0.03/250
    sharper_atio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()
    TA1=round(total_ret['策略净值']*100,2)
    TA2=round(total_ret['指数净值']*100,2)
    AR1=round(annual_ret['策略净值']*100,2)
    AR2=round(annual_ret['指数净值']*100,2)
    MD1=round(d['策略净值']*100,2)
    MD2=round(d['指数净值']*100,2)
    S=round(sharper_atio,2)
    df1[['策略净值','指数净值']].plot(figsize=(15,7))
    plt.title(stock+'海龟交易策略简单回测',size=15)
    bbox = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9)
    plt.text(df1.index[int(len(df1)/5)], df1['指数净值'].max()/1.08, f'累计收益率:\
    策略{TA1}%,指数{TA2}%;\n年化收益率:策略{AR1}%,指数{AR2}%;\n最大回撤: 策略{MD1}%,指数{MD2}%;\n\
    策略alpha: {round(alpha,2)},策略beta:{round(beta,2)}; \n夏普比率: {S}',size=13,bbox=bbox) 
    plt.xlabel('')
    ax=plt.gca()
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    plt.show()
    # return df1.loc[:,['close','ret','H_N1','L_N2','当天仓位','策略净值','指数净值']]

直接调用

strategy("sh.600000","2023-01-01","2023-10-19")

其他其他策略的收益情况

strategy('sz.300576','2023-01-01','2023-10-19')

在这里插入图片描述

结论

经过上述步骤,我们就实现了一个简单的海龟交易策略。交易次数并不多,另外可通过对上述代码做进一步的扩展,使其更加完善和复杂。

原始的海龟交易采用唐奇安通道来追踪趋势,在趋势比较明显的行情表现不错,但是在震荡的行情中效果不佳,当然这是所有趋势型策略的通病。下面着重使用Python对唐奇安通道进行可视化,并利用简化版的海龟交易法则进行简单的历史回测。

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

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

相关文章

Quirks(怪癖)模式是什么?它和 Standards(标准)模式有什么区别?

目录 前言: 用法: 代码: Quirks模式示例: Standards模式示例: 理解: Quirks模式&#xff1a; Standards模式&#xff1a; 高质量讨论: 前言: "Quirks模式"和"Standards模式"是与HTML文档渲染模式相关的两种模式。它们影响着浏览器如何解释和渲染HT…

华夏版-超功能记事本 Ⅲ 8.8易语言源码

华夏版-超功能记事本 Ⅲ 8.8易语言源码 下载地址&#xff1a;https://user.qzone.qq.com/512526231

VisualStudio[WPF/.NET]基于CommunityToolkit.Mvvm架构开发

一、创建 "WPF应用程序" 新项目 项目模板选择如下&#xff1a; 暂时随机填一个目标框架&#xff0c;待会改&#xff1a; 二、修改“目标框架” 双击“解决方案资源管理器”中<项目>CU-APP, 打开<项目工程文件>CU-APP.csproj, 修改目标框架TargetFramew…

windows开机自启动和忘记密码-备忘

windows开机自启动和忘记密码-备忘 文章目录 windows开机自启动和忘记密码-备忘1.自启动网址定时任务方式 2.忘记windows用户密码 1.自启动 网址 参考博文&#xff1a;https://blog.csdn.net/wwzmvp/article/details/113656544&#xff0c;感谢博主。 定时任务方式 如图&#…

uniapp如何跳转系统授权管理页?

如何跳转系统授权管理页&#xff1f; 跳转APP应用授权设置页面 文章目录 如何跳转系统授权管理页&#xff1f;效果图打开系统App的权限设置界面 效果图 例&#xff1a;Android 打开系统App的权限设置界面 App端&#xff1a;打开系统App的权限设置界面微信小程序&#xff1a;打开…

20231024后端研发面经整理

1.如何在单链表O(1)删除节点&#xff1f; 狸猫换太子 2.redis中的key如何找到对应的内存位置&#xff1f; 哈希碰撞的话用链表存 3.线性探测哈希法的插入&#xff0c;查找和删除 插入&#xff1a;一个个挨着后面找&#xff0c;知道有空位 查找&#xff1a;一个个挨着后面找…

express session

了解 Session 认证的局限性 Session 认证机制需要配合 cookie 才能实现。由于 Cookie 默认不支持跨域访问&#xff0c;所以&#xff0c;当涉及到前端跨域请求后端接口的时候&#xff0c;需要做很多额外的配置&#xff0c;才能实现跨域 Session 认证。 注意&#xff1a; 当前端…

Unity实现方圆多少米范围随机生成怪物

using System.Collections; using System.Collections.Generic; using UnityEngine;public class CreatMonster : MonoBehaviour {// S这个脚本间隔一点时间生成怪物/*1.程序逻辑* 1. 设计一个计时器* 2.间隔一段时间3s执行一下 * */float SaveTime 0f;public GameObject …

【C++笔记】C++继承

【C笔记】C继承 一、继承的概念二、继承的语法和权限三、父类和子类成员之间的关系3.1、子类赋值给父类(切片)3.2、同名成员 四、子类中的默认成员函数4.1、构造函数4.2、拷贝构造4.3、析构函数 五、C继承大坑之“菱形继承”5.1、什么是“菱形继承”5.2、解决方法 一、继承的概…

为什么自学或是培训完软件测试后,找不到工作?原因可能是这几种

最近我的一个表弟想学习软件测试&#xff0c;但他一直在犹豫是报班还是自学&#xff0c;甚至担心学完后市场饱和了&#xff0c;学完找不到工作。那么借用这次机会&#xff0c;跟大家进行分析一下软件测试行业找不到工作的几个原因&#xff0c;希望能够帮助到大家&#xff0c;少…

Python(一)关键字、内置函数

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&am…

随笔:使用Python爬取知乎上相关问题的所有回答

项目中数据分析的需要自己从知乎某个专门的问题上爬数据&#xff0c;但众所周知&#xff0c;知乎的问题的显示方式有点胃疼&#xff08;指滑动后下翻加载更多回答&#xff0c;还经常卡住&#xff09;&#xff0c;翻了翻网上的教程发现有的要么就是很老了要么就是付费的&#xf…

ubuntu 安装 gnome 安装 xrdp

先安装xrdp 更新 apt-get sudo apt-get update && apt-get upgrade安装图形包 apt-get install xubuntu-desktop安装 xrdp apt-get install xrdp安装 xfce4 apt-get install xfce4配置 xfce4 Add xfce to the xfce desktop window manager autorun by fixing the …

静电模型PIC方法的Matlab仿真设计

任务要求&#xff1a; 采用PIC模拟方法的静电模型来模拟多环形电子注在圆柱系统中的运动轨迹。模拟电子枪阴极表面发射电子注&#xff0c;电子在静态场的作用下运动直至稳定的运动过程。其中 系统长&#xff1a;0.01m 系统半径&#xff1a;0.005m 入射的每个宏电子电流&#x…

RedHat8升级GLIBC_2.29,解决ImportError: /lib64/libm.so.6: version `GLIBC_2.29

问题背景 在做大模型微调训练时&#xff0c;执行python脚本时出现如下报错&#xff1a; 查看当前服务器版本&#xff0c;确实没有GLIBC_2.29的 strings /lib64/libm.so.6 | grep GLIBC_ GLIBC_2.2.5 GLIBC_2.4 GLIBC_2.15 GLIBC_2.18 GLIBC_2.23 GLIBC_2.24 GLIBC_2.25 GLIB…

Java后端开发——实现登录验证程序

一、实现一个简单登录验证程序 实现一个简单的用户登录验证程序&#xff0c;如果用户名是 abc &#xff0c;密码是 123&#xff0c;则显示欢迎用户的信息&#xff0c;否则显示“用户名或密码不正确”。 【分析】 该案例采用 JSP 页面只完成提交信息和验证结果的显示&#xff…

零基础Linux_22(多线程)线程控制和和C++的多线程和笔试选择题

目录 1. 线程控制 1.1 线程创建(pthread_create) 1.2 线程结束(pthread_exit) 1.3 线程等待(pthread_join) 1.4 线程取消(pthread_cancel结束) 1.5 线程tid(pthread_self()) 1.6 线程局部存储(__thread) 1.7 线程分离(pthread_detach) 2. C的多线程 3. 笔试选择题 答…

百济神州:受专利侵权诉讼影响,股价暴跌,估值已被华尔街大幅下调

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 百济神州股价暴跌估值已被下调 今年以来&#xff0c;百济神州(BGNE)在美股的股价已经下跌了26.1%。在2023年10月18日的的交易日结束时&#xff0c;百济神州的最后最后交易价为167.54美元&#xff0c;与2023年1月20日的52周…

Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析

最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制&#xff0c;方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础…

优化单元测试效率:Spring 工程启动耗时统计

相关文章&#xff1a; Java Agent 的简单使用 本文相关代码地址&#xff1a;https://gitee.com/dongguabai/blog 单元测试在软件项目的可持续发展中扮演着不可或缺的角色&#xff0c;这一点毫无疑问。不久前&#xff0c;公司大佬在内部分享时也提到过&#xff1a;单元测试是…