コード例 #1
0
def update_return_data_300(ds, **kwargs):
    ref_date = kwargs['next_execution_date']

    if not isBizDay('china.sse', ref_date):
        logger.info("{0} is not a business day".format(ref_date))
        return 0

    start_date = advanceDateByCalendar('china.sse', ref_date, '-30b')

    for date in bizDatesList('china.sse', start_date, ref_date):

        date = date.strftime('%Y-%m-%d')

        conn1 = create_ms_engine('PortfolioManagements300')
        df = fetch_date('StockReturns', date, conn1)

        conn2 = create_my_engine()

        delete_data('return_300', date, conn2)
        insert_data('return_300', df, conn2)

        conn3 = create_my_engine2()
        delete_data('return_300', date, conn3)
        insert_data('return_300', df, conn3)
    return 0
コード例 #2
0
ファイル: test_sql_engine.py プロジェクト: rlcjj/alpha-mind
 def setUp(self):
     self.engine = SqlEngine(DATA_ENGINE_URI)
     dates_list = bizDatesList('china.sse', '2010-10-01', '2018-04-27')
     self.ref_date = random.choice(dates_list).strftime('%Y-%m-%d')
     alpha_logger.info("Test date: {0}".format(self.ref_date))
コード例 #3
0
ファイル: Tears.py プロジェクト: rlcjj/VisualPortfolio
def createPerformanceTearSheet(prices=None, returns=None, benchmark=None, benchmarkReturns=None, plot=True):

    if prices is not None and not isinstance(prices, pd.Series):
        raise TypeError("prices series should be a pandas time series.")
    elif returns is not None and prices is not None:
        raise ValueError("prices series and returns series can't be both set.")

    if benchmark is not None and not (isinstance(benchmark, pd.Series) or isinstance(benchmark, str)):
        raise TypeError("benchmark series should be a pandas time series or a string ticker.")

    if returns is None:
        returns = np.log(prices / prices.shift(1))
        returns.fillna(0, inplace=True)
        returns = returns[~np.isinf(returns)]

    if benchmark is not None and isinstance(benchmark, str) and benchmarkReturns is None:
        startDate = advanceDateByCalendar("China.SSE", prices.index[0], '-1b', BizDayConventions.Preceding)

        benchmarkPrices = get_benchmark_data(benchmark,
                                             start_date=startDate.strftime('%Y-%m-%d'),
                                             end_data=returns.index[-1].strftime("%Y-%m-%d"))

        # do the linear interpolation on the target time line
        date_index = prices.index
        new_index = benchmarkPrices.index.union(date_index)
        benchmarkPrices = benchmarkPrices.reindex(new_index)
        benchmarkPrices = benchmarkPrices.interpolate().ix[date_index].dropna()

        benchmarkReturns = np.log(benchmarkPrices['closePrice'] / benchmarkPrices['closePrice'].shift(1))
        benchmarkReturns.name = benchmark
        benchmarkReturns.fillna(0, inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)
    elif benchmark is not None and isinstance(benchmark, pd.Series):
        benchmarkReturns = np.log(benchmark / benchmark.shift(1))
        try:
            benchmarkReturns.name = benchmark.name
        except AttributeError:
            benchmarkReturns.name = "benchmark"
        benchmarkReturns.dropna(inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)

    aggregateDaily = aggregateReturns(returns)
    drawDownDaily = drawDown(aggregateDaily)

    # perf metric
    annualRet = annualReturn(aggregateDaily)
    annualVol = annualVolatility(aggregateDaily)
    sortino = sortinoRatio(aggregateDaily)
    sharp = sharpRatio(aggregateDaily)
    maxDrawDown = np.min(drawDownDaily['draw_down'])
    winningDays = np.sum(aggregateDaily > 0.)
    lossingDays = np.sum(aggregateDaily < 0.)

    perf_metric = pd.DataFrame([annualRet, annualVol, sortino, sharp, maxDrawDown, winningDays, lossingDays],
                                index=['annual_return',
                                       'annual_volatiltiy',
                                       'sortino_ratio',
                                       'sharp_ratio',
                                       'max_draw_down',
                                       'winning_days',
                                       'lossing_days'],
                                columns=['metrics'])

    perf_df = pd.DataFrame(index=aggregateDaily.index)
    perf_df['daily_return'] = aggregateDaily
    perf_df['daily_cum_return'] = np.exp(aggregateDaily.cumsum()) - 1.0
    perf_df['daily_draw_down'] = drawDownDaily['draw_down']

    if benchmarkReturns is not None:
        perf_df['benchmark_return'] = benchmarkReturns
        perf_df['benchmark_cum_return'] = benchmarkReturns.cumsum()
        perf_df.dropna(inplace=True)
        perf_df['benchmark_cum_return'] = np.exp(perf_df['benchmark_cum_return']
                                                     - perf_df['benchmark_cum_return'][0]) - 1.0
        perf_df['access_return'] = aggregateDaily - benchmarkReturns
        perf_df['access_cum_return'] = (1.0 + perf_df['daily_cum_return']) \
                                           / (1.0 + perf_df['benchmark_cum_return']) - 1.0
        perf_df.fillna(0.0, inplace=True)
        accessDrawDownDaily = drawDown(perf_df['access_return'])
    else:
        accessDrawDownDaily = None

    if 'benchmark_cum_return' in perf_df:
        benchmarkCumReturns = perf_df['benchmark_cum_return']
        benchmarkCumReturns.name = benchmarkReturns.name
        accessCumReturns = perf_df['access_cum_return']
        accessReturns = perf_df['access_return']

        index = perf_df.index

        length1 = len(bizDatesList('China.SSE', index[0], index[-1]))
        length2 = len(perf_df)
        factor = length1 / float(length2)

        rb = RollingBeta(perf_df['daily_return'], perf_df['benchmark_return'], [1, 3, 6], factor=factor)
        rs = RollingSharp(perf_df['daily_return'], [1, 3, 6], factor=factor)
    else:
        benchmarkCumReturns = None
        accessReturns = None
        accessCumReturns = None

    if len(perf_df['daily_return']) > APPROX_BDAYS_PER_MONTH and benchmarkCumReturns is not None:
        rollingRisk = pd.concat([pd.concat(rs, axis=1), pd.concat(rb, axis=1)], axis=1)
    else:
        rollingRisk = None

    if plot:
        verticalSections = 2
        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axRollingReturns = plt.subplot(gs[0, :])
        axDrawDown = plt.subplot(gs[1, :], sharex=axRollingReturns)

        plottingRollingReturn(perf_df['daily_cum_return'], benchmarkCumReturns, axRollingReturns)
        plottingDrawdownPeriods(perf_df['daily_cum_return'], drawDownDaily, 5, axDrawDown)

        if rollingRisk is not None:
            plt.figure(figsize=(16, 7 * verticalSections))
            gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
            axRollingBeta = plt.subplot(gs[0, :])
            axRollingSharp = plt.subplot(gs[1, :])

            bmName = benchmarkReturns.name
            plottingRollingBeta(rb, bmName, ax=axRollingBeta)
            plottingRollingSharp(rs, ax=axRollingSharp)

        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axUnderwater = plt.subplot(gs[0, :])
        axMonthlyHeatmap = plt.subplot(gs[1, 0])
        axAnnualReturns = plt.subplot(gs[1, 1])
        axMonthlyDist = plt.subplot(gs[1, 2])

        plottingUnderwater(drawDownDaily['draw_down'], axUnderwater)
        plottingMonthlyReturnsHeapmap(returns, axMonthlyHeatmap)
        plottingAnnualReturns(returns, axAnnualReturns)
        plottingMonthlyRetDist(returns, axMonthlyDist)

    if accessReturns is not None and plot:
         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
         axRollingAccessReturns = plt.subplot(gs[0, :])
         axAccessDrawDown = plt.subplot(gs[1, :], sharex=axRollingAccessReturns)
         plottingRollingReturn(accessCumReturns, None, axRollingAccessReturns, title='Access Cumulative Returns w.r.t. ' + benchmarkReturns.name)
         plottingDrawdownPeriods(accessCumReturns, accessDrawDownDaily, 5, axAccessDrawDown, title=('Top 5 Drawdown periods w.r.t. ' + benchmarkReturns.name))

         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

         axAccessUnderwater = plt.subplot(gs[0, :])
         axAccessMonthlyHeatmap = plt.subplot(gs[1, 0])
         axAccessAnnualReturns = plt.subplot(gs[1, 1])
         axAccessMonthlyDist = plt.subplot(gs[1, 2])

         plottingUnderwater(accessDrawDownDaily['draw_down'], axAccessUnderwater, title='Underwater Plot w.r.t. '
                                                                                        + benchmarkReturns.name)
         plottingMonthlyReturnsHeapmap(accessReturns, ax=axAccessMonthlyHeatmap, title='Monthly Access Returns (%)')
         plottingAnnualReturns(accessReturns, ax=axAccessAnnualReturns, title='Annual Access Returns')
         plottingMonthlyRetDist(accessReturns, ax=axAccessMonthlyDist, title='Distribution of Monthly Access Returns')

    return perf_metric, perf_df, rollingRisk
コード例 #4
0
class StocksPositionsBook(object):

    _bizDatesList = bizDatesList("China.SSE", dt.datetime(1993, 1, 1), dt.datetime(2025, 12, 31))

    def __init__(self, assets):

        self.assets = assets
        self._lags = {s: self.assets[s].lag for s in self.assets.keys()}
        self._shortable = {s: self.assets[s].short for s in self.assets.keys()}
        self._cachedSaleAmount = {}
        self._allPositions = {}

    def positions(self, symbol):
        return self._allPositions[symbol]

    def avaliableForTrade(self, symbol, currDT):
        if symbol in self._cachedSaleAmount:
            record = self._cachedSaleAmount[symbol]
            if record['date'] < currDT:
                return self._avaliableForTrade(symbol, currDT)
            else:
                return record['amount']
        else:
            return self._avaliableForTrade(symbol, currDT)

    def _avaliableForTrade(self, symbol, currDT):
        if symbol not in self._allPositions:
            avaliableForSell, avaliableForBuy = 0, 0
        else:
            symbolPositionsHistory = self._allPositions[symbol]
            avaliableForSell, avaliableForBuy =\
                symbolPositionsHistory.avaliableForTrade(currDT,
                                                         StocksPositionsBook._bizDatesList)
        self._cachedSaleAmount[symbol] = {'date': currDT, 'amount': (avaliableForSell, avaliableForBuy)}
        return avaliableForSell, avaliableForBuy

    def updatePositionsByOrder(self, symbol, currDT, quantity, direction):
        direction = convertDirection(direction)
        if symbol not in self._allPositions:
            if not self._shortable[symbol] and direction == -1:
                raise ValueError("Short sell is not allowed for {0}".format(symbol))
        else:
            symbolPositionsHistory = self._allPositions[symbol]
            symbolPositionsHistory.updatePositionsByOrder(currDT, quantity, direction)

        # update cache for future usage
        self._avaliableForTrade(symbol, currDT)

    def updatePositionsByCancelOrder(self, symbol, currDT, quantity, direction):
        direction = convertDirection(direction)
        if symbol in self._allPositions:
            symbolPositionsHistory = self._allPositions[symbol]
            symbolPositionsHistory.updatePositionsByCancelOrder(currDT, quantity, direction)

        # update cache for future usage
        self._avaliableForTrade(symbol, currDT)

    def updatePositionsByFill(self, fill_evevt):
        posClosed = 0
        pnl = 0.
        symbol = fill_evevt.symbol
        currDT = fill_evevt.timeindex.date()
        quantity = fill_evevt.quantity
        direction = convertDirection(fill_evevt.direction)
        value = fill_evevt.nominal / quantity / direction
        if symbol not in self._allPositions:
            lag = self._lags[symbol]
            short = self._shortable[symbol]
            self._allPositions[symbol] = SymbolPositionsHistory(symbol,
                                                                lag,
                                                                short,
                                                                currDT,
                                                                quantity,
                                                                0,
                                                                direction,
                                                                value)
            posOpened = quantity
        else:
            symbolPositionsHistory = self._allPositions[symbol]
            posClosed, posOpened, pnl = \
                symbolPositionsHistory.updatePositionsByFill(currDT, quantity, direction, value)

            if symbolPositionsHistory.empty():
                del self._allPositions[symbol]

        self._avaliableForTrade(symbol, currDT)
        return -posClosed * direction, posOpened * direction, pnl

    def getBookValueAndBookPnL(self, symbol, currentPrice):

        if symbol not in self._allPositions:
            return 0., 0.
        else:
            symbolPositionsHistory = self._allPositions[symbol]
            return symbolPositionsHistory.bookValueAndBookPnL(currentPrice)
コード例 #5
0
ファイル: Tears.py プロジェクト: yushaoli/VisualPortfolio
def createPerformanceTearSheet(prices=None,
                               returns=None,
                               benchmark=None,
                               benchmarkReturns=None,
                               other_curves=None,
                               turn_over=None,
                               tc_cost=0.,
                               plot=True):

    if prices is not None and not isinstance(prices, pd.Series):
        raise TypeError("prices series should be a pandas time series.")
    elif returns is not None and prices is not None:
        raise ValueError("prices series and returns series can't be both set.")

    if benchmark is not None and not (isinstance(benchmark, pd.Series) or isinstance(benchmark, str)):
        raise TypeError("benchmark series should be a pandas time series or a string ticker.")

    if returns is None:
        returns = np.log(prices / prices.shift(1))
        returns.fillna(0, inplace=True)
        returns = returns[~np.isinf(returns)]

    if benchmark is not None and isinstance(benchmark, str) and benchmarkReturns is None:
        startDate = advanceDateByCalendar("China.SSE", prices.index[0], '-1b', BizDayConventions.Preceding)

        benchmarkPrices = get_benchmark_data(benchmark,
                                             start_date=startDate.strftime('%Y-%m-%d'),
                                             end_data=returns.index[-1].strftime("%Y-%m-%d"))

        # do the linear interpolation on the target time line
        date_index = prices.index
        new_index = benchmarkPrices.index.union(date_index)
        benchmarkPrices = benchmarkPrices.reindex(new_index)
        benchmarkPrices = benchmarkPrices.interpolate().ix[date_index].dropna()

        benchmarkReturns = np.log(benchmarkPrices['closePrice'] / benchmarkPrices['closePrice'].shift(1))
        benchmarkReturns.name = benchmark
        benchmarkReturns.fillna(0, inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)
    elif benchmark is not None and isinstance(benchmark, pd.Series):
        benchmarkReturns = np.log(benchmark / benchmark.shift(1))
        try:
            benchmarkReturns.name = benchmark.name
        except AttributeError:
            benchmarkReturns.name = "benchmark"
        benchmarkReturns.dropna(inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)

    aggregateDaily, aggregateDailyAfterTC = aggregateReturns(returns, turn_over, tc_cost)

    if aggregateDailyAfterTC is not None:
        aggregateDailyBeforeTC = aggregateDaily
        aggregateDaily = aggregateDailyAfterTC
    else:
        aggregateDailyBeforeTC = aggregateDaily

    drawDownDaily = drawDown(aggregateDaily)

    # perf metric
    annualRet = annualReturn(aggregateDaily)
    annualVol = annualVolatility(aggregateDaily)
    sortino = sortinoRatio(aggregateDaily)
    sharp = sharpRatio(aggregateDaily)
    maxDrawDown = np.min(drawDownDaily['draw_down'])
    winningDays = np.sum(aggregateDaily > 0.)
    lossingDays = np.sum(aggregateDaily < 0.)

    perf_metric = pd.DataFrame([annualRet, annualVol, sortino, sharp, maxDrawDown, winningDays, lossingDays],
                                index=['annual_return',
                                       'annual_volatiltiy',
                                       'sortino_ratio',
                                       'sharp_ratio',
                                       'max_draw_down',
                                       'winning_days',
                                       'lossing_days'],
                                columns=['metrics'])

    perf_df = pd.DataFrame(index=aggregateDaily.index)
    perf_df['daily_return'] = aggregateDaily
    perf_df['daily_return (w/o tc)'] = aggregateDailyBeforeTC
    perf_df['daily_cum_return'] = np.exp(aggregateDaily.cumsum()) - 1.0
    perf_df['daily_cum_return (w/o tc)'] = np.exp(aggregateDailyBeforeTC.cumsum()) - 1.0
    perf_df['daily_draw_down'] = drawDownDaily['draw_down']

    if benchmarkReturns is not None:
        perf_df['benchmark_return'] = benchmarkReturns
        perf_df['benchmark_cum_return'] = benchmarkReturns.cumsum()
        perf_df.fillna(0.0, inplace=True)
        perf_df['benchmark_cum_return'] = np.exp(perf_df['benchmark_cum_return']
                                                 - perf_df['benchmark_cum_return'][0]) - 1.0
        perf_df['access_return'] = aggregateDaily - perf_df['benchmark_return']
        perf_df['access_cum_return'] = (1.0 + perf_df['daily_cum_return']) \
                                       / (1.0 + perf_df['benchmark_cum_return']) - 1.0
        accessDrawDownDaily = drawDown(perf_df['access_return'])
    else:
        accessDrawDownDaily = None

    if 'benchmark_cum_return' in perf_df:
        benchmarkCumReturns = perf_df['benchmark_cum_return']
        benchmarkCumReturns.name = benchmarkReturns.name
        accessCumReturns = perf_df['access_cum_return']
        accessReturns = perf_df['access_return']

        index = perf_df.index

        length1 = len(bizDatesList('China.SSE', index[0], index[-1]))
        length2 = len(perf_df)
        factor = length1 / float(length2)

        rb = RollingBeta(perf_df['daily_return'], perf_df['benchmark_return'], [1, 3, 6], factor=factor)
        rs = RollingSharp(perf_df['daily_return'], [1, 3, 6], factor=factor)
    else:
        benchmarkCumReturns = None
        accessReturns = None
        accessCumReturns = None

    if len(perf_df['daily_return']) > APPROX_BDAYS_PER_MONTH and benchmarkCumReturns is not None:
        rollingRisk = pd.concat([pd.concat(rs, axis=1), pd.concat(rb, axis=1)], axis=1)
    else:
        rollingRisk = None

    if plot:
        verticalSections = 2
        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axRollingReturns = plt.subplot(gs[0, :])
        axDrawDown = plt.subplot(gs[1, :])

        plottingRollingReturn(perf_df['daily_cum_return'],
                              perf_df['daily_cum_return (w/o tc)'],
                              benchmarkCumReturns,
                              other_curves, axRollingReturns)
        plottingDrawdownPeriods(perf_df['daily_cum_return'], drawDownDaily, 5, axDrawDown)

        if rollingRisk is not None:
            plt.figure(figsize=(16, 7 * verticalSections))
            gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
            axRollingBeta = plt.subplot(gs[0, :])
            axRollingSharp = plt.subplot(gs[1, :])

            bmName = benchmarkReturns.name
            plottingRollingBeta(rb, bmName, ax=axRollingBeta)
            plottingRollingSharp(rs, ax=axRollingSharp)

        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axUnderwater = plt.subplot(gs[0, :])
        axMonthlyHeatmap = plt.subplot(gs[1, 0])
        axAnnualReturns = plt.subplot(gs[1, 1])
        axMonthlyDist = plt.subplot(gs[1, 2])

        plottingUnderwater(drawDownDaily['draw_down'], axUnderwater)
        plottingMonthlyReturnsHeapmap(aggregateDaily, axMonthlyHeatmap)
        plottingAnnualReturns(aggregateDaily, axAnnualReturns)
        plottingMonthlyRetDist(aggregateDaily, axMonthlyDist)

    if accessReturns is not None and plot:
         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
         axRollingAccessReturns = plt.subplot(gs[0, :])
         axAccessDrawDown = plt.subplot(gs[1, :], sharex=axRollingAccessReturns)
         plottingRollingReturn(accessCumReturns, None, None, None, axRollingAccessReturns, title='Access Cumulative Returns w.r.t. ' + benchmarkReturns.name)
         plottingDrawdownPeriods(accessCumReturns, accessDrawDownDaily, 5, axAccessDrawDown, title=('Top 5 Drawdown periods w.r.t. ' + benchmarkReturns.name))

         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

         axAccessUnderwater = plt.subplot(gs[0, :])
         axAccessMonthlyHeatmap = plt.subplot(gs[1, 0])
         axAccessAnnualReturns = plt.subplot(gs[1, 1])
         axAccessMonthlyDist = plt.subplot(gs[1, 2])

         plottingUnderwater(accessDrawDownDaily['draw_down'], axAccessUnderwater, title='Underwater Plot w.r.t. '
                                                                                        + benchmarkReturns.name)
         plottingMonthlyReturnsHeapmap(accessReturns, ax=axAccessMonthlyHeatmap, title='Monthly Access Returns (%)')
         plottingAnnualReturns(accessReturns, ax=axAccessAnnualReturns, title='Annual Access Returns')
         plottingMonthlyRetDist(accessReturns, ax=axAccessMonthlyDist, title='Distribution of Monthly Access Returns')

    return perf_metric, perf_df, rollingRisk
コード例 #6
0
def test_calc101():
    INDU_STYLES = ['Bank','RealEstate','Health','Transportation','Mining','NonFerMetal',
                   'HouseApp','LeiService','MachiEquip','BuildDeco','CommeTrade','CONMAT',
                   'Auto','Textile','FoodBever','Electronics','Computer','LightIndus',
                   'Utilities','Telecom','AgriForest','CHEM','Media','IronSteel',
                   'NonBankFinan','ELECEQP','AERODEF']
    alpha_number = 101
    engine = create_engine('')
    begin_date = '2018-12-01'
    end_date = '2018-12-28'
    query = select([Market]).where(
            and_(Market.trade_date >= begin_date, Market.trade_date <= end_date, ))
    mkt_df = pd.read_sql(query, engine)
    mkt_df.rename(columns={'preClosePrice':'pre_close','openPrice':'open_price',
                      'highestPrice':'highest_price','lowestPrice':'lowest_price',
                      'closePrice':'close_price','turnoverVol':'turnover_vol',
                      'turnoverValue':'turnover_value','accumAdjFactor':'accum_adj',
                      'vwap':'vwap','negMarketValue':'neg_mkt_value','marketValue':'mkt_value',
                      'chgPct':'chg_pct','PE':'pe_ttm','PE1':'pe','PB':'pb'}, inplace=True)
    mkt_df = mkt_df[[('000000' + str(code))[-6:][0] in '036' for code in mkt_df['code']]]
    trade_date_list = list(set(mkt_df.trade_date))
    trade_date_list.sort(reverse=True)
    mkt_df = mkt_df[mkt_df['turnover_vol'] > 0]
    for p in mkt_df.columns:
        if p in ['open_price', 'highest_price', 'lowest_price', 'close_price', 'vwap']:
            mkt_df[p+'_raw'] = mkt_df[p]
            mkt_df[p] = mkt_df[p] * mkt_df['accum_adj']
    # multiplier for pe, pb, mkt_value and neg_mkt_value
    mkt_multiplier = mkt_df[['trade_date', 'code', 'accum_adj', 'close_price', 
                             'neg_mkt_value', 'mkt_value', 'pe_ttm', 'pe', 'pb']]
    for p in ['neg_mkt_value', 'mkt_value', 'pe_ttm', 'pe', 'pb']:
        mkt_multiplier[p] = mkt_multiplier[p] / mkt_multiplier['close_price']
    mkt_multiplier.drop('close_price', axis=1, inplace=True)
    mkt_df.drop(['accum_adj', 
                 'neg_mkt_value', 'mkt_value', 'pe_ttm', 'pe', 'pb'], axis=1, inplace=True)
    mkt_df = mkt_df.merge(mkt_multiplier, on=['trade_date', 'code'], how='left')
    mkt_df['turnover'] = mkt_df['turnover_value'] / mkt_df['mkt_value']
    mkt_df = mkt_df.set_index(['trade_date', 'code'])
    
    
    query = select([Exposure]).where(
            and_(Exposure.trade_date >= begin_date, Exposure.trade_date <= end_date))
    risk_df = pd.read_sql(query, engine)
    risk_df = risk_df[[('000000' + str(code))[-6:][0] in '036' for code in risk_df['code']]]
    risk_df = risk_df.sort_values(['trade_date', 'code']).reset_index(drop=True)

    date_list = bizDatesList('China.SSE', begin_date, end_date)
    indu_dict = {}
    indu_names = INDU_STYLES + ['COUNTRY']
    for date in date_list:
        date_indu_df = risk_df[risk_df['trade_date'] == date_list[-1]].set_index('code')[indu_names]
        indu_check_se = date_indu_df.sum(axis=1).sort_values()
        date_indu_df.drop(indu_check_se[indu_check_se < 2].index, inplace=True)
        indu_dict[date] = date_indu_df.sort_index()
    # total dataframe to dataframe dict
    total_data = {}
    for col in ['open_price', 'highest_price', 'lowest_price', 'close_price', 
                'vwap', 'turnover_vol','turnover_value',
                'neg_mkt_value','mkt_value',  'pe_ttm', 'pe', 'pb',
                'open_price_raw', 'highest_price_raw', 'lowest_price_raw', 
                'close_price_raw', 'vwap_raw',
                'accum_adj']:
        total_data[col] = mkt_df[col].unstack().sort_index()
    total_data['returns'] = total_data['close_price'].pct_change()
    total_data['indu'] = indu_dict
    #58, 59, 67,69, 76, 80, 82, 87, 90, 91, 97
    alpha_num_list = [58, 59, 67, 69, 76, 80, 82, 87, 90, 91, 97]
    pdb.set_trace()
    for date in trade_date_list:
        for number in alpha_num_list:
            print('Alpha101().alpha_' + str(number), date)
            alpha_fun = eval('Alpha101().alpha_' + str(number))
            fun_param = inspect.signature(alpha_fun).parameters
            dependencies = fun_param['dependencies'].default
            max_window = fun_param['max_window'].default
        #若在外部指定参数则可计算出max_windows
            begin = advanceDateByCalendar('china.sse', date, '-%sb' % (max_window - 1))
            data = {}
            for dep in dependencies:
                data[dep] = total_data[dep].loc[begin:date]
                data['indu'] = total_data['indu']
            alpha_fun(data)
コード例 #7
0
                                   how='left',
                                   on=['trade_date', 'code'])
            total_data['risk_cov'] = risk_cov

        industry_info = self.fetch_industry_range(universe,
                                                  start_date=start_date,
                                                  end_date=end_date,
                                                  dates=dates,
                                                  category=industry)

        factor_data = pd.merge(factor_data,
                               industry_info,
                               on=['trade_date', 'code'])
        total_data['factor'] = factor_data
        return total_data


if __name__ == '__main__':

    from PyFin.api import bizDatesList
    engine = SqlEngine()
    ref_date = '2017-05-03'
    universe = Universe('zz800')
    dates = bizDatesList('china.sse', '2018-05-01', '2018-05-10')
    codes = engine.fetch_codes(ref_date, universe)

    res = engine.fetch_dx_return_range(universe,
                                       dates=dates,
                                       horizon=4,
                                       benchmark=300)
    print(res)
コード例 #8
0
class StocksPositionsBook(object):

    _bizDatesList = bizDatesList("China.SSE", dt.datetime(1993, 1, 1),
                                 dt.datetime(2025, 12, 31))

    def __init__(self, assets):

        self._allPositions = {}
        self.assets = assets
        self._lags = {s: self.assets[s].lag for s in self.assets.keys()}
        self._shortable = {s: self.assets[s].short for s in self.assets.keys()}
        self._cachedSaleAmount = {}
        self._allPositions = {}

    def avaliableForTrade(self, symbol, currDT):
        if symbol in self._cachedSaleAmount:
            record = self._cachedSaleAmount[symbol]
            if record['date'] < currDT:
                return self._avaliableForTrade(symbol, currDT)
            else:
                return record['amount']
        else:
            return self._avaliableForTrade(symbol, currDT)

    def _avaliableForTrade(self, symbol, currDT):
        lag = self._lags[symbol]
        if symbol not in self._allPositions:
            avaliableForSell = 0
            avaliableForBuy = 0
        elif lag == 0:
            _, positions, locked, existDirections, _ = self._allPositions[
                symbol]
            avaliableForSell = 0
            avaliableForBuy = 0
            for i, direction in enumerate(existDirections):
                if direction == 1:
                    avaliableForSell += positions[i] - locked[i]
                else:
                    avaliableForBuy += positions[i] - locked[i]
        else:
            dates, positions, locked, existDirections, _ = self._allPositions[
                symbol]
            i = len(dates) - 1
            date = dates[i]

            while date > currDT:
                i -= 1
                if i < 0:
                    break
                date = dates[i]

            while i >= 0:
                startPos = bisect.bisect_left(
                    StocksPositionsBook._bizDatesList, date)
                endPos = bisect.bisect_left(StocksPositionsBook._bizDatesList,
                                            currDT)
                bizDates = endPos - startPos + 1
                if StocksPositionsBook._bizDatesList[endPos] == currDT:
                    bizDates -= 1
                else:
                    bizDates -= 2
                if bizDates >= lag:
                    break
                i -= 1
                if i < 0:
                    break
                date = dates[i]

            avaliableForSell = 0
            avaliableForBuy = 0
            if i >= 0:
                for k in range(i + 1):
                    if existDirections[k] == 1:
                        avaliableForSell += positions[k] - locked[k]
                    else:
                        avaliableForBuy += positions[k] - locked[k]
        self._cachedSaleAmount[symbol] = {
            'date': currDT,
            'amount': (avaliableForSell, avaliableForBuy)
        }
        return avaliableForSell, avaliableForBuy

    def updatePositionsByOrder(self, symbol, currDT, quantity, direction):
        if symbol not in self._allPositions:
            if not self._shortable[symbol] and direction == -1:
                raise ValueError(
                    "Short sell is not allowed for {0}".format(symbol))
        else:
            dates, positions, locked, existDirections, _ = self._allPositions[
                symbol]

            toFinish = quantity
            i = 0
            while toFinish != 0 and i != len(dates):
                if existDirections[i] != direction:
                    amount = positions[i] - locked[i]
                    if amount >= toFinish:
                        locked[i] += toFinish
                        toFinish = 0
                        break
                    else:
                        locked[i] = positions[i]
                        i += 1
                        toFinish -= amount
                else:
                    i += 1

            if toFinish > 0 and direction == -1 and not self._shortable[symbol]:
                raise ValueError(
                    "Existing amount is not enough to cover sell order. Short sell is not allowed for {0}"
                    .format(symbol))

        self._avaliableForTrade(symbol, currDT)

    def updatePositionsByFill(self, fill_evevt):
        posClosed = 0
        posOpened = 0
        pnl = 0.
        symbol = fill_evevt.symbol
        currDT = fill_evevt.timeindex.date()
        quantity = fill_evevt.quantity
        direction = fill_evevt.direction
        value = fill_evevt.nominal / quantity / direction
        if symbol not in self._allPositions:
            self._allPositions[symbol] = [currDT], [quantity], [0
                                                                ], [direction
                                                                    ], [value]
            posOpened = quantity
        else:
            dates, positions, locked, existDirections, existValues = self._allPositions[
                symbol]
            toFinish = quantity
            for i, d in enumerate(existDirections):
                if d != direction:
                    amount = positions[i]
                    if amount >= toFinish:
                        positions[i] -= toFinish
                        locked[i] -= toFinish
                        posClosed += toFinish
                        pnl += (value - existValues[i]) * d * toFinish
                        toFinish = 0
                        break
                    else:
                        toFinish -= amount
                        positions[i] = 0
                        locked[i] = 0
                        posClosed += amount
                        pnl += (value - existValues[i]) * d * amount
            if toFinish != 0:
                dates.append(currDT)
                positions.append(toFinish)
                locked.append(0)
                existDirections.append(direction)
                existValues.append(value)
                posOpened = toFinish

            deleted = 0
            for k in range(i + 1):
                if positions[k - deleted] == 0:
                    del dates[k - deleted]
                    del positions[k - deleted]
                    del locked[k - deleted]
                    del existDirections[k - deleted]
                    del existValues[k - deleted]
                    deleted += 1

            if not dates:
                del self._allPositions[symbol]

        self._avaliableForTrade(symbol, currDT)
        return -posClosed * direction, posOpened * direction, pnl

    def getBookValueAndBookPnL(self, symbol, currentPrice):

        if symbol not in self._allPositions:
            return 0., 0.
        else:
            bookValue = 0.
            bookPnL = 0.
            _, positions, _, existDirections, existCosts = self._allPositions[
                symbol]
            for p, d, c in zip(positions, existDirections, existCosts):
                bookValue += p * d * currentPrice
                bookPnL += p * d * (currentPrice - c)
            return bookValue, bookPnL