【新】新手向文章 十行代码带你量化交易入门
使用JoinQuant编写量化策略需要具备一定的金融知识和编程基础,如果你不会使用Python编程,推荐你用几天时间学习一下这篇Python基础教程
(1)取行情数据
详见:股票行情数据
(2)取财务数据
详见:基本面数据
可以使用get_index_stocks、get_industry_stocks或是自行设置股票池列表。
例如:
# 获取所有沪深300的股票, 设为股票池 stocks = get_index_stocks('000300.XSHG') set_universe(stocks)
或者指定自定义的股票池:
stocks = ['000009.XSHE','002222.XSHE','000005.XSHE','000002.XSHE'] set_universe(stocks)
详见:订单
下订单方法
1. order
API原文:order
买卖一定数量(单位:股)股票。
2. order_target
API原文:order_target
通过买卖,将股票仓位调整至一定数量(单位:股)。
3. order_value
API原文:order_value
买卖一定价值量(单位:元)股票。
4. order_target_value
API原文:order_target_value
通过买卖,将股票仓位调整至一定价值量(单位:元)。
context.portfolio.positions中包含持有的某个股票的信息,详见:positions
可以使用持有的每只股票的持仓成本与当前价格实现止盈或止损,示例如下:
*g_cost = context.portfolio.positions[stock].*g_cost price = context.portfolio.positions[stock].price# 收益50%止盈 if (price/*g_cost) >= 1.5: order_target(stock, 0)# 亏损10%止损if (price/*g_cost) <= 0.9: order(stock, amount)
API文档中提供了几个策略,这几个策略包含了大部分的使用方法。
详见:策略示例
下面对用户需要实现几个函数做下简单介绍:
1. [initialize](https://www.joinquant.com/api#initialize)
初始化方法,在整个回测、模拟实盘中最开始执行一次,用于初始一些全局变量,如设置基准、交易的手续费、股票池或滑点等等。示例如下:
def initialize(context):# 设定沪深300为基准set_benchmark('000300.XSHG')# 调用此函数设置手续费,每笔交易时的手续费是, 买入时万分之三,卖出时万分之三加千分之一印花税, 每笔交易最低扣5块钱set_commission(PerTrade(buy_cost=0.0001, sell_cost=0.001, min_cost=5))# 调用此函数设置滑点set_slippage(PriceRelatedSlippage(0.002))
2. [handle_data](https://www.joinquant.com/api#handledata)
该函数每个单位时间会调用一次, 如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次。
函数内部就是你的交易思路,详情可参考示例代码。
3. [before_trading_start](https://www.joinquant.com/api#beforetradingstart-可选) 和 [after_trading_end](https://www.joinquant.com/api#aftertradingend-可选)(可选)
这两个函数与handle_data基本相同,只是没有传入data参数。before_trading_start 会在每天开始交易前被调用一次,而after_trading_end 会在每天结束交易后被调用一次。
JoinQuant提供了微信消息推送的功能,API为send_message
教程见:send_message用法
(1) 清仓止损(发送消息)
def before_trading_start(context):g.is_stop = dp_stoploss(kernel=2, n=10, zs=0.03)if g.is_stop:if len(context.portfolio.positions.keys())>0:for stock in context.portfolio.positions.keys(): order_target(stock, 0) send_message("清仓")return
(2) 购买股票(发送股票池)
def before_trading_start(context): g.is_stop = dp_stoploss(kernel=2, n=10, zs=0.03) df = get_fundamentals(query( valuation.code, valuation.market_cap ).filter( valuation.code.in_(chosed_stocks) ).order_by(# 按市值降序排列valuation.market_cap.asc() )) g.per_buylist = list(df['code']) send_message(g.per_buylist)
指数平滑均线
# 指数平滑均线函数,以收盘价计算,可以换开盘价等其他价格,N为时间周期,m用于计算平滑系数a=m/(N 1)def f_expma(N,m):# 获取EXPMA初始值为回测时间段和上市交集的前N-1个收盘价均值global init_price,EXPMA2,EXPMA1 close_price = history(N, unit='1d', field='close', security_list=None)if init_price is None and not math.isnan(close_price[security][1]): init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值EXPMA2 = init_price EXPMA1 = EXPMA2#log.info(EXPMA1)#log.info(EXPMA2)if not math.isnan(close_price[security][0]):# 回测T时间,取得T-1的收盘价current_close = close_price[security][-1] a = m/(N 1) EXPMA2 = a * current_close (1 - a)*EXPMA1 log.info(EXPMA1) log.info(EXPMA2)return EXPMA1,EXPMA2#1为前一天值,2为后一天值
MACD
import talibdef MACD(prices, fastperiod=12, slowperiod=26, signalperiod=9):''' 参数设置: fastperiod = 12 slowperiod = 26 signalperiod = 9 返回: macd - signal '''macd, signal, hist = talib.MACD(prices, fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)return macd[-1] - signal[-1]
KDJ死叉金叉
#定义KDJ计算函数,输入为基期长度count、平滑因子a,输出为KDJ指标值。#K1为前一日k值,D1为前一日D值,K2为当日k值,D2为当日D值,J为当日J值def KDJ(count,a,b,K1,D1):h = attribute_history(security, count, unit='1d',fields=('close', 'high', 'low'),skip_paused=True)# 取得过去count天的最低价格low_price = h['low'].min()# 取得过去count天的最高价格high_price = h['high'].max()# 取得当日收盘价格current_close = h['close'][-1]if high_price!=low_price:#计算未成熟随机值RSV(n)=(Ct-Ln)/(Hn-Ln)×100RSV = 100*(current_close-low_price)/(high_price-low_price)else: RSV = 50#当日K值=(1-a)×前一日K值 a×当日RSVK2=(1-a)*K1 a*RSV#当日D值=(1-a)×前一日D值 a×当日K值D2=(1-b)*D1 b*K2#计算J值J2 = 3*K2-2*D2return K1,D1,K2,D2,J2
RSI指数
def calRSI(stocks):rsi = []for stock in stocks:# 获取股票的收盘价数据,talib参数取14,前14天的rsi无法计算,所以取15天的数据prices = attribute_history(stock, 15, '1d', ('close'))# 创建RSI买卖信号,包括参数timeperiod# 注意:RSI函数使用的price必须是narrayrsi = [talib.RSI(prices['close'].values, timeperiod=14)[-1]]return rsi
OBV指标
#定义多空力量比率加权修正成交量的obv函数def obv(df,init_obv):obv1 = []for i in range(0,len(df)): jinge = ((df['close'].values[i]-df['low'].values[i])-(df['high'].values[i]-df['close'].values[i]))/(df['high'].values[i]-df['low'].values[i])if i==0: obv1.append(init_obv jinge*df['volume'].values[i])else: obv1.append(obv1[-1] jinge*df['volume'].values[i]) obv1=np.array(obv1)return obv1
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程