Ejemplo n.º 1
0
def main(select_stock_1day_func,trade_1day_func,techList,signalDataAddr = '', dailyQuoteAddr = '', startDate = '2004-01-01', endDate = '2005-12-31'):
    start = time.clock()

    signalData = SourceDataDao.load_signal_data(signalDataAddr) #ByDate
    #dailyQuote = SourceDataDao.loadDailyQuote()
    dailyQuote = SourceDataDao.load_new_daily_quote(dailyQuoteAddr) #ByDate

    start_1 = time.clock()
    signalData = signalData[(signalData.index.get_level_values(0) >= startDate) & (signalData.index.get_level_values(0) <= endDate) ]
    end_1 = time.clock()
    print("signalData花费时间:%f s" % (end_1 - start_1))

    # print(startDate)
    # print(endDate)
    dateList = SourceDataDao.select_date_from_signal(signalData, startDate, endDate)
    # print(dateList)

    # 统计结果
    stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                    columns=['netValue', 'changePCT', 'buyCnt', 'sellCnt', 'prevHoldCnt',
                                             'currHoldCnt', 'cannotSellCnt', 'cannotBuyCnt',
                                         'usableCach', 'mv'])
    # 每日持仓
    stockHoldDailyList = []
    # 交易结果
    stockTradeList = []

    start_trade = time.clock()
    # 交易
    t1d = process1day(startDate, endDate, dailyQuote, signalData, dateList, stockStatDailyDf, stockHoldDailyList, stockTradeList)
    res = signalData.groupby(level=StockConst.TRADINGDAY).apply(t1d.deal, techList, select_stock_1day_func, trade_1day_func)
    end_trade = time.clock()
    print("交易花费时间:%f s" % (end_trade - start_trade))


    result = ''

    start_stat = time.clock()
    # 信号数据
    #groupedSelectStock.to_csv(StockConst.root + '\export\groupedSelectStock.csv')

    # 每日交易
    # print('每日交易:')
    # print(stockTradeList)
    stockTradeDailyDf = pd.DataFrame(stockTradeList)
    stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True)
    # stockTradeDailyDf.to_csv(StockConst.root + '\export\stockTradeDaily.csv')

    # 每日持仓
    #print('每日持仓:')
    stockHoldDailyDf = pd.DataFrame(stockHoldDailyList)
    stockHoldDailyDf.sort_values(by=['tradingDate'],ascending=True)
    # stockHoldDailyDf.to_csv(StockConst.root + '\export\stockHoldDaily.csv')

    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDailyDf = stockStatDailyDf.dropna(how='all')
    result += '--' * 70 + '\n'
    result += '每日统计:' + '\n'
    result += stockStatDailyDf.to_string() + '\n'
    # stockStatDailyDf.to_csv(StockConst.root + '\export\stockStatDaily.csv')

    # 每年统计
    result += '--' * 70 + '\n'
    yearDf = StockYearService.main(stockStatDailyDf)
    result += '每年统计:' + '\n'
    result += yearDf.to_string() + '\n'

    # 最大回撤
    result += '--' * 70 + '\n'
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf)
    result += '最大回撤:' + '\n'
    result += SetUtil.dict_to_string(maxdrop) + '\n'
    #每年的最大回撤
    maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year(stockStatDailyDf)
    maxdropDf.sort_values(by=["year"])
    result += '每年的最大回撤:' + '\n'
    result += maxdropDf.to_string() + '\n'

    #夏普比率
    result += '--' * 70 + '\n'
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf)
    result += '夏普比率:' + '\n'
    result += str(sharpRatio) + '\n'
    #每年的夏普比率
    sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(stockStatDailyDf)
    sharpRatioDf.sort_values(by=["year"])
    result += '每年的夏普比率:' + '\n'
    result += sharpRatioDf.to_string() + '\n'

    end_stat = time.clock()
    print("统计花费时间:%f s" % (end_stat - start_stat))

    # result += '回测完成'
    end = time.clock()
    print("main花费时间:%f s" % (end - start))

    # 净值曲线图
    stockStatDailyDf['netValue'].plot()
    plt.show()

    resultDic={'stockStatDailyDf':stockStatDailyDf,'result':result}

    print(result)
    return resultDic
Ejemplo n.º 2
0
def main(read_func,select_stock_func,trade_func,techList,sliceDict,signalDataAddr = '', dailyQuoteAddr = '', indexQuoteAddr='', benchmark='',
         startDate = '2004-01-01', endDate = '2005-12-31', doPlot=True, table_name=None):
    start = time.clock()

    # signalData = SourceDataDao.loadSignalData(signalDataAddr)
    # dailyQuote = SourceDataDao.loadNewDailyQuote(dailyQuoteAddr)
    # indexQuote = SourceDataDao.loadH5(indexQuoteAddr) #StockConst.root + StockConst.fakeIndexQuoteH5

    # signalData = SourceDataDao.read_file_set_index(signalDataAddr)
    signalData = read_func(signalDataAddr, table_name)

    dailyQuote = SourceDataDao.read_file_set_index(dailyQuoteAddr)
    indexQuote = SourceDataDao.read_file_set_index(indexQuoteAddr)

    if signalDataAddr is not None:
        maxSignalDate = SourceDataDao.get_max_date(signalDataAddr)
        minSignalDate = SourceDataDao.get_min_date(signalDataAddr)
    else:
        maxSignalDate = SignalDataMSSQLDao.select_max_data(table_name)
        minSignalDate = SignalDataMSSQLDao.select_min_data(table_name)
        # print('print')
        # print(maxSignalDate)
        # print(minSignalDate)

    maxDailyQuoteDate = SourceDataDao.get_max_date(dailyQuoteAddr)
    minDailyQuoteDate = SourceDataDao.get_min_date(dailyQuoteAddr)

    maxIndexQuoteDate = SourceDataDao.get_max_date(indexQuoteAddr)
    minIndexQuoteDate = SourceDataDao.get_min_date(indexQuoteAddr)

    # print('minSignalDate:' + minSignalDate)
    # print('maxSignalDate:' + maxSignalDate)
    #
    # print('minDailyQuoteDate:' + minDailyQuoteDate)
    # print('maxDailyQuoteDate:' + maxDailyQuoteDate)
    #
    # print('minIndexQuoteDate:' + minIndexQuoteDate)
    # print('maxIndexQuoteDate:' + maxIndexQuoteDate)

    #
    if minSignalDate < minDailyQuoteDate:
        startDate = minDailyQuoteDate
    else:
        startDate = minSignalDate

    if maxSignalDate > maxDailyQuoteDate:
        endDate = maxDailyQuoteDate
    else:
        endDate = maxSignalDate

    #
    if startDate < minIndexQuoteDate:
        startDate = minIndexQuoteDate
    else:
        pass

    if endDate > maxIndexQuoteDate:
        endDate = maxIndexQuoteDate
    else:
        pass


    print('startDate:'+startDate)
    print('endDate:' + endDate)

    #TODO 暂时不需要
    # dailyQuotePn = SourceDataDao.loadNewDailyQuoteToPn(dailyQuoteAddr)
    dailyQuotePn = None

    #参数
    #初始资金
    initialCash = 1000000 #1000000

    #选股结果(外部传入)
    #select top 5 group by TradingDay order by Mom desc
    allSelectStock = select_stock_func(signalData,techList,sliceDict)
    print('allSelectStock:'+str(len(allSelectStock)))
    # print(allSelectStock)
    if len(allSelectStock) == 0:
        return

    #当前持仓
    currHoldSet = {}
    #资金情况
    capitalEntity = CapitalEntity.CapitalEntity(initialCash, 0, initialCash)
    lastCapitalEntity = copy.copy(capitalEntity)
    #初始化每日统计表
    stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate),
                columns=['netValue','changePCT','buyCnt','sellCnt','prevHoldCnt','currHoldCnt','cannotSellCnt','cannotBuyCnt',
                         'usableCash','totalAsset','indexChangePCT','relativeChangePCT','relativeNetValue'])
    #初始化每日持仓表
    stockHoldDailyList = []
    stockTradeList = []

    #从信号表中取得唯一性日期
    dateList = SourceDataDao.select_date_from_signal(dailyQuote, startDate, endDate) #signalData dailyQuote
    # print(dateList)

    # lastTradingDay = None
    # lastTradingDayStr = None
    lastRelativeNetValue = 1 #昨日相对净值

    start_loop = time.clock()
    for index, item in enumerate(dateList):
    #for date in dateList:
        #print('index:'+str(index)+' len:'+str(len(dateList)))
        # start_inloop0 = time.clock()

        #信号日
        signalDay = dateList[index]
        # 非最后一天
        if index < (len(dateList) - 1):
            #交易日
            tradingDay = dateList[index + 1]
            tradingDayStr = DateUtil.datetime2_str(tradingDay)
            # tradingDayTsp = pd.Timestamp(tradingDayStr)
            # print(tradingDay)
            # print(tradingDayStr)
            # print(tradingDayTsp)
            # print(type(tradingDay))
            # print(type(tradingDayStr))
            # print(type(tradingDayTsp))
            #print('dateStr:'+dateStr)
        # 最后一天
        else:
            break

        # dailyQuote1day = dailyQuote[dailyQuote.index.get_level_values(0) == tradingDay]

        #TODO
        # start_slice = time.clock()
        # print(str(len(dailyQuote)))
        # print(type(tradingDay))

        #交易日行情
        dailyQuote1day = dailyQuote.xs(tradingDay)
        # print('dailyQuote1day:'+str(len(dailyQuote1day)))
        # end_slice = time.clock()
        # print("切片花费时间:%f s" % (end_slice - start_slice))
        # dailyQuote1day = None

        #print(dateStr)

        #信号日选股
        currSelectStock = allSelectStock.xs(signalDay)  #.xs(signalDay)
        # print('currSelectStock:'+str(len(currSelectStock)))



        # if StockConst.isDebug:
        # print('tradingDayStr:'+tradingDayStr+' currSignalData:'+str(len(currSignalData)))
            #print(currSignalData)

        # end_inloop0 = time.clock()
        # print("inloop0花费时间:%f s" % (end_inloop0 - start_inloop0))

        #交易方法(外部传入)
        # start_inloop1 = time.clock()
        dict = trade_func(currSelectStock, currHoldSet, dailyQuote, tradingDay, signalData, capitalEntity, dailyQuotePn, dailyQuote1day, lastCapitalEntity)
        # end_inloop1 = time.clock()
        # print("trade_func花费时间:%f s" % (end_inloop1 - start_inloop1))

        actualBuyList = dict['actualBuyList']
        actualSellList = dict['actualSellList']
        prevHoldList = dict['prevHoldList']
        cannotBuyList = dict['cannotBuyList']
        cannotSellList = dict['cannotSellList']
        stockTradeListDaily = dict['stockTradeList']

        if len(stockTradeListDaily) > 0 :
            stockTradeList.extend(stockTradeListDaily)

        # print(currHoldSet)

        #3.计算当日市值
        # start_inloop2 = time.clock()
        calculate_daily_mv(currHoldSet, capitalEntity, dailyQuote, tradingDay, stockHoldDailyList, initialCash)
        totalAsset = capitalEntity.get_total_asset()

        # end_inloop2 = time.clock()
        # print("calculateDailyMV花费时间:%f s" % (end_inloop2 - start_inloop2))


        # start_inloop3 = time.clock()
        #4.个数
        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(currHoldSet)
        cannotSellCnt = len(cannotSellList)
        cannotBuyCnt = len(cannotBuyList)

        # print(currMV)

        #if StockConst.isDebug:
            #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) +
                  #" changePCTHold:" + str(changePCTHold))

        #当日净值
        netValue = totalAsset / initialCash
        #print("netValue:" + str(netValue))
        #当日收益(%)
        dailyChangePCT = NumUtil.get_change_pct(lastCapitalEntity.get_total_asset(), totalAsset, 5)
        #当日可用现金
        usableCash = capitalEntity.get_usable_cash()

        # 当日的指数
        indexQuote1day = None
        indexChangePCT = 0
        if indexQuote is not None:
            indexQuote1day = indexQuote.ix[(tradingDay, benchmark)]
            indexChangePCT = indexQuote1day['ChangePCT']
        #相对收益=每日收益-指数收益 (%)
        relativeChangePCT = dailyChangePCT - indexChangePCT
        #相对净值=昨日相对净值*(1+相对收益/100)
        relativeNetValue = lastRelativeNetValue*(1+relativeChangePCT/100)

        #统计表
        stockStatDailyDf.ix[tradingDayStr] = netValue,dailyChangePCT,buyCnt,sellCnt,prevHoldCnt,currHoldCnt,cannotSellCnt,cannotBuyCnt,usableCash,totalAsset,indexChangePCT,relativeChangePCT,relativeNetValue
        #昨日资产
        lastCapitalEntity = copy.copy(capitalEntity)
        #昨日相对净值
        lastRelativeNetValue = relativeNetValue

        # lastTradingDay = tradingDay
        # lastTradingDayStr = tradingDayStr
        # end_inloop3 = time.clock()
        # print("inloop3花费时间:%f s" % (end_inloop3 - start_inloop3))


    end_loop = time.clock()
    print("for循环花费时间:%f s" % (end_loop - start_loop))

    result = ''

    start_stat = time.clock()
    # 信号数据
    #allSelectStock.to_csv(StockConst.root + '\export\allSelectStock.csv')


    # # 每日交易
    # # print('每日交易:')
    # # print(stockTradeList)
    # stockTradeDailyDf = pd.DataFrame(stockTradeList)
    # stockTradeDailyDf.sort_values(by=['tradingDay'], ascending=True)
    # # stockTradeDailyDf.to_csv(StockConst.root + '\export\stockTradeDaily.csv')

    # # 每日持仓
    # #print('每日持仓:')
    # stockHoldDailyDf = pd.DataFrame(stockHoldDailyList)
    # stockHoldDailyDf.sort_values(by=['tradingDay'],ascending=True)
    # # stockHoldDailyDf.to_csv(StockConst.root + '\export\stockHoldDaily.csv')

    start_stat_1 = time.clock()
    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDailyDf = stockStatDailyDf.dropna(how='all')
    result += '--' * 70 + '\n'
    result += '每日统计:' + '\n'
    result += stockStatDailyDf.to_string() + '\n'
    stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv')
    end_stat_1 = time.clock()
    print("统计1花费时间:%f s" % (end_stat_1 - start_stat_1))

    start_stat_2 = time.clock()
    # 每年统计
    result += '--' * 70 + '\n'
    yearDf = StockYearService.main(stockStatDailyDf)
    result += '每年统计:' + '\n'
    result += yearDf.to_string() + '\n'
    end_stat_2 = time.clock()
    print("统计2花费时间:%f s" % (end_stat_2 - start_stat_2))

    start_stat_3 = time.clock()
    # 最大回撤
    result += '--' * 70 + '\n'
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf)
    result += '最大回撤:' + '\n'
    result += SetUtil.dict_to_string(maxdrop) + '\n'
    # #每年的最大回撤
    # maxdropDf = StockMaxDropNewService.getMaxDropForEachYear(stockStatDailyDf)
    # maxdropDf.sort_values(by=["year"])
    # result += '每年的最大回撤:' + '\n'
    # result += maxdropDf.to_string() + '\n'
    end_stat_3 = time.clock()
    print("统计3花费时间:%f s" % (end_stat_3 - start_stat_3))

    start_stat_4 = time.clock()
    #夏普比率
    result += '--' * 70 + '\n'
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf)
    result += '夏普比率:' + '\n'
    result += str(sharpRatio) + '\n'
    #每年的夏普比率
    sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(stockStatDailyDf)
    sharpRatioDf.sort_values(by=["year"])
    result += '每年的夏普比率:' + '\n'
    result += sharpRatioDf.to_string() + '\n'
    end_stat_4 = time.clock()
    print("统计4花费时间:%f s" % (end_stat_4 - start_stat_4))

    end_stat = time.clock()
    print("统计花费时间:%f s" % (end_stat - start_stat))

    # result += '回测完成'
    end = time.clock()
    print("main花费时间:%f s" % (end - start))

    if doPlot:
        # # # 净值曲线图
        # stockStatDailyDf['netValue'].plot()
        # plt.show()
        #
        # # # 相对净值曲线图
        # stockStatDailyDf['relativeNetValue'].plot()
        # plt.show()
        pass

    #
    resultDic={
        'stockStatDailyDf': stockStatDailyDf,
        'result': result,
        'sharpRatio': sharpRatio
    }

    print(result)
    return resultDic
Ejemplo n.º 3
0
def main():
    signalData = SourceDataDao.getSignalData()
    #dailyQuote = SourceDataDao.getDailyQuote()
    dailyQuote = SourceDataDao.getNewDailyQuote()

    #columns filter
    #df3 = sourceData.loc[(df['Mom'] <= 4) & (df['Mom'] <= 4), ['Mom']]

    #index filter
    #startDate=DateUtils.str2Datetime('20010105');
    #endDate=DateUtils.str2Datetime('20010111');
    #df4 = df3.ix[startDate:endDate]

    numOfDailyHolding = 5

    #select top 5 group by TradingDay order by Mom desc
    groupedSignalData = signalData.groupby(level='TradingDay').apply(
        SelectUtil.top, numOfDailyHolding, 'Mom', False)

    #param
    #period = 5
    #startDate = '1/8/2001'
    startDate = '1/8/2001'
    #endDate = '1/1/2017'
    #eendDate = '5/18/2001'
    endDate = '12/31/2016'
    #endDate = '12/31/2002'
    #endDate = '1/9/2001'

    #time series
    #dateList = DateUtil.getDateList2(startDate,endDate)

    #当前持仓 key:innerCode value:
    currHoldSet = {}
    stockHoldDF = {}
    stockTradeList = []
    #资金情况
    #capitalDict = {'usableCach':1000000}
    #初始资金
    initialMV = 1000000
    capitalEntity = CapitalEntity.CapitalEntity(initialMV)
    lastMV = initialMV

    #lastSignalData = pd.DataFrame()
    usableVol = 100
    netValue = 1
    #初始化每日统计表
    stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                    columns=[
                                        'netValue', 'changePCT', 'buyCnt',
                                        'sellCnt', 'prevHoldCnt',
                                        'currHoldCnt', 'cannotSellCnt',
                                        'cannotBuyCnt', 'usableCach', 'mv'
                                    ])
    #初始化每日持仓表
    stockHoldDailyList = []
    #从信号表中取得唯一性日期
    dateList = SourceDataDao.select_date_from_signal(signalData, startDate,
                                                     endDate)
    for date in dateList:
        dateStr = DateUtil.datetime2_str(date)
        #print(dateStr)
        #isinstance(date, datetime)

        # select by single date
        #try:

        #print(1)
        currSignalData = groupedSignalData.ix[date]
        if StockConst.IS_DEBUG:
            print("currSignalData:" + str(len(currSignalData)))
        #print(2)
        buyList = getBuyList(currSignalData, currHoldSet)
        #print(3)
        sellList = getSellList(currSignalData, currHoldSet)
        #print(4)
        prevHoldList = getPrevHoldList(currSignalData, currHoldSet)
        #print(currSignalData)
        """
        if (dateStr >= '2015-01-05') & (dateStr <= '2015-01-05'):
            print('-----'+dateStr+'-----')
            #print(currSignalData)
            #print(buyList)
            print(list(currHoldSet.keys()))
            for key in currHoldSet.keys():
                print(str(key) + ':' + currHoldSet.get(key).openDate)
            print('----------------')
        """
        #except:
        #假期,双休日,原数据问题
        #if StockConst.isDebug:
        #print(DateUtil.datetime2Str(date) + ': no data')
        #continue

        dailyChangePCT = 0
        actualSellList = []
        actualBuyList = []
        cannotSellList = []
        cannotBuyList = []

        #实际买入个数
        numOfActualBuy = getNumOfActualBuy(date, buyList, dailyQuote)
        #1.sell changePCTSell
        handleSellList(date, sellList, dailyQuote, usableVol, stockHoldDF,
                       stockTradeList, currHoldSet, actualSellList,
                       cannotSellList, capitalEntity, numOfActualBuy,
                       signalData, prevHoldList, numOfDailyHolding)
        #usableVol = calculateUsableVol(currHoldSet)
        #2.buy changePCTBuy
        handleBuyList(date, buyList, dailyQuote, usableVol, stockHoldDF,
                      stockTradeList, currHoldSet, actualBuyList,
                      cannotBuyList, capitalEntity)
        #3.hold
        #changePCTHold = handleHoldList(date,prevHoldList,dailyQuote,usableVol,stockHoldDF,stockTradeDF,currHoldSet)
        #changePCTHold = 0

        currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote, date,
                                  stockHoldDailyList, initialMV)

        #handleStockHoldDaily(currHoldSet, stockHoldDailyList, date)

        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(currHoldSet)
        cannotSellCnt = len(cannotSellList)
        cannotBuyCnt = len(cannotBuyList)

        #if StockConst.isDebug:
        #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) +
        #" changePCTHold:" + str(changePCTHold))

        #dailyChangePCT = changePCTBuy+changePCTSell+changePCTHold
        #print("dailyChangePCT:"+str(dailyChangePCT))
        #netValue = netValue * (1 + dailyChangePCT / 100)
        #每日净值
        netValue = currMV / initialMV
        #print("netValue:" + str(netValue))
        #每日收益
        dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2)
        #每日可用现金
        usableCach = capitalEntity.get_usable_cash()
        stockStatDailyDf.ix[
            dateStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV

        lastMV = currMV

    #debug 行情数据
    debugDailyQuote(groupedSignalData)

    # 信号数据
    #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv')

    # 每日交易
    # print('每日交易:')
    stockTradeDailyDf = pd.DataFrame(stockTradeList)
    stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True)
    stockTradeDailyDf.to_csv(StockConst.ROOT + '\export\stockTradeDaily.csv')

    # 每日持仓
    #print('每日持仓:')
    stockHoldDailyDf = pd.DataFrame(stockHoldDailyList)
    stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True)
    stockHoldDailyDf.to_csv(StockConst.ROOT + '\export\stockHoldDaily.csv')

    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDailyDf = stockStatDailyDf.dropna(how='all')
    print('每日统计:')
    print(stockStatDailyDf)
    stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv')

    # 每年统计
    yearDf = StockYearService.main(stockStatDailyDf)
    print('每年统计:')
    print(yearDf)

    # 最大回撤
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf)
    print('最大回撤:')
    print(maxdrop)
    #每年的最大回撤
    maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year(
        stockStatDailyDf)
    maxdropDf.sort_values(by=["year"])
    print('每年的最大回撤:')
    print(maxdropDf)

    #夏普比率
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf)
    print('夏普比率:')
    print(sharpRatio)
    #每年的夏普比率
    sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(
        stockStatDailyDf)
    sharpRatioDf.sort_values(by=["year"])
    print('每年的夏普比率:')
    print(sharpRatioDf)
Ejemplo n.º 4
0
def main(select_stock_func,
         trade_func,
         techList,
         signalDataAddr='',
         dailyQuoteAddr='',
         startDate='1/1/2004',
         endDate='12/31/2005'):
    start = time.clock()

    signalData = SourceDataDao.load_signal_data(signalDataAddr)
    #dailyQuote = SourceDataDao.loadDailyQuote()
    dailyQuote = SourceDataDao.load_new_daily_quote(dailyQuoteAddr)

    #参数
    #每天信号数
    #numOfDailySignal = 5
    #初始资金
    initialMV = 1000000  #1000000
    #开始结束日期
    #startDate = '1/8/2001'
    #startDate = '1/1/2004'
    #endDate = '1/1/2017'
    #eendDate = '5/18/2001'
    #endDate = '12/31/2005'
    #endDate = '12/31/2002'
    #endDate = '1/9/2001'

    #选股结果(外部传入)
    #select top 5 group by TradingDay order by Mom desc
    groupedSignalData = select_stock_func(signalData, techList)
    #当前持仓 key:innerCode value:
    currHoldSet = {}
    #资金情况
    capitalEntity = CapitalEntity.CapitalEntity(initialMV)
    lastMV = initialMV
    #初始化每日统计表
    stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                    columns=[
                                        'netValue', 'changePCT', 'buyCnt',
                                        'sellCnt', 'prevHoldCnt',
                                        'currHoldCnt', 'cannotSellCnt',
                                        'cannotBuyCnt', 'usableCach', 'mv'
                                    ])
    #初始化每日持仓表
    stockHoldDailyList = []
    stockTradeList = []

    #从信号表中取得唯一性日期
    dateList = SourceDataDao.select_date_from_signal(signalData, startDate,
                                                     endDate)
    # print(dateList)

    start_loop = time.clock()
    for index, item in enumerate(dateList):
        #for date in dateList:
        #print('index:'+str(index)+' len:'+str(len(dateList)))
        start_inloop0 = time.clock()

        #信号日
        signalDay = dateList[index]
        # 非最后一天
        if index < (len(dateList) - 1):
            #交易日
            tradingDay = dateList[index + 1]
            tradingDayStr = DateUtil.datetime2_str(tradingDay)
            #print('dateStr:'+dateStr)
        # 最后一天
        else:
            break

        #print(dateStr)
        currSignalData = groupedSignalData.ix[signalDay]
        # print(currSignalData)
        if StockConst.IS_DEBUG:
            print("currSignalData:" + str(len(currSignalData)))
            #print(currSignalData)

        end_inloop0 = time.clock()
        print("inloop0花费时间:%f s" % (end_inloop0 - start_inloop0))

        #交易方法(外部传入)
        start_inloop1 = time.clock()
        dict = trade_func(currSignalData, currHoldSet, dailyQuote, tradingDay,
                          signalData, capitalEntity)
        end_inloop1 = time.clock()
        print("trade_func花费时间:%f s" % (end_inloop1 - start_inloop1))

        actualBuyList = dict['actualBuyList']
        actualSellList = dict['actualSellList']
        prevHoldList = dict['prevHoldList']
        cannotBuyList = dict['cannotBuyList']
        cannotSellList = dict['cannotSellList']
        stockTradeListDaily = dict['stockTradeList']

        if len(stockTradeListDaily) > 0:
            stockTradeList.extend(stockTradeListDaily)

        # print(currHoldSet)

        #3.计算当日市值
        start_inloop2 = time.clock()
        currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote,
                                  tradingDay, stockHoldDailyList, initialMV)
        end_inloop2 = time.clock()
        print("calculateDailyMV花费时间:%f s" % (end_inloop2 - start_inloop2))

        start_inloop3 = time.clock()
        #4.个数
        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(currHoldSet)
        cannotSellCnt = len(cannotSellList)
        cannotBuyCnt = len(cannotBuyList)

        # print(currMV)

        #if StockConst.isDebug:
        #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) +
        #" changePCTHold:" + str(changePCTHold))

        #当日净值
        netValue = currMV / initialMV
        #print("netValue:" + str(netValue))
        #当日收益
        dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2)
        #当日可用现金
        usableCach = capitalEntity.get_usable_cash()
        #
        stockStatDailyDf.ix[
            tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV
        #
        lastMV = currMV
        end_inloop3 = time.clock()
        print("inloop3花费时间:%f s" % (end_inloop3 - start_inloop3))

        pass

    end_loop = time.clock()
    print("for循环花费时间:%f s" % (end_loop - start_loop))

    result = ''

    start_stat = time.clock()
    # 信号数据
    #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv')

    # 每日交易
    # print('每日交易:')
    # print(stockTradeList)
    stockTradeDailyDf = pd.DataFrame(stockTradeList)
    stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True)
    # stockTradeDailyDf.to_csv(StockConst.root + '\export\stockTradeDaily.csv')

    # 每日持仓
    #print('每日持仓:')
    stockHoldDailyDf = pd.DataFrame(stockHoldDailyList)
    stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True)
    # stockHoldDailyDf.to_csv(StockConst.root + '\export\stockHoldDaily.csv')

    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDailyDf = stockStatDailyDf.dropna(how='all')
    result += '--' * 70 + '\n'
    result += '每日统计:' + '\n'
    result += stockStatDailyDf.to_string() + '\n'
    # stockStatDailyDf.to_csv(StockConst.root + '\export\stockStatDaily.csv')

    # 每年统计
    result += '--' * 70 + '\n'
    yearDf = StockYearService.main(stockStatDailyDf)
    result += '每年统计:' + '\n'
    result += yearDf.to_string() + '\n'

    # 最大回撤
    result += '--' * 70 + '\n'
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf)
    result += '最大回撤:' + '\n'
    result += SetUtil.dict_to_string(maxdrop) + '\n'
    #每年的最大回撤
    maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year(
        stockStatDailyDf)
    maxdropDf.sort_values(by=["year"])
    result += '每年的最大回撤:' + '\n'
    result += maxdropDf.to_string() + '\n'

    #夏普比率
    result += '--' * 70 + '\n'
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf)
    result += '夏普比率:' + '\n'
    result += str(sharpRatio) + '\n'
    #每年的夏普比率
    sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(
        stockStatDailyDf)
    sharpRatioDf.sort_values(by=["year"])
    result += '每年的夏普比率:' + '\n'
    result += sharpRatioDf.to_string() + '\n'

    end_stat = time.clock()
    print("统计花费时间:%f s" % (end_stat - start_stat))

    # result += '回测完成'
    end = time.clock()
    print("main花费时间:%f s" % (end - start))

    # 净值曲线图
    stockStatDailyDf['netValue'].plot()
    plt.show()

    resultDic = {'stockStatDailyDf': stockStatDailyDf, 'result': result}

    print(result)
    return resultDic
Ejemplo n.º 5
0
def main(select_stock, numOfDailySignal):
    signalData = SourceDataDao.getSignalData()
    #dailyQuote = SourceDataDao.getDailyQuote()
    dailyQuote = SourceDataDao.getNewDailyQuote()

    #参数
    #每天信号数
    #numOfDailySignal = 5
    #初始资金
    initialMV = 1000000  #1000000
    #开始结束日期
    #startDate = '1/8/2001'
    startDate = '1/1/2004'
    #endDate = '1/1/2017'
    #eendDate = '5/18/2001'
    endDate = '12/31/2005'
    #endDate = '12/31/2002'
    #endDate = '1/9/2001'

    #select top 5 group by TradingDay order by Mom desc
    groupedSignalData = select_stock(signalData, numOfDailySignal)
    #groupedSignalData = signalData.groupby(level=StockConst.TradingDay).apply(SelectUtil.top,numOfDailySignal,StockConst.Mom,False) #False True

    #当前持仓 key:innerCode value:
    currHoldSet = {}
    stockTradeList = []
    #
    capitalEntity = CapitalEntity.CapitalEntity(initialMV)
    lastMV = initialMV

    #netValue = 1;
    #初始化每日统计表
    stockStatDailyDf = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                    columns=[
                                        'netValue', 'changePCT', 'buyCnt',
                                        'sellCnt', 'prevHoldCnt',
                                        'currHoldCnt', 'cannotSellCnt',
                                        'cannotBuyCnt', 'usableCach', 'mv'
                                    ])
    #初始化每日持仓表
    stockHoldDailyList = []
    #从信号表中取得唯一性日期
    dateList = SourceDataDao.select_date_from_signal(signalData, startDate,
                                                     endDate)
    for index, item in enumerate(dateList):
        #for date in dateList:
        #print('index:'+str(index)+' len:'+str(len(dateList)))

        #信号日
        signalDay = dateList[index]
        # 非最后一天
        if index < (len(dateList) - 1):
            #交易日
            tradingDay = dateList[index + 1]
            tradingDayStr = DateUtil.datetime2_str(tradingDay)
            #print('dateStr:'+dateStr)
        # 最后一天
        else:
            break

        #print(dateStr)
        currSignalData = groupedSignalData.ix[signalDay]
        if StockConst.IS_DEBUG:
            print("currSignalData:" + str(len(currSignalData)))
            #print(currSignalData)

        # 计划买入列表
        planBuyList = getPlanBuyList(currSignalData, currHoldSet)
        # 计划卖出列表
        planSellList = getPlanSellList(currSignalData, currHoldSet)
        # 昨日持仓部分(在今日持仓中)
        prevHoldList = getPrevHoldList(currSignalData, currHoldSet)
        """
        if (dateStr >= '2015-01-05') & (dateStr <= '2015-01-05'):
            print('-----'+dateStr+'-----')
            #print(currSignalData)
            #print(buyList)
            print(list(currHoldSet.keys()))
            for key in currHoldSet.keys():
                print(str(key) + ':' + currHoldSet.get(key).openDate)
            print('----------------')
        """
        #dailyChangePCT = 0
        cannotSellList = []
        cannotBuyList = []
        # 实际买入列表
        actualBuyList = getActualBuyList(planBuyList, dailyQuote, tradingDay,
                                         cannotBuyList)
        # "卖出列表"中要保留的股票数
        numOfToKeepInSellList = numOfDailySignal - len(actualBuyList) - len(
            prevHoldList)
        # 实际卖出列表
        actualSellList = getActualSellList(planSellList, tradingDay,
                                           signalData, dailyQuote,
                                           numOfToKeepInSellList,
                                           cannotSellList)

        #1.处理实际卖出
        handleSellList(tradingDay, dailyQuote, stockTradeList, currHoldSet,
                       capitalEntity, actualSellList)
        #2.处理实际买入
        handleBuyList(tradingDay, dailyQuote, stockTradeList, currHoldSet,
                      capitalEntity, actualBuyList)
        #3.计算当日市值
        currMV = calculateDailyMV(currHoldSet, capitalEntity, dailyQuote,
                                  tradingDay, stockHoldDailyList, initialMV)

        #4.个数
        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(currHoldSet)
        cannotSellCnt = len(cannotSellList)
        cannotBuyCnt = len(cannotBuyList)

        #if StockConst.isDebug:
        #print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) + " changePCTSell:" + str(changePCTSell) +
        #" changePCTHold:" + str(changePCTHold))

        #当日净值
        netValue = currMV / initialMV
        #print("netValue:" + str(netValue))
        #当日收益
        dailyChangePCT = NumUtil.get_change_pct(lastMV, currMV, 2)
        #当日可用现金
        usableCach = capitalEntity.get_usable_cash()
        #
        stockStatDailyDf.ix[
            tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV
        #
        lastMV = currMV

    # 信号数据
    #groupedSignalData.to_csv(StockConst.root + '\export\groupedSignalData.csv')

    # 每日交易
    # print('每日交易:')
    stockTradeDailyDf = pd.DataFrame(stockTradeList)
    stockTradeDailyDf.sort_values(by=['tradingDate'], ascending=True)
    stockTradeDailyDf.to_csv(StockConst.ROOT + '\export\stockTradeDaily.csv')

    # 每日持仓
    #print('每日持仓:')
    stockHoldDailyDf = pd.DataFrame(stockHoldDailyList)
    stockHoldDailyDf.sort_values(by=['tradingDate'], ascending=True)
    stockHoldDailyDf.to_csv(StockConst.ROOT + '\export\stockHoldDaily.csv')

    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDailyDf = stockStatDailyDf.dropna(how='all')
    print('每日统计:')
    print(stockStatDailyDf)
    stockStatDailyDf.to_csv(StockConst.ROOT + '\export\stockStatDaily.csv')

    # 每年统计
    yearDf = StockYearService.main(stockStatDailyDf)
    print('每年统计:')
    print(yearDf)

    # 最大回撤
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDailyDf)
    print('最大回撤:')
    print(maxdrop)
    #每年的最大回撤
    maxdropDf = StockMaxDropNewService.get_max_drop_for_each_year(
        stockStatDailyDf)
    maxdropDf.sort_values(by=["year"])
    print('每年的最大回撤:')
    print(maxdropDf)

    #夏普比率
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDailyDf)
    print('夏普比率:')
    print(sharpRatio)
    #每年的夏普比率
    sharpRatioDf = SharpRatioNewService.get_sharp_ratio_for_each_year(
        stockStatDailyDf)
    sharpRatioDf.sort_values(by=["year"])
    print('每年的夏普比率:')
    print(sharpRatioDf)
Ejemplo n.º 6
0
def main():
    signalData = SourceDataDao.getSignalData()
    dailyQuote = SourceDataDao.getDailyQuote()

    #columns filter
    #df3 = sourceData.loc[(df['Mom'] <= 4) & (df['Mom'] <= 4), ['Mom']]

    #index filter
    #startDate=DateUtils.str2Datetime('20010105');
    #endDate=DateUtils.str2Datetime('20010111');
    #df4 = df3.ix[startDate:endDate]

    #select top 5 group by TradingDay order by Mom desc
    groupedSignalData = signalData.groupby(level='TradingDay').apply(
        SelectUtil.top, 5, 'Mom', False)

    #param
    #period = 5
    #startDate = '1/8/2001'
    startDate = '1/8/2001'
    #endDate = '1/1/2017'
    endDate = '2/18/2002'
    #endDate = '12/31/2016'
    #endDate = '12/31/2002'

    #time series
    #dateList = DateUtil.getDateList2(startDate,endDate)

    currHoldSet = {}
    stockHoldDF = {}
    stockTradeDF = {}
    #lastSignalData = pd.DataFrame()
    usableVol = 100
    netValue = 1
    #初始化每日统计表
    stockStatDaily = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                  columns=[
                                      'netValue', 'changePCT', 'buyCnt',
                                      'sellCnt', 'prevHoldCnt', 'currHoldCnt',
                                      'cannotSellCnt', 'cannotBuyCnt'
                                  ])
    #从信号表中取得唯一性日期
    dateList = SourceDataDao.select_date_from_signal(signalData, startDate,
                                                     endDate)
    for date in dateList:
        #for date in dateList.index:
        #print(date)
        dateStr = DateUtil.datetime2_str(date)
        #print(dateStr)
        #isinstance(date, datetime)

        # select by single date
        #try:

        #print(1)
        currSignalData = groupedSignalData.ix[date]
        if StockConst.IS_DEBUG:
            print("currSignalData:" + str(len(currSignalData)))
        #print(2)
        buyList = getBuyList(currSignalData, currHoldSet)
        #print(3)
        sellList = getSellList(currSignalData, currHoldSet)
        #print(4)
        prevHoldList = getPrevHoldList(currSignalData, currHoldSet)
        #print(currSignalData)

        #except:
        #假期,双休日,原数据问题
        #if StockConst.isDebug:
        #print(DateUtil.datetime2Str(date) + ': no data')
        #continue

        dailyChangePCT = 0
        actualSellList = []
        actualBuyList = []
        cannotSellList = []
        cannotBuyList = []
        #1.sell
        changePCTSell = handleSellList(date, sellList, dailyQuote, usableVol,
                                       stockHoldDF, stockTradeDF, currHoldSet,
                                       actualSellList, cannotSellList)
        usableVol = calculateUsableVol(currHoldSet)
        #2.buy
        changePCTBuy = handleBuyList(date, buyList, dailyQuote, usableVol,
                                     stockHoldDF, stockTradeDF, currHoldSet,
                                     actualBuyList, cannotBuyList)
        #3.hold
        changePCTHold = handleHoldList(date, prevHoldList, dailyQuote,
                                       usableVol, stockHoldDF, stockTradeDF,
                                       currHoldSet)
        #changePCTHold = 0

        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(currHoldSet)
        cannotSellCnt = len(cannotSellList)
        cannotBuyCnt = len(cannotBuyList)

        if StockConst.IS_DEBUG:
            print("dateStr:" + dateStr + " changePCTBuy:" + str(changePCTBuy) +
                  " changePCTSell:" + str(changePCTSell) + " changePCTHold:" +
                  str(changePCTHold))

        dailyChangePCT = changePCTBuy + changePCTSell + changePCTHold
        #print("dailyChangePCT:"+str(dailyChangePCT))
        netValue = netValue * (1 + dailyChangePCT / 100)
        #print("netValue:" + str(netValue))
        stockStatDaily.ix[
            dateStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt

        #innerCodeList = currSignalData["InnerCode"]
        #print(innerCodeList)

        #lastSignalData = currSignalData

    #每日统计(收益,净值,买入数,卖出数,持有数)
    stockStatDaily = stockStatDaily.dropna(how='all')
    print('每日统计:')
    print(stockStatDaily)
    stockStatDaily.to_csv('F:\export\stockStatDaily.csv')

    # 每年统计
    yearList = StockYearService.main(stockStatDaily)
    print('每年统计:')
    print(yearList)

    # 最大回撤
    maxdrop = StockMaxDropNewService.get_max_drop(stockStatDaily)
    print('最大回撤:')
    print(maxdrop)
    #每年的最大回撤
    maxdropList = StockMaxDropNewService.get_max_drop_for_each_year(
        stockStatDaily)
    maxdropList.sort_values(by=["year"])
    print('每年的最大回撤:')
    print(maxdropList)

    #夏普比率
    sharpRatio = SharpRatioNewService.get_sharp_ratio(stockStatDaily)
    print('夏普比率:')
    print(sharpRatio)
    #每年的夏普比率
    sharpRatioList = SharpRatioNewService.get_sharp_ratio_for_each_year(
        stockStatDaily)
    sharpRatioList.sort_values(by=["year"])
    print('每年的夏普比率:')
    print(sharpRatioList)