def update_price_db(self, filtered=False):
        # 다운로드 한 이후로는 설정 값 변경 불가
        self.comboBox.setEnabled(False)
        self.checkBox.setEnabled(False)

        if filtered:
            fetch_code_df = self.f_sv_code_df
            db_code_df = self.f_db_code_df
        else:
            fetch_code_df = self.sv_code_df
            db_code_df = self.db_code_df

        if self.comboBox.currentIndex() == 0:  # 1분봉
            tick_unit = '분봉'
            count = 200000  # 서버 데이터 최대 reach 약 18.5만 이므로 (18/02/25 기준)
            tick_range = 1
        elif self.comboBox.currentIndex() == 1:  # 5분봉
            tick_unit = '분봉'
            count = 100000
            tick_range = 5
        elif self.comboBox.currentIndex() == 2:  # 일봉
            tick_unit = '일봉'
            count = 10000  # 10000개면 현재부터 1980년 까지의 데이터에 해당함. 충분.
            tick_range = 1
        elif self.comboBox.currentIndex() == 3:  # 주봉
            tick_unit = '주봉'
            count = 2000
        else:  # 월봉
            tick_unit = '월봉'
            count = 500

        if self.checkBox.isChecked():
            columns = ['open', 'high', 'low', 'close', 'volume']
            ohlcv_only = True
        else:
            columns = [
                'open', 'high', 'low', 'close', 'volume', '상장주식수', '외국인주문한도수량',
                '외국인현보유수량', '외국인현보유비율', '기관순매수', '기관누적순매수'
            ]
            ohlcv_only = False

        # 분봉/일봉에 대해서만 아래 코드가 효과가 있음.
        if not is_market_open():
            latest_date = available_latest_date()
            if tick_unit == '일봉':
                latest_date = latest_date // 10000
            # 이미 DB 데이터가 최신인 종목들은 가져올 목록에서 제외한다
            already_up_to_date_codes = db_code_df.loc[
                db_code_df['갱신날짜'] == latest_date]['종목코드'].values
            fetch_code_df = fetch_code_df.loc[fetch_code_df['종목코드'].apply(
                lambda x: x not in already_up_to_date_codes)]

        with sqlite3.connect(self.db_path) as con:
            cursor = con.cursor()
            tqdm_range = tqdm.trange(len(fetch_code_df), ncols=100)
            for i in tqdm_range:
                code = fetch_code_df.iloc[i]
                self.update_status_msg = '[{}] {}'.format(code[0], code[1])
                tqdm_range.set_description(
                    preformat_cjk(self.update_status_msg, 25))

                from_date = 0
                if code[0] in self.db_code_df['종목코드'].tolist():
                    cursor.execute(
                        "SELECT date FROM {} ORDER BY date DESC LIMIT 1".
                        format(code[0]))
                    from_date = cursor.fetchall()[0][0]

                if tick_unit == '일봉':  # 일봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('D'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue
                elif tick_unit == '분봉':  # 분봉 데이터 받기
                    if self.objStockChart.RequestMT(code[0], ord('m'),
                                                    tick_range, count, self,
                                                    from_date,
                                                    ohlcv_only) == False:
                        continue
                elif tick_unit == '주봉':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('W'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue
                elif tick_unit == '월봉':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('M'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue

                df = pd.DataFrame(self.rcv_data,
                                  columns=columns,
                                  index=self.rcv_data['date'])

                # 기존 DB와 겹치는 부분 제거
                if from_date != 0:
                    df = df.loc[:from_date]
                    df = df.iloc[:-1]

                # 뒤집어서 저장 (결과적으로 date 기준 오름차순으로 저장됨)
                df = df.iloc[::-1]
                df.to_sql(code[0], con, if_exists='append', index_label='date')

                # 메모리 overflow 방지
                del df
                gc.collect()

        self.update_status_msg = ''
        self.connect_code_list_view()
Exemplo n.º 2
0
    def update_price_db(self, db_path, tick_unit='day', ohlcv_only=False):
        """
        db_path: db 파일 경로.
        tick_unit: '1min', '5min', 'day'. 이미 db_path가 존재할 경우, 입력값 무시하고 기존에 사용된 값 사용.
        ohlcv_only: ohlcv 이외의 데이터도 저장할지 여부. 이미 db_path가 존재할 경우, 입력값 무시하고 기존에 사용된 값 사용 
                    'day' 아닌경우 False 선택 불가 고정.
        """
        if tick_unit != 'day':
            ohlcv_only = True

        # 로컬 DB에 저장된 종목 정보 가져와서 dataframe으로 저장
        con = sqlite3.connect(db_path)
        cursor = con.cursor()

        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        db_code_list = cursor.fetchall()
        for i in range(len(db_code_list)):
            db_code_list[i] = db_code_list[i][0]
        db_name_list = list(map(self.objCodeMgr.get_code_name, db_code_list))

        db_latest_list = []
        for db_code in db_code_list:
            cursor.execute(
                "SELECT date FROM {} ORDER BY date DESC LIMIT 1".format(
                    db_code))
            db_latest_list.append(cursor.fetchall()[0][0])

        # 현재 db에 저장된 'date' column의 tick_unit 확인
        # 현재 db에 저장된 column 명 확인. (ohlcv_only 여부 확인)
        if db_latest_list:
            cursor.execute(
                "SELECT date FROM {} ORDER BY date ASC LIMIT 2".format(
                    db_code_list[0]))
            date0, date1 = cursor.fetchall()

            # 날짜가 분 단위 인 경우
            if date0[0] > 99999999:
                if date1[0] - date0[0] == 5:  # 5분 간격인 경우
                    tick_unit = '5min'
                else:  # 1분 간격인 경우
                    tick_unit = '1min'
            elif date0[0] % 100 == 0:  # 월봉인 경우
                tick_unit = 'month'
            elif date0[0] % 10 == 0:  # 주봉인 경우
                tick_unit = 'week'
            else:  # 일봉인 경우
                tick_unit = 'day'

            # column개수로 ohlcv_only 여부 확인
            cursor.execute('SELECT * FROM {}'.format(db_code_list[0]))
            column_names = [
                description[0] for description in cursor.description
            ]
            if len(column_names) > 7:  # date, o, h, l, c, v
                ohlcv_only = False
            else:
                ohlcv_only = True

        db_code_df = pd.DataFrame(
            {
                '종목코드': db_code_list,
                '종목명': db_name_list,
                '갱신날짜': db_latest_list
            },
            columns=('종목코드', '종목명', '갱신날짜'))
        fetch_code_df = self.sv_code_df

        # 분봉/일봉에 대해서만 아래 코드가 효과가 있음.
        if not is_market_open():
            latest_date = available_latest_date()
            if tick_unit == 'day':
                latest_date = latest_date // 10000
            # 이미 DB 데이터가 최신인 종목들은 가져올 목록에서 제외한다
            already_up_to_date_codes = db_code_df.loc[
                db_code_df['갱신날짜'] == latest_date]['종목코드'].values
            fetch_code_df = fetch_code_df.loc[fetch_code_df['종목코드'].apply(
                lambda x: x not in already_up_to_date_codes)]

        if tick_unit == '1min':
            count = 200000  # 서버 데이터 최대 reach 약 18.5만 이므로 (18/02/25 기준)
            tick_range = 1
        elif tick_unit == '5min':
            count = 100000
            tick_range = 5
        elif tick_unit == 'day':
            count = 10000  # 10000개면 현재부터 1980년 까지의 데이터에 해당함. 충분.
            tick_range = 1
        elif tick_unit == 'week':
            count = 2000
        elif tick_unit == 'month':
            count = 500

        if ohlcv_only:
            columns = ['open', 'high', 'low', 'close', 'volume']
        else:
            columns = [
                'open', 'high', 'low', 'close', 'volume', '상장주식수', '외국인주문한도수량',
                '외국인현보유수량', '외국인현보유비율', '기관순매수', '기관누적순매수'
            ]

        with sqlite3.connect(db_path) as con:
            cursor = con.cursor()
            tqdm_range = tqdm.trange(len(fetch_code_df), ncols=100)
            for i in tqdm_range:
                code = fetch_code_df.iloc[i]
                update_status_msg = '[{}] {}'.format(code[0], code[1])
                tqdm_range.set_description(preformat_cjk(
                    update_status_msg, 25))

                from_date = 0
                if code[0] in db_code_df['종목코드'].tolist():
                    cursor.execute(
                        "SELECT date FROM {} ORDER BY date DESC LIMIT 1".
                        format(code[0]))
                    from_date = cursor.fetchall()[0][0]

                if tick_unit == 'day':  # 일봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('D'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue
                elif tick_unit == '1min' or tick_unit == '5min':  # 분봉 데이터 받기
                    if self.objStockChart.RequestMT(code[0], ord('m'),
                                                    tick_range, count, self,
                                                    from_date,
                                                    ohlcv_only) == False:
                        continue
                elif tick_unit == 'week':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('W'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue
                elif tick_unit == 'month':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('M'), count,
                                                     self, from_date,
                                                     ohlcv_only) == False:
                        continue
                df = pd.DataFrame(self.rcv_data,
                                  columns=columns,
                                  index=self.rcv_data['date'])

                # 기존 DB와 겹치는 부분 제거
                if from_date != 0:
                    df = df.loc[:from_date]
                    df = df.iloc[:-1]

                # 뒤집어서 저장 (결과적으로 date 기준 오름차순으로 저장됨)
                df = df.iloc[::-1]
                df.to_sql(code[0], con, if_exists='append', index_label='date')

                # 메모리 overflow 방지
                del df
                gc.collect()
    def update_price_db(self, filtered=False):
        if filtered:
            fetch_code_df = self.f_sv_code_df
            db_code_df = self.f_db_code_df
        else:
            fetch_code_df = self.sv_code_df
            db_code_df = self.db_code_df

        if not is_market_open():
            latest_date = available_latest_date()
            print(latest_date)
            # 이미 DB 데이터가 최신인 종목들은 가져올 목록에서 제외한다
            already_up_to_date_codes = db_code_df.loc[
                db_code_df['갱신날짜'] == latest_date]['종목코드'].values
            fetch_code_df = fetch_code_df.loc[fetch_code_df['종목코드'].apply(
                lambda x: x not in already_up_to_date_codes)]

        if self.radioButton.isChecked():  # 1분봉
            tick_unit = '분봉'
            count = 200000  # 서버 데이터 최대 reach 약 18.5만 이므로 (18/02/25 기준)
            tick_range = 1
        elif self.radioButton_3.isChecked():  # 5분봉
            tick_unit = '분봉'
            count = 100000
            tick_range = 5
        elif self.radioButton_2.isChecked():  # 일봉
            tick_unit = '일봉'
            count = 10000  # 10000개면 현재부터 1980년 까지의 데이터에 해당함. 충분.
            tick_range = 1
        elif self.radioButton_4.isChecked():  # 주봉
            tick_unit = '주봉'
            count = 2000
        else:  # 월봉
            tick_unit = '월봉'
            count = 500

        with sqlite3.connect(self.db_path) as con:
            cursor = con.cursor()

            for i, (_, code) in enumerate(fetch_code_df.iterrows()):
                self.update_status_msg = '[{}/{}]: [{}] {}'.\
                    format(i+1, len(fetch_code_df), code[0], code[1])
                print(self.update_status_msg)

                from_date = 0
                if code[0] in self.db_code_df['종목코드'].tolist():
                    cursor.execute(
                        "SELECT date FROM {} ORDER BY date DESC LIMIT 1".
                        format(code[0]))
                    from_date = cursor.fetchall()[0][0]

                if tick_unit == '일봉':  # 일봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('D'), count,
                                                     self, from_date) == False:
                        continue
                elif tick_unit == '분봉':  # 분봉 데이터 받기
                    if self.objStockChart.RequestMT(code[0], ord('m'),
                                                    tick_range, count, self,
                                                    from_date) == False:
                        continue
                elif tick_unit == '주봉':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('W'), count,
                                                     self, from_date) == False:
                        continue
                elif tick_unit == '월봉':  #주봉 데이터 받기
                    if self.objStockChart.RequestDWM(code[0], ord('M'), count,
                                                     self, from_date) == False:
                        continue

                df = pd.DataFrame(
                    self.rcv_data,
                    columns=['open', 'high', 'low', 'close', 'volume'],
                    index=self.rcv_data['date'])

                # 기존 DB와 겹치는 부분 제거
                if from_date != 0:
                    df = df.loc[:from_date]
                    df = df.iloc[:-1]

                # 뒤집어서 저장 (결과적으로 date 기준 오름차순으로 저장됨)
                df = df.iloc[::-1]
                df.to_sql(code[0], con, if_exists='append', index_label='date')

                # 메모리 overflow 방지
                del df
                gc.collect()

        self.update_status_msg = ''
        self.connect_code_list_view()
while marketOpen == True :
    for stock_name,tradeStatus in stockList.items():
        quote = rs.stocks.get_quotes(stock_name)
        last_trade_price = float(quote[0]['last_trade_price'])
        previous_close = float(quote[0]['previous_close'])
        logging.info(f'{stock_name.rjust(5)}: Last trade price is {last_trade_price:10.3f} and previous close was {previous_close:10.3f}')
        for ctr in range(len(buyThresholds)):
            if last_trade_price/previous_close < buyThresholds[ctr] and tradeStatus[ctr] == True:
                tradeConf = utils.buy_stock_units(stock_name,buyStockUnits[ctr],last_trade_price) 
                if tradeConf == True :
                    logging.info(f'Bought {str(buyStockUnits[ctr]):3} stocks of {stock_name}\n')
                    tradeStatus[ctr] = False
                # End If
            # End if
        # End For

        for ctr in range(len(sellThresholds)):
            if last_trade_price/previous_close > sellThresholds[ctr] and tradeStatus[ctr] == True:
                tradeConf = utils.sell_stock_units(stock_name,sellStockUnits[ctr],last_trade_price) 
                if tradeConf == True :
                    logging.info(f'Sold {str(sellStockUnits[ctr]):3} stocks of {stock_name}\n')
                    tradeStatus[ctr] = False
                # End If
            # End If
        # End For
    #Wait for 5 minutes before running the script again. 
    sleep(300)
    marketOpen = utils.is_market_open()
    # End If Else
# End While
Exemplo n.º 5
0
tradePlaced = False

tradeQuantity = 2  #Quantity of trades to be placed on each stock
scalpThicknessByPrice = {
    10: 0.005,
    20: 0.003,
    30: 0.002,
    40: 0.001,
    50: 0.001
}  # Set different scalp thicknesses for different prices. at $10, a thickness of 0.005 would create a spread of 10 c (+/- 5c)

#This is the robinhood watchlist for straddle strategy
straddleList = "Straddle"

while tradePlaced == False:
    marketStatus = utils.is_market_open()
    if marketStatus:
        login()
        stockList = utils.build_stocklist(straddleList)
        for stock in stockList:
            quote = rs.stocks.get_quotes(stock)
            lastTradePrice = round(float(quote[0]['last_trade_price']), 2)
            scalpIndex = (int(lastTradePrice / 10) + 1) * 10
            if scalpIndex > 50:
                scalpIndex = 50
            scalpThickness = scalpThicknessByPrice[scalpIndex]
            buyPrice = round(
                lastTradePrice * (1 - scalpThickness), 2
            )  # Buy order at scalp% below lower of current or last close price
            sellPrice = round(
                lastTradePrice * (1 + scalpThickness),