コード例 #1
0
def init_signal_data_info(signalDataAddr):
    # 取得技术指标
    techListOrigin = SourceDataDao.get_colums_from_h5(signalDataAddr)
    techList.clear()
    for x in techListOrigin:
        techList.append(x)

    # 删除已有指标控件
    for widget in techframe.winfo_children():
        widget.destroy()
    # 新增指标控件
    for index, item in enumerate(techListOrigin):
        R1 = Radiobutton(techframe,
                         text=item,
                         variable=techRadioVar,
                         value=index,
                         command=select_tech_radio)
        R1.pack(anchor=W)

    # 信号文件地址
    signalDataAddrVal.set(signalDataAddr)

    #
    originStartDate = SourceDataDao.get_first_record_from_h5(
        signalDataAddr).index[0][0]
    originEndDate = SourceDataDao.get_last_record_from_h5(
        signalDataAddr).index[0][0]
    originStartDate = DateUtil.datetime2_str(originStartDate)
    originEndDate = DateUtil.datetime2_str(originEndDate)
    originStartDateVar.set(originStartDate)
    originEndDateVar.set(originEndDate)

    #开始时间 结束时间
    startDateVal.set(originStartDate)
    endDateVal.set(originEndDate)
コード例 #2
0
    def test_back_test_main_hill(self):
        techList = [StockConst.MOM]
        signalDataAddr = StockConst.ROOT + '/export/SignalDataHill.h5'
        databaseDict = None
        dailyQuoteAddr = StockConst.ROOT + '/export/DailyQuoteHill.h5'
        indexQuoteAddr = StockConst.ROOT + StockConst.FAKE_INDEX_QUOTE_H5_2  # 基准(算相对收益)
        benchmark = StockConst.HS300_CODE  # 基准(算相对收益)
        sliceIdx = None
        numOfDailySignal = 5
        sliceTotalNum = None
        doPlot = True
        sliceDict = {
            'sliceIdx': sliceIdx,
            'numOfDailySignal': numOfDailySignal,
            'sliceTotalNum': sliceTotalNum
        }
        signalColumnDict = {
            StockConst.TRADING_DAY_NAME: 'TradingDay',
            StockConst.WIND_CODE_NAME: 'WindCode',
            StockConst.TECH_NAME: 'Mom'
        }
        resultDic = BackTestMainNew.main(
            BackTestMainNew.read_func1, BackTestMainNew.select_stock_func1,
            BackTestMainNew.trade_func1, techList, sliceDict, signalDataAddr,
            dailyQuoteAddr, indexQuoteAddr, benchmark, '2005-01-04',
            '2005-12-31', doPlot, databaseDict, signalColumnDict)
        # result = resultDic['result']

        #校验结果(每日净值)
        stockStatDailyDf = resultDic['stockStatDailyDf']
        rowno = 1
        lastNetValue = 0
        for index, row in stockStatDailyDf.iterrows():
            netValue = row['netValue']
            tradeday = index
            if rowno > 1:
                if tradeday <= pd.Timestamp('2004-07-01'):
                    diff = lastNetValue * (1.001) - netValue
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' +
                        str(netValue) + ' ' + str(diff))
                    self.assertTrue(abs(diff) < 0.000000001)

                elif tradeday >= pd.Timestamp('2004-07-03'):
                    diff = lastNetValue * (0.999) - netValue
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' +
                        str(netValue) + ' ' + str(diff))
                    self.assertTrue(abs(diff) < 0.000000001)

                else:
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' + str(netValue))

            lastNetValue = netValue
            rowno += 1
コード例 #3
0
def handle_buy_list(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualBuyListMV):
    usableCash = capitalEntity.get_usable_cash()
    if usableCash == 0:
        return

    if len(actualBuyListMV) == 0:
        return

    # buyCash = usableCash/len(actualBuyList)

    #print('vol:'+vol)
    #partChangePCT = 0
    # buyList全部可以买入
    for actualDict in actualBuyListMV:
        innerCode = actualDict.get(StockConst.INNERCODE)
        buyCash = actualDict.get('MV')  # 实际买入现金
        buyPrice = actualDict.get('price')  # 实际买入价格
        # partialFlg = actualDict.get('partialFlg')  # 实际是否部分买入

        # dailyQuoteRow = SourceDataDao.selectByInnerCodeAndDate(dailyQuote,tradingDay,innerCode)
        #print('innerCode:'+str(innerCode))
        #print(dailyQuoteRow)
        #可买
        #if buyFlg != -1:
        #平均买入价(没有算佣金)
        # buyPrice = BackTestHelper.getVWap(dailyQuoteRow)
        #成本价(算佣金)
        cost = buyPrice*(1 + StockConst.BUY_COMMISSION / 100)
        #仓位(股)
        #vol = NumUtil.getRound(turnover/cost,StockConst.volScale)
        #佣金(元)
        commission = BackTestHelper.get_buy_commission(buyCash, StockConst.BUY_COMMISSION / 100)
        #买入市值
        buyMV = buyCash - commission
        #更新可用金额(减少)
        capitalEntity.reduce_usable_cash(buyCash)
        #changePCT = NumUtil.getChangePCT(cost, closePrice, 2)
        #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0
        #partChangePCT = partChangePCT + realChangePCT
        #
        #stockHold = StockHoldEntity.StockHoldEntity(tradingDay,innerCode,vol)
        #stockTrade = StockTradeEntity.StockTradeEntity(tradingDay, innerCode, 1, vol, cost, '', '')
        dateStr = DateUtil.datetime2_str(tradingDay)
        stockTradeDict = {'tradingDay':dateStr,'innerCode':innerCode,'type':1,
                          'price':buyPrice,'buyMV':buyMV,'sellMV':'','commission': commission,
                          'sellCash':'','buyCash':buyCash,'openDate':''}
        stockTradeList.append(stockTradeDict)
        #插入表
        #stockHoldDF.setdefault(innerCode,stockHold)
        #当前持仓: a_innerCode,a_buyPrice,a_cost,a_openDate,a_buyMV,a_originBuyPrice,a_originBuyMV
        stockHoldEntity = StockHoldEntity.StockHoldEntity(innerCode, buyPrice, cost, DateUtil.datetime2_str(tradingDay), buyMV, buyPrice, buyMV)
        currHoldSet.setdefault(innerCode,stockHoldEntity)
        """
コード例 #4
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'
    #endDate = '1/1/2017'
    endDate = '18/1/2001'

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

    stockHoldDF = {}
    stockTradeDF = {}
    lastSignalData = pd.DataFrame()
    usableVol = 100
    netValue = 1
    stockStatDaily = pd.DataFrame(index=pd.date_range(startDate, endDate),
                                  columns=['netValue', 'changePCT'])
    for date in dateList.index:
        #print(date)
        dateStr = DateUtil.datetime2_str(date)
        #print(dateStr)
        #isinstance(date, datetime)
        #DateUtil.str2Datetime('20010108')

        # select by single date
        try:
            #print(1)
            currSignalData = groupedSignalData.ix[date]
            print("currSignalData:" + str(len(currSignalData)))
            print(currSignalData)

        except:
            #假期,双休日,原数据问题
            print(DateUtil.datetime2_str(date) + ': no data')
            continue
コード例 #5
0
def handle_sell_list(tradingDay, dailyQuote, stockTradeList, currHoldSet, capitalEntity, actualSellListMV):
    #partChangePCT = 0
    dateStr = DateUtil.datetime2_str(tradingDay)

    if len(actualSellListMV) == 0:
        return

    #sellList全部可以卖出
    for actualDict in actualSellListMV:
        innerCode = actualDict.get(StockConst.INNERCODE)
        sellMV = actualDict.get('MV') #实际卖出市值
        sellPrice = actualDict.get('price') #实际卖出价格
        isAdjust = actualDict.get('isAdjust')
        partialFlg = actualDict.get('partialFlg') #实际是否部分卖出

        #print('innerCode:' + str(innerCode))
        #try:
        # dailyQuoteRow = SourceDataDao.selectByInnerCodeAndDate(dailyQuote, tradingDay, innerCode)
        #except:
            #退市的股票: 查询不到行情,取最后一个交易日
            #dailyQuoteRow = SourceDataDao.selectByLastDay(dailyQuote,innerCode)
        # print(dailyQuoteSingle)

        #可卖
        #if sellFlg != -1:
        #actualSellList.append(innerCode)

        #全部卖出
        if partialFlg is None:
            stockHoldEntity = currHoldSet.pop(innerCode)
        #部分卖出(更新持仓)
        elif partialFlg == 1:
            stockHoldEntity = currHoldSet.get(innerCode)
            #当前市值
            currMV = BackTestHelper.get_sell_mv(stockHoldEntity.closePrice, stockHoldEntity.closeMV, sellPrice) #stockHoldEntity.buyPrice, stockHoldEntity.buyMV
            #卖掉部分后的市值
            currMV = currMV - sellMV
            #更新持仓(价格,仓位,变更日)
            stockHoldEntity.set_last_trade_price(sellPrice)
            stockHoldEntity.set_last_trade_mv(currMV)
            stockHoldEntity.set_change_date(tradingDay)

        #vol = stockHoldEntity.vol
        # sellPrice = BackTestHelper.getVWap(dailyQuoteRow)
        #卖出市值(没有扣佣金)
        #turnover = sellPrice * vol
        # sellMV = BackTestHelper.getSellMV(stockHoldEntity.buyPrice, stockHoldEntity.buyMV, sellPrice)
        #佣金(元)
        commission = BackTestHelper.get_sell_commission(sellMV, StockConst.SELL_COMMISSION / 100)
        #卖出后所得资金(扣掉佣金后所得金额)
        sellCash = sellMV - commission
        # 更新可用金额(增加)
        capitalEntity.increase_usable_cash(sellCash)
        # 开仓日
        openDate = stockHoldEntity.openDate
        # 加入交易表
        stockTradeDict = {'tradingDay': dateStr, 'innerCode': innerCode, 'type': -1, 'price': sellPrice,
                          'buyMV': '', 'sellMV': sellMV, 'commission': commission,
                          'sellCash': sellCash,'buyCash':'','openDate':openDate,'isAdjust':isAdjust,'partialFlg':partialFlg}
        stockTradeList.append(stockTradeDict)
コード例 #6
0
    def testBackTestMainHill(self):
        techList = [StockConst.MOM]
        signalDataAddr = StockConst.ROOT + '/export/SignalDataHill.h5'
        dailyQuoteAddr = StockConst.ROOT + '/export/DailyQuoteHill.h5'
        sliceIdx = None
        numOfDailySignal = 5
        sliceTotalNum = None
        sliceDict = {
            'sliceIdx': sliceIdx,
            'numOfDailySignal': numOfDailySignal,
            'sliceTotalNum': sliceTotalNum
        }
        resultDic = BackTestMainNew.main(BackTestMainNew.select_stock_func1,
                                         BackTestMainNew.trade_func1, techList,
                                         sliceDict, signalDataAddr,
                                         dailyQuoteAddr, '2004-01-01',
                                         '2005-12-31')
        # result = resultDic['result']

        #校验结果(每日净值)
        stockStatDailyDf = resultDic['stockStatDailyDf']
        rowno = 1
        lastNetValue = 0
        for index, row in stockStatDailyDf.iterrows():
            netValue = row['netValue']
            tradeday = index
            if rowno > 1:
                if tradeday <= pd.Timestamp('2004-07-01'):
                    diff = lastNetValue * (1.001) - netValue
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' +
                        str(netValue) + ' ' + str(diff))
                    self.assertTrue(abs(diff) < 0.000000001)

                elif tradeday >= pd.Timestamp('2004-07-03'):
                    diff = lastNetValue * (0.999) - netValue
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' +
                        str(netValue) + ' ' + str(diff))
                    self.assertTrue(abs(diff) < 0.000000001)

                else:
                    print(
                        DateUtil.datetime2_str(tradeday) + ' ' + str(netValue))

            lastNetValue = netValue
            rowno += 1
コード例 #7
0
def handleBuyList(tradingDate,dailyQuote,stockTradeList,currHoldSet,capitalEntity,actualBuyList):
    usableCach = capitalEntity.get_usable_cash()
    if usableCach == 0:
        return

    if len(actualBuyList) == 0:
        return

    buyCach = usableCach/len(actualBuyList)
    #print('vol:'+vol)
    #partChangePCT = 0
    # buyList全部可以买入
    for innerCode in actualBuyList:
        dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode)
        #print('innerCode:'+str(innerCode))
        #print(dailyQuoteRow)
        #可买
        #if buyFlg != -1:
        #平均买入价(没有算佣金)
        buyPrice = BackTestHelper.get_vwap(dailyQuoteRow)
        #成本价(算佣金)
        cost = buyPrice*(1 + StockConst.BUY_COMMISSION / 100)
        #仓位(股)
        #vol = NumUtil.getRound(turnover/cost,StockConst.volScale)
        #佣金(元)
        commission = BackTestHelper.get_buy_commission(buyCach, StockConst.BUY_COMMISSION / 100)
        #买入市值
        buyMV = buyCach - commission
        #更新可用金额(减少)
        capitalEntity.reduce_usable_cash(buyCach)
        #changePCT = NumUtil.getChangePCT(cost, closePrice, 2)
        #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0
        #partChangePCT = partChangePCT + realChangePCT
        #
        #stockHold = StockHoldEntity.StockHoldEntity(tradingDate,innerCode,vol)
        #stockTrade = StockTradeEntity.StockTradeEntity(tradingDate, innerCode, 1, vol, cost, '', '')
        dateStr = DateUtil.datetime2_str(tradingDate)
        stockTradeDict = {'tradingDate':dateStr,'innerCode':innerCode,'type':1,
                          'price':buyPrice,'buyMV':buyMV,'sellMV':'','commission': commission,
                          'sellCach':'','buyCach':buyCach,'openDate':''}
        stockTradeList.append(stockTradeDict)
        #插入表
        #stockHoldDF.setdefault(innerCode,stockHold)
        #当前持仓
        stockHoldEntity = StockHoldEntity.StockHoldEntity(innerCode, buyPrice, cost, DateUtil.datetime2_str(tradingDate), buyMV)
        currHoldSet.setdefault(innerCode,stockHoldEntity)
        """
コード例 #8
0
def get_max_drop(net_value_list_param):
    net_value_list = net_value_list_param.copy()
    net_value_list.insert(1, 'hightestNetValue', Series())
    net_value_list.insert(2, 'drop', Series())
    hightest = 0
    #算出历史最高,和当日相对于历史最高的回撤
    for index, row in net_value_list.iterrows():
        #print(row['netValue'])
        if row['netValue'] > hightest:
            hightest = row['netValue']
        net_value_list.ix[index, ['hightestNetValue']] = hightest
        net_value_list.ix[index, ['drop']] = NumUtil.get_change_pct(
            hightest, row['netValue'], 2) * -1

    #最大回撤
    max_drop = net_value_list['drop'].max()

    # 最大回撤
    max_drop_rows = net_value_list.loc[(net_value_list['drop'] == max_drop)]
    # 最大回撤发生日
    max_drop_end_date = DateUtil.datetime2_str(
        max_drop_rows.index[0])  #& (netValueList.index > maxDropStartDate)
    hightest_net_value = max_drop_rows.ix[0, ['hightestNetValue']][
        0]  #['hightestNetValue']

    #print('maxDropEndDate:'+str(maxDropEndDate))
    #print('hightestNetValue:' + str(hightestNetValue))

    # 最大回撤开始日
    # 找到净值最高的记录 且 离开回撤发生日最近
    hightest_rows = net_value_list.loc[(
        net_value_list['netValue'] == hightest_net_value
    )]  # & (DateUtil.datetime2Str(netValueList.index) <= maxDropEndDate)
    hightest_rows = hightest_rows.sort_index(ascending=False)
    max_drop_start_date = DateUtil.datetime2_str(hightest_rows.index[0])
    #print('maxDropStartDate:' + str(maxDropStartDate))

    max_drop_dict = {
        'maxDrop': NumUtil.get_round(max_drop, 2),
        'maxDropStartDate': max_drop_start_date,
        'maxDropEndDate': max_drop_end_date
    }

    return max_drop_dict
コード例 #9
0
def handleSellList(tradingDate,dailyQuote,stockTradeList,currHoldSet,capitalEntity,actualSellList):
    #partChangePCT = 0
    dateStr = DateUtil.datetime2_str(tradingDate)

    if len(actualSellList) == 0:
        return

    #sellList全部可以卖出
    for innerCode in actualSellList:
        #print('innerCode:' + str(innerCode))
        #try:
        dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode)
        #except:
            #退市的股票: 查询不到行情,取最后一个交易日
            #dailyQuoteRow = SourceDataDao.selectByLastDay(dailyQuote,innerCode)
        # print(dailyQuoteSingle)

        #可卖
        #if sellFlg != -1:
        #actualSellList.append(innerCode)
        stockHoldEntity = currHoldSet.pop(innerCode)
        #vol = stockHoldEntity.vol
        sellPrice = BackTestHelper.get_vwap(dailyQuoteRow)
        #卖出市值(没有扣佣金)
        #turnover = sellPrice * vol
        sellMV = BackTestHelper.get_sell_mv(stockHoldEntity.buyPrice, stockHoldEntity.buyMV, sellPrice)
        #佣金(元)
        commission = BackTestHelper.get_sell_commission(sellMV, StockConst.SELL_COMMISSION / 100)
        #卖出后所得资金(扣掉佣金后所得金额)
        sellCach = sellMV - commission
        # 更新可用金额(增加)
        capitalEntity.increase_usable_cash(sellCach)
        # 开仓日
        openDate = stockHoldEntity.openDate
        # 加入交易表
        stockTradeDict = {'tradingDate': dateStr, 'innerCode': innerCode, 'type': -1, 'price': sellPrice,
                          'buyMV': '', 'sellMV': sellMV, 'commission': commission,
                          'sellCach': sellCach,'buyCach':'','openDate':openDate}
        stockTradeList.append(stockTradeDict)
        """
        if DateUtil.datetime2Str(tradingDate) == '2014-12-09':
            print('-----handleSellList-----')
            print(DateUtil.datetime2Str(tradingDate))
            print(innerCode)
            print(vol)
            print(sellPrice)
            print(turnoverValue)
            print(dailyQuoteRow)
            print('----------')
        """

        #changePCT = NumUtil.getChangePCT(prevClosePrice, sellPrice, 2)
        #realChangePCT = (changePCT - StockConst.sellCommission) * vol / 100.0
        #partChangePCT = partChangePCT + realChangePCT
        """
コード例 #10
0
ファイル: BackTestMain.py プロジェクト: dxcv/backtest-2
def handleSellList(tradingDate, sellList, dailyQuote, usableVol, stockHoldDF,
                   stockTradeDF, currHoldSet, actualSellList, cannotSellList):
    partChangePCT = 0
    dateStr = DateUtil.datetime2_str(tradingDate)

    if len(sellList) == 0:
        return 0

    for innerCode in sellList:
        dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(
            dailyQuote, tradingDate, innerCode)
        #print('innerCode:' + str(innerCode))
        # print(dailyQuoteSingle)
        turnoverValue = dailyQuoteRow["TurnoverValue"]
        turnoverVolume = dailyQuoteRow["TurnoverVolume"]
        prevClosePrice = dailyQuoteRow["PrevClosePrice"]
        closePrice = dailyQuoteRow["ClosePrice"]
        highPrice = dailyQuoteRow["HighPrice"]
        lowPrice = dailyQuoteRow["LowPrice"]
        #非停牌 且 非一字跌停: 可以卖出
        check = not BackTestHelper.isYiZiDieTing(highPrice, lowPrice,
                                                 prevClosePrice)
        if (closePrice != 0) & (turnoverValue != float(0)) & check:
            actualSellList.append(innerCode)
            vol = currHoldSet.pop(innerCode)
            sellPrice = turnoverValue / turnoverVolume
            changePCT = NumUtil.get_change_pct(prevClosePrice, sellPrice, 2)
            realChangePCT = (changePCT -
                             StockConst.SELL_COMMISSION) * vol / 100.0
            partChangePCT = partChangePCT + realChangePCT
            """
            if dateStr == '2001-01-17':
                print("vol:"+str(vol)+" turnoverValue:"+str(turnoverValue)+" turnoverVolume:"+str(turnoverVolume)+
                      " prevClosePrice:"+str(prevClosePrice)+" closePrice:"+str(closePrice)+" sellPrice:"+str(sellPrice)+
                      " changePCT:"+str(changePCT)+
                      " realChangePCT:"+str(realChangePCT)+" partChangePCT:"+str(partChangePCT))
            """
        else:
            cannotSellList.append(innerCode)
    return partChangePCT
コード例 #11
0
def handleSellList(tradingDate,sellList,dailyQuote,usableVol,stockHoldDF,stockTradeDF):
    partChangePCT = 0
    dateStr = DateUtil.datetime2_str(tradingDate)
    for innerCode in sellList:
        dailyQuoteSingle = SourceDataDao.select_by_inner_code_and_date(dailyQuote, tradingDate, innerCode)
        #print('innerCode:' + str(innerCode))
        hold = stockHoldDF.pop(innerCode)
        vol = hold.vol
        # print(dailyQuoteSingle)
        turnoverValue = dailyQuoteSingle["TurnoverValue"]
        turnoverVolume = dailyQuoteSingle["TurnoverVolume"]
        prevClosePrice = dailyQuoteSingle["PrevClosePrice"]
        sellPrice = turnoverValue / turnoverVolume
        changePCT = NumUtil.get_change_pct(prevClosePrice, sellPrice, 2)
        realChangePCT = changePCT * vol / 100.0
        partChangePCT = partChangePCT + realChangePCT;

        if dateStr == '2001-01-17':
            print("vol:"+str(vol)+" turnoverValue:"+str(turnoverValue)+" turnoverVolume:"+str(turnoverVolume)+
                  " prevClosePrice:"+str(prevClosePrice)+" sellPrice:"+str(sellPrice)+" changePCT:"+str(changePCT)+
                  " realChangePCT:"+str(realChangePCT)+" partChangePCT:"+str(partChangePCT))

    return partChangePCT
コード例 #12
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
コード例 #13
0
def main(netValueList):
    standardMaxDrop = -5

    stockTradeResultMaxDropList = []

    startPoint = None
    startDate = None
    endDate = None
    changePCTToStart = None

    maxDrop = None
    happenDate = None
    maxDate = None
    maxDropNumOfDay = None

    dateIndexFromStart = 1
    dateIndexFromHappen = 1
    dateIndex = 1

    totalNumOfDay = len(netValueList)

    #for stockTradeResultDailyEntity in netValueList:
    for index, row in netValueList.iterrows():
        msgIsNewMaxDrop = ""
        msgIsNewStartPoint = ""
        msgIsEndPoint = ""
        msgInsert = ""

        currNetValue = row['netValue']
        currDate = DateUtil.datetime2_str(index)

        if (startPoint == None):
            startPoint = currNetValue
            startDate = currDate
            dateIndexFromStart = 1
            dateIndexFromHappen = 1
            msgIsNewStartPoint = "newStartPoint"

            dateIndexFromStart = dateIndexFromStart + 1
            dateIndexFromHappen = dateIndexFromHappen + 1
            dateIndex = dateIndex + 1

        else:

            changePCTToStart = NumUtil.get_change_pct(startPoint, currNetValue,
                                                      2)

            if maxDrop == None:
                check = True
            elif changePCTToStart < maxDrop:
                check = True
            else:
                check = False

            if ((changePCTToStart <= standardMaxDrop) & check):

                if (maxDrop == None):
                    happenDate = currDate
                    dateIndexFromHappen = 1

                maxDrop = changePCTToStart
                maxDate = currDate

                maxDropNumOfDay = dateIndexFromHappen
                msgIsNewMaxDrop = "newMaxDrop"

            if ((currNetValue >= startPoint) | (dateIndex == totalNumOfDay)):

                if (maxDrop != None):
                    endDate = currDate

                    #msgInsert = "    [insert]" + startDate + " " + endDate + " " + happenDate + " " + maxDrop + " " + maxDate + " " + maxDropNumOfDay;
                    #StockTradeResultMaxDropEntity stockTradeResultMaxDropEntity = new StockTradeResultMaxDropEntity(
                    # execModelId, startDate, endDate, happenDate, maxDrop, maxDate,
                    #maxDropNumOfDay, DateUtils.getCurrentDateWithSecond3());

                    #if (stockTradeResultMaxDropList == null):stockTradeResultMaxDropList = new ArrayList();

                    #stockTradeResultMaxDropList.add(stockTradeResultMaxDropEntity);
                    dict1 = {
                        'startDate': startDate,
                        'endDate': endDate,
                        'happenDate': happenDate,
                        'maxDrop': maxDrop,
                        'maxDate': maxDate
                    }
                    stockTradeResultMaxDropList.append(dict1)

                    maxDrop = None
                    happenDate = None
                    maxDate = None
                    maxDropNumOfDay = None
                    msgIsEndPoint = "endPoint"

            if (currNetValue >= startPoint):
                startPoint = currNetValue
                startDate = currDate
                dateIndexFromStart = 1
                msgIsNewStartPoint = "newStartPoint"

            dateIndexFromStart = dateIndexFromStart + 1
            dateIndexFromHappen = dateIndexFromHappen + 1
            dateIndex = dateIndex + 1

    #非时间序列DF
    df = pd.DataFrame(stockTradeResultMaxDropList)
    return df
コード例 #14
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)
コード例 #15
0
def handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF,
                  stockTradeList, currHoldSet, actualBuyList, cannotBuyList,
                  capitalEntity):
    usableCach = capitalEntity.get_usable_cash()
    if usableCach == 0:
        return 0

    #if usableVol == 0:
    #return 0

    if len(buyList) == 0:
        return 0

    turnover = usableCach / len(buyList)
    #print('vol:'+vol)
    partChangePCT = 0
    for innerCode in buyList:
        dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(
            dailyQuote, tradingDate, innerCode)
        #print('innerCode:'+str(innerCode))
        #print(dailyQuoteRow)
        turnoverValue = dailyQuoteRow["TurnoverValue"]
        turnoverVolume = dailyQuoteRow["TurnoverVolume"]
        buyFlg = dailyQuoteRow[StockConst.BUY_FLG]
        #可买
        if buyFlg != -1:
            actualBuyList.append(innerCode)
            #平均买入价(没有算佣金)
            buyPrice = turnoverValue / turnoverVolume
            #成本价(算佣金)
            cost = buyPrice * (1 + StockConst.BUY_COMMISSION / 100)
            #仓位(股)
            vol = NumUtil.get_round(turnover / cost, StockConst.VOL_SCALE)
            #佣金(元)
            commission = BackTestHelper.get_buy_commission(
                turnover, StockConst.BUY_COMMISSION / 100)
            #更新可用金额(减少)
            capitalEntity.reduce_usable_cash(turnover)
            #changePCT = NumUtil.getChangePCT(cost, closePrice, 2)
            #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0
            #partChangePCT = partChangePCT + realChangePCT
            #
            #stockHold = StockHoldEntity.StockHoldEntity(tradingDate,innerCode,vol)
            #stockTrade = StockTradeEntity.StockTradeEntity(tradingDate, innerCode, 1, vol, cost, '', '')
            stockTradeDict = {
                'tradingDate': tradingDate,
                'innerCode': innerCode,
                'type': 1,
                'vol': vol,
                'price': buyPrice,
                'turnover': turnover,
                'commission': commission
            }
            stockTradeList.append(stockTradeDict)
            #插入表
            #stockHoldDF.setdefault(innerCode,stockHold)
            #当前持仓
            stockHoldEntity = StockHoldEntity.StockHoldEntity(
                innerCode, vol, buyPrice, cost,
                DateUtil.datetime2_str(tradingDate))  #tradingDate,
            currHoldSet.setdefault(innerCode, stockHoldEntity)  #vol
            """
            if (DateUtil.datetime2Str(tradingDate) == '2014-12-08') | (DateUtil.datetime2Str(tradingDate) == '2014-12-09'):
                print('-----handleBuyList-----')
                print(DateUtil.datetime2Str(tradingDate))
                print(innerCode)
                print(vol)
                print(buyPrice)
                print(cost)
                print(turnoverValue)
                print(dailyQuoteRow)
                print('----------')
            """
        else:
            cannotBuyList.append(innerCode)
コード例 #16
0
def handleSellList(tradingDate, sellList, dailyQuote, usableVol, stockHoldDF,
                   stockTradeList, currHoldSet, actualSellList, cannotSellList,
                   capitalEntity, numOfActualBuy, signalData, prevHoldList,
                   numOfDailyHolding):
    partChangePCT = 0
    dateStr = DateUtil.datetime2_str(tradingDate)

    if len(sellList) == 0:
        return

    #卖出列表中要保留的股票数
    numOfToKeepInSellList = numOfDailyHolding - numOfActualBuy - len(
        prevHoldList)

    #卖出数 > 实际买入数:对卖出列表进行排序
    #if len(sellList) > numOfActualBuy:
    sellList = getToSellInSellList(sellList, tradingDate, signalData,
                                   dailyQuote, numOfToKeepInSellList,
                                   cannotSellList, currHoldSet)
    if len(sellList) == 0:
        return

    #numOfActualSell = 0
    for innerCode in sellList:
        #print('innerCode:' + str(innerCode))
        try:
            dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(
                dailyQuote, tradingDate, innerCode)
        except:
            #退市的股票: 查询不到行情,取最后一个交易日
            dailyQuoteRow = SourceDataDao.selectByLastDay(
                dailyQuote, innerCode)
        #print('innerCode:' + str(innerCode))
        # print(dailyQuoteSingle)
        #try:
        turnoverValue = dailyQuoteRow["TurnoverValue"]
        #except:
        #print('tradingDate:'+dateStr)
        #print('innerCode:' + str(innerCode))
        #print(dailyQuoteRow)
        turnoverVolume = dailyQuoteRow["TurnoverVolume"]
        #prevClosePrice = dailyQuoteRow["PrevClosePrice"]
        #closePrice = dailyQuoteRow["ClosePrice"]
        #highPrice = dailyQuoteRow["HighPrice"]
        #lowPrice = dailyQuoteRow["LowPrice"]
        #sellFlg = dailyQuoteRow[StockConst.sellFlg]
        #buyFlg = dailyQuoteRow["buyFlg"]
        #sellFlg = dailyQuoteRow["sellFlg"]
        #非停牌
        #check1 = not BackTestHelper.isStop(closePrice, turnoverValue)
        #非一字跌停: 可以卖出
        #check2 = not BackTestHelper.isYiZiDieTing(highPrice,lowPrice,prevClosePrice)

        #可卖
        #if sellFlg != -1:
        #实际卖出数不能大于实际买入数
        #if numOfActualSell >= numOfActualBuy:
        #continue
        actualSellList.append(innerCode)
        stockHoldEntity = currHoldSet.pop(innerCode)
        vol = stockHoldEntity.vol
        sellPrice = turnoverValue / turnoverVolume
        #卖出后所得资金(没有扣佣金)
        turnover = sellPrice * vol
        # 佣金(元)
        commission = BackTestHelper.get_sell_commission(
            turnover, StockConst.SELL_COMMISSION / 100)
        # 扣掉佣金后所得金额
        turnover = turnover - commission
        # 更新可用金额(增加)
        capitalEntity.increase_usable_cash(turnover)
        # 加入交易表
        stockTradeDict = {
            'tradingDate': tradingDate,
            'innerCode': innerCode,
            'type': -1,
            'vol': vol,
            'price': sellPrice,
            'turnover': turnover,
            'commission': commission
        }
        stockTradeList.append(stockTradeDict)
        #实际卖出数
        #numOfActualSell += 1
        """
        if DateUtil.datetime2Str(tradingDate) == '2014-12-09':
            print('-----handleSellList-----')
            print(DateUtil.datetime2Str(tradingDate))
            print(innerCode)
            print(vol)
            print(sellPrice)
            print(turnoverValue)
            print(dailyQuoteRow)
            print('----------')
        """

        #changePCT = NumUtil.getChangePCT(prevClosePrice, sellPrice, 2)
        #realChangePCT = (changePCT - StockConst.sellCommission) * vol / 100.0
        #partChangePCT = partChangePCT + realChangePCT
        """
コード例 #17
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)
コード例 #18
0
def handleBuyList(tradingDate, buyList, dailyQuote, usableVol, stockHoldDF,
                  stockTradeList, currHoldSet, actualBuyList, cannotBuyList,
                  capitalEntity):
    usableCach = capitalEntity.get_usable_cash()
    if usableCach == 0:
        return

    #if usableVol == 0:
    #return 0

    if len(buyList) == 0:
        return

    #可买列表
    buyList = getToBuyInBuyList(buyList, dailyQuote, tradingDate,
                                cannotBuyList)
    if len(buyList) == 0:
        return

    turnover = usableCach / len(buyList)
    #print('vol:'+vol)
    partChangePCT = 0
    for innerCode in buyList:
        dailyQuoteRow = SourceDataDao.select_by_inner_code_and_date(
            dailyQuote, tradingDate, innerCode)
        #print('innerCode:'+str(innerCode))
        #print(dailyQuoteRow)
        turnoverValue = dailyQuoteRow[StockConst.TURNOVER_VALUE]
        turnoverVolume = dailyQuoteRow[StockConst.TURNOVER_VOLUME]
        #buyFlg = dailyQuoteRow[StockConst.buyFlg]
        #可买
        #if buyFlg != -1:
        #actualBuyList.append(innerCode)
        #平均买入价(没有算佣金)
        buyPrice = turnoverValue / turnoverVolume
        #成本价(算佣金)
        cost = buyPrice * (1 + StockConst.BUY_COMMISSION / 100)
        #仓位(股)
        #vol = NumUtil.getRound(turnover/cost,StockConst.volScale)
        #佣金(元)
        commission = BackTestHelper.get_buy_commission(
            turnover, StockConst.BUY_COMMISSION / 100)
        #买入市值
        buyMV = turnover - commission
        #更新可用金额(减少)
        capitalEntity.reduce_usable_cash(turnover)
        #changePCT = NumUtil.getChangePCT(cost, closePrice, 2)
        #realChangePCT = (changePCT - StockConst.buyCommission) * vol / 100.0
        #partChangePCT = partChangePCT + realChangePCT
        #
        #stockHold = StockHoldEntity.StockHoldEntity(tradingDate,innerCode,vol)
        #stockTrade = StockTradeEntity.StockTradeEntity(tradingDate, innerCode, 1, vol, cost, '', '')
        stockTradeDict = {
            'tradingDate': tradingDate,
            'innerCode': innerCode,
            'type': 1,
            'vol': 0,
            'price': buyPrice,
            'turnover': turnover,
            'commission': commission,
            'MV': buyMV
        }
        stockTradeList.append(stockTradeDict)
        #插入表
        #stockHoldDF.setdefault(innerCode,stockHold)
        #当前持仓
        stockHoldEntity = StockHoldEntity.StockHoldEntity(
            innerCode, vol, buyPrice, cost,
            DateUtil.datetime2_str(tradingDate))  #tradingDate,
        currHoldSet.setdefault(innerCode, stockHoldEntity)  #vol
        """
コード例 #19
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
コード例 #20
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'
    #endDate = '1/1/2017'
    endDate = '1/18/2001'

    #time series
    dateList = DateUtil.get_date_list2(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','holdCnt'])
    for date in dateList.index:
        #print(date)
        dateStr = DateUtil.datetime2_str(date)
        #print(dateStr)
        #isinstance(date, datetime)
        #DateUtil.str2Datetime('20010108')

        # select by single date
        try:
            #print(1)
            currSignalData = groupedSignalData.ix[date]
            print("currSignalData:"+str(len(currSignalData)))
            #print(2)
            buyList = getBuyList(currSignalData,lastSignalData)
            #print(3)
            sellList = getSellList(currSignalData,lastSignalData)
            #print(4)
            holdList = getHoldList(currSignalData,lastSignalData)
            #print(currSignalData)
            #print("len:"+str(len(currSignalData)))
        except:
            #假期,双休日,原数据问题
            print(DateUtil.datetime2_str(date) + ': no data')
            continue

        buyCnt = len(buyList)
        sellCnt = len(sellList)
        holdCnt = len(holdList)

        dailyChangePCT = 0
        changePCTBuy = handleBuyList(date,buyList,dailyQuote,usableVol,stockHoldDF,stockTradeDF)
        releasedVol = getReleasedVol(sellList, stockHoldDF)
        usableVol = usableVol + releasedVol
        changePCTSell = handleSellList(date,sellList,dailyQuote,usableVol,stockHoldDF,stockTradeDF)
        #changePCTHold = handleHoldList(date, sellList, dailyQuote, usableVol, stockHoldDF, stockTradeDF)
        changePCTHold = 0

        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,holdCnt

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

        #lastSignalData = currSignalData

    print(stockStatDaily)
コード例 #21
0
    def deal(self,signalData1day,techList,select_stock_1day_func,trade_1day_func):
        #是否有更好的获取当天日期的方法?
        signalDay = signalData1day.index.get_level_values(0).unique()
        signalDayIndex = self.dateList.index(signalDay)

        #非最后一天
        if signalDayIndex < (len(self.dateList) - 1):
            #交易日
            tradingDay = self.dateList[signalDayIndex + 1]
            tradingDayStr = DateUtil.datetime2_str(tradingDay)
            #print('dateStr:'+dateStr)
        # 最后一天
        else:
            return

        #选股结果(当天)
        currSelectStock = select_stock_1day_func(signalData1day,techList)

        #交易结果
        dict = trade_1day_func(currSelectStock, self.currHoldSet, self.dailyQuote, tradingDay, self.signalData, self.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 :
            self.stockTradeList.extend(stockTradeListDaily)

        #当日市值
        currMV = calculateDailyMV(self.currHoldSet, self.capitalEntity, self.dailyQuote, tradingDay, self.stockHoldDailyList, self.initialMV)

        #个数
        buyCnt = len(actualBuyList)
        sellCnt = len(actualSellList)
        prevHoldCnt = len(prevHoldList)
        currHoldCnt = len(self.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 / self.initialMV
        # print("netValue:" + str(netValue))
        # 当日收益
        dailyChangePCT = NumUtil.get_change_pct(self.lastMV, currMV, 2)
        # 当日可用现金
        usableCach = self.capitalEntity.get_usable_cash()
        #
        self.stockStatDailyDf.ix[tradingDayStr] = netValue, dailyChangePCT, buyCnt, sellCnt, prevHoldCnt, currHoldCnt, cannotSellCnt, cannotBuyCnt, usableCach, currMV
        #
        self.lastMV = currMV
コード例 #22
0
ファイル: BackTestMain.py プロジェクト: dxcv/backtest-2
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)