将quantopian的动量策略迁移到老虎证券量化api
原quantopian的动量策略,感谢原策略作者
首先需要获取数据
dataframe的列是各个股票的代码,index是时间,日频
def get_price(bars_num):stocks = read_sp_500code()df=pd.DataFrame(columns=['symbol','time','open','high','low','close','volume'])#每次取数据要取的条目数量items=math.floor(1000/bars_num)stock_num=len(stocks)print(stock_num)roundtrip=math.floor(stock_num/items)print(roundtrip)for i in range(roundtrip):bars = quote_client.get_bars(stocks[i*items:i*items+items],period=BarPeriod.DAY,begin_time=-1, end_time=-1,right=QuoteRight.BR,limit=bars_num)df=df.append(bars,ignore_index=True)print(bars)bars = quote_client.get_bars(stocks[roundtrip*items:stock_num],\period=BarPeriod.DAY,begin_time=-1,end_time=-1,right=QuoteRight.BR,limit=bars_num)df=df.append(bars,ignore_index=True)df.drop(['time','open','high','low','volume'],axis=1,inplace=True)print(df)return_df=pd.DataFrame(columns=stocks)for i in range(len(stocks)):close = df[i*bars_num:i*bars_num+bars_num]['close'].valuesprint(close)print(type(close))return_df[stocks[i]]=closeprint(return_df)return return_df
"""
Simple equity momentum model by Andreas Clenow
cloned from https://www.quantopian.com/posts/equity-momentum
Purpose:
To capture momentum effect in US stock markets.
Implements two methods of reducing downside.
Index level trend filter, and minimum momentum.Momentum analytic:
Uses annualized exponential regression slope, multiplied by R2, to adjust for fit.
Possibility to use average of two windows.Settings:
* Investment universe
* Momentum windows (x2)
* Index trend filter on/off
* Index trend filter window
* Minimum required slope
* Exclude recent x days
* Trading frequency
* Cash management via bond etf, on off
* Bond ETF selection
* Sizing method, inverse vola or equal.Suggested areas of research and improvements:
* Use pipeline to limit number of processed stocks, by putting the regression logic in there.
* Adding fundamental factors.
* Portfolio sizes
* Market cap weighting / inverse market cap weighting. (you may want to z-score and winsorize)
* Momentum analytic: There are many possible ways. Try simplifications and variations."""from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume, CustomFactor, SimpleMovingAverage, Latest
from quantopian.pipeline.filters.morningstar import Q500US, Q1500US
from quantopian.pipeline.data import morningstarimport numpy as np # we're using this for various math operations
from scipy import stats # using this for the reg slope
import pandas as pddef slope(ts):"""Input: Price time series.Output: Annualized exponential regression slope, multipl"""x = np.arange(len(ts))log_ts = np.log(ts)#print('This is ts',ts)#print('This is log_ts:\n',log_ts)#print(' ')slope, intercept, r_value, p_value, std_err = stats.linregress(x, log_ts)#print(slope)annualized_slope = (np.power(np.exp(slope), 250) - 1) * 100#print('This is annualized_slope',annualized_slope)return annualized_slope * (r_value ** 2)def inv_vola_calc(ts):"""Input: Price time series.Output: Inverse exponential moving average standard deviation. Purpose: Provides inverse vola for use in vola parity position sizing."""returns = np.log(ts).diff()#print (type(returns))stddev = returns.ewm(halflife=20, ignore_na=True, min_periods=0,adjust=True).std(bias=False).dropna()return 1 / stddev.iloc[-1]def initialize(context):"""Setting our variables. Modify here to test differentiterations of the model."""# Investment Universe 1 = Q500US, 2 = Q1500UScontext.investment_set = 1# This version uses the average of two momentum slopes.# Want just one? Set them both to the same number.context.momentum_window = 60 # first momentum window.context.momentum_window2 = 90 # second momentum window# Limit minimum slope. Keep in mind that shorter momentum windows# yield more extreme slope numbers. Adjust one, and you may want# to adjust the other.context.minimum_momentum = 60 # momentum score cap# Fixed number of stocks in the portfolio. How diversified# do you want to be?context.number_of_stocks = 25 # portfolio sizecontext.index_id = sid(8554) # identifier for the SPY. used for trend filter.context.index_average_window = 100 # moving average periods for index filter# enable/disable trend filter.context.index_trend_filter = True # Most momentum research excludes most recent data.context.exclude_days = 5 # excludes most recent days from momentum calculation# Set trading frequency here.context.trading_frequency = date_rules.month_start()# identifier for the cash management etf, if used.context.use_bond_etf = Truecontext.bond_etf = sid(23870) # 1 = inv.vola. 2 = equal size. Suggest to implement # market cap and inverse market cap as well. There's # lots of room for development here.context.size_method = 2 # Schedule rebalanceschedule_function(my_rebalance,context.trading_frequency,time_rules.market_open(hours=1))# Schedule daily recording of number of positions - For display in back# test results only.schedule_function(my_record_vars,date_rules.every_day(),time_rules.market_close())# Create our dynamic stock selector - getting the top 500 most liquid US# stocks.if(context.investment_set == 1):inv_set = Q500US()print(type(inv_set))elif(context.investment_set == 2):inv_set = Q1500US()attach_pipeline(make_pipeline(inv_set), 'investment_universe')def make_pipeline(investment_set): """This will return the selected stocks by market cap, dynamically updated."""# Base universe base_universe = investment_set yesterday_close = USEquityPricing.close.latestpipe = Pipeline(screen=base_universe,columns={'close': yesterday_close,})return pipedef my_rebalance(context, data):"""Our monthly rebalancing routine"""# First update the stock universe. context.output = pipeline_output('investment_universe')context.security_list = context.output.indexprint(context.security_list)print(context.security_list[0])print(type(context.security_list[0]))# Get datahist_window = max(context.momentum_window,context.momentum_window2) + context.exclude_dayshist = data.history(context.security_list, "close", hist_window, "1d")#hist_only = data.history('Equity(24 [AAPL])', "close", hist_window, "1d")#print(hist_only)#print(hist)data_end = -1 * context.exclude_days # exclude most recent datamomentum1_start = -1 * (context.momentum_window + context.exclude_days)momentum_hist1 = hist[momentum1_start:data_end]momentum2_start = -1 * (context.momentum_window2 + context.exclude_days)momentum_hist2 = hist[momentum2_start:data_end]# Calculate momentum scores for all stocks.momentum_list = momentum_hist1.apply(slope) # Mom Window 1momentum_list2 = momentum_hist2.apply(slope) # Mom Window 2#print(momentum_list)# Combine the lists and make averagemomentum_concat = pd.concat((momentum_list, momentum_list2))mom_by_row = momentum_concat.groupby(momentum_concat.index)mom_means = mom_by_row.mean()# Sort the momentum list, and we've got ourselves a ranking table.ranking_table = mom_means.sort_values(ascending=False)# Get the top X stocks, based on the setting above. Slice the dictionary.# These are the stocks we want to buy.buy_list = ranking_table[:context.number_of_stocks]final_buy_list = buy_list[buy_list > context.minimum_momentum] # those who passed minimum slope requirement# Calculate inverse volatility, for position size.inv_vola_table = hist[buy_list.index].apply(inv_vola_calc)# sum inv.vola for all selected stocks.sum_inv_vola = np.sum(inv_vola_table)# Check trend filter if enabled.if (context.index_trend_filter):index_history = data.history(context.index_id,"close",context.index_average_window,"1d") # Gets index historyindex_sma = index_history.mean() # Average of index historycurrent_index = index_history[-1] # get last element# declare bull if index is over averagebull_market = current_index > index_sma# if trend filter is used, only buy in bull markets# else always buyif context.index_trend_filter:can_buy = bull_marketelse:can_buy = Trueequity_weight = 0.0 # for keeping track of exposure to stocks# Sell positions no longer wanted.for security in context.portfolio.positions:if (security not in final_buy_list):if (security.sid != context.bond_etf):# print 'selling %s' % securityorder_target(security, 0.0)vola_target_weights = inv_vola_table / sum_inv_volafor security in final_buy_list.index:# allow rebalancing of existing, and new buys if can_buy, i.e. passed trend filter.if (security in context.portfolio.positions) or (can_buy): if (context.size_method == 1):weight = vola_target_weights[security]elif (context.size_method == 2):weight = (1.0 / context.number_of_stocks)print context.number_of_stocksorder_target_percent(security, weight)equity_weight += weight# Fill remaining portfolio with bond ETFetf_weight = max(1 - equity_weight, 0.0)print 'equity exposure should be %s ' % equity_weightif (context.use_bond_etf):order_target_percent(context.bond_etf, etf_weight)def my_record_vars(context, data):"""This routine just records number of open positions and exposure levelfor display purposes."""etf_exp = 0.0pos_count = 0eq_exp = 0.0for position in context.portfolio.positions.itervalues():pos_count += 1if (position.sid == context.bond_etf):etf_exp += (position.amount * position.last_sale_price) / \context.portfolio.portfolio_valueelse:eq_exp += (position.amount * position.last_sale_price) / \context.portfolio.portfolio_valuerecord(equity_exposure=eq_exp)record(bond_exposure=etf_exp)record(tot_exposure=context.account.leverage)record(positions=pos_count)
将quantopian的动量策略迁移到老虎证券量化api相关推荐
- python画老虎_老虎证券量化API Python SDK
TigerOpen - 老虎量化开放平台 (Tiger Quant Open API) 简介 老虎开放平台可以为个人开发者和机构客户提供接口服务,投资者可以充分的利用老虎的交易服务.行情服务.账户服务 ...
- 运行于老虎证券开放api的一个小小策略
经过两周的时间,在老虎证券开放api基础上起一个策略,上穿20日均线买入,下穿20日均线卖出,标普500股票池,运行在阿里云上.用crontab定时,美股开盘前运行.策略文件夹下需要有sp500cod ...
- 在ubuntu16阿里云服务器上vnpy1.9.2连接老虎证券开放api以及裸api开发
接着vnpy1.9.2的话题,把老虎证券的接口解决.在命令终端先敲入source activate py27_quant命令,进入conda的虚拟python环境,再pip install tiger ...
- 老虎证券开放api期货合约建立
目前老虎证券开放api有比较方便的股票和期权的contract建立方法,详见官网接入文档.期货的contract需要自己建立,目前实测不能交易,只能建立order,不能place order. 下面是 ...
- 老虎证券开放api期货合约的创建
获取期货 Contract 对象¶ 目前没有提供直接获取期货 Contract 对象的方法, 需要用户自己构建. 示例如下: >>> from tigeropen.trade.dom ...
- python 开放_老虎证券开放api的使用python
使用的开发工具是winpython的Spyder 把下载好的压缩包解压得到最重要的tigeropen文件夹 pyasn,rsa,delorean这几个包默认是没有的,要去网上下好,直接把同名文件夹粘贴 ...
- 老虎证券开放api返回信息太长太啰嗦,返回值与账户api请求对应
输入: contract = openapi_client.get_contracts('AAPL')[0] 输出:2019-03-26 05:50:41,292 INFO [c2fc0681-4fc ...
- 老虎证券开放api的使用python
使用的开发工具是winpython的Spyder 把下载好的压缩包解压得到最重要的tigeropen文件夹 pyasn,rsa,delorean这几个包默认是没有的,要去网上下好,直接把同名文件夹粘贴 ...
- 动量策略 python_在Python中使用动量通道进行交易
动量策略 python Most traders use Bollinger Bands. However, price is not normally distributed. That's why ...
最新文章
- [Cocoa]XCode的一些调试技巧
- java 取pdf表格内容数据_Java 在PDF中添加表格
- 什么是Code Review 代码审查
- ubuntu系统批量端口永久开放
- 服务器控件的异步请求——UpdatePanel和ScriptManager
- 各国家分析之- 阿根廷与乌拉圭
- Qt pro工程文件中判断宏定义是否存在
- group by后可以join吗_去韩国留学毕业后可以留在韩国吗
- 大数据项目实战数仓4——常用脚本
- 互联网金融并不是传统银行的颠覆者
- mysql主键和聚簇索引_MYSQL:聚簇索引和主键索引
- BOOST库介绍(七)——时间处理相关的库
- Cat5e、Cat6、Cat6a和Cat7网线有什么区别?哪个更好?
- LabVIEW开发结构监控系统
- git error Missing tree 解决办法
- 商用密码产品认证-IPSec/SSL网关技术与产品
- 听听那冷雨 -- 余光中
- 头歌--Java面向对象 - String类
- hadoop之大数据生态系统的前世今生
- 山东大学软件工程期末复习知识点总结