コード例 #1
0
ファイル: __init__.py プロジェクト: reinhardtken/backtest-py
def AllHS300Code2DB(path):
    df = pd.read_excel(path, dtype=str)
    out = df.to_dict('list')
    all = set()
    out2 = {}
    code2Map = {}
    for k, v in out.items():
        if isinstance(k, int):
            id = util.String2pdTimestamp(str(k), '%Y%m')
        else:
            id = util.String2pdTimestamp(k, '%Y%m')
        tmpList = []
        for one in v:
            try:
                if isinstance(one, str) and len(one) == 6:
                    tmp = one
                else:
                    tmp = '{:06}'.format(int(one))
                all.add(tmp)
                tmpList.append(tmp)
            except Exception as e:
                util.PrintException(e)
        out2[id] = {}
        out2[id]['data'] = tmpList
    print(all)

    allCodes = util.QueryAll()
    out = []
    for k, row in allCodes.iterrows():
        if k in all:
            out.append({'_id': k, 'name': row['名称']})
        code2Map[k] = {'_id': k, 'name': row['名称']}
    util.SaveMongoDBList(out, 'stock_codeList', 'allHS300')

    notInAll = set()
    for k, v in out2.items():
        for index in range(0, len(v['data'])):
            try:
                v['data'][index] = code2Map[v['data'][index]]
            except Exception as e:
                util.PrintException(e)
                notInAll.add(v['data'][index])

    print('not in all################################')
    print(notInAll)
    print('in all################################')
    print(out2)
    util.SaveMongoDBDict(out2, 'stock_codeList', 'allHS300Detail')
コード例 #2
0
    def Run(codes):
        out = []
        for one in codes:
            try:
                baseCounter = 0
                hitCounter = 0
                firstQuarter = None
                lastQuarter = None
                baseCounter2010 = 0
                hitCounter2010 = 0
                firstQuarter2010 = None
                lastQuarter2010 = None
                df = util.LoadData('stock',
                                   'yjbg2-' + one['_id'],
                                   condition={},
                                   sort=[('_id', 1)])
                for quarter, row in df.iterrows():
                    id = datetime.strptime(quarter, '%Y-%m-%d')
                    value = util.String2Number(row['sjltz'])
                    if not np.isnan(value):
                        if firstQuarter is None:
                            firstQuarter = id
                        lastQuarter = id
                        baseCounter += 1
                        if id.year >= 2010:
                            if firstQuarter2010 is None:
                                firstQuarter2010 = id
                            lastQuarter2010 = id
                            baseCounter2010 += 1
                        if value < -10:
                            hitCounter += 1
                            if id.year >= 2010:
                                hitCounter2010 += 1

                percent = 0
                percent2010 = 0
                if baseCounter > 0:
                    percent = hitCounter / baseCounter
                if baseCounter2010 > 0:
                    percent2010 = hitCounter2010 / baseCounter2010
                out.append({
                    '_id': one['_id'],
                    'begin': firstQuarter,
                    'end': lastQuarter,
                    'base': baseCounter,
                    'hit': hitCounter,
                    'percent': percent,
                    'begin2010': firstQuarter2010,
                    'end2010': lastQuarter2010,
                    'base2010': baseCounter2010,
                    'hit2010': hitCounter2010,
                    'percent2010': percent2010
                })
            except Exception as e:
                util.PrintException(e)
        dfOut = pd.DataFrame(out)
        util.SaveMongoDB_DF(dfOut, 'stock_statistics2',
                            'dangerousQuarterRatio')
コード例 #3
0
ファイル: server.py プロジェクト: reinhardtken/backtest-py
def serve():
    # 启动 rpc 服务
    print("version=1.0.6  run server ....")
    server = None
    try:
        server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
        py_rpc_pb2_grpc.add_HelloServicer_to_server(Greeter(), server)
        py_rpc_pb2_grpc.add_StockPriceServicer_to_server(
            StockService(), server)
        py_rpc_pb2_grpc.add_StockSignalServicer_to_server(
            StockSignalService(), server)
        server.add_insecure_port('[::]:7070')
        server.start()

        while True:
            time.sleep(60 * 60 * 24)  # one day in seconds
    except KeyboardInterrupt:
        if server is not None:
            server.stop(0)
    except Exception as e:
        util.PrintException(e)
コード例 #4
0
ファイル: dv3.py プロジェクト: reinhardtken/py-code
    def Run(self):

        # 准备判定条件
        now = datetime.now()
        stopYear = now.year
        for year in range(self.startYear - 1, stopYear + 1):
            self.forecast[year] = {}
            if year not in self.checkPoint:
                self.checkPoint[year] = {}
            if year + 1 not in self.checkPoint:
                self.checkPoint[year + 1] = {}
            # 加载对应年的年报中报
            yearPaper = util.LoadYearPaper(year, self.code)
            self.checkPoint[year]['midYear'] = yearPaper[0]
            self.checkPoint[year]['year'] = yearPaper[1]

            # 加载对应的季报
            quarterPaper = util.LoadQuaterPaper(year, self.code)
            self.checkPoint[year]['first'] = quarterPaper[0]
            self.checkPoint[year]['second'] = quarterPaper[1]
            self.checkPoint[year]['third'] = quarterPaper[2]
            self.checkPoint[year]['forth'] = quarterPaper[3]

            #加载业绩预告
            forecast = util.LoadForecast(year, self.code)
            self.forecast[year]['first'] = forecast[0]
            self.forecast[year]['second'] = forecast[1]
            self.forecast[year]['third'] = forecast[2]
            self.forecast[year]['forth'] = forecast[3]

        self.statisticsYears = len(self.checkPoint)
        # 对加载出来的数据做初步处理
        for k, v in self.checkPoint.items():
            try:
                if 'notExist' in v['year'] and 'notExist' in v['midYear']:
                    # 没有查到年报数据的年份,可能是公司就没上市,需要扣减
                    self.statisticsYears -= 1
                # 计算分红
                v['midYear']['dividend'] = 0
                v['year']['dividend'] = 0
                self.CalcDividend(k, 'midYear')
                self.CalcDividend(k, 'year')
                v['year']['allDividend'] = v['midYear']['dividend'] + v[
                    'year']['dividend']
                # 计算股利支付率,如果这个数字超过100%,则分红不能当真
                try:
                    if GPFH_KEY['EarningsPerShare'] in v['year']:
                        v['year']['dividendRatio'] = v['year'][
                            'allDividend'] / v['year'][
                                GPFH_KEY['EarningsPerShare']]

                    # 计算分红是不是大于每股收益,如果大于每股收益,显然不可持续
                    # 002351 漫步者 买入:"date" : ISODate("2011-06-17T00:00:00.000Z"),
                    # 不可持续的分红,需要调整为实际每股收益的80%来测算
                    # 2019/12/26此段逻辑很好的改善了回测中差标的集合的表现
                    if GPFH_KEY['EarningsPerShare'] in v['midYear']:
                        if 0.8 * v['midYear'][
                                GPFH_KEY['EarningsPerShare']] < v['midYear'][
                                    'dividend']:
                            v['unsustainable'] = True
                            v['midYear']['dividend'] = 0.8 * v['midYear'][
                                GPFH_KEY['EarningsPerShare']]
                            v['year']['allDividend'] = v['midYear'][
                                'dividend'] + v['year']['dividend']
                    if GPFH_KEY['EarningsPerShare'] in v['year']:
                        if 0.8 * v['year'][GPFH_KEY['EarningsPerShare']] < v[
                                'year']['dividend']:
                            v['unsustainable'] = True
                            v['year']['dividend'] = 0.8 * v['year'][
                                GPFH_KEY['EarningsPerShare']]
                            v['year']['allDividend'] = v['midYear'][
                                'dividend'] + v['year']['dividend']
                except Exception as e:
                    if v['year'][GPFH_KEY['EarningsPerShare']] == '-':
                        v['year'][GPFH_KEY['EarningsPerShare']] = 0
                    util.PrintException(e)
                # 根据分红计算全年和半年的买入卖出价格
                # allDividend影响下一年
                if v['year']['allDividend'] > 0:
                    # 统计分红过的年数
                    self.dividendYears += 1
                    self.checkPoint[
                        k +
                        1]['buyPrice'] = v['year']['allDividend'] / BUY_PERCENT
                    self.checkPoint[k + 1][
                        'sellPrice'] = v['year']['allDividend'] / SELL_PERCENT
                else:
                    self.checkPoint[k + 1]['buyPrice'] = INVALID_BUY_PRICE
                    self.checkPoint[k + 1]['sellPrice'] = INVALID_SELL_PRICE

                # midYear的dividend影响8月31号以后的当年
                if v['midYear']['dividend'] > 0:
                    self.checkPoint[k][
                        'buyPrice2'] = v['midYear']['dividend'] / BUY_PERCENT
                    self.checkPoint[k][
                        'sellPrice2'] = v['midYear']['dividend'] / SELL_PERCENT
                else:
                    self.checkPoint[k]['buyPrice2'] = INVALID_BUY_PRICE
                    self.checkPoint[k]['sellPrice2'] = INVALID_SELL_PRICE

                # 检查净利润同比下降10%以上的位置
                self.ProcessQuarterPaper(k, 'first')
                self.ProcessQuarterPaper(k, 'second')
                self.ProcessQuarterPaper(k, 'third')
                self.ProcessQuarterPaper(k, 'forth')
            except KeyError as e:
                print(e)

        # 针对dangerousPoint清理dividendPoint
        tmp = []
        have = set()
        for one in self.dividendPoint:
            for two in self.dangerousPoint:
                if two[0] <= one.date and two[1] >= one.date:
                    print("清理除权 {} {} {}".format(one.date, two[0], two[1]))
                    break
            else:
                if one.date not in have:
                    tmp.append(one)
                    have.add(one.date)
        self.dividendPoint = tmp

        # 对所有派股的情况,记录除权日,并调整买卖价格
        for one in self.dividendPoint:
            tmp = {}
            # 有派股
            if one.gift > 0:
                try:
                    if one.position == 'midYear' and self.checkPoint[
                            one.year]['buyPrice2'] != INVALID_BUY_PRICE:
                        tmp['buyPriceX'] = self.checkPoint[
                            one.year]['buyPrice2'] / (1 + one.gift)
                        tmp['sellPriceX'] = self.checkPoint[
                            one.year]['sellPrice2'] / (1 + one.gift)
                        tmp['y'] = one.year
                        tmp['p'] = 'midYear'
                        tmp['date'] = one.date
                        self.checkPoint[
                            one.year]['midYear']['dividendAdjust'] = tmp
                    elif one.position == 'year' and self.checkPoint[
                            one.year + 1]['buyPrice'] != INVALID_BUY_PRICE:
                        # 送股調整的時候,年报的调整需要囊括半年报的送股
                        # TODO 年报调整为何要包括半年报?感觉此处有问题。。。
                        midYearGift = 0
                        try:
                            midYearGift = self.checkPoint[
                                one.year]['midYear']['gift']
                        except Exception as e:
                            pass
                        if midYearGift != 0:
                            assert 0
                        tmp['buyPriceX'] = self.checkPoint[
                            one.year + 1]['buyPrice'] / ((1 + one.gift) *
                                                         (1 + midYearGift))
                        tmp['sellPriceX'] = self.checkPoint[
                            one.year + 1]['sellPrice'] / ((1 + one.gift) *
                                                          (1 + midYearGift))
                        tmp['y'] = one.year + 1
                        tmp['p'] = 'year'
                        tmp['date'] = one.date
                        self.checkPoint[one.year +
                                        1]['year']['dividendAdjust'] = tmp
                    if len(tmp) > 0:
                        # 有配股有分红才调整价格
                        self.dividendAdjust[one.date] = tmp
                except Exception as e:
                    print(e)

        # 清理所有截止日期早于startDate的cooldown
        # Test2('601288', 26405, '农业银行', False, True) ,有2010年的cooldown
        tmp = []
        for one in self.dangerousPoint:
            if one[1] < self.startDate:
                continue
            else:
                tmp.append(one)
        self.dangerousPoint = tmp
コード例 #5
0
ファイル: server.py プロジェクト: reinhardtken/backtest-py
            time.sleep(60 * 60 * 24)  # one day in seconds
    except KeyboardInterrupt:
        if server is not None:
            server.stop(0)
    except Exception as e:
        util.PrintException(e)


if __name__ == '__main__':
    if len(sys.argv) >= 2:
        logPath = sys.argv[1]
    else:
        logPath = r'C:\workspace\tmp\stockPyConfig.json'
    util.log.Init('main', logPath)
    # df = ts.get_index()
    # # print(df)
    # re = py_rpc_pb2.LastPriceRsp(error=-1)
    # AStock = df.loc[df.code == '000001']
    # print(AStock)
    # re.code = AStock.loc[0, 'code']
    # re.name = AStock.loc[0, 'name']
    # re.closePrice = AStock.loc[0, 'close']
    # re.openPrice = AStock.loc[0, 'open']
    log.current().info("server run....")
    try:
        a = 1
        b = 0
        c = a / b
    except Exception as e:
        util.PrintException(e)
    serve()