Exemplo n.º 1
0
 async def test_load_bars_batch(self):
     codes = ["000001.XSHE", "000001.XSHG"]
     # end = arrow.now(tz=cfg.tz).datetime
     # async for code, bars in Security.load_bars_batch(codes, end, 10,
     #                                                  FrameType.MIN30):
     #     print(bars[-2:])
     #     self.assertEqual(10, len(bars))
     #
     # codes = ['000001.XSHE', '000001.XSHG']
     end = arrow.get("2020-08-27").datetime
     async for code, bars in Security.load_bars_batch(
             codes, end, 5, FrameType.DAY):
         print(code, bars[-2:])
         self.assertEqual(5, len(bars))
         self.assertEqual(bars[-1]["frame"], end.date())
         if code == "000001.XSHG":
             self.assertAlmostEqual(3350.11, bars[-1]["close"], places=2)
Exemplo n.º 2
0
    async def distribution(self):
        # 涨停、跌停
        zt, dt = 0, 0
        codes = Securities().choose(['stock'])
        end = arrow.now(cfg.tz).floor('minute').datetime
        pct = []
        async for code, bars in Security.load_bars_batch(
                codes, end, 2, FrameType.DAY):
            c1, c0 = bars[-2:]['close']
            if (c0 + 0.01) / c1 - 1 > 0.1:
                zt += 1
            if (c0 - 0.01) / c1 - 1 < -0.1:
                dt += 1

            pct.append(c0 / c1 - 1)

        # 分布
        cuts = np.histogram(
            pct, bins=[-0.2, -0.1, -0.07, -0.03, 0, 0.03, 0.07, 0.1, 0.2])

        self.price_change_history.append((zt, dt, cuts))
        if len(self.price_change_history) == 8:
            self.price_change_history.pop(0)

        now = arrow.now(tz=cfg.tz)
        if now.hour >= 15:
            dt = tf.date2int(now)
            await cache.sys.hset(
                f"glance{dt}", "distribution",
                json.dumps({
                    "zt": zt,
                    "dt": dt,
                    "cuts": cuts
                }))

        return zt, dt, cuts
Exemplo n.º 3
0
    async def scan(self,
                   frame_type: Union[str, FrameType] = FrameType.DAY,
                   end: Frame = None,
                   codes: List[str] = None):
        logger.info("running momentum scan at %s level", frame_type)
        if end is None:
            end = arrow.now(cfg.tz).datetime

        assert type(end) in (datetime.date, datetime.datetime)

        frame_type = FrameType(frame_type)
        ft = frame_type.value
        codes = codes or Securities().choose(['stock'])
        day_bars = {}
        async for code, bars in Security.load_bars_batch(
                codes, end, 2, FrameType.DAY):
            day_bars[code] = bars

        if len(day_bars) == 0:
            return

        async for code, bars in Security.load_bars_batch(
                codes, end, 11, frame_type):
            if len(bars) < 11:
                continue

            fired = bars[-1]['frame']
            day_bar = day_bars.get(code)
            if day_bar is None:
                continue

            c1, c0 = day_bars.get(code)[-2:]['close']
            cmin = min(bars['close'])

            # 还处在下跌状态、或者涨太多
            if c0 == cmin or (c0 / c1 - 1) > self.baseline(f"up_limit"):
                continue

            ma5 = signal.moving_average(bars['close'], 5)

            err, (a, b, c), (vx, _) = signal.polyfit(ma5[-7:] / ma5[-7])
            # 无法拟合,或者动能不足
            if err > self.baseline(f"ma5:{ft}:err") or a < self.baseline(
                    f"ma5:{ft}:a"):
                continue

            # 时间周期上应该是信号刚出现,还在窗口期内
            vx_range = self.baseline(f"ma5:{ft}:vx")
            if not vx_range[0] < vx < vx_range[1]:
                continue

            p = np.poly1d((a, b, c))
            y = p(9) / p(6) - 1
            # 如果预测未来三周期ma5上涨幅度不够
            if y < self.baseline(f"ma5:{ft}:y"):
                continue

            sec = Security(code)

            if frame_type == FrameType.DAY:
                start = tf.shift(tf.floor(end, frame_type), -249, frame_type)
                bars250 = await sec.load_bars(start, end, frame_type)
                ma60 = signal.moving_average(bars250['close'], 60)
                ma120 = signal.moving_average(bars250['close'], 120)
                ma250 = signal.moving_average(bars250['close'], 250)

                # 上方无均线压制
                if (c0 > ma60[-1]) and (c0 > ma120[-1]) and (c0 > ma250[-1]):
                    logger.info("%s, %s, %s, %s, %s, %s", sec, round(a, 4),
                                round(b, 4), round(vx, 1),
                                round(c0 / c1 - 1, 3), round(y, 3))
                    await self.enter_stock_pool(code,
                                                fired,
                                                frame_type,
                                                a=a,
                                                b=b,
                                                err=err,
                                                y=y,
                                                vx=self.fit_win - vx)
            elif frame_type == FrameType.WEEK:
                await self.enter_stock_pool(code,
                                            fired,
                                            frame_type,
                                            a=a,
                                            b=b,
                                            err=err,
                                            y=y,
                                            vx=self.fit_win - vx)
            elif frame_type == FrameType.MIN30:
                await self.fire_trade_signal('long',
                                             code,
                                             fired,
                                             frame_type,
                                             a=a,
                                             b=b,
                                             err=err,
                                             y=y,
                                             vx=self.fit_win - vx)
Exemplo n.º 4
0
 async def test_something(self):
     end = arrow.get('2020-8-27 10:00:00').datetime
     async for code, bars in Security.load_bars_batch(['300589.XSHE'], end,
                                                      26, FrameType.DAY):
         print(code, bars[-1])