Exemplo n.º 1
0
    def __init__(self):
        QMainWindow.__init__(self)

        # Application Configuration
        # UI
        self.setupUi(self)

        # Font(ko)
        self.set_ko_font()

        # Logger
        self.logger = TTlog(logger_name="TTRealCondi").logger

        # DB
        self.dbm = DBM('TopTrader')

        # Slack
        self.slack = Slacker(config_manager.get_slack_token())

        # Kiwoom
        self.kw = Kiwoom()
        self.login()
        self.stock_info = self.kw.get_stock_basic_info()

        # app main
        self.main()
Exemplo n.º 2
0
 def __init__(self):
     super().__init__()
     # self.setupUi(self)  # load app screen
     self.logger = TTlog().logger
     self.dbm = DBM('TopTrader')
     self.mongo = MongoClient()
     self.db = self.mongo.TopTrader
     self.slack = Slack(config_manager.get_slack_token())
     self.kw = Kiwoom()
     self.login()
     self.main()
Exemplo n.º 3
0
 def __init__(self, strg_name, condi_index, condi_name):
     self.strategy_name = strg_name  # 사용한 전략명
     self.condi_name = condi_index  # buy signal을 제공한 조건검색식(buy에서만 사용)
     self.condi_index = condi_name  # buy signal을 제공한 조건검색식 index (buy에서만 사용)
     self.history = []
     self.dbm = DBM('TopTrader')
     self.logger = TTlog().logger
Exemplo n.º 4
0
    def __init__(self):
        QMainWindow.__init__(self)

        # Application Configuration
        # UI
        self.setupUi(self)

        # Font(ko)
        self.set_ko_font()

        # Logger
        self.logger = TTlog(logger_name="TTRealCondi").logger

        # DB
        self.mongo = MongoClient()
        self.db = self.mongo.TopTrader
        self.dbm = DBM('TopTrader')

        # Slack
        self.slack = Slack(cfg_mgr.get_slack_token())

        # Kiwoom
        self.kw = Kiwoom()
        self.login()
        cfg_mgr.STOCK_INFO = self.kw.get_stock_basic_info()

        # app main
        cfg_mgr.MODE = constant.DEBUG
        self.main()
Exemplo n.º 5
0
    def __init__(self, init_balance, th):

        self.시작잔고 = init_balance
        self.예수금 = init_balance
        self.총평가금액 = 0.0
        self.총매입금액 = 0.0
        self.총최대매입금액 = 0.0
        self.총평가손익 = 0.0
        self.총손익 = 0.0  # 총평가손익 + 총누적손익
        self.추정자산 = init_balance
        self.총수익률 = 0.0
        self.총누적손익 = 0.0
        self.총누적수익률 = 0.0
        self.보유주식 = {}
        self.core_index = ['시작잔고', '예수금', '총평가금액', '총최대매입금액', '총매입금액', '총평가손익', '총손익',
                           '추정자산', '총수익률', '총누적손익', '총누적수익률']

        self.core_index = ['총누적손익', '총누적수익률', '총손익', '총수익률', '총평가손익', '총평가금액', '총매입금액',
                           '추정자산', '총최대매입금액', '예수금', '시작잔고']

        self.check_core_index()

        self.dbm = DBM('TopTrader')
        self.timestamp = None
        self.trading_history = th
        self.logger = TTlog().logger
Exemplo n.º 6
0
    def __init__(self, code):
        self.empty = True
        self.first_trading = True  # 첫 거래인지
        self.timestamp = None
        self.first_buy_time = None

        # if add/delete index, must update self.core_index
        self.timestamp = None
        self.code = code
        self.stock_name = cfg_mgr.STOCK_INFO[code]['stock_name']
        self.현재가 = 0
        self.매매수량 = 0
        self.보유수량 = 0
        self.매매금액 = 0
        self.매입금액 = 0
        self.최대매입금액 = 0
        self.매입평균가 = 0.0
        self.평가손익 = 0.0
        self.실현손익 = 0
        self.누적손익 = 0
        self.평가금액 = 0.0
        self.수익률 = 0.0
        self.누적수익률 = 0.0
        self.평가금액변동 = 0.0
        self.매입금액변동 = 0.0
        self.실현손익변동 = 0.0
        self.core_index = [
            'timestamp', 'code', 'stock_name', '현재가', '매매수량', '보유수량', '매매금액',
            '매입금액', '최대매입금액', '매입평균가', '평가손익', '실현손익', '누적손익', '평가금액', '수익률',
            '누적수익률', '평가금액변동', '매입금액변동', '실현손익변동'
        ]
        self.check_core_index()

        self.time_series_sec1 = None
        self.logger = TTlog().logger
        self.dbm = DBM('TopTrader')
Exemplo n.º 7
0
class TopTrader(QMainWindow, ui):
    def __init__(self):
        super().__init__()
        self.logger = TTlog().logger
        self.slack = Slack(config_manager.get_slack_token())
        self.dbm = DBM('TopTrader')
        self.main()

    def complete_tick_data(self, date):
        return self.dbm.get_collect_tick_data_status(date, tick="1") == "END"

    def main(self):
        date = datetime(2018, 8, 2)
        with open("base_date_when_collect_tick_data.txt", "w") as f:
            f.write("{} {} {}\n".format(date.year, date.month, date.day))

        while not self.complete_tick_data(date):
            os.system("python collect_1tick_data_real_condi_search.py")
Exemplo n.º 8
0
class TopTrader(QMainWindow, ui):
    def __init__(self):
        QMainWindow.__init__(self)

        # Application Configuration
        # UI
        self.setupUi(self)

        # Font(ko)
        self.set_ko_font()

        # Logger
        self.logger = TTlog(logger_name="TTRealCondi").logger

        # DB
        self.dbm = DBM('TopTrader')

        # Slack
        self.slack = Slacker(config_manager.get_slack_token())

        # Kiwoom
        self.kw = Kiwoom()
        self.login()
        self.stock_info = self.kw.get_stock_basic_info()

        # app main
        self.main()

    def login(self):
        err_code = self.kw.login()
        if err_code != 0:
            self.logger.error("Login Fail")
            exit(-1)
        self.logger.info("Login success")

    def set_ko_font(self):
        # 그래프에서 마이너스 폰트 깨지는 문제에 대한 대처
        mpl.rcParams['axes.unicode_minus'] = False

        path = 'c:/Windows/Fonts/D2Coding-Ver1.3-20171129.ttc'
        font_name = fm.FontProperties(fname=path).get_name()
        plt.rcParams["font.family"] = font_name

    def main(self):
        print("Start Application")
        target_date = datetime(2018, 8, 2)
        y, m, d = target_date.year, target_date.month, target_date.day
        s_time = datetime(y, m, d, 9, 0, 0)
        e_time = datetime(y, m, d, 15, 30, 0)
        self.code = '000020'
        df = pd.DataFrame(
            self.dbm.get_tick_data(self.code, target_date, tick="1"))
        ts_group = df.groupby('timestamp')
        volumn = pd.DataFrame(ts_group.sum()['거래량'])
        price = pd.DataFrame(ts_group.max()['현재가'])
        index = pd.date_range(s_time, e_time, freq='S')
        volumn = volumn.reindex(index, method='ffill', fill_value=0)
        price = price.reindex(index, method='ffill', fill_value=0)
        price['volumn'] = volumn

        from trading.account import Stock

        tick_data = defaultdict(list)
        stock_list = [
            Stock('900100', '주식1'),
            Stock('200710', '주식2'),
            Stock('206560', '주식3')
        ]
        for stock in stock_list:
            stock.gen_time_series_sec1(target_date)
            tick_data[stock.code] = stock.time_series_sec1
        pdb.set_trace()

        db_data = self.dbm.get_real_condi_search_data(target_date,
                                                      "소형주_급등_005_003")

        condi_hist = defaultdict(defaultdict)
        for data in db_data[:5]:
            code, date = data['code'], data['date'].replace(microsecond=0)
            price = tick_data[code].ix[date]['현재가']
            condi_hist[code][date] = price

        pdb.set_trace()
        print("End Application")
Exemplo n.º 9
0
 def __init__(self, condi_index, condi_name):
     self.condi_index = condi_index
     self.condi_name = condi_name
     self.dbm = DBM('TopTrader')
     self.disable_code_list = []
Exemplo n.º 10
0
class ConditionalSearch(object):
    _inst = {}

    def __init__(self, condi_index, condi_name):
        self.condi_index = condi_index
        self.condi_name = condi_name
        self.dbm = DBM('TopTrader')
        self.disable_code_list = []

    @classmethod
    def get_instance(cls, condi_index, condi_name):
        if condi_index not in cls._inst:
            cls._inst[condi_index] = ConditionalSearch(condi_index, condi_name)
        return cls._inst[condi_index]

    def set_disable_code_list(self, code_list):
        self.disable_code_list = code_list

    def detected_code_list(self, date):
        """특정일에 조건검색식으로부터 검출된 모든 code list 를 반환

        :param data:
        :return:
        """
        db_data = self.dbm.get_real_condi_search_data(date, self.condi_name)
        code_list = list(set([data['code'] for data in db_data]))
        if bool(self.disable_code_list):
            code_list = list(set(code_list) - set(self.disable_code_list))
        code_list.sort()

        return code_list

    def get_stock_list(self, date):
        """특정일에 조건검색식으로부터 검출된 모든 stock list 를 반환

        :param date:
        :return:
        """
        code_list = self.detected_code_list(date)
        stock_list = [
            Stock.get_instance(code) for code in code_list
            if code not in self.disable_code_list
        ]
        return stock_list

    def get_stock_list_at_timestamp(self, timestamp):
        """특정시간(timestamp)에 조건검색식으로부터 검출된 stock list를 반환

        :param timestamp:
        :return:
        """
        ret = []
        for code, time_series in self.condi_hist.items():
            if code in self.disable_code_list:
                continue
            if timestamp in time_series:
                ret.append(Stock.get_instance(code))
        return ret

    def gen_condi_history(self, target_date):
        """조건검색식으로 부터 검색된 종목의 time series 정보를 생성
            {
              code1: {t1: {현재가: xx, 거래량: xx}, t1: {현재가: xx, 거래량: xx}, .., t1: {현재가: xx, 거래량: xx}},
              code2: {t1: {현재가: xx, 거래량: xx}, t1: {현재가: xx, 거래량: xx}, .., t1: {현재가: xx, 거래량: xx}}
            }
        :param target_date:
        :param condi_index:
        :return:
        """
        db_data = self.dbm.get_real_condi_search_data(target_date,
                                                      self.condi_name)
        self.condi_hist = defaultdict(list)
        for data in db_data:
            if data['code'] in self.disable_code_list:
                continue
            code, timestamp = data['code'], data['date'].replace(microsecond=0)
            self.condi_hist[code].append(timestamp)
        return self.condi_hist
Exemplo n.º 11
0
class TopTrader(QMainWindow, ui):
    def __init__(self):
        super().__init__()
        # self.setupUi(self)  # load app screen
        self.logger = TTlog().logger
        self.dbm = DBM('TopTrader')
        self.mongo = MongoClient()
        self.db = self.mongo.TopTrader
        self.slack = Slack(config_manager.get_slack_token())
        self.kw = Kiwoom()
        self.login()
        self.main()

    def load_tick_data(self,
                       code,
                       stock_name,
                       date,
                       tick="1",
                       screen_no="1234"):
        """특정 종목의 하루단위 tick data를 가져오는 함수
        tick_data가 DB에 있으면 DB에서 가져오고, 없으면 kw module로부터 가져온다.

        :param code:
        :param stock_name:
        :param date:
        :param tick:
        :param screen_no:
        :return:
        """
        ret, cur = self.dbm.check_tick_cache(code, date, tick="1")

        if ret:
            tick_data = cur.next()
        else:
            base_date = datetime(date.year, date.month, date.day, 0, 0, 0)
            raw_data = self.kw.stock_price_by_tick(code,
                                                   tick=tick,
                                                   screen_no=screen_no,
                                                   date=base_date)
            tick_data = {
                'code':
                code,
                'stock_name':
                stock_name,
                'date':
                base_date,
                'time_series_1tick': [{
                    'timestamp': _d['date'],
                    '현재가': _d['현재가'],
                    '거래량': _d['거래량']
                } for _d in raw_data]
            }
        return tick_data

    def collect_tick_data(self,
                          code,
                          stock_name,
                          s_date,
                          e_date,
                          tick="1",
                          screen_no="1234"):
        """특정 종목의 일정 기간의 tick data를 DB에 저장하는 함수
        DB에 이미 값이 저장되어 있으면 저장하지 않고 skip 한다.
        s_date, e_date는 초단위까지 지정이 가능하지만, 저장은 일단위로 저장한다.
        tick은 1, 3, 5, 10, 30 선택 가능하다.

        :param code:
        :param stock_name:
        :param tick:
        :param s_date:
        :param e_date:
        :return:
        """
        s_base_date = datetime(s_date.year, s_date.month, s_date.day, 0, 0, 0)
        e_base_date = datetime(e_date.year, e_date.month, e_date.day, 0, 0, 0)
        days = (e_base_date - s_base_date).days + 1
        date_list = [s_base_date + timedelta(days=x) for x in range(0, days)]
        for base_date in date_list:
            ret, cur = self.dbm.check_tick_cache(code, base_date, tick="1")
            if ret:
                self.logger.debug(
                    "No need to save data. already has data in DB")
                continue

            raw_data = self.kw.stock_price_by_tick(code,
                                                   tick=tick,
                                                   screen_no=screen_no,
                                                   date=base_date)
            tick_data = {
                'code':
                code,
                'stock_name':
                stock_name,
                'date':
                base_date,
                'time_series_1tick': [{
                    'timestamp': _d['date'],
                    '현재가': _d['현재가'],
                    '거래량': _d['거래량']
                } for _d in raw_data]
                # 'time_series': [{'timestamp': _d['date'], '현재가': _d['현재가'], '거래량': _d['거래량']} for _d in raw_data]
            }
            # DB에 없으면 수행되는 부분이라서 insert 함수를 사용.
            self.dbm.save_tick_data(tick_data, tick="1")

    def main(self):
        # 사용자 정의 부분_S
        # 8/2일자 조건검색식으로 검출된 모든 종목의 1tick data를 수집한다.
        with open("base_date_when_collect_tick_data.txt") as f:
            year, month, day = [int(i) for i in f.read().strip().split(" ")]
        self.base_date = datetime(year, month, day)
        # 사용자 정의 부분_E

        # kospi, kosdaq 모든 종목의 코드와 종목명 정보를 불러온다.
        self.stock_info = self.kw.get_stock_basic_info()

        code_list = self.dbm.get_code_list_condi_search_result(self.base_date)
        code_list.sort()
        self.dbm.record_collect_tick_data_status("START",
                                                 self.base_date,
                                                 tick="1")
        for num, code in enumerate(code_list, 1):
            stock_name = self.stock_info[code]["stock_name"]
            if self.dbm.already_collect_tick_data(code,
                                                  self.base_date,
                                                  tick="1"):
                self.logger.debug(
                    "{}/{} - {}:{} Skip. Already saved data!".format(
                        num, len(code_list), code, stock_name))
                continue

            self.logger.debug("{}/{} - {}:{} Start !".format(
                num, len(code_list), code, stock_name))
            self.collect_tick_data(code,
                                   stock_name,
                                   self.base_date,
                                   self.base_date,
                                   tick="1",
                                   screen_no="1234")
            self.logger.debug("{}/{} - {}:{} Completed !".format(
                num, len(code_list), code, stock_name))

            self.dbm.save_collect_tick_data_history(code,
                                                    self.base_date,
                                                    tick="1")
            self.dbm.record_collect_tick_data_status("WORKING",
                                                     self.base_date,
                                                     tick="1")

        self.dbm.record_collect_tick_data_status("END",
                                                 self.base_date,
                                                 tick="1")
        self.logger.debug("save all 1tick information..")
        exit(0)  # program exit

    def login(self):
        err_code = self.kw.login()
        if err_code != 0:
            self.logger.error("Login Fail")
            exit(-1)
        self.logger.info("Login success")
Exemplo n.º 12
0
 def __init__(self):
     super().__init__()
     self.logger = TTlog().logger
     self.slack = Slack(config_manager.get_slack_token())
     self.dbm = DBM('TopTrader')
     self.main()
Exemplo n.º 13
0
class Stock(object):
    """code당 1개의 객체(singleton/code)를 생성한다.

    """
    _inst = {}

    def __init__(self, code):
        self.empty = True
        self.first_trading = True  # 첫 거래인지
        self.timestamp = None
        self.first_buy_time = None

        # if add/delete index, must update self.core_index
        self.timestamp = None
        self.code = code
        self.stock_name = cfg_mgr.STOCK_INFO[code]['stock_name']
        self.현재가 = 0
        self.매매수량 = 0
        self.보유수량 = 0
        self.매매금액 = 0
        self.매입금액 = 0
        self.최대매입금액 = 0
        self.매입평균가 = 0.0
        self.평가손익 = 0.0
        self.실현손익 = 0
        self.누적손익 = 0
        self.평가금액 = 0.0
        self.수익률 = 0.0
        self.누적수익률 = 0.0
        self.평가금액변동 = 0.0
        self.매입금액변동 = 0.0
        self.실현손익변동 = 0.0
        self.core_index = [
            'timestamp', 'code', 'stock_name', '현재가', '매매수량', '보유수량', '매매금액',
            '매입금액', '최대매입금액', '매입평균가', '평가손익', '실현손익', '누적손익', '평가금액', '수익률',
            '누적수익률', '평가금액변동', '매입금액변동', '실현손익변동'
        ]
        self.check_core_index()

        self.time_series_sec1 = None
        self.logger = TTlog().logger
        self.dbm = DBM('TopTrader')

    def print_attr(self, trading_type, attr_list=None):
        if not cfg_mgr.STOCK_MONITOR:
            return
        self.logger.debug("\n" + ("-" * 100))
        self.logger.debug("[Stock] Information : {}/{}".format(
            self.stock_name, self.code))
        self.logger.debug("[Trading Type] -> {}-{}".format(
            trading_type, self.trading_reason))
        if bool(attr_list):
            attr_val = []
            for attr in attr_list:
                val = self.__getattribute__(attr)
                log_str = "{}: {}".format(attr, val)
                if isinstance(val, float):
                    log_str = "{}: {:.2f}".format(attr, val)
                attr_val.append(log_str)
            self.logger.debug("\t".join(attr_val))
        else:
            self.logger.debug(self.__repr__())
        # pass

    def __repr__(self):
        core_index = self.core_index

        # log = ["{}: {}".format(attr, str(self.__getattribute__(attr))) for attr in core_index]
        log = []
        for attr in core_index:
            val = self.__getattribute__(attr)
            log_str = "{}: {}".format(attr, val)
            if isinstance(val, float):
                log_str = "{}: {:.2f}".format(attr, val)
            log.append(log_str)
        return "\t".join(log)

    @classmethod
    def get_instance(cls, code):
        if code not in cls._inst:
            cls._inst[code] = Stock(code)
        return cls._inst[code]

    @classmethod
    def get_new_instance(cls, code, recycle_time_series=False):
        if code in cls._inst and recycle_time_series:
            time_series_sec1 = cls._inst[code].time_series_sec1
            cls._inst[code] = Stock(code)
            cls._inst[code].time_series_sec1 = time_series_sec1
        else:
            cls._inst[code] = Stock(code)
        return cls._inst[code]

    def get_holding_period(self, timestamp=None):
        """최초 해당 주식을 보유한 시간으로부터 경과된 시간을 반환한다.

        :return:
        """
        if not bool(timestamp):
            timestamp = self.timestamp

        if not bool(self.first_buy_time) or timestamp <= self.first_buy_time:
            return timedelta(seconds=0)
        return timestamp - self.first_buy_time

    def bep(self, event, price, amount=None):
        """Backup/Evaluate/PostAction

            prev : 기존 데이터
        :return:
        """
        # Backup
        self.backup()

        # dispatch Evaluate function
        eval_fn = self.__getattribute__("evaluate_{}".format(event))
        eval_fn(**{'price': price, 'amount': amount})

        # dispatch Post function
        post_fn = self.__getattribute__("post_{}".format(event))
        post_fn(**{'price': price, 'amount': amount})

        # Update

    def backup(self):
        """중요 지표들을 모두 백업한다.
        백업 지표는 앞에 '기존' 키워드가 붙는다.

        :return:
        """
        core_index = [
            '현재가', '매매수량', '보유수량', '매매금액', '매입금액', '최대매입금액', '매입평균가', '평가손익',
            '실현손익', '누적손익', '평가금액', '수익률', '누적수익률'
        ]

        for index in core_index:
            val = self.__getattribute__(index)
            self.__setattr__('기존' + index, val)

    def evaluate_buy(self, **kwargs):
        price, amount = kwargs['price'], kwargs['amount']
        self.현재가 = price
        self.매매수량 = amount
        self.보유수량 = self.기존보유수량 + self.매매수량
        self.매매금액 = self.현재가 * self.매매수량
        self.매입금액 = self.기존매입금액 + self.매매금액
        self.매입금액변동 = self.매입금액 - self.기존매입금액
        self.최대매입금액 = max(self.최대매입금액, self.매입금액)
        self.매입평균가 = self.매입금액 / self.보유수량
        self.평가손익 = (self.현재가 - self.매입평균가) * self.보유수량
        # self.실현손익 = self.실현손익
        self.실현손익변동 = 0
        # self.누적손익 = self.누적손익
        self.평가금액 = self.현재가 * self.보유수량
        if self.보유수량 == 0:
            self.수익률 = 0.0
        else:
            self.수익률 = round((self.평가금액 - self.매입금액) / self.매입금액 * 100, 2)
        self.누적수익률 = round(float(self.누적손익) / self.최대매입금액 * 100, 2)
        self.평가금액변동 = self.평가금액 - self.기존평가금액

        if self.first_trading:
            self.first_buy_time = self.timestamp
        self.first_trading = False

    def post_buy(self, **kwargs):
        price, amount = kwargs['price'], kwargs['amount']
        core_index = [
            'timestamp', '현재가', '매입평균가', '수익률', '누적수익률', '누적손익', '매매수량',
            '보유수량', '매입금액', '최대매입금액', '평가손익', '실현손익', '평가금액', '매매금액'
        ]
        self.print_attr('BUY', core_index)
        # pdb.set_trace()

    def evaluate_sell(self, **kwargs):
        price, amount = kwargs['price'], kwargs['amount']
        self.현재가 = price
        self.매매수량 = amount
        self.보유수량 = self.기존보유수량 - self.매매수량
        self.매매금액 = self.현재가 * self.매매수량
        self.매입금액 = self.기존매입평균가 * self.보유수량
        self.매입금액변동 = self.매입금액 - self.기존매입금액
        self.최대매입금액 = max(self.최대매입금액, self.매입금액)
        # self.매입평균가 = self.매입평균가
        self.평가손익 = (self.현재가 - self.매입평균가) * self.보유수량
        self.실현손익 = (self.현재가 - self.매입평균가) * self.매매수량
        self.실현손익변동 = self.실현손익 - self.기존실현손익
        self.누적손익 += self.실현손익
        self.평가금액 = self.현재가 * self.보유수량
        # self.기존수익률 = round((self.기존평가금액 - self.기존매입금액) / self.기존매입금액 * 100, 2)
        if self.보유수량 == 0:
            self.수익률 = 0.0
        else:
            self.수익률 = round((self.평가금액 - self.매입금액) / self.매입금액 * 100, 2)
        self.누적수익률 = round(float(self.누적손익) / self.최대매입금액 * 100, 2)
        self.평가금액변동 = self.평가금액 - self.기존평가금액

        if self.보유수량 == 0:
            self.first_trading = True
            self.first_buy_time = None

    def post_sell(self, **kwargs):
        price, amount = kwargs['price'], kwargs['amount']
        core_index = [
            'timestamp', '현재가', '매입평균가', '실현손익', '기존수익률', '기존누적수익률', '누적손익',
            '매매수량', '보유수량', '매입금액', '최대매입금액', '평가손익', '평가금액', '매매금액'
        ]
        self.print_attr('SELL', core_index)
        # pdb.set_trace()

    def evaluate_change_price(self, **kwargs):
        price, amount = kwargs['price'], 0
        self.현재가 = price
        self.매매수량 = amount
        # self.보유수량 = self.기존보유수량 - self.매매수량
        self.매매금액 = 0
        # self.매입금액 = self.기존매입평균가 * self.보유수량
        # self.최대매입금액 = max(self.최대매입금액, self.매입금액)
        # self.매입평균가 = self.매입평균가
        self.평가손익 = (self.현재가 - self.매입평균가) * self.보유수량
        # self.실현손익 = (self.현재가 - self.매입평균가) * self.매매수량
        # self.누적손익 += self.실현손익
        self.평가금액 = self.현재가 * self.보유수량
        if self.보유수량 == 0:
            self.수익률 = 0.0
        else:
            self.수익률 = round((self.평가금액 - self.매입금액) / self.매입금액 * 100, 2)
        # self.누적수익률 = round(float(self.누적손익) / self.최대매입금액 * 100, 2)
        self.평가금액변동 = self.평가금액 - self.기존평가금액

    def post_change_price(self, **kwargs):
        price, amount = kwargs['price'], 0
        core_index = [
            '현재가', '매매수량', '보유수량', '매매금액', '매입금액', '최대매입금액', '매입평균가', '평가손익',
            '실현손익', '누적손익', '평가금액', '수익률', '누적수익률'
        ]
        # self.print_attr('CHANGE PRICE')

    @common.type_check
    def update_sell(self, price_per_stock: int, amount: int):
        """현재가에 amount 만큼 매도를 하여, 내부 정보를 업데이트 한다.

        :param amount:
        :return:
        """
        self.bep('sell', price_per_stock, amount)

    @common.type_check
    def update_buy(self, price_per_stock: int, amount: int):
        """해당 주식을 매수하였을 경우, 관련 지표를 업데이트

        :param price_per_stock:
        :param amount:
        :return:
        """
        self.bep('buy', price_per_stock, amount)

    def update_stock_value(self, timestamp):
        """해당 주식의 현재가가 변경되었을 경우, 관련 지표를 업데이트

        :param timestamp:
        :return:
        """
        self.timestamp = timestamp
        현재가 = self.time_series_sec1.ix[timestamp]['현재가']
        self.bep('change_price', 현재가)

    def set_strategy(self, strg):
        """

        :param strg:
        :return:
        """
        self.strg = strg

    def gen_time_series_sec1(self, target_date):
        """특정종목 특정일의 초단위 tick_data(DataFrame 객체)를 생성한다.

                timestamp                현재가  volumn
                2018-08-02 09:00:00      0.0     0.0
                2018-08-02 09:00:01  15000.0   130.0
                2018-08-02 09:00:02  15000.0    91.0
                2018-08-02 09:00:03  15500.0     0.0
                ...(생략)

        :param target_date:
        :return:
        """

        if self.time_series_sec1 is not None:
            self.logger.info(
                "{}/{} use existing gen_time_series_sec1..".format(
                    self.stock_name, self.code))
            return self.time_series_sec1

        self.logger.info("{}/{} gen_time_series_sec1..".format(
            self.stock_name, self.code))
        y, m, d = target_date.year, target_date.month, target_date.day
        s_time = datetime(y, m, d, 9, 0, 0)
        e_time = datetime(y, m, d, 15, 30, 0)
        df = pd.DataFrame(
            self.dbm.get_tick_data(self.code, target_date, tick="1"))
        ts_group = df.groupby('timestamp')
        price = pd.DataFrame(ts_group.max()['현재가'])
        index = pd.date_range(s_time, e_time, freq='S')
        price = price.reindex(index, method='ffill', fill_value=0)
        # volumn = pd.DataFrame(ts_group.sum()['거래량'])
        # volumn = volumn.reindex(index, method='ffill', fill_value=0)
        # price['volumn'] = volumn
        # index = timestamp (freq=second)
        # 현재가 = max, ffill, fill_value=0
        # 거래량 = sum, ffill, fill_value=0
        self.time_series_sec1 = price
        return self.time_series_sec1

    def get_curr_price(self, timestamp):
        """현 시점(timestamp)의 주가를 반환한다.

        :param timestamp:
        :return:
        """
        if self.time_series_sec1 is None:
            y, m, d = timestamp.year, timestamp.month, timestamp.day
            self.time_series_sec1 = self.gen_time_series_sec1(datetime(
                y, m, d))

        return self.time_series_sec1.ix[timestamp]['현재가']

    def get_core_index(self):
        """Stock객체의 핵심 지표 리스트. 반드시 Stock객체의 속성값과 동기화가 되어야 함.
        
        :return: 
        """
        return self.core_index

    def check_core_index(self):
        """

        :return:
        """
        for index in self.get_core_index():
            self.__getattribute__(index)