请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365794 新帖:1

如何使用JoinQuant编写策略?

随心所致发表于:5 月 9 日 21:13回复(1)

【新】新手向文章  十行代码带你量化交易入门

写在前面的话:

使用JoinQuant编写量化策略需要具备一定的金融知识和编程基础,如果你不会使用Python编程,推荐你用几天时间学习一下这篇Python基础教程

如何使用JoinQuant取数据?

(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

全部回复

0/140

量化课程

    移动端课程