Пример #1
0
def collect_his_trading(stock_number, stock_name):
    if stock_number.startswith('6'):
        req_url = history_trading.format(stock_number+'01')
    else:
        req_url = history_trading.format(stock_number+'02')
    his_html = send_request(req_url)

    his_soup = BeautifulSoup(his_html, 'lxml')
    his_table = his_soup.find('table', id='tablefont')

    if his_table:
        his_data = his_table.find_all('tr')[1:]
        for i in his_data:
            date = datetime.datetime.strptime(i.find('p', class_='date').text, '%Y-%m-%d')
            today_opening_price = float(i.find_all('td')[1].text.replace('&nbsp', '').strip())
            today_highest_price = float(i.find_all('td')[2].text.replace('&nbsp', '').strip())
            today_lowest_price = float(i.find_all('td')[3].text.replace('&nbsp', '').strip())
            today_closing_price = float(i.find_all('td')[4].text.replace('&nbsp', '').strip())
            increase_rate = i.find_all('td')[5].text.replace('&nbsp', '').strip() + '%'
            increase_amount = float(i.find_all('td')[6].text.replace('&nbsp', '').strip())
            turnover_rate = i.find_all('td')[7].text.replace('&nbsp', '').strip() + '%'

            if float(increase_rate.replace('%', '')) == 0.0 and float(turnover_rate.replace('%', '')) == 0.0:
                # 去掉停牌期间的行情数据
                continue

            if not check_exists(stock_number, date):
                sdt = SDT(stock_number=stock_number, stock_name=stock_name, date=date,
                          today_opening_price=today_opening_price, today_highest_price=today_highest_price,
                          today_lowest_price=today_lowest_price, today_closing_price=today_closing_price,
                          increase_rate=increase_rate, increase_amount=increase_amount, turnover_rate=turnover_rate)
                sdt.save()
Пример #2
0
def quant_stock(stock_number, **kwargs):
    sdt_li = SDT.objects(Q(stock_number=stock_number) & Q(today_closing_price__ne=0.0) &
                         Q(date__lte=kwargs['date'])).order_by('date')
    stock_name = sdt_li[0].stock_name

    trading_data = []
    for s in sdt_li:
        trading_data.append({'date': s.date, 'price': s.today_closing_price, 'total_stock': s.total_stock})
    # trading_data = restore_right(trading_data)

    df = DataFrame(trading_data).set_index(['date'])
    df['short_ema'] = df['price'].ewm(span=kwargs['short_ema']).mean()
    df['long_ema'] = df['price'].ewm(span=kwargs['long_ema']).mean()
    df['dif'] = df['short_ema'] - df['long_ema']
    df['dea'] = df['dif'].ewm(span=kwargs['dif_ema']).mean()
    df['macd'] = df['dif'] - df['dea']

    today_macd = df.iloc[-1]
    yestoday_macd = df.iloc[-2]

    if today_macd['dif'] < 0 and today_macd['dea'] < 0 < today_macd['macd'] and yestoday_macd['macd'] < 0:
        strategy_direction = 'long'
        strategy_name = 'macd_long_%s_%s_%s' % (kwargs['short_ema'], kwargs['long_ema'], kwargs['dif_ema'])

        qr = QR(
            stock_number=stock_number, stock_name=stock_name, date=today_macd.name,
            strategy_direction=strategy_direction, strategy_name=strategy_name, init_price=today_macd['price']
        )

        if not check_duplicate(qr):
            qr.save()
Пример #3
0
def quant_stock(stock_number, short_ma_num, long_ma_num, qr_date, half_year=False):
    sdt = SDT.objects(Q(stock_number=stock_number) & Q(today_closing_price__ne=0.0) & Q(date__lte=qr_date)).order_by('-date')

    trading_data = list(sdt)
    if len(trading_data) < long_ma_num + 5 or len(trading_data) < short_ma_num + 5:
        """
        如果交易数据不够,跳过
        """
        return

    if half_year and sdt.count() >= 120:
        today_price = sdt[0].today_closing_price
        avg_price = sdt.limit(120).average('today_closing_price')
        if today_price < avg_price:
            return

    if short_ma_num <= long_ma_num:
        strategy_direction = 'long'
    else:
        strategy_direction = 'short'

    if half_year:
        strategy_name = 'ma_halfyear_%s_%s_%s' % (strategy_direction, short_ma_num, long_ma_num)
    else:
        strategy_name = 'ma_%s_%s_%s' % (strategy_direction, short_ma_num, long_ma_num)

    short_ma_list = calculate_ma_list(trading_data, short_ma_num, 2)
    long_ma_list = calculate_ma_list(trading_data, long_ma_num, 2)
    ma_difference = calculate_ma_difference(short_ma_list, long_ma_list)

    if ma_difference[0] > 0 > ma_difference[1]:
        """
        当短期均线向上穿过长期均线的时候
        """
        save_quant_result(trading_data[0], strategy_name, strategy_direction)
Пример #4
0
def strategy_statistics(strategy_name):
    all_qr = QR.objects(strategy_name=strategy_name)
    if not all_qr:
        print "Wrong Strategy Name!"
        return

    trading_date = SDT.objects(stock_number__startswith="300").distinct("date")
    trading_date.sort()
    bt_result = {}
    for d in trading_date:
        bt_result[str(d.date())] = back_test_success(strategy_name, d)

    frame = DataFrame(bt_result)
    pd.set_option("display.width", 200)
    pd.set_option("display.max_rows", 400)
    print frame.reindex(
        [
            "count",
            "one_back_test",
            "one_yield_expectation",
            "three_back_test",
            "three_yield_expectation",
            "five_back_test",
            "five_yield_expectation",
        ]
    ).T
    pd.set_option("display.width", None)
    pd.set_option("display.max_rows", None)
Пример #5
0
def quant_stock(stock_number, short_ma_num, long_ma_num, qr_date):
    if short_ma_num <= long_ma_num:
        strategy_direction = 'long'
        quant_count = long_ma_num + 5
    else:
        strategy_direction = 'short'
        quant_count = short_ma_num + 5
    strategy_name = 'ma_%s_%s_%s' % (strategy_direction, short_ma_num, long_ma_num)

    sdt = SDT.objects(Q(stock_number=stock_number) & Q(today_closing_price__ne=0.0) &
                      Q(date__lte=qr_date)).order_by('-date')[:quant_count]
    if len(sdt) < quant_count:
        # trading data not enough
        return

    trading_data = format_trading_data(sdt, qr_date)
    if not trading_data:
        return

    df = DataFrame(trading_data).set_index(['date'])
    df['short_ma'] = df['price'].rolling(window=short_ma_num, center=False).mean()
    df['long_ma'] = df['price'].rolling(window=long_ma_num, center=False).mean()
    df['diff'] = df['short_ma'] - df['long_ma']

    today_ma = df.iloc[-1]
    yestoday_ma = df.iloc[-2]

    if today_ma['diff'] > 0 > yestoday_ma['diff']:
        qr = QR(
            stock_number=stock_number, stock_name=today_ma['stock_name'], date=today_ma.name,
            strategy_direction=strategy_direction, strategy_name=strategy_name, init_price=today_ma['price']
        )

        if not check_duplicate(qr):
            qr.save()
Пример #6
0
def test_by_day(qr, day):
    if isinstance(qr, QR):
        sdt = SDT.objects(Q(stock_number=qr.stock_number) & Q(date__gt=qr.date)).order_by('date')

        if sdt.count() >= day:
            back_test_sdt = sdt[day-1]
            if back_test_sdt.today_closing_price == 0.0:
                # 去掉停牌的情况
                return

            qr[test_pattern[day]['price']] = back_test_sdt.today_closing_price
            price_spread = back_test_sdt.today_closing_price - qr.init_price

            if qr.strategy_direction == 'long':
                if price_spread >= 0:
                    qr[test_pattern[day]['test']] = True
                else:
                    qr[test_pattern[day]['test']] = False
            elif qr.strategy_direction == 'short':
                if price_spread > 0:
                    qr[test_pattern[day]['test']] = False
                else:
                    qr[test_pattern[day]['test']] = True

            qr.save()
def check_duplicate(sdt):
    """
    检查某一天的交易数据是否与之前一天完全相同,如果完全相同,则不会保存这些交易数据
    为了规避一些法定假日不交易的情况,还有股票停牌的时候,停牌中的数据是不记录的
    """
    if isinstance(sdt, SDT):
        trading_date = SDT.objects(stock_number=sdt.stock_number).order_by("-date")
        if trading_date:
            latest_sdt = trading_date[0]
            check_item = [
                "yesterday_closed_price",
                "today_opening_price",
                "today_closing_price",
                "today_highest_price",
                "today_lowest_price",
                "turnover_amount",
                "turnover_volume",
                "increase_amount",
                "increase_rate",
                "today_average_price",
                "quantity_relative_ratio",
                "turnover_rate",
            ]
            for i in check_item:
                if sdt[i] != latest_sdt[i]:
                    return False
            logging.warning("%s trading data is same with latest STD, this data will not be saved." % sdt.stock_number)
            return True
        else:
            return False
def collect_his_trading(stock_number, stock_name):
    if stock_number.startswith('6'):
        req_url = history_trading.format(stock_number+'01')
    else:
        req_url = history_trading.format(stock_number+'02')
    his_html = send_request(req_url)

    his_soup = BeautifulSoup(his_html, 'lxml')
    his_table = his_soup.find('table', id='tablefont')

    if his_table:
        his_data = his_table.find_all('tr')[1:]
        for i in his_data:
            date = datetime.datetime.strptime(i.find('p', class_='date').text.strip(), '%Y-%m-%d')
            try:
                today_opening_price = float(i.find_all('td')[1].text.replace('&nbsp', '').strip())
                today_highest_price = float(i.find_all('td')[2].text.replace('&nbsp', '').strip())
                today_lowest_price = float(i.find_all('td')[3].text.replace('&nbsp', '').strip())
                today_closing_price = float(i.find_all('td')[4].text.replace('&nbsp', '').strip())
                increase_rate = i.find_all('td')[5].text.replace('&nbsp', '').strip() + '%'
                increase_amount = float(i.find_all('td')[6].text.replace('&nbsp', '').strip())
                turnover_rate = i.find_all('td')[7].text.replace('&nbsp', '').strip() + '%'
                total_stock = int(i.find_all('td')[10].text.replace('&nbsp', '').replace(',', '').strip())
                circulation_stock = int(i.find_all('td')[12].text.replace('&nbsp', '').replace(',', '').strip())
            except Exception, e:
                if '--' not in str(e):
                    logging.error('Collect %s %s trading data failed:%s' % (stock_number, str(date), e))
                continue

            if float(increase_rate.replace('%', '')) == 0.0 and float(turnover_rate.replace('%', '')) == 0.0:
                # 去掉停牌期间的行情数据
                continue

            if check_exists(stock_number, date):
                sdt = SDT.objects(Q(stock_number=stock_number) & Q(date=date)).next()
                if not sdt.total_stock or not sdt.circulation_stock:
                    sdt.total_stock = total_stock
                    sdt.circulation_stock = circulation_stock
                    sdt.save()
            else:  # 添加股本相关数据
                sdt = SDT(stock_number=stock_number, stock_name=stock_name, date=date,
                          today_opening_price=today_opening_price, today_highest_price=today_highest_price,
                          today_lowest_price=today_lowest_price, today_closing_price=today_closing_price,
                          increase_rate=increase_rate, increase_amount=increase_amount, turnover_rate=turnover_rate,
                          total_stock=total_stock, circulation_stock=circulation_stock)
                sdt.save()
def collect_his_trading(stock_number, stock_name):
    if stock_number.startswith("6"):
        req_url = history_trading.format(stock_number + "01")
    else:
        req_url = history_trading.format(stock_number + "02")
    his_html = send_request(req_url)

    his_soup = BeautifulSoup(his_html, "lxml")
    his_table = his_soup.find("table", id="tablefont")

    if his_table:
        his_data = his_table.find_all("tr")[1:]
        for i in his_data:
            date = datetime.datetime.strptime(i.find("p", class_="date").text, "%Y-%m-%d")
            try:
                today_opening_price = float(i.find_all("td")[1].text.replace("&nbsp", "").strip())
                today_highest_price = float(i.find_all("td")[2].text.replace("&nbsp", "").strip())
                today_lowest_price = float(i.find_all("td")[3].text.replace("&nbsp", "").strip())
                today_closing_price = float(i.find_all("td")[4].text.replace("&nbsp", "").strip())
                increase_rate = i.find_all("td")[5].text.replace("&nbsp", "").strip() + "%"
                increase_amount = float(i.find_all("td")[6].text.replace("&nbsp", "").strip())
                turnover_rate = i.find_all("td")[7].text.replace("&nbsp", "").strip() + "%"
            except Exception, e:
                if "--" not in str(e):
                    logging.error("Collect %s %s trading data failed:%s" % (stock_number, str(date), e))
                continue

            if float(increase_rate.replace("%", "")) == 0.0 and float(turnover_rate.replace("%", "")) == 0.0:
                # 去掉停牌期间的行情数据
                continue

            if not check_exists(stock_number, date):
                sdt = SDT(
                    stock_number=stock_number,
                    stock_name=stock_name,
                    date=date,
                    today_opening_price=today_opening_price,
                    today_highest_price=today_highest_price,
                    today_lowest_price=today_lowest_price,
                    today_closing_price=today_closing_price,
                    increase_rate=increase_rate,
                    increase_amount=increase_amount,
                    turnover_rate=turnover_rate,
                )
                sdt.save()
Пример #10
0
def start_quant_analysis(short_ma_num, long_ma_num, qr_date, half_year=False):
    if not SDT.objects(date=qr_date).count():
        print 'Not a Trading Date'
        return

    try:
        all_stocks = StockInfo.objects()
    except Exception, e:
        logging.error('Error when query StockInfo:' + str(e))
        raise e
Пример #11
0
def quant_stock():
    today = datetime.date.today()
    increase_rate = '5%'
    quantity_relative_ratio = 2.5
    try:
        sdt = SDT.objects(Q(date=today) & Q(increase_rate__gte=increase_rate) &
                          Q(quantity_relative_ratio__gte=quantity_relative_ratio))
    except Exception, e:
        logging.error('Query DB failed:%s' % e)
        raise e
Пример #12
0
def cal_buffett_index():
    today = datetime.date.today()
    sdt = SDT.objects(date=today)
    if not sdt:
        return

    bi = BuffettIndex.objects(date=today)
    if bi:
        return

    save_data()
Пример #13
0
def save_index_data(idt):
    if isinstance(idt, IDT):
        today = datetime.date.today()
        sdt = SDT.objects(date=today)
        if not sdt:
            return

        exists_data = IDT.objects(Q(date=today) & Q(index_number=idt.index_number))
        if exists_data:
            return

        try:
            idt.save()
        except Exception, e:
            logging.error('Error when save market index data:' + str(e))
Пример #14
0
def quant_stock(stock_number, stock_name, **kwargs):
    sdt_li = SDT.objects(Q(stock_number=stock_number) & Q(today_closing_price__ne=0.0) &
                         Q(date__lte=kwargs['date'])).order_by('-date')[:ema_volume]
    if len(sdt_li) < 20:
        return

    trading_data = []
    qr_date = kwargs['date']
    standard_total_stock = sdt_li[0].total_stock
    if not standard_total_stock:
        standard_total_stock = sdt_li[1].total_stock
    if not standard_total_stock:
        standard_total_stock = sdt_li[2].total_stock
    if not standard_total_stock:
        return

    for s in sdt_li:
        total_stock = s.total_stock
        if total_stock and total_stock != standard_total_stock:
            today_closing_price = s.today_closing_price * float(total_stock) / float(standard_total_stock)
        else:
            today_closing_price = s.today_closing_price
        trading_data.append({'date': s.date, 'price': today_closing_price, 'total_stock': s.total_stock})
    trading_data.reverse()

    df = DataFrame(trading_data).set_index(['date'])
    df['short_ema'] = df['price'].ewm(span=kwargs['short_ema']).mean()
    df['long_ema'] = df['price'].ewm(span=kwargs['long_ema']).mean()
    df['dif'] = df['short_ema'] - df['long_ema']
    df['dea'] = df['dif'].ewm(span=kwargs['dif_ema']).mean()
    df['macd'] = df['dif'] - df['dea']

    today_macd = df.iloc[-1]
    yestoday_macd = df.iloc[-2]

    if yestoday_macd['macd'] < 0 < today_macd['macd']:
        strategy_direction = 'long'
        strategy_name = 'macd_long_%s_%s_%s' % (kwargs['short_ema'], kwargs['long_ema'], kwargs['dif_ema'])

        qr = QR(
            stock_number=stock_number, stock_name=stock_name, date=today_macd.name,
            strategy_direction=strategy_direction, strategy_name=strategy_name, init_price=today_macd['price']
        )

        if not check_duplicate(qr):
            qr.save()
def check_duplicate(sdt):
    """
    检查某一天的交易数据是否与之前一天完全相同,如果完全相同,则不会保存这些交易数据
    为了规避一些法定假日不交易的情况,还有股票停牌的时候,停牌中的数据是不记录的
    """
    if isinstance(sdt, SDT):
        trading_date = SDT.objects(stock_number=sdt.stock_number).order_by('-date')
        if trading_date:
            latest_sdt = trading_date[0]
            check_item = ['today_opening_price', 'today_closing_price', 'today_highest_price', 'today_lowest_price',
                          'increase_amount', 'increase_rate', 'quantity_relative_ratio', 'turnover_rate']
            for i in check_item:
                if sdt[i] != latest_sdt[i]:
                    return False
            logging.info('%s trading data is same with latest STD, this data will not be saved.' % sdt.stock_number)
            return True
        else:
            return False
Пример #16
0
def strategy_statistics(strategy_name):
    all_qr = QR.objects(strategy_name=strategy_name)
    if not all_qr:
        print 'Wrong Strategy Name!'
        return

    trading_date = SDT.objects(stock_number__startswith='300').distinct('date')
    trading_date.sort()
    bt_result = {}
    for d in trading_date:
        bt_result[str(d.date())] = back_test_success(strategy_name, d)

    frame = DataFrame(bt_result)
    pd.set_option('display.width', 200)
    pd.set_option('display.max_rows', 400)
    print frame.reindex(['count', 'one_back_test', 'one_yield_expectation', 'three_back_test', 'three_yield_expectation',
                         'five_back_test', 'five_yield_expectation']).T
    pd.set_option('display.width', None)
    pd.set_option('display.max_rows', None)
Пример #17
0
def quant_stock(stock_number, short_ma_num=1, long_ma_num=30):
    strategy_name = 'ma_long_%s_%s' % (short_ma_num, long_ma_num)
    sdt = SDT.objects(stock_number=stock_number).order_by('-date')[:long_ma_num + 10]

    if float(sdt[0].increase_rate.replace('%', '')) == 0.0 and float(sdt[0].turnover_rate.replace('%', '')) == 0.0:
        """
        如果最新一天股票的状态是停牌,跳过
        """
        return

    trading_data = []
    for i in sdt:
        """
        去除交易数据里的停牌数据
        """
        if float(i.increase_rate.replace('%', '')) == 0.0 and float(i.turnover_rate.replace('%', '')) == 0.0:
            continue
        else:
            trading_data.append(i)
    if len(trading_data) < long_ma_num + 5 or len(trading_data) < short_ma_num + 5:
        """
        如果交易数据不够,跳过
        """
        return

    if short_ma_num <= long_ma_num:
        strategy_direction = 'long'
        if float(sdt[0].increase_rate.replace('%', '')) < 0.0:
            return
    else:
        strategy_direction = 'short'
        if float(sdt[0].increase_rate.replace('%', '')) > 0.0:
            return

    short_ma_list = calculate_ma_list(trading_data, short_ma_num, 2)
    long_ma_list = calculate_ma_list(trading_data, long_ma_num, 2)
    ma_difference = calculate_ma_difference(short_ma_list, long_ma_list)

    if ma_difference[0] > 0 > ma_difference[1]:
        """
        当短期均线向上穿过长期均线的时候
        """
        save_quant_result(trading_data[0], strategy_name, strategy_direction)
Пример #18
0
def start_quant_analysis(**kwargs):
    if not SDT.objects(date=kwargs['date']):
        print 'Not a Trading Day'
        return

    stock_count = StockInfo.objects().count()
    skip = 0

    while skip < stock_count:
        try:
            stocks = StockInfo.objects().skip(skip).limit(step)
        except Exception, e:
            logging.error('Error when query StockInfo:' + str(e))
            stocks = []

        for s in stocks:
            if s.account_firm and u'瑞华会计师' in s.account_firm:
                # 过滤瑞华的客户
                continue

            try:
                quant_stock(s.stock_number, s.stock_name, **kwargs)
            except Exception, e:
                logging.error('Error when macd quant %s:%s' % (s.stock_number, e))
Пример #19
0
def check_exists(stock_number, date):
    cursor = SDT.objects(Q(stock_number=stock_number) & Q(date=date))
    if cursor:
        return True
    else:
        return False
Пример #20
0
def persist_increase(stock_number):
    try:
        trading_data = SDT.objects(stock_number=stock_number).order_by('-date')[:3]
    except Exception, e:
        logging.error('Query %s SDT failed:%s' % (stock_number, e))
def collect_stock_daily_trading():
    """
    获取并保存每日股票交易数据
    """
    url = eastmoney_stock_api
    data = request_and_handle_data(url)

    stock_data = data["rank"]
    for i in stock_data:
        stock = i.split(",")
        stock_number = stock[1]
        stock_name = stock[2]
        sdt = SDT(stock_number=stock_number, stock_name=stock_name)
        sdt.yesterday_closed_price = float(stock[3])
        sdt.today_opening_price = float(stock[4])
        sdt.today_closing_price = float(stock[5])
        sdt.today_highest_price = float(stock[6])
        sdt.today_lowest_price = float(stock[7])
        sdt.turnover_amount = int(stock[8])
        sdt.turnover_volume = int(stock[9])
        sdt.increase_amount = float(stock[10])
        sdt.increase_rate = stock[11]
        sdt.today_average_price = float(stock[12])
        sdt.quantity_relative_ratio = float(stock[22])
        sdt.turnover_rate = stock[23]

        if not check_duplicate(sdt):
            sdt.save()
Пример #22
0
def query_latest_trading(stock_number):
    sdt = SDT.objects(stock_number=stock_number).order_by('-date')[0]
    return sdt
Пример #23
0
    skip = 0

    notice_data = []
    while skip < stocks_count:
        try:
            stocks = StockInfo.objects().skip(skip).limit(query_step)
        except Exception, e:
            logging.error('Error when query skip %s  StockInfo:%s' % (skip, e))
            stocks = []

        for i in stocks:
            if i.account_firm and u'瑞华会计师' in i.account_firm:
                # 过滤瑞华的客户
                continue

            sdt = SDT.objects(Q(stock_number=i.stock_number) & Q(date=datetime.date.today()))
            if not sdt:
                # 过滤仍在停牌的票
                continue

            try:
                notice = collect_event_notice(i.stock_number)
            except Exception, e:
                logging.error('Error when collect %s notice: %s' % (i.stock_number, e))
            if notice:
                notice_data += notice
        skip += query_step

    if not notice_data:
        return
    df = DataFrame(notice_data).sort_values(by=['stock_number', 'date'], ascending=[True, True])\