精华内容
下载资源
问答
  • Python交易策略回测器 支持主动,被动或混合策略。 积极策略占领市场 被动策略造就了市场 混合策略可以是主动的也可以是被动的 依存关系: Pandas , Numpy , Python ,这些东西都需要,例如Cython等。
  • 快速回测器 基于pandas/matplotlib等的快速Python交易策略回测平台,支持多工具策略。
  • %作者:Moeti Ncube %这是可用于回测交易策略的代码。 所使用的示例策略部分用于开发中频算法交易策略; 这是我们用来分析刻度数据的一些回测编码。 此代码可用于回测时间序列的交易策略,该时间序列的第一列是价格...
  • 将您的工作目录设置为“TradingStrat > CSV”(CSV 文件夹包含使用回测器所需的逗号分隔值数据) 3. 通过在 Matlab 提示符下键入 runCSV 来运行文件“runCSV.mat”。 4.将打开一个新窗口。 在“输入:”窗口中,...
  • 数量 执照 版权所有(C)2011 Michael Ihde 该程序是免费软件; 您可以根据自由软件基金会发布的GNU通用... Quant的目标是提供一个有用的实验框架,以探索适用于管理401k,IRA或其他长期投资的临时投资者的交易策略
  • 本文探讨了使用机器学习模型来构建市场生成器。... 然后,文章提出了一种估计回测统计概率分布的新方法。 最终目标是开发一个框架来改进量化投资策略的风险管理,特别是在聪明贝塔、因子投资和另类风险溢价空间。
  • 程序参数 PARAMS = { "start_time": "2017-02-01 00:00:00", "end_time": "2017-08-01 00:00... "slippage": 0.003, # 此处“slippage"包含佣金(千二)+交易滑点(千一) "account_initial": {"huobi_cny_cash"...

     

    程序参数

    PARAMS = {
        "start_time": "2017-02-01 00:00:00",
        "end_time": "2017-08-01 00:00:00",
        "slippage": 0.003,  # 此处“slippage"包含佣金(千二)+交易滑点(千一)
        "account_initial": {"huobi_cny_cash": 100000, "huobi_cny_btc": 0},
    }

     

    基准收益:

    179.59%

     

     回测结果:单位%

     

    结论:

    1. 部分策略直接穿越牛熊猴,超越市场收益
    2. 周期越长,效果越显著,其中1d周期有5个策略收益超过200%
    3. 越简单越牛,双均线策略达到最高

     

    展开全文
  • 我们今天来介绍几个经典的策略模型,在数字货币市场中的表现, 基本参数: (1)回测区间:2016-01-01至2016-12-31 (2)行情订阅:bitcoin(频率:日) (3)初始资金:1000000 数据来源:matrixdata.io ...

    我们今天来介绍几个经典的策略模型,在数字货币市场中的表现,

    基本参数:

    (1)回测区间:2016-01-01至2016-12-31

    (2)行情订阅:bitcoin(频率:日)

    (3)初始资金:1000000

    数据来源:matrixdata.io

    MATRIX DATA 是一家专业的数据服务商,提供可同时获取多家数字货币交易所行情数据的API,以及历史高频行情数据CSV下载,Websocket推送等服务。为用户节省大量时间与精力。可用于量化交易者进行策略构建和回测,以及数字货币相关应用开发。

    本文选取的数据来自MATRIX DATA中的币种行情数据接口:https://matrixdata.io/document/quotation/5


    1. 双均线策略

    交易规则:

    短均线:最近3日的收盘价平均值

    长均线:最近5日的收盘价平均值

    开仓条件:短均线大于长均线,并且上一个交易日的短均线小于长均线

    平仓条件:短均线小于长均线,并且上一个交易日的短均线大于长均线

    资金投入规模:满仓

    回测结束时平仓

    年化收益:84.56%,累计收益率:86.81%,夏普比率:2.49,最大回撤率:-12.27%


    2.海龟交易策略

    交易规则:

    真实波幅TR=max(当前交易日最高价-当前交易日最低价,当前交易日最高价-上一个交易日收盘价,上一个交易日收盘价-当前交易日最低价)

    平均真实波幅N=(19*上一个交易日N值+当前交易日TR)/20

    开仓条件:当日最高价>前20个交易日的最高价;

    开仓数量unit=(1%*当前账户可用资金/N)取整

    加仓条件:当日收盘价>上一次开仓的价格+0.5*N,并且之前加仓次数<4次(即最多加仓四次)

    加仓数量unit同上

    平仓条件:当日最低价<前10个交易日的最低价

    平仓数量:全部持仓

    止损平仓条件:当日收盘价<上一次开仓的价格-2*N

    止损平仓数量:全部持仓

    回测结束时平仓

    年化收益:94.42%,累计收益率:67.27%,夏普比率:2.59,最大回撤率:-25.19%


    3.Dual Thrust策略

    交易规则:

    N=10;K1=0.7;K2=0.7

    N日最高价:HH

    N日最低收盘价:LC

    N日最高收盘价:HC

    N日最低价:LL

    区间Range=max(HH-LC,HC-LL)

    买入线BL=当日开盘价+K1*Range

    卖出线SL=当日开盘价-K2*Range

    开仓条件:当日收盘价>BL

    平仓条件:当日收盘价<SL

    回测结束时平仓

    年化收益:131.45%,累计收益率:84.55%,夏普比率:3.12,最大回撤率:-24.23%

     

     

     

    展开全文
  • 本系列文章将会介绍如何使用DolphinDB优雅而高效的实现量化交易策略回测。本文将介绍在华尔街广泛应用的多因子Alpha策略的回测。多因子模型是量化交易选股中最重要的一类模型,基本思路是找到某些和回报率最相关的...

    本系列文章将会介绍如何使用DolphinDB优雅而高效的实现量化交易策略回测。本文将介绍在华尔街广泛应用的多因子Alpha策略的回测。多因子模型是量化交易选股中最重要的一类模型,基本思路是找到某些和回报率最相关的指标,并根据这些指标,构建股票投资组合(做多正相关的股票,做空负相关的股票)。多因子模型中,单独一个因子的个股权重一般实现多空均衡(市场中性),没有暴露市场风险的头寸(beta为0,所以称之为alpha策略),能实现绝对收益。多个因子之间相互正交,方便策略配置,实现回报和风险的最优控制。另外,相比于套利策略(通常可以实现更高的sharpe ratio,但是scale不好),多因子alpha策略有很好的scale,可以配置大量的资金。多因子Alpha策略在对冲基金中的使用非常普遍。

    1. 生成因子

    本文的重点是实现多因子Alpha策略的回测框架。因子不是重点,这部分通常由金融工程师或策略分析师来完成。为了方便大家理解,文章以动量因子、beta因子、规模因子和波动率因子4个常用的风险因子为例,介绍如何在 DolphinDB database 中实现多因子回测。

    输入数据表inData包含6个字段:sym (股票代码), date(日期), close (收盘价), RET(日回报), MV(市值), VOL(交易量)

    def genSignals(inData){
    	USstocks = select sym, date, close, RET, MV from inData where weekday(date) between 1:5, close>5, VOL>0, MV>100000 order by sym, date
    	update USstocks set prevMV=prev(MV), cumretIndex=cumprod(1+RET), signal_size=-sqrt(MV), signal_vol=-mstd(RET, 21)*sqrt(252) context by sym
    	update USstocks set mRet = wavg(RET, prevMV) context by date
    	update USstocks set signal_mom = move(cumretIndex,21)/move(cumretIndex,252)-1, signal_beta=mbeta(RET, mRet, 63) from USstocks context by sym
    	return select sym, date, close, RET as ret, signal_size, signal_beta, signal_vol, signal_mom from USstocks where date>=1991.01.01
    }

    DolphinDB函数说明:

    abs:取绝对值。

    prev:把向量中的所有元素向右移动一个位置。

    cumprod:计算累计乘积。

    sqrt:计算平方根。

    mstd(X, k):计算移动标准差。

    wavg(X, k):计算加权平均数。

    move(X, k):如果k为正数,则把向量的所有元素向右移动k个位置,如果k为负数,则把向量的所有元素向左移动k个位置。

    mbeta(X, Y, k):计算普通最小二乘回归的系数估计。

    genSignals 函数说明:

    首先数据过滤,选择市值较高的股票在交易日中的数据。接着使用过滤后的数据计算4个风险因子:

    • 规模因子(signal_size):MV的平方根的相反数
    • 波动率因子(signal_vol):过去一个月的股价波动率的相反数
    • 动量因子(signal_mom):过去12个月(去除最近一个月)的动量因子
    • beta因子(signal_beta):利用过去三个月的数据计算个股跟市场的beta

    2. 回测框架

    多因子Alpha策略的回测框架包含3个部分。首先是在每个历史周期上,生成每个股票在每个策略上的权重。一个历史周期上的所有仓位可以成为一个tranche。然后根据tranche的持有时间,生成每一个股票在每一个tranche的每一个策略上每一天的仓位和盈亏。最后统计分析每个策略和所有策略的业绩。

    2.1 计算历史周期的投资仓位

    首先定义一个函数formPeriodPort计算一个周期(一天)的股票仓位。然后使用并行计算获得历史上每一个周期的投资仓位。

    2.1.1 计算一天的股票投资组合

    这一步的输入是每一个股票在不同因子上的值,输出是每一个股票在每一个因子上的投资权重。股票权重要满足两个条件:(1)一个因子中所有股票的权重和为零,也就是说多空均衡。(2)不同因子之间相互正交,也就是说第i个因子的权重wi和第j个因子的值sj的内积为0(i<>j)。为了实现上述目标,我们引入了因子矩阵(矩阵的每一列表示一个因子,每一行表示一个股票),并且将单位因子(所有元素均为1)添加到因子矩阵中。

    实践中,还需要考虑的一个问题是,去除权重较小的股票。一个股票池有几千个股票,大部分的股票获得的权重很小,几乎可以忽略。我们定义了一个嵌套函数f来调整单个因子中股票的权重。

    函数formPeriodPort的输入参数有3个:

    • signals 是由genSignals函数生成的数据表,包含8个字段:股票代码、日期、收盘价格、回报率和4个因子。
    • signalNames 是所有因子的名称,用向量表示。
    • stockPercentile 用于控制股票的数量。

    函数的输出是一个数据表,存储一天的股票投资组合,包括4个字段:tranche, sym, signalIdx, exposure。

    def formPeriodPort(signals, signalNames, stockPercentile){
    	stockCount = signals.size()
    	signalCount = signalNames.size()
    	tranche = signals.date.first()
    	
            //demean all signals and add a unit column to the signal matrix
    	sigMat = matrix(take(1, stockCount), each(x->x - avg(x), signals[signalNames]))
    
    	//form weight matrix. 
    	transSigMat = sigMat.transpose()
    	weightMat = transSigMat.dot(sigMat).inv().dot(transSigMat).transpose()[1:]
    
    	/* form exposures. allocate two dollars on each signal, one for long and one for short
    	   trim small weights. In practice, we don't want to trade too many stocks */
    	f = def(sym, tranche, stockPercentile, signalVec, signalIdx){
    		t = table(sym, signalVec as exposure, iif(signalVec > 0, 1, -1) as sign)
    		update t set exposure = exposure * (abs(exposure) < percentile(abs(exposure), stockPercentile)) context by sign
    		update t set exposure = exposure / sum(exposure).abs() context by sign
    		return select tranche as tranche, sym, signalIdx as signalIdx, exposure from t where exposure != 0
    	}
    	return loop(f{signals.sym, tranche, stockPercentile}, weightMat, 1..signalCount - 1).unionAll(false)
    }

    DolphinDB函数说明:

    size:返回向量中元素的个数

    first:返回第一个元素

    matrix:构建矩阵

    transpose:矩阵转置

    dot:矩阵或向量内积

    inv:矩阵求逆

    iif(condition, trueResult, falseResult):如果满足条件condition,则返回trueResult,否则返回falseResult。它相当于对每个元素分别运行if...else语句。

    loop(func,args):高价模板函数,把函数func应用到参数args的每一个元素上,并将结果汇总到一个元组中。如果args包含三个k个参数,每个参数的长度是n,那么loop将运行n次。

    unionAll:合并多个表

     

    2.1.2 计算过去每天的股票投资组合

    回测时使用 的数据量非常庞大,因此我们把数据放到内存的分区数据库中,然后使用并行计算。如果想要了解更多关于分区数据库的内容,可以参考DolphinDB分区数据库教程。我们把genSignals函数生成的数据保存到分区表partSignals中,一个分区表示一天。接着,创建一个分区表ports,用于保存计算出来的股票投资组合,一个分区表示一年。然后,使用 map-reduce函数,把formPeriodPort函数应用到每一天,把每个结果合并到分区表ports中。

    def formPortfolio(signals, signalNames, stockPercentile){
    	dates = (select count(*) from signals group by date having count(*)>1000).date.sort()
    	db = database("", VALUE, dates)
    	partSignals = db.createPartitionedTable(signals, "signals", `date).append!(signals)
    	db = database("", RANGE, datetimeParse(string(year(dates.first()) .. (year(dates.last()) + 1)) + ".01.01", "yyyy.MM.dd"))
    	symType = (select top 10 sym from signals).sym.type()
    	ports = db.createPartitionedTable(table(1:0, `tranche`sym`signalIdx`exposure, [DATE,symType,INT,DOUBLE]), "", `tranche)
     	return mr(sqlDS(<select * from partSignals>), formPeriodPort{,signalNames,stockPercentile},,unionAll{,ports})
    }

    DolphinDB函数说明:

    sort:把向量中的元素排序

    database(directory, [partitionType], [partitionScheme], [locations]):创建数据库。如果directory为空,则创建内存数据库。

    createPartitionedTable(dbHandle, table, [tableName], partitionColumns):在数据库中创建分区表。

    datatimeParse(X, format):把字符串转换成DolphinDB中时间类型数据。

    unionAll:合并表

    type:返回数据类型的ID。

    mr(ds, mapFunc, [reduceFunc], [finalFunc], [parallel=true]):map-reduce函数。

     

    2.2 计算仓位和盈亏

    这一步的任务是根据持有的仓位以及持有时间,生成每一个股票在每一个tranche的每一个因子上每一天的仓位和盈亏。首先定义一个嵌套函数来f来计算部分股票投资仓位的盈亏,接着把嵌套函数应用到所有股票投资组合(使用mr函数),计算所有股票投资组合的盈亏,并把结果保存到分区表pnls中。

    函数caclStockPnL的输入参数包括:

    • ports: 每一天的投资组合表,包括4个字段 tranche, sym, signalIdx, exposure
    • dailyRtn:股票每天的回报表,包括3个字段 date, sym, ret
    • holdingDays: 股票持有的天数

    函数的输出是股票的盈亏明细表,包括字段8个字段 date, sym, signalIdx, tranche, age, ret, exposure, pnl

    def calcStockPnL(ports, dailyRtn, holdingDays){
    	ages = table(1..holdingDays as age)
    	dates = sort exec distinct(tranche) from ports
    	dictDateIndex = dict(dates, 1..dates.size())
            dictIndexDate = dict(1..dates.size(), dates)
            lastDaysTable = select max(date) as date from dailyRtn group by sym
    	lastDays = dict(lastDaysTable.sym, lastDaysTable.date)
    
            // define a anonymous function to calculate the pnl for a part of the porfolios.
    	f = def(ports, dailyRtn, holdingDays, ages, dictDateIndex, dictIndexDate,lastDays){
    		pos = select dictIndexDate[dictDateIndex[tranche]+age] as date, sym, signalIdx, tranche, age, take(0.0,size age) as ret, exposure, take(0.0,size age) as pnl from cj(ports,ages) where isValid(dictIndexDate[dictDateIndex[tranche]+age]), dictIndexDate[dictDateIndex[tranche]+age]<=lastDays[sym]
    		update pos set ret = dailyRtn.ret from ej(pos, dailyRtn,`date`sym)
    		update pos set exposure = exposure*cumprod(1+ret) from pos context by tranche, signalIdx, sym
    		update pos set pnl = exposure*ret/(1+ret)
    		return pos
    	}
    
            // calculate pnls for all portfolios and save the result to a partitioned in-memory table pnls
    	db = database("", RANGE, datetimeParse(string(year(dates.first()) .. (year(dates.last()) + 1)) + ".01.01", "yyyy.MM.dd"))
    	symType = (select top 10 sym from ports).sym.type()
    	modelPnls = table(1:0, `date`sym`signalIdx`tranche`age`ret`exposure`pnl, [DATE,symType,INT,DATE,INT,DOUBLE,DOUBLE,DOUBLE])
    	pnls = db.createPartitionedTable(modelPnls, "", `tranche)
     	return mr(sqlDS(<select * from ports>), f{,dailyRtn,holdingDays,ages,dictDateIndex, dictIndexDate,lastDays},,unionAll{,pnls})
    }     

    DolphinDB函数说明:

    dict(key, value):创建字典。

    cj(leftTable, rightTable) :交叉连接两个表。

    isValid:检查元素是否为NULL。如果不是NULL,则返回1,如果是NULL,则返回0。

    ej(leftTable, rightTable, matchingCols, [rightMatchingCols]) :等值连接两个表。

     

    3. 运行实例

    我们以美国股市为例,运行多因子Alpha策略回测。输入的股票日数据表USPrices包含6个字段:sym (股票代码), date(日期), close (收盘价), RET(日回报), MV(市值)和VOL(交易量)。

    //加载数据
    USPrices = ...
    
    holdingDays = 5
    stockPercentile = 20
    signalNames = `signal_mom`signal_vol`signal_beta`signal_size
    
    //生成因子
    signals=genSignals(USPrices)
    
    //计算每天的股票投资组合
    ports = formPortfolio(signals, signalNames, stockPercentile)
    
    //计算盈亏
    dailyRtn = select sym,date,ret from signals
    pos = calcStockPnL(ports, dailyRtn, holdingDays)
    
    //绘制四个因子的累计盈亏走势图
    pnls = select sum(pnl) as pnl from pos group by date, signalIdx
    factorPnl = select pnl from pnls pivot by date, signalIdx
    plot(each(cumsum,factorPnl[`C0`C1`C2`C3]).rename!(signalNames), factorPnl.date, "The Cumulative Pnl of All Four Signals")
    
    //绘制动量因子不同持仓日的累计盈亏走势图
    pnls = select sum(pnl) as pnl from pos where signalIdx=0 group by date, age
    momAgePnl = select pnl from pnls pivot by date, age
    plot(each(cumsum,momAgePnl[`C1`C2`C3`C4`C5]).rename!(`C1`C2`C3`C4`C5), momAgePnl.date)

    4个因子的累计盈亏走势图

    动量因子的累计盈亏走势图

    DolphinDB虽然是一个通用的分布式时序数据库,但因为内置极其高效的多范式编程语言,用于量化交易,开发效率非常高。上面的多因子回测框架,仅用了3个自定义函数,50余行代码。DolphinDB的运行效率更是惊人,对美国股市25年中市值较高的股票按日进行回测,最后产生的盈亏明细表包含1亿余条记录。如此复杂的计算量,在单机(4核)上执行耗时仅50秒。

     

    4. 讨论

    前面的回测框架,仅仅解决了多因子策略的一部分问题,也就是说单个因子中股票的配置。我们还有两个重要的问题需要解决:(1)多个因子之间,如何配置权重,平衡投资的回报和风险。(2)一个新的因子有没有带来额外的Alpha,换句话说,一个新的因子是不是可以有已经存在的多个因子来表示,如果可以,那么这个新因子可能没有存在的必要。下一篇文章,我们会介绍如何使用DolphinDB来回答上面两个问题。

    展开全文
  • python 量化策略回测Pairs trading is one of the many mean-reversion strategies. It is considered non-directional and relative as it aims to trade on both related stocks with similar statistical and ...

    python 量化策略回测

    Pairs trading is one of the many mean-reversion strategies. It is considered non-directional and relative as it aims to trade on both related stocks with similar statistical and economical properties. It first identifies a historical relationship that has been recently broken and then buys the implied undervalued security while shorting the overvalued security in attempt to revert to the original relationship. We must first understand the difference between correlation and cointegration. Correlation (ρ) measures the degree of the linear relationship between variables, it has the following features:

    货币对交易是许多均值回复策略之一。 它被认为是无方向性和相对性的,因为它旨在买卖具有相似统计和经济特性的两种相关股票。 它首先确定最近被破坏的历史关系,然后购买隐含的被低估的证券,同时卖空被高估的证券,以尝试恢复为原始关系。 我们必须首先了解关联和协整之间的区别。 相关度(ρ)度量变量之间的线性关系的程度,它具有以下特征:

    • ρ = -1, means a perfectly negative relationship. They move in the opposite direction.

      ρ= -1,表示完全负关系。 它们朝相反的方向移动。
    • ρ = 0, means there is no linear relationship between the two.

      ρ= 0,表示两者之间没有线性关系。
    • ρ = 1, means a perfect linear relationship between the datasets. They move hand in hand.

      ρ= 1,表示数据集之间的理想线性关系。 他们携手并进。

    Correlation does not imply causality. It is not used to explain variations in one dataset caused by the other. We use regression analysis for that issue. Negatively correlated assets can be used to hedge one another, and it is the basic diversification rule for portfolio management. If we have two different datasets and their two respective variances, we can calculate a measure called covariance. Covariance has the same principle as correlation except that it is unbounded and therefore not really meaningful. It is however used in the formula of correlation:

    相关并不意味着因果关系。 它不用于解释一个数据集由另一数据集引起的变化。 对于该问题,我们使用回归分析。 负相关的资产可以用来对冲,这是资产组合管理的基本多元化规则。 如果我们有两个不同的数据集以及它们各自的两个方差,则可以计算一个称为协方差的度量。 协方差与相关具有相同的原理,除了协方差是无界的,因此实际上没有意义。 但是,它用在相关公式中:

    If the correlation coefficient is zero, it does not necessarily mean that there is absolutely no relationship between the two datasets. It simply means that there is not a linear one.

    如果相关系数为零,则不一定意味着两个数据集之间绝对没有关系。 它仅表示没有线性关系。

    Image for post
    A chart showing perfect correlation between two datasets. Correlation = 1
    该图显示了两个数据集之间的完美相关性。 相关= 1
    Image for post
    A chart showing a strong correlation between two datasets. Correlation = 0.7
    该图显示了两个数据集之间的强相关性。 相关= 0.7
    Image for post
    A chart showing a strong negative correlation between two datasets. Correlation = -0.7
    该图显示了两个数据集之间的强烈负相关。 相关= -0.7

    Disclaimer: The below choice for the two related securities is inspired by Dr. Ernest Chan. The back-test to follow does not take into account the transaction costs and therefore the reality may differ with respect to the results found at the end of the article.

    免责声明:两种相关证券的以下选择均受Ernest Chan博士的启发。 遵循的回测未考虑交易成本,因此,对于本文结尾处的结果,实际情况可能有所不同。

    We must be extremely cautious with correlation. With financial data you will most likely have to calculate correlations of returns and not prices. If you’re interested in short-term relationships, go for returns’ correlations, otherwise, opt for prices if you’re in it for the long-term. Cointegration, on the other hand, is not too dissimilar to correlation. In plain terms, it means that the ratio between the two financial time series will vary around a constant mean. Pairs trading can rely on the constant ratio that is expected to revert to its long-term mean (i.e. converge). Below are two ETFs with the following details:

    我们对关联必须非常谨慎。 使用财务数据,您最有可能必须计算收益而不是价格的相关性。 如果您对短期关系感兴趣,请寻求收益的相关性,否则,如果您长期处于收益关系中,请选择价格。 另一方面,协整与相关并不太相似。 简而言之,这意味着两个财务时间序列之间的比率将围绕恒定的平均值变化。 货币对交易可以依靠恒定比率,该比率有望恢复为长期均值(即收敛)。 以下是两个具有以下详细信息的ETF:

    • EWA: iShares MSCI Australia ETF, seeks to replicate investment results that correspond to the price and yield performance of publicly traded securities in the Australian market.

      EWA :iShares MSCI澳大利亚ETF,力求复制与澳大利亚市场上公开交易证券的价格和收益表现相对应的投资结果。

    • EWC: iShares MSCI Canada ETF seeks to replicate investment results that correspond to the price and yield performance of publicly traded securities in the Canadian market.

      EWC :iShares MSCI加拿大ETF寻求复制与加拿大市场上公开交易证券的价格和收益表现相对应的投资结果。

    Image for post
    EWA and EWC chart.
    EWA和EWC图表。

    They do seem very correlated, but are they cointegrated? In other words, is their spread mean-reverting and stationary? That’s what we will be back-testing. If the series are indeed stationary then we will form a pairs trading simple strategy based on their spread (ignoring the hedge ratio). Let’s consider EWA to be Asset_2 variable and EWC to be Asset_1 variable in our code. The calculated correlation between the two seems to be the first unlocked door towards the strategy:

    它们看起来确实很相关,但是它们是协整的吗? 换句话说,它们的扩散是否是均值回归且平稳的? 这就是我们将进行回测的内容。 如果该系列确实是平稳的,那么我们将基于它们的价差(忽略对冲比率)形成一个交易简单策略的货币对。 让我们在代码中将EWA视为Asset_2变量,将EWC视为Asset_1变量。 两者之间的计算出的相关性似乎是通向该策略的第一个解锁门:

    import numpy as np
    np.corrcoef(Asset_1, Asset2)

    The result we get will be around 0.85 which is a pretty strong linear correlation. Next, we will separately check whether the two time series are stationary or not, and then check if they are cointegrated or not. We will use statsmodels.tsa.stattools for the below.

    我们得到的结果约为0.85,这是一个非常强的线性相关性。 接下来,我们将分别检查两个时间序列是否稳定,然后检查它们是否协整。 我们将在下面使用statsmodels.tsa.stattools。

    def stationarity(a, cutoff = 0.05):
    a = np.ravel(a)
    if adfuller(a)[1] < cutoff:
    print(‘The series is stationary’)
    print(‘p-value = ‘, adfuller(a)[1])
    else:
    print(‘The series is NOT stationary’)
    print(‘p-value = ‘, adfuller(a)[1])stationarity(Asset_1)
    stationarity(Asset_2)def cointegration(a, b):
    if coint(a, b)[1] < 0.05:
    print(‘The series are cointegrated’)
    print(‘p-value = ‘, coint(a, b)[1])
    else:
    print(‘The series are NOT cointegrated’)
    print(‘p-value = ‘, coint(a, b)[1])cointegration(Asset_1, Asset_2)

    The above code will give these results. Naturally, we do not expect that these two random-like time series to be stationary (I just needed an excuse to provide the code) but what interests us is the result of the cointegration test which has a p-value of less than our chosen cut-off (5%), thus, rejecting the null hypothesis that there is no cointegration. Now, we have confirmation to back-test a strategy based on the two assets.

    上面的代码将给出这些结果。 自然,我们不希望这两个类似随机的时间序列是固定的(我只是需要一个借口来提供代码),但是让我们感兴趣的是协整测试的结果,该协整测试的p值小于我们选择的p值截止(5%),因此拒绝没有协整的原假设。 现在,我们已经确认可以基于这两种资产对策略进行回测。

    The series is NOT stationary (Asset_1):

    系列不是固定的(Asset_1):

    p-value = 0.057

    p值= 0.057

    The series is NOT stationary (Asset_2):

    系列不是固定的(Asset_2):

    p-value = 0.20

    p值= 0.20

    The series are cointegrated:

    该系列是协整的:

    p-value = 0.048

    p值= 0.048

    # Another check for stationarity in the ratio between the twoData[:, 2] = Asset_2 / Asset_1
    Ratio = Data[:, 2]stationarity(Ratio)

    When we calculate the ratio between the two and plot it we will have the next graph which seems to be mean-reverting. The spread seems to satisfy the stationarity test as well.

    当我们计算两者之间的比率并将其绘制时,我们将得到下一个似乎均值回归的图形。 价差似乎也满足了平稳性测试。

    The series is stationary

    该系列是固定的

    p-value = 0.032

    p值= 0.032

    Image for post
    The ratio between EWA and EWC.
    EWA与EWC之间的比率。

    Now, we should standardize the ratio we have in order to normalize the signals.

    现在,我们应该标准化比率以标准化信号。

    # Standardization assuming the spreadfor i in range(len(Data)):
    try:
    Data[i, 3] = (Data[i — lookback:i + 1, 2].mean())
    except IndexError:
    pass# Calculating Standard deviationfor i in range(len(Data)):
    Data[i, 4] = ((Data[i — lookback:i + 1, 2].std()))# Standardizingfor i in range(len(Data)):
    Data[i, 5] = (Data[i, 2] — Data[i, 3]) / Data[i, 4]
    Image for post
    The standardized ratio between EWA and EWC. The arbitrarily chosen barriers of 2 and -2 will be used to initiate trades. If the standardized ratio reaches -2, we go long the ratio while if it reaches 2, we go short the ratio.
    EWA和EWC之间的标准化比率。 任意选择的2和-2的壁垒将用于启动交易。 如果标准化比率达到-2,则使该比率变长;如果标准化比率达到2,则使该比率变短。

    Main idea: We will back-test a dollar-neutral pairs trading strategy on the EWA and EWC ETFs. As we have explained above, the conditions of the back-test will be the following:

    主要思想:我们将在EWA和EWC ETF上对美元中性货币对交易策略进行回测。 如上文所述,回测的条件如下:

    • Holding period = 60

      持有期= 60
    • Lookback period = 9

      回溯期= 9
    • Upper barrier = 2

      上限= 2
    • Lower barrier = -2

      下屏障= -2

    We can also use a variable period that relies on the when the mean reverts back to normality but in our back-test the holding period will be fixed.

    我们还可以使用可变期间,该期间取决于均值恢复正常状态的时间,但在我们的回测中,保持期间将是固定的。

    Image for post
    Signals generated from the strategy with red downwards pointing arrows as sell signals and green upwards pointing arrows as buy signals.
    从策略生成的信号,红色向下的箭头表示卖出信号,绿色向上的箭头表示买入信号。
    # Buy/Sell Conditionsfor i in range(len(Data)):
    try:
    if Data[i, 2] <= lower_barrier and Data[i — 1, 2] > lower_barrier:
    Data[i + 1, 4] = -1
    Data[i + 1, 5] = 1
    elif Data[i, 2] >= upper_barrier and Data[i — 1, 2] < upper_barrier:
    Data[i + 1, 6] = 1
    Data[i + 1, 7] = -1
    else:
    continue
    except IndexError:
    passfor i in range(len(Data)):
    try:
    if Data[i, 5] == 1:
    Data[i + holding_period, 8] = (Data[i + holding_period, 1] — Data[i, 1])
    if Data[i, 6] == 1:
    Data[i + holding_period, 8] = (Data[i + holding_period, 0] — Data[i, 0])
    if Data[i, 4] == -1:
    Data[i + holding_period, 9] = (Data[i, 0] — Data[i + holding_period, 0])
    if Data[i, 7] == -1:
    Data[i + holding_period, 9] = (Data[i, 1] — Data[i + holding_period, 1])
    except IndexError:
    pass

    The next graph shows the equity curve from the strategy (gross of fees) and the results (assuming $1 investment with no leverage).

    下一张图显示了该策略的权益曲线(费用总额)和结果(假设无杠杆的1美元投资)。

    Image for post
    Equity curve following the strategy.
    策略遵循的股权曲线。
    Image for post

    It is worth-mentioning again that the profit was only indicative as it is gross of fees and any other costs. Also, no leverage was used, so, the profit is not magnified which explains its weakness, but the strategy does seem to work even though we have a small bias by choosing the barriers and the lookback before starting.

    再次值得一提的是,利润仅是指示性的,因为它是费用和任何其他费用的总额。 同样,没有使用杠杆,因此利润没有被放大,这说明了它的弱点,但是即使我们在开始之前通过选择壁垒和回溯有小的偏见,该策略也确实有效。

    Image for post
    https://pixabay.com/illustrations/trading-forex-system-laptop-4453011/https://pixabay.com/illustrations/trading-forex-system-laptop-4453011/

    翻译自: https://medium.com/swlh/creating-and-back-testing-a-pairs-trading-strategy-in-python-caa807b70373

    python 量化策略回测

    展开全文
  • 算法交易策略的成功回测

    千次阅读 2019-06-28 10:49:02
    本来来自英文网站 QuantStart 中对于算法交易策略回测描述的一篇文章,原文可以参见脚注。[ Successful Backtesting of Algorithmic Trading Strategies - Part I] 市面上介绍算法交易的文章虽然不算多,但也不少,...
  • 均线交易策略回测 rR Programming language is an open-source software developed by statisticians and it is widely used among Data Miners for developing Data Analysis. R can be best programmed and ...
  • ./backtest包含一些策略回测示例。 ./notebook存放策略研究相关文件,如.ipynb文件 ./web量化交易接口API(纯websocket版),利用此接口可以支持C / C ++,Go,Java,Javascript等语言进行策略开发 快速体验 框架...
  • price 买入价格 datetime 买入时间 position 每次买入股数 remained 总仓位 下图是我用python编写的分钟K指标,程式执行的买卖策略也是经过几百只个股大数据计算后编写出来的。 报表中最后一笔 2-19号11点卖出后就...
  • 我们可以尝试做这样的改进:在股票a,b,c……的历史数据上分别进行策略回测,找到一个能够稳定收益策略B,来避免时间成本浪费的问题。但是这样仍然存在问题,在等待股票a出现买点的时候,股票b,c……的买点可能也...
  • 策略回测指标

    千次阅读 2018-08-03 16:32:17
    交易次数:交易次数其实是一个可以初步衡量策略回测结果是否可靠的指标,过少往往意味着回测结果不可靠。 Beta(贝塔):在资本资产定价模型(CAPM)中,投资组合的收益被分为和市场系统风险相关与和市场系统风险...
  • python实现证券量化策略回测平台的模拟交易功能 20200114写了份作业,以下是需要作业需要完成的功能: 采用面向对象程序设计的思想,设计并完成证券量化策略回测平台的模拟交易功能: 设计交易账户,在创建之初指定...
  • 这篇文章主要介绍如何使用Python对一些简单的交易策略进行回测,对这块比较感兴趣的朋友可以看一看。1.获取证券数据本文以A股市场为例,先获取A股近10年的数据并保存到数据库。1.1.安装数据库(MongoDB)为了提升...
  • 量化交易回测需要注意哪些事项

    千次阅读 2019-06-26 17:43:08
    本来来自英文网站 QuantStart中对于算法交易策略回测描述的一篇文章,原文可以参见脚注。1市面上介绍算法交易的文章虽然不算多,但也不少,很多量化爱好者也会在各大论坛对自己的策略进行分享,一般的流程就是策略...
  • [交易策略]周线四进两出策略回测

    千次阅读 2016-09-14 18:09:18
    四周期最高线:HV(H,4); 两周期最低线:LV(L,2); 四进:=C>四周期最高线; 两出:=C<两周期最低线; 四进=1,BK; 两出=1,SP; AUTOFILTER;
  • VNPY - CTA策略模块策略回测

    千次阅读 2018-08-10 16:50:05
    作者:魔元 目录 使用回测引擎 读懂回测报告 优化策略参数 多进程优化 量化策略主要是从历史数据统计或者发现...CTA策略模块的主要回测目标是验证交易信号是否正确,仓位大小的问题在实盘中则由交易员来确定。...
  • 本来来自英文网站 QuantStart 中对于算法交易策略回测描述的一篇文章,原文可以参见脚注。[ Successful Backtesting of Algorithmic Trading Strategies - Part I] 市面上介绍算法交易的文章虽然不算多,但也不少,...
  • 使用 MATLAB:registered: 和 Financial Toolbox:trade_mark: 中的功能,您只需 8 行代码即可执行策略回溯测试。 这包括: • 数据准备• 交易信号生成• 计算投资组合回报、夏普比率和最大回撤• 权益曲线绘制事实上...
  • 交易模拟器 概述 我对各种股票分析和数据挖掘的讨论。 先决条件 Python 2.7 NumPy( ) 科学( ) 熊猫( ) mpl_finance( ) 快速开始 运行(并可能编辑) download_historical_data.sh以在本地下载历史库存...
  • 因此我们对于期权交易的学习,以及策略验证有了更好的工具。 Deribit 期权回测 回测系统中定义的Deribit期权为欧式,一张合约价值为1BTC。期权合约代码为:BTC-7AUG20-12750-C。 标的物 行权日期 行权价格 ...
  • 量化交易入门笔记-策略回测与评估

    千次阅读 2018-10-15 12:56:26
    首先,编写一个简单的“双无线量化策略” 代码如下: def initialize(context): &amp;quot;&amp;quot;&amp;quot;双均线量化策略的初始化函数&amp;quot;&amp;quot;&amp;quot; # ...
  • v11是第一个策略回测程序的最后一个版本,将对策略参数进行优化。 很多财经书籍里都指出,不同股票、不同书籍都有个各自的特点和节奏,因此使用同一策略参数应用于所有的交易是不明智的。 在之前的例子中,我们尝试...
  • 这篇文章主要介绍如何使用Python对一些简单的交易策略进行回测,对这块比较感兴趣的朋友可以看一看。1.获取证券数据本文以A股市场为例,先获取A股近10年的数据并保存到数据库。1.1.安装数据库(MongoDB)为了提升...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,574
精华内容 1,829
关键字:

交易策略回测