def save_oscillation_strength_to_db(self, method='1'): # method = 1:calc_oscillation_strength_by_meet_aptitude_days # method = 2:calc_oscillation_strength_by_aptitude_expectation stock_basics = Data().get_stock_basics() num_stock = stock_basics.index.size df = pd.DataFrame(columns=('code', 'name', 'aptitude', 'start date', 'end date')) for i in range(num_stock): code = '%06d' % int(stock_basics['code'][i]) name = stock_basics['name'][i] aptitude = self.calc_oscillation_strength(code, method) aptitude = '%.2f' % aptitude if self.mode == 'fixed_interval': start_date = Data().get_k_line_date_by_reverse_days( code, self.calc_head_to_start_or_end + self.calc_end_to_tail) else: start_date = Data().get_k_line_date_by_sequential_days( code, self.calc_head_to_start_or_end) end_date = Data().get_k_line_date_by_reverse_days( code, self.calc_end_to_tail + 1) df.loc[i] = [code, name, aptitude, start_date, end_date] LOG('analyse_oscillation {0} {1:4d}/{2:4d} '.format( code, i + 1, num_stock)) Base.save_data( self, df, self.path_result + 'oscillation_strength_' + self.mode + '_m' + method + '_s' + str( self.calc_head_to_start_or_end )\ + '_e' + str( self.calc_end_to_tail ) + '_m' + str( self.threshold_min_market_days ) + '_t' + str( self.threshold_oscillation_aptitude ) + '.xlsx' )
def download_divi_data( self, year, top ): try: df_tmp = ts.profit_data( year, top ) except: ERROR( 'exception occurs when update divi data of year {0}'.format( year ) ) return pd.DataFrame() else: LOG( 'update divi data of year {0}'.format( year ) ) thread_queue.put( df_tmp )
def update_stock_basics( self ): if not os.path.exists( self.__basics_file_name ): try: df_stock_basics = ts.get_stock_basics() except: ERROR( 'exception occurs when update stock_basics' ) else: LOG( 'update basics data' ) Utils.save_data( df_stock_basics, self.__basics_file_name, 'stock basics' )
def update_concept_classified( self ): if not os.path.exists( self.__concept_classified_file_name ): try: df_concept_classified = ts.get_concept_classified() except: ERROR( 'exception occurs when update concept classified data' ) else: LOG( 'update concept classified' ) Utils.save_data( df_concept_classified, self.__concept_classified_file_name, 'concept classified' )
def get_all_stock_data( self ): LOG( 'loading data...') df_stock_basics = self.get_stock_basics() df_stock_basics = df_stock_basics.set_index( 'code' ) df_quarter_report_data = self.get_quarter_report_data() df_quarter_report_data = df_quarter_report_data.set_index( 'code' ) df_profit_data = self.get_profit_data() df_profit_data = df_profit_data.set_index( 'code' ) df_operation_data = self.get_operation_data() df_operation_data = df_operation_data.set_index( 'code' ) df_growth_data = self.get_growth_data() df_growth_data = df_growth_data.set_index( 'code' ) df_debtpaying_data = self.get_debtpaying_data() df_debtpaying_data = df_debtpaying_data.set_index( 'code' ) df_cashflow_data = self.get_cashflow_data() df_cashflow_data = df_cashflow_data.set_index( 'code' ) df_divi_data = self.get_divi_data() df_divi_data = df_divi_data.set_index( 'code' ) df_forcast_quarter_report_data = self.get_forcast_quarter_report_data() df_forcast_quarter_report_data = df_forcast_quarter_report_data.set_index( 'code' ) df_restrict_stock_data = self.get_restrict_stock_data() df_restrict_stock_data = df_restrict_stock_data.set_index( 'code' ) df_concept_classified = self.get_concept_classified_data() df_concept_classified = df_concept_classified.set_index( 'code' ) LOG( 'finish loading.' ) return [ df_stock_basics, df_quarter_report_data, df_profit_data, df_operation_data, df_growth_data, df_debtpaying_data, \ df_cashflow_data, df_divi_data, df_forcast_quarter_report_data, df_restrict_stock_data, df_concept_classified ]
def update_k_line_data_range( self, df_stock_basics, id_start, id_end ): for i in range( id_start, id_end ): code = '%06d' % int( df_stock_basics['code'][i] ) cur_k_line_file = self.__k_line_file_path + code + '.xlsx' if not os.path.exists( cur_k_line_file ): try: df_k_line_data = ts.get_k_data( code, ktype = 'D', autype = 'qfq' ) except: ERROR( 'exception occurs when update k_line data {0}'.format( code ) ) else: LOG( '{3} update {0} k_line data {1:4d}/{2:4d} '.format( code, i + 1, num_stock, threading.current_thread().getName() ) ) Utils.save_data( df_k_line_data, cur_k_line_file, code )
def update_forcast_quarter_report_data( self ): if not os.path.exists( self.__forcast_quarter_report_file_name ): list_date_quarter = Utils.parse_date_to_ymd( self.__date ) df_forcast_quarter_report_data = pd.DataFrame() for year in range( 2003, int( list_date_quarter[0] ) + 1 ): for quarter in range( 1, 5 ): try: df_tmp = ts.forecast_data( year, quarter ) except: ERROR( 'exception occurs when update forcast quarter report data of year {0} quarter {1}'.format( year, quarter ) ) else: df_forcast_quarter_report_data = df_forcast_quarter_report_data.append( df_tmp ) LOG( 'update forcast quarter report data of year {0} quarter {1}'.format( year, quarter ) ) if year == int( list_date_quarter[0] ) and quarter == list_date_quarter[3]: break Utils.save_data( df_forcast_quarter_report_data, self.__forcast_quarter_report_file_name, 'forcast quarter report' )
def update_restrict_stock_data( self, extend_years = 3 ): if not os.path.exists( self.__restrict_stock_file_name ): list_date_quarter = Utils.parse_date_to_ymd( self.__date ) df_restrict_stock_data = pd.DataFrame() for year in range( 2010, int( list_date_quarter[0] ) + extend_years + 1 ): for month in range( 1, 13 ): try: df_tmp = ts.xsg_data( year, month ) except: ERROR( 'exception occurs when update restrict stock data of year {0} month {1}'.format( year, month ) ) else: df_restrict_stock_data = df_restrict_stock_data.append( df_tmp ) LOG( 'update restrict stock data of year {0} month {1}'.format( year, month ) ) if year == int( list_date_quarter[0] ) + extend_years and month == int( list_date_quarter[1] ): break Utils.save_data( df_restrict_stock_data, self.__restrict_stock_file_name, 'restrict stock' )
def update_cashflow_data( self ): if not os.path.exists( self.__cashflow_file_name ): list_date_quarter = Utils.parse_date_to_ymd( self.__date ) df_cashflow_data = pd.DataFrame() for year in range( 2003, int( list_date_quarter[0] ) + 1 ): for quarter in range( 1, 5 ): if year == int( list_date_quarter[0] ) and quarter == list_date_quarter[3]: break try: df_tmp = ts.get_cashflow_data( year, quarter ) except: ERROR( 'exception occurs when update cashflow data of year {0} quarter {1}'.format( year, quarter ) ) return else: df_tmp[ 'year' ] = year df_tmp[ 'quarter' ] = quarter df_cashflow_data = df_cashflow_data.append( df_tmp ) LOG( 'update cashflow data of year {0} quarter {1}'.format( year, quarter ) ) Utils.save_data( df_cashflow_data, self.__cashflow_file_name, 'cashflow' )
def update_profit_data( self ): if not os.path.exists( self.__profit_file_name ): list_date_quarter = Utils.parse_date_to_ymd( self.__date ) df_profit_data = pd.DataFrame() for year in range( 2003, int( list_date_quarter[0] ) + 1 ): for quarter in range( 1, 5 ): if year == int( list_date_quarter[0] ) and quarter == list_date_quarter[3]: break try: df_tmp = ts.get_profit_data( year, quarter ) except: ERROR( 'exception occurs when update profit data of year {0} quarter {1}'.format( year, quarter ) ) return else: df_tmp[ 'year' ] = year df_tmp[ 'quarter' ] = quarter df_profit_data = df_profit_data.append( df_tmp ) LOG( 'update profit data of year {0} quarter {1}'.format( year, quarter ) ) # 解决 ts.get_growth_data() 拿不到数据时一直等待的问题 #self.update_growth_data() Utils.save_data( df_profit_data, self.__profit_file_name, 'quarter report' )
def notify_realtime_earnings(self): # 实时持仓盈亏检测通知 while True: df_position = DataFrame() if os.path.exists(self.__file_path_position): try: df_position = Utils.read_data(self.__file_path_position) except: # 可能在修改文件,等一分钟 sleep(60) continue else: ERROR('file {0} not exists.'.format(self.__file_path_position)) return cur_time = Utils.cur_time() hour = int(cur_time.split(':')[0]) minute = int(cur_time.split(':')[1]) if hour < 9 or (hour == 9 and minute < 30): LOG( 'notify_realtime_earnings: morning\n{0} hours {1} minutes later market open'\ .format( int( Utils.now2market_morning_time() / 3600 ), int( Utils.now2market_morning_time() % 3600 / 60 ) ) ) sleep(Utils.now2market_morning_time()) elif (hour == 11 and minute >= 30) or hour == 12: LOG('notify_realtime_earnings: nooning\n{0} hours {1} minutes later market open' .format(int(Utils.now2market_nooning_time() / 3600), int(Utils.now2market_nooning_time() % 3600 / 60))) sleep(Utils.now2market_nooning_time()) elif hour >= 15: LOG('notify_realtime_earnings: market close') break content_notify = '' content_notify += '{0}\n'.format(cur_time) total_earn = 0 for index in df_position.index: code = '%06d' % df_position.loc[index]['code'] name = df_position.loc[index]['name'] try: df_realtime_quotes = Data().get_realtime_quotes(code) buy_price = float(df_position.loc[index]['buy_price']) cur_price = float(df_realtime_quotes['price']) position = df_position.loc[index]['position'] earn = (cur_price - buy_price) * position total_earn += earn content_notify += '-{0} {1} cur:{2:.2f} cost:{3:.2f} sell:{4:.2f} position:{5} earn:{6:.2f}\n'\ .format( code, name, cur_price, buy_price, float( df_position.loc[ index ][ 'sell_price' ] ), position, earn) except: pass content_notify += 'total_earn:{0:.2f}'.format(total_earn) if SEND_EMAIL: Utils.send_email(content_notify, 'position notification') sleep(60 * 10) else: LOG(content_notify) sleep(60 * 10)
def notify_investment_opportunity(self): df_spill_wave_stock = Utils.read_data( model.spill_wave.Analyse().spill_wave_stock_file) df_model_basics = Basics().get_basics().set_index('code') while True: cur_time = Utils.cur_time() hour = int(cur_time.split(':')[0]) minute = int(cur_time.split(':')[1]) if hour < 9 or (hour == 9 and minute < 30): LOG( 'notify_investment_opportunity: morning\n{0} hours {1} minutes later market open'\ .format( int( Utils.now2market_morning_time() / 3600 ), int( Utils.now2market_morning_time() % 3600 / 60 ) ) ) sleep(Utils.now2market_morning_time()) elif (hour == 11 and minute >= 30) or hour == 12: LOG('notify_investment_opportunity: nooning\n{0} hours {1} minutes later market open' .format(int(Utils.now2market_nooning_time() / 3600), int(Utils.now2market_nooning_time() % 3600 / 60))) sleep(Utils.now2market_nooning_time()) elif hour >= 15: LOG('notify_investment_opportunity: market close') break content_notify = '' content_notify += '{0}\n'.format(cur_time) for index in df_spill_wave_stock.index: code = '%06d' % df_spill_wave_stock.loc[index]['code'] name = df_spill_wave_stock.loc[index]['name'] try: df_realtime_quotes = Data().get_realtime_quotes(code) if float(df_realtime_quotes['price']) >= (float( df_spill_wave_stock.loc[index]['buy_price']) * 0.99): content_notify += '-{0} {1} cur price:{2:.2f} buy price:{3:.2f} sell price:{4:.2f} expect earn:{5:.2f}\n'\ .format( code, name, float( df_realtime_quotes[ 'price' ] ), \ float( df_spill_wave_stock.loc[ index ][ 'buy_price' ] ), \ float( df_spill_wave_stock.loc[ index ][ 'sell_price' ] ), \ float( df_spill_wave_stock.loc[ index ][ 'expect_earn_rate' ] ), \ float( df_spill_wave_stock.loc[ index ][ 'min_earn_rate' ] ) ) content_notify += '\tprofit rank:{0}\n \tindustry:{1} pe rank:{2}\n'.format( df_model_basics[ 'rank_profit_grow' ][ int( code ) ],\ df_model_basics[ 'industry' ][ int( code ) ], df_model_basics[ 'rank_pe' ][ int( code ) ] ) id_concept = 1 id_rank = 1 name_concept = '_'.join(['concept', str(id_concept)]) name_rank = '_'.join(['rank_pe', str(id_rank)]) while df_model_basics[name_concept][int( code)] is not np.nan: content_notify += '\tconcept:{0} pe rank:{1}\n'.format( df_model_basics[ name_concept ][ int( code ) ], \ df_model_basics[ name_rank ][ int( code ) ] ) id_concept += 1 id_rank += 1 if id_concept > 20: break name_concept = '_'.join( ['concept', str(id_concept)]) name_rank = '_'.join(['rank_pe', str(id_rank)]) content_notify += '\n' except: pass if SEND_EMAIL: # 如果发送邮件,10分钟发一次 Utils.send_email(content_notify, 'opportunity notification') sleep(10 * 60) else: LOG('*********************************') LOG(content_notify) LOG('*********************************') sleep(60 * 5)
def query_stock_info(ls_code, ls_all_stock_data, df_model_basics): [ df_stock_basics, df_quarter_report_data, df_profit_data, df_operation_data, df_growth_data, df_debtpaying_data, \ df_cashflow_data, df_divi_data, df_forcast_quarter_report_data, df_restrict_stock_data, df_concept_classified ] = ls_all_stock_data space = lambda x: ' ' * x # 方便区分不同季度数据 pd.options.mode.chained_assignment = None # 不显示warn信息 default='warn' dict_stock_info = {} for code in ls_code: try: basics = df_stock_basics.loc[int(code)] content = '\n{0} {1}\n'.format(code, basics['name']) try: cur_price = float( Data().get_k_line_data(code).iloc[-1]['close']) except: cur_price = float( Data().get_realtime_quotes(code)['price']) content += '\nbasics:\n上市日期:{0}\n所属行业:{1}\t行业市盈率排名:{6}\n地区:{2}\n市盈率(动态):{3}\n市盈率(静态):{4:.2f}\n市净率:{5}\n'\ .format( basics[ 'timeToMarket' ], basics[ 'industry' ], basics[ 'area' ], basics[ 'pe' ], \ cur_price / float( basics[ 'esp' ] ), float( basics[ 'pb' ] ), df_model_basics[ 'rank_pe' ][ int( code ) ] ) content += '每股公积金:{0}\n每股未分配利润:{1}\n'\ .format( basics[ 'reservedPerShare' ], basics[ 'perundp' ] ) content += '总市值:{0:.2f} 亿元\n流动市值:{1:.2f} 亿元\n'\ .format( cur_price * float( basics[ 'totals' ] ), cur_price * float( basics[ 'outstanding' ] ) ) content += '总资产:{0:.2f} 亿元\n固定资产:{1:.2f} 亿元\n流动资产:{2:.2f} 亿元\n'\ .format( float( basics[ 'totalAssets' ] ) / 10000, float( basics[ 'fixedAssets' ] ) / 10000, \ float( basics[ 'liquidAssets' ] ) / 10000 ) except: content = '\n{0}\n'.format(code) try: content += '\nconcept:\n' id_concept = 1 id_rank = 1 name_concept = '_'.join(['concept', str(id_concept)]) name_rank = '_'.join(['rank_pe', str(id_rank)]) while df_model_basics[name_concept][int(code)] is not np.nan: content += '{0} 市盈率排名:{1}\n'.format( df_model_basics[ name_concept ][ int( code ) ], \ df_model_basics[ name_rank ][ int( code ) ] ) id_concept += 1 id_rank += 1 if id_concept > 20: break name_concept = '_'.join(['concept', str(id_concept)]) name_rank = '_'.join(['rank_pe', str(id_rank)]) content += '\n' except: pass try: profit = df_profit_data.loc[int(code)].sort_values( by=['year', 'quarter'], axis=0, ascending=True).drop_duplicates() content += '\nprofit:\n排名:{0}\n年份 季度 净资产收益率 净利润(百万) 每股收益(元)每股主营业务收入(元)\n'\ .format( df_model_basics[ 'rank_profit_grow' ][ int( code ) ] ) for id in range(profit.index.size): content += '{5}{0} {1} {2:-10.2f} {3:-12.2f} {4:-15.2f} {6:-20.2f}\n'.format( profit.iloc[ id ][ 'year' ], profit.iloc[ id ][ 'quarter' ], \ profit.iloc[ id ][ 'roe' ], profit.iloc[ id ][ 'net_profits' ], profit.iloc[ id ][ 'eps' ], \ space( int( profit.iloc[ id ][ 'quarter' ] ) - 1 ), profit.iloc[ id ][ 'bips' ] ) except: pass try: operation = df_operation_data.loc[int(code)].sort_values( by=['year', 'quarter'], axis=0, ascending=True).drop_duplicates() content += '\noperation:\n年份 季度 应收账款周转天数 存货周转天数 流动资产周转天数\n' for id in range(operation.index.size): content += '{5}{0} {1} {2:-16.2f} {3:-8.2f} {4:-15.2f}\n'.format( operation.iloc[ id ][ 'year' ], \ operation.iloc[ id ][ 'quarter' ],operation.iloc[ id ][ 'arturndays' ], operation.iloc[ id ][ 'inventory_days' ], \ operation.iloc[ id ][ 'currentasset_days' ], space( int( operation.iloc[ id ][ 'quarter' ] ) - 1 ) ) except: pass try: debtpaying = df_debtpaying_data.loc[int(code)].sort_values( by=['year', 'quarter'], axis=0, ascending=True).drop_duplicates() content += '\ndebtpaying:\n年份 季度 流动比率 利息支付倍数 股东权益比率 股东权益增长率\n' for col in ['currentratio', 'icratio', 'sheqratio', 'adratio']: for id in range(debtpaying.index.size): try: float(debtpaying[col].iloc[id]) except: debtpaying[col].iloc[id] = np.nan for id in range(debtpaying.index.size): content += '{5}{0} {1} {2:-8.2f} {3:-12.2f} {4:-10.2f} {6:-14.2f}\n'.format( debtpaying.iloc[ id ][ 'year' ], \ debtpaying.iloc[ id ][ 'quarter' ], float( debtpaying.iloc[ id ][ 'currentratio' ] ), float( debtpaying.iloc[ id ][ 'icratio' ] ), \ float( debtpaying.iloc[ id ][ 'sheqratio' ] ), space( int( debtpaying.iloc[ id ][ 'quarter' ] ) - 1 ), \ float( debtpaying.iloc[ id ][ 'adratio' ] ) ) except: pass try: divi = df_divi_data.loc[int(code)] content += '\ndivision:\n年份 公布日期 分红金额(每10股) 转增股数(每10股)\n' if type(divi) == pd.Series: divi = divi.to_frame().T if type(divi) == pd.DataFrame: divi = divi.sort_values(by=['year', 'report_date'], axis=0, ascending=True) for id in range(divi.index.size): content += '{0} {1} {2:-12d} {3:-16d}\n'.format( divi.iloc[ id ][ 'year' ], divi.iloc[ id ][ 'report_date' ], int( divi.iloc[ id ][ 'divi' ] ), \ int( divi.iloc[ id ][ 'shares' ] ) ) else: ERROR('divi type error.') except: pass try: forcast_quarter_data = df_forcast_quarter_report_data.loc[int( code)] content += '\nforcast quarter report:\n发布日期 业绩变动类型 上年同期每股收益 业绩变动范围\n' if type(forcast_quarter_data) == pd.Series: forcast_quarter_data = forcast_quarter_data.to_frame().T if type(forcast_quarter_data) == pd.DataFrame: forcast_quarter_data = forcast_quarter_data.sort_values( by='report_date', axis=0, ascending=True) for id in range(forcast_quarter_data.index.size): content += '{0} {1:>8s} {2:-14.2f} {3:>12s}\n'.format( forcast_quarter_data.iloc[ id ][ 'report_date' ], \ forcast_quarter_data.iloc[ id ][ 'type' ], float( forcast_quarter_data.iloc[ id ][ 'pre_eps' ] ), \ forcast_quarter_data.iloc[ id ][ 'range' ] ) else: ERROR('forcast_quarter_data type error.') except: pass try: restrict = df_restrict_stock_data.loc[int(code)] content += '\nrestrict:\n解禁日期 解禁数量(万股) 占总盘比率\n' if type(restrict) == pd.Series: restrict = restrict.to_frame().T if type(restrict) == pd.DataFrame: restrict = restrict.sort_values(by='date', axis=0, ascending=True) for id in range(restrict.index.size): content += '{0} {1:-12.2f} {2:-10.2f}\n'.format( restrict.iloc[ id ][ 'date' ], \ float( restrict.iloc[ id ][ 'count' ] ), float( restrict.iloc[ id ][ 'ratio' ] ) ) else: ERROR('restrict type error.') except: pass try: df_news = ts.get_notices(code) content += '\nnotice:\n' for index in range(0, 10): # df_news.index: content += '{3}、{0}\t{1}\tdate:{2}\n'.format( df_news[ 'title' ][ index ], \ df_news[ 'type' ][ index ], df_news[ 'date' ][ index ], index + 1 ) if index < 3: content += ts.notice_content(df_news['url'][index]) content += '\n\n' content += '\n' except: pass LOG(content) dict_stock_info[code] = content return dict_stock_info
ls_all_stock_data = Data().get_all_stock_data() df_latest_news = ts.get_latest_news(top=1000) while True: content = '' str_input = input('input stock code or \'news\':\n') try: int(str_input) pattern = re.compile( '[●┊\-■:∶%;!?;&.,:?!.‘’“”"\'、,。><(())\[\]\{\}【】―《》『』//・…_——\s]+' ) ls_code = re.split(pattern, str_input.strip()) Query.query_stock_info(ls_code, ls_all_stock_data, df_model_basics) except: if len(str_input.split()) == 1: for index in range(0, 20): content += '{0}、{1}\t{2}\n'.format( index, df_latest_news['title'][index], df_latest_news['time'][index]) elif len(str_input.split()) == 2: content = '{0}'.format( ts.latest_content(df_latest_news['url'][int( str_input.split()[1])])) elif len(str_input.split()) == 3: for index in range(int(str_input.split()[1]), int(str_input.split()[2])): content += '{0}、{1}\t{2}\n'.format( index, df_latest_news['title'][index], df_latest_news['time'][index]) LOG(content)
def sub_calc_divi_earn(self, list_code, id_start, id_end, df_divi_data, queue_process): ls_tmp = [] object_Data = Data() for id in range(id_start, id_end): code = list_code[id] tmp_divi = df_divi_data.loc[code] code = '%06d' % code # 判断tmp_divi类型 if type(tmp_divi) == pd.Series: name = tmp_divi['name'] elif type(tmp_divi) == pd.DataFrame: name = tmp_divi.iloc[0]['name'] else: ERROR('tmp_divi type error when calc divi earn') continue try: # 获取不到k线数据 或 k线数据为空,则跳过 df_k_line_data = object_Data.get_k_line_data(code) if df_k_line_data.index.size == 0 or df_k_line_data.empty: continue except: continue earn_rate = 0 if type(tmp_divi) == pd.Series: date = tmp_divi['report_date'] divi = float('{0:.2f}'.format(tmp_divi['divi'])) shares = tmp_divi['shares'] if divi == 0 and shares == 0: continue try: df_divi_k_line_data = df_k_line_data[df_k_line_data.date == date] except: continue else: if not df_divi_k_line_data.empty: earn_rate = self.calc_earn(df_k_line_data, df_divi_k_line_data) if earn_rate is None: continue ls_tmp.append( [code, name, date, divi, shares, earn_rate]) LOG([code, name, date, divi, shares, earn_rate]) else: continue elif type(tmp_divi) == pd.DataFrame: for i in range(tmp_divi.index.size): date = tmp_divi.iloc[i]['report_date'] divi = float('{0:.2f}'.format(tmp_divi.iloc[i]['divi'])) shares = tmp_divi.iloc[i]['shares'] if divi == 0 and shares == 0: continue try: df_divi_k_line_data = df_k_line_data[ df_k_line_data.date == date] except: continue else: if not df_divi_k_line_data.empty: earn_rate = self.calc_earn(df_k_line_data, df_divi_k_line_data) if earn_rate is None: continue ls_tmp.append( [code, name, date, divi, shares, earn_rate]) LOG([code, name, date, divi, shares, earn_rate]) else: continue queue_process.put_nowait(ls_tmp)
def do_realtime_trade( self ): pd.options.mode.chained_assignment = None # 不显示warn信息 default='warn' df_model_basics = Basics().get_basics().set_index( 'code' ) if os.path.exists( self.__file_path_trade ): self.df_trade = Utils.read_data( self.__file_path_trade ) if self.df_trade.index.size >= 1: self.remain_money = self.df_trade.loc[ self.df_trade.index.size - 1 ][ 'remain' ] if os.path.exists( self.__file_path_position ): self.df_position = Utils.read_data( self.__file_path_position ) while True: cur_time = Utils.cur_time() hour = int( cur_time.split( ':' )[ 0 ] ) minute = int( cur_time.split( ':' )[ 1 ] ) if hour < 9 or ( hour == 9 and minute < 30 ): LOG( 'Trade_Simulator: morning\n{0} hours {1} minutes later market open'\ .format( int( Utils.now2market_morning_time() / 3600 ), int( Utils.now2market_morning_time() % 3600 / 60 ) ) ) sleep( Utils.now2market_morning_time() ) elif ( hour == 11 and minute >= 30 ) or hour == 12: LOG( 'Trade_Simulator: nooning\n{0} hours {1} minutes later market open' .format( int( Utils.now2market_nooning_time() / 3600 ), int( Utils.now2market_nooning_time() % 3600 / 60 ) ) ) sleep( Utils.now2market_nooning_time() ) elif hour >= 15: LOG( 'Trade_Simulator: market close' ) break # sell for index in self.df_position.index: code = '%06d' % int( self.df_position.loc[ index ][ 'code' ] ) df_realtime_quotes = Data().get_realtime_quotes( code ) # T + 1 交易 if self.df_position.loc[ index ][ 'buy_date' ] < Utils.cur_date(): name = self.df_position.loc[ index ][ 'name' ] if float( df_realtime_quotes[ 'price' ] ) >= self.df_position.loc[ index ][ 'sell_price' ]: self.remain_money += float( df_realtime_quotes[ 'price' ] ) * float( self.df_position.loc[ index ][ 'position' ] ) total_earn = '{0:.2f}'.format( ( float( df_realtime_quotes[ 'price' ] ) - float( self.df_position.loc[ index ][ 'cost_price' ] ) ) \ * float( self.df_position.loc[ index ][ 'position' ] ) + float( self.df_trade.loc[ self.df_trade.index.size - 1 ][ 'total_earn' ] ) ) self.df_trade.loc[ self.df_trade.index.size ] = [ ' '.join( [ Utils.cur_date(), Utils.cur_time() ] ), code, name, 'sell', \ self.df_position.loc[ index ][ 'position' ], total_earn, self.remain_money ] self.df_position = self.df_position.drop( index ) continue self.df_position[ 'earn' ][ index ] = '{0:.2f}'.format( ( float( df_realtime_quotes[ 'price' ] ) - float( self.df_position.loc[ index ][ 'cost_price' ] ) ) \ * float( self.df_position.loc[ index ][ 'position' ] ) ) sleep( 1 ) # buy for index in self.df_model_stock.index: code = '%06d' % int( self.df_model_stock.loc[ index ][ 'code' ] ) name = self.df_model_stock.loc[ index ][ 'name' ] # 每只在仓股不再买入 if int( code ) in self.df_position[ 'code' ].to_dict().values() or \ code in self.df_position[ 'code' ].to_dict().values(): continue try: df_realtime_quotes = Data().get_realtime_quotes( code ) if float( df_realtime_quotes[ 'price' ] ) >= ( float( self.df_model_stock.loc[ index ][ 'buy_price' ] ) * 0.99 ) and \ float( df_realtime_quotes[ 'price' ] ) <= ( float( self.df_model_stock.loc[ index ][ 'buy_price' ] ) * 1.002 ) and \ float( self.df_model_stock.loc[ index ][ 'expect_earn_rate' ] ) >= 0.2: try: if float( df_model_basics[ 'rank_profit_grow' ][ int( code ) ].split( '/' )[ 0 ] ) / \ float( df_model_basics[ 'rank_profit_grow' ][ int( code ) ].split( '/' )[ 1 ] ) >= 0.5: continue # LOG( '{0} {1}'.format( code, df_model_basics[ 'rank_profit_grow' ][ int( code ) ].split( '/' ) ) ) except:pass buy_hand_num = 0 # 至少剩余买一手的资金 if 100 * float( df_realtime_quotes[ 'price' ] ) <= self.remain_money: buy_hand_num = int( min( self.initial_fund * float( self.df_model_stock.loc[ index ][ 'expect_earn_rate' ] ) * 0.5 / float( df_realtime_quotes[ 'price' ] ) / 100, \ self.max_buy_each_stock / float( df_realtime_quotes[ 'price' ] ) / 100, self.remain_money / float( df_realtime_quotes[ 'price' ] ) / 100 ) ) if self.df_trade.index.size >= 1: total_earn = self.df_trade.loc[ self.df_trade.index.size - 1 ][ 'total_earn' ] else: total_earn = 0 self.remain_money -= buy_hand_num * 100 * float( df_realtime_quotes[ 'price' ] ) self.df_trade.loc[ self.df_trade.index.size ] = [ ' '.join( [ Utils.cur_date(), Utils.cur_time() ] ), code, name, 'buy', \ buy_hand_num * 100, total_earn, self.remain_money ] self.df_position.loc[ self.df_position.index.size ] = [ code, name, Utils.cur_date(), float( df_realtime_quotes[ 'price' ] ), \ float( df_realtime_quotes[ 'price' ] ) * ( 0.2 * float( self.df_model_stock.loc[ index ][ 'expect_earn_rate' ] ) + 1.0 ), \ buy_hand_num * 100, 0 ] sleep( 1 ) except: pass self.save_data( self.df_trade, self.__file_path_trade ) self.save_data( self.df_position, self.__file_path_position )