编辑代码

# 导入函数库
from jqdata import *
import numpy as np
import talib as ta
from scipy.fftpack import fft

# 获取场内基金疑问
# 在研究中get_all_securities(['type']=='etf')与get_all_securities(['etf'])等价?文档没看清楚?
# https://www.joinquant.com/view/community/detail/6947b627837ae4f1ea55c5b02a7d8a63?type=1

# 初始化函数,设定基准等等
def initialize(context):
    set_backtest()
    set_params()
  
    ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
      # 开盘前运行
    run_daily(onStart, time='before_open', reference_security='000300.XSHG')
    run_daily(onUpdate, 'every_bar')
    run_daily(onClose, time='after_close', reference_security='000300.XSHG')


def set_params():  # g -- 全局函数
    g.days = 0  # 起始日期为0
    g.refresh_rate = 10  # 调仓周期设置为10日
    g.last_dt = '9999-12-31' # 前一天的日期
    
    g.etfs = [
        '511380.XSHG', # 转债ETF
        '515220.XSHG', # 煤炭ETF
        '159980.XSHE', # 有色ETF
        '159985.XSHE', # 豆粕ETF
    ]
    
    g.etfPrx5 = {'511380.XSHG': 0,
    '515220.XSHG': 1,
    '159980.XSHE': 2,
    '159985.XSHE': 3}
    
    g.etfDatas = pd.DataFrame()


def set_backtest():
    set_benchmark('000300.XSHG')  # 设定沪深300作为基准
    set_option('use_real_price', True) # 开启动态复权模式(真实价格)
    log.set_level('order', 'error')  # 设置报错等级
     
     ### 股票相关设定 ###
    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
def onStart(context):
    pass


def onUpdate(context):
    g.days += 1
    AllTargetPrx(g.etfs, 5, '1d', ['close'])
    pxdf = getLastPrice(context, g.etfs)
    MergeData(pxdf)
    print(g.etfDatas)


def onClose(context):
    g.etfDatas = g.etfDatas.drop(index=g.etfDatas.index)
    trades = get_trades()
    for _trade in trades.values():
        log.info('成交记录:'+str(_trade))
    log.info('一天结束')
    log.info('##############################################################')


def cull(context):   # 筛选标的物
    pass


def Strategy(context):  # 写策略
    pass


# Return DataFrame Object format:{0, close, code}
def getLastPrice(context, etfs):
    g.last_dt = (context.current_dt - datetime.timedelta(1)).strftime('%Y-%m-%d')
    df = get_price(etfs, g.last_dt, context.previous_date, frequency='1d', fields=['open', 'close', 'high', 'low'])
    dresult = df['close']
    colsArray = dresult.columns  # Index(['511380.XSHG', '515220.XSHG', '159980.XSHE', '159985.XSHE'], dtype='object')
    
    resDict={}
    result = pd.DataFrame()
    for i in range(len(colsArray)):
        temp = dresult[colsArray[i]].values
        if(len(temp) != 0):
            resDict = {
                'code': colsArray[i],
                'close':temp[0]
            }
            df = pd.DataFrame([resDict])
            result = pd.concat([result, df])
    # if not result.empty:
    #     pass
    return result  
    

# g.DataFrame format: {0,code, ma5}
def AllTargetPrx(etfs, count=5, unit='1d', fields=['close']):
    for etf in etfs:
        prx = get_bars(etf, count, unit, fields)
        if prx['close'].size != 0:
            ma5 = prx['close'].mean()
            prx5Dic = {'code':etf, 'ma5': ma5}
            df = pd.DataFrame(prx5Dic, index=[0])
            g.etfDatas = pd.concat([g.etfDatas, df])


def MergeData(joiner):
    # 要先解决这个问题,再处理合并
    # print(g.etfDatas) # (0, code, ma5) [0, 511380.XSHG, 10.9948]
    # print(joiner)  #[]
    if not joiner.empty:
        g.etfDatas = pd.merge(g.etfDatas,joiner,how='left',on='code')