def _get_bonus_ratio(self, code, year): dividens = self.bonusDataManager.get_data( code=code, table_name=constant.table_name_dividend, crawler=cj.DividendsCrawler()) if base.is_df_validate(dividens): dividens = dividens.loc[(dividens['bonus_type'] == '年度分红')] if base.is_df_validate(dividens): dividens = dividens.sort_values(by=['report_date'], ascending=False).head(1) return dividens['bonus_ratio_rmb'].iloc[0]
def is_excuted(self, df, status_key): if not base.is_df_validate(df): return False try: return not np.isnan(df[status_key].iloc[0]) except Exception: return False
def regress(self, code, amount): yesterday = datetime.date.today() - datetime.timedelta(days=356 * 5) year_five = datetime.date.today() - datetime.timedelta(days=356 * 10) df_history = self.historyManager.get_day_k_history( code, str(year_five), str(yesterday)) if not base.is_df_validate(df_history): return amount df_history = df_history.sort_values(by=['date'], ascending=True) df_history = df_history.drop_duplicates(['code', 'date']) buy_count = 0 buy_price = 0.0 cur_price = 0.0 for index, row in df_history.iterrows(): date = row['date'] cur_price = float(row['close']) if _is_support(row['peTTM']) and 0 is buy_count: buy_count = amount // cur_price buy_price = float(row['close']) logging.info( 'time :{} buy counts:{}, price:{}, amount: {}'.format( date, buy_count, buy_price, amount)) amount -= buy_count * buy_price if not _is_support(row['peTTM']) and 0 is not buy_count: amount += cur_price * buy_count logging.info( 'time :{} sell counts:{}, price:{}, amount:{}'.format( date, buy_count, float(row['close']), amount)) buy_count = 0 #logging.info('time :{} pass, price:{} '.format(date, cur_price)) return amount + float(cur_price) * float(buy_count)
def is_supported(self, code, date): last_year = date.year - 1 cashflows = self.bonusDataManager.get_data( code, constant.talbe_name_cashflow, cj.CashflowCrawler()) rtn = get_value_year(cashflows, last_year, 'pub_date', ['total_liability', 'total_current_assets']) if not base.is_df_validate(rtn): return False # 流动资产 total_current_assets = float( rtn.get('total_current_assets') if rtn.get('total_current_assets' ) is not None else 0.0) balances = self.bonusDataManager.get_data(code, constant.table_name_balance, cj.BalanceCrawler()) rtn = get_value_year(balances, last_year, 'pub_date', ['total_current_liability']) if rtn is None: logging.info( ' filter_safecurrentratio drop, no last year capitals code {} ' .format(code)) return False # 流动负债合计 total_current_liability = float(rtn.get('total_current_liability')) rtn = (total_current_assets / total_current_liability) > 2 if not rtn: logging.info( ' filter_safecurrentratio drop,code: {}, total_current_assets: {}, total_current_liability: {}' .format(code, total_current_assets, total_current_liability)) return rtn
def filter(self, codes): #df_support_history = om.df_from_mongo(self.get_tmp_support_name()) df_support_history = None for code in codes: if base.is_df_validate(df_support_history) and \ len(df_support_history.loc[df_support_history['code'] == code]) > 0: logging.info( " history is supported in table: {} code {}".format( self.get_tmp_support_name(), code)) continue status = 0 try: yesterday = datetime.date.today() - datetime.timedelta(days=1) if self.is_supported(code, yesterday): status = 1 logging.info(' {} is supported code :{}'.format( self.get_tmp_support_name(), code)) except Exception as e: logging.error(' is supported error :{}'.format(e.args)) status = 0 value = { 'code': code, 'status': status, 'last_modify': constant.current_time_in_formate } om.update(self.get_tmp_support_name(), value, {'code': code})
def is_supported(self, code, date): last_year = date.year - 1 # 获取上一个报告日的有形资产 totle_tangibles = self._get_totle_tangibles(code, last_year) if None is totle_tangibles: return False cashflows = self.bonusDataManager.get_data( code, constant.talbe_name_cashflow, cj.CashflowCrawler()) rtn = get_value_year(cashflows, last_year, 'pub_date', ['total_liability', 'total_current_assets']) if base.is_df_validate(rtn): # 总负债 total_liability = float(rtn.get('total_liability')) # 流动资产 total_current_assets = float( rtn.get('total_current_assets') if rtn. get('total_current_assets') is not None else 0.0) if not total_liability < totle_tangibles: logging.info( 'filter SafeTotalLiability drop code {} :, total_liability: {} , totle_tangibles: {} ' .format(code, total_liability, totle_tangibles)) return False if not total_current_assets < totle_tangibles: logging.info( 'filter SafeTotalLiability drop code {} :, total_current_assets: {} , totle_tangibles: {} ' .format(code, total_current_assets, totle_tangibles)) return True else: return False
def getLastDf(date): date_str = date.strftime("%Y-%m-%d") resDf = om.df_from_mongo(constant.table_name_k_data, {'date': date_str}, translate_types={'date': datetime.date}) if not base.is_df_validate(resDf) or len(resDf) < 10: date -= datetime.timedelta(days=1) return getLastDf(date) return resDf
def is_supported(self, df, status_key): # 还没处理过,返回true 为了处理 if not base.is_df_validate(df): return True if not status_key in df.keys(): return False return df[status_key].iloc[0] == 1
def update_history(self, code, key, status): value = om.get(constant.table_name_task_order_graham_tendency, {'code': code}) if not base.is_df_validate(value): value = {'code': code} value[key] = status value['last_modify'] = constant.current_time_in_formate om.update(constant.table_name_task_order_graham_tendency, value, {'code': code})
def filter(self, codes): df_task_history = om.df_from_mongo( constant.table_name_task_order_graham_tendency) for code in codes: row = None if base.is_df_validate(df_task_history): row = df_task_history.loc[df_task_history['code'] == code] for key, value in self.grahams.items(): if not self.excute_one(key, value, code, row): break
def get_data(self, code, table_name, crawler): values = om.df_from_mongo(table_name, {'code':code}, translate_types=crawler.get_translate_types()) if not base.is_df_validate(values): values = crawler.excute(code) values['code'] = code om.df_to_mongo(table_name, values, crawler.get_keys()) values = om.df_from_mongo(table_name, {'code': code}, translate_types=crawler.get_translate_types()) return values
def regress(date, trade): #sql = 'select * from k_data where code = \'{}\' '.format(code) resDf = om.df_from_mongo(constant.table_name_k_data, {'date': date}, translate_types={'date': datetime.date}) if not base.is_df_validate(resDf): return None df = resDf.sort_values(by=['psTTM'], ascending=False) logging.info('regress :{}'.format(date)) for index, row in df.iterrows(): if _is_support(row['peTTM']): trade.buy(row) else: trade.sell(row)
def _get_totle_tangibles(self, code, year): df_balance = self.bonusDataManager.get_data( code, constant.table_name_balance, cj.BalanceCrawler()) if base.is_df_validate(df_balance): df_balance = df_balance.sort_values(by=['report_date'], ascending=False).head(1) intangible_assets = df_balance['intangible_assets'].iloc[0].astype( float) if intangible_assets > 0: totle_tangibles = df_balance['total_assets'].iloc[0].astype( float) - intangible_assets else: totle_tangibles = df_balance['total_assets'].iloc[0].astype( float) return totle_tangibles
def modify_k_data_history(): df_company = om.df_from_mongo(constant.table_name_company) codes = df_company['code'].to_list() for code in codes: start = time.perf_counter() df = om.df_from_mongo(constant.table_name_k_data, {'code': code}) if base.is_df_validate(df): df = df.sort_values(by=['date'], ascending=True) date = df.head(1)['date'].iloc[0] om.update(constant.table_name_k_data_history, {'$set': { 'code': code, 'start_date': date }}, {'code': code}) print((time.perf_counter() - start))
def is_supported(self, code, date): last_year = date.year cashflows = self.bonusDataManager.get_data( code, constant.talbe_name_cashflow, cj.CashflowCrawler()) rtn = get_value_year(cashflows, last_year, 'pub_date', ['total_liability', 'total_current_assets']) if base.is_df_validate(rtn): # 总负债 total_liability = float(rtn.get('total_liability')) # 流动资产 total_current_assets = float( rtn.get('total_current_assets') if rtn. get('total_current_assets') is not None else 0.0) capitals = self.bonusDataManager.get_data( code, constant.talbe_name_capital, cj.CapitalCrawler()) rtn = get_value_year(capitals, last_year, 'pub_date', ['share_total']) share_total = float(rtn.get('share_total')) * 10000 # print("cashflow : close {} current {}".format(close, (total_current_assets - total_liability)/ share_total* 2 / 3)) tmp = (total_current_assets - total_liability) / share_total if not tmp > 0: return False close = self._get_close(code) if None is close: return False rtn = close < tmp * 2 / 3 if not rtn: logging.info('filter_cashflow drop code {} : {} '.format( code, tmp)) return not rtn return False
def main(code, start, end='', startcash=10000, qts=500, com=0.001): print('###code:' + code) # 创建主控制器 cerebro = bt.Cerebro() # 导入策略参数寻优 cerebro.optstrategy(MyStrategy) # 获取数据 historyManager = HistoryDataManager.HistoryDataManager() df = historyManager.get_day_k_history(code, '2016-01-01', '2020-07-07') if not base.is_df_validate(df): return startcash df = df.sort_values(by=['date'], ascending=True) df = df[df['volume'].astype(float) > 0.0] if len(df) < 100: return startcash df.index = pd.to_datetime(df.date) df = df[['open', 'high', 'low', 'close', 'volume']].astype(float) data = bt.feeds.PandasData(dataname=df) # 初始化cerebro回测系统设置 cerebro = bt.Cerebro() # 加载数据 cerebro.adddata(data) # 将交易策略加载到回测系统中 cerebro.addstrategy(MyStrategy) # 设置初始资本为100,000 cerebro.broker.setcash(100000.0) # 每次固定交易数量 cerebro.addsizer(bt.sizers.FixedSize, stake=1000) # 手续费 cerebro.broker.setcommission(commission=0.001) print(code + '初始资金: %.2f' % cerebro.broker.getvalue()) cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='SharpeRatio') cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW') results = cerebro.run() return cerebro.broker.getvalue()
def is_supported(self, code, date): yesterday = date year_five = yesterday - datetime.timedelta(days=356 * 5) df = self.historyManager.get_day_k_history(code, str(year_five), str(yesterday)) if not base.is_df_validate(df): return False df = df.sort_values(by=['date'], ascending=False) try: cur_peTTM = float(df.iloc[0].loc['peTTM']) if cur_peTTM < 0: return False df['peTTM'] = df['peTTM'].astype(float, errors='ignore') df = df.sort_values(by=['peTTM'], ascending=False) max_peTTM = df['peTTM'].iloc[0] return cur_peTTM < max_peTTM * 0.4 except Exception: logging.error('peTTM ratio support exception {}'.format(code)) return False