mhy的量化笔记 之 老鼠仓识别

最近看到一个股市中非常有趣的趋势——老鼠仓

大概的原理可自行百度,而这只股票每隔10天左右会有一个约9%的下影线,换句话说,如果提前在当日开盘价-9%位置埋单,并且成交,就能在隔日获得几乎一个涨停的收益!

于是现在希望写一个脚本找出所有可能形成老鼠仓的股票——

满足老鼠仓的K线图满足如下要求:

  • 单日涨跌幅小于2%
  • 单日最低价大于-8%
  • 从跌2%到接近最低价所用时间小于5分钟
  • 整体平均值跌幅小于3%

在代码编写中,发现一个问题,即可能在分时图上股价并没有太大的变化,但在日K线中有一个很长的下影线,这是由于一单非理性限价单成交导致的。这也对于K线实际的意义产生了质疑。任意一个挂单都可以使K线产生巨大的形态变化,这应该能够成为操作市场的一个方式(如果我没有理解错的话)

代码

import tushare as ts
import time
import numpy as np
import logging
'''
通过识别“老鼠仓”实现的套利策略
'''

def check_rat(stock,date,end_day):
    logger = logging.getLogger(__name__)
    logger.info("Check Pit <%s,%s,%s>..."%(stock,date,end_day))
    if end_day:
        summary = get_hist_data_sp(stock,date)
        #summary = ts.get_hist_data(stock,date,date)
        if len(summary['low']) != 1:
            logger.warning("Error occur at <%s>"%stock)
            return False
        if (float(summary['low'][0])/float(summary['open'][0]) > 0.92):
            return False
        logger.debug("Big Hole...checked")
        if (abs(1.0-float(summary['open'][0])/float(summary['close'][0])) > .2):
            return False
        if (float(summary['high'][0])/float(summary['open']) > 1.2):
            return False
        logger.debug("Slightly fluctuating...checked")
        rt = get_tick_data(stock,date = date)
        rt = rt[['time','price','change']]
        low_value = np.min(rt['price'])
        if (low_value/float(summary['open'][0]) > 0.92):
            return False
        #rt.to_csv('save.csv',sep='\t')

        lower_bound = float(low_value) * 1.01
        upper_bound = float(summary['open'][0]) * 0.985
        pos_x = rt['time'].size-1
        pos_y = -1
        for i in range(rt['time'].size-1,-1,-1):
            if (rt['price'][i] > upper_bound):
                pos_x = i
            if (rt['price'][i] < lower_bound):
                pos_y = i
                break
        time_x = time.strptime('2000 '+rt['time'][pos_x],'%Y %H:%M:%S')
        time_y = time.strptime('2000 '+rt['time'][pos_y],'%Y %H:%M:%S')
        time_x = time.mktime(time_x)
        time_y = time.mktime(time_y)
        delta = time_y-time_x
        if (delta > 5 * 60):
            return False
        logger.debug("Fast down...checked")
        return True


def build_list():
    logger = logging.getLogger(__name__)
    info = ts.get_stock_basics()
    stocks = info.index
    for stock in stocks:
        realtime = ts.get_realtime_quotes(stock)
        logger.info("Begin Stock <%s>"%stock)
        check_result = True
        if (float(realtime['low']) < float(realtime['open'])*0.92):
            check_result = True
        if (check_result):
            recent =ts.get_k_data(stock)
            check_range = 80
            if (recent.size < 100):
                continue
            recentId = recent.index[-check_range:]
            for w in recentId:
                count = 0
                check_h_result = check_rat(stock,end_day = True, date = recent['date'][w])
                if (check_h_result):
                    logger.warning("Pit found <%s,%s>"%(stock,recent['date'][w]))
                    count += 1
            if (count > 2):
                logger.error("Pit Stock Found <%s,%s/%s>"%(stock,count,check_range))

效果:高频率的老鼠仓只存在于002072一支股票,也让我非常失望。

对于该算法的拓展,我又尝试获得所有影线较长,但是开盘收盘价相差较小的股票,最后发现识别出的股票本身都是在强烈的震荡情况,也就是说无法判断一个大幅下跌属于影线还是正常的大跌,也就没有太强的实用价值。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据