量化分析之倍量處理(一)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @license : (C) Copyright 2017-2020.
# @contact : [email protected]
# @Time    : 2020/5/19 14:57
# @File    : lesson1.py
# @Software: PyCharm
# @desc    :

import os
import pandas as pd
import tushare as ts
import progressbar as pb

class gpc_volume():
    def __init__(self):
        self._vol_data = pd.DataFrame()
        self._vol_file = './volume.csv'
        self._amount_filter = True
        self._vol_mean_filter = True

    def gpc_calc_volume_ratio(self, k_data,
                              code_serial,
                              is_amount_filter=False,
                              is_mean=True,
                              threshold=5,
                              is_logger=True
                              ):

        volume = pd.Series(k_data.volume)
        v_ma_x = 'v_ma' + str(threshold)
        k_data[v_ma_x] = volume.rolling(threshold).mean()
        last_top = k_data.iloc[-1]
        open = last_top['open']
        close = last_top['close']
        vol = last_top['volume']

        # 收盤價
        if 'p_change' in last_top:
            change = last_top['p_change']
        else:
            _pre_close = k_data.iloc[-2]['close']
            change = round((close - _pre_close) * 100 / _pre_close, 4)

        # 漲幅2%,需紅盤
        if change < 2 or close < open:
            return False

        if is_amount_filter:
            amount = close * vol * 100
            if amount < 200000000:
                return False

        if is_mean:
            '''5日平均量能'''
            vol_ma_x = round(last_top[v_ma_x], 4)
            vol_rat = round(vol / vol_ma_x, 4)
        else:
            '''僅比較與前一交易日'''
            vol_sec = k_data.iloc[-2]['volume']
            vol_rat = round(vol / vol_sec, 4)

        # 倍量
        is_double_volume = (vol_rat >= 2)

        if is_double_volume:
            if is_logger:
                print(
                    f'\n{code_serial["code"]} {code_serial["name"]:8} volume ratio {vol_rat:.2f}, change {change:.2f}')

        return is_double_volume, vol_rat  # , vol_rat_sec

    def volume_filter(self, all_code, threshold=5):
        print('volume filter')
        ma_x = 'ma' + str(threshold)
        is_ma_x = 'is_' + ma_x
        all_code[ma_x] = 0
        all_code[is_ma_x] = False
        index, max_num = 0, len(all_code)
        with pb.ProgressBar(max_value=max_num) as bar:
            for idx in all_code.index:
                try:
                    code = all_code.loc[idx, 'code']
                    k_data = ts.get_k_data(code)
                    if k_data is None: continue
                    if len(k_data.index) > 60:
                        all_code.loc[idx, [is_ma_x, ma_x]] = \
                            self.gpc_calc_volume_ratio(k_data,
                                                       all_code.loc[idx],
                                                       is_amount_filter=self._amount_filter,
                                                       is_mean=self._vol_mean_filter,
                                                       threshold=threshold)
                except Exception as e:
                    print(e)
                bar.update(index)
                index += 1
        self._vol_data = all_code[all_code[is_ma_x]]
        if len(self._vol_data):
            self._vol_data.to_csv(self._vol_file, encoding='utf_8_sig')
            return self._vol_data

    def filter_result(self, data):
        print(f'start parse volume, code number = {len(data)}')
        if os.path.exists(self._vol_file):
            self._vol_data = pd.read_csv(self._vol_file, encoding='utf_8_sig', index_col=0, dtype=object)
        else:
            self._vol_data = self.volume_filter(data)
        print(f'double volume, code number = {len(self._vol_data)}')
        return self._vol_data


if __name__ == '__main__':
    gv = gpc_volume()
    
    # 可使用ts.get_today_all() 獲取股票列表,本處使用存儲本地的
    path = r'stocks.csv'
    df = pd.read_csv(path, encoding='utf_8_sig', index_col=0, dtype=object)
    gv.filter_result(df)

測試結果:

....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章