def do_trade_by_policy(stock_info, action_item, action_item_policy, current_date): logging.debug("begin try_trade_by_policy, current_date:%s", current_date) current_date_str = DatetimeUtil.to_datetime_str(current_date) current_stock_daily_info = PolicyReportUtil.get_the_stock_daily_info( stock_info, current_date_str) if current_stock_daily_info is None: logging.debug("no stock info for %s", current_date_str) return assert 0 <= len(action_item.buy_stock_action) - len( action_item.sell_stock_action) assert len(action_item.buy_stock_action) - len( action_item.sell_stock_action) <= 1 if not PolicyUtil.check_if_allow_trade(action_item, current_date): logging.debug("not allow trade for %s", current_date) logging.debug("end try_trade_by_policy") return if len(action_item.buy_stock_action) == len( action_item.sell_stock_action): stock_daily_info_list = PolicyUtil.filter_stock_daily_info_list( stock_info, action_item_policy.buy.days_watch, current_date_str) trend_daily_info_list = PolicyUtil.filter_stock_daily_info_list( stock_info, action_item_policy.buy.trend.days_watch, current_date_str) if stock_daily_info_list: previous_stock_daily_info = PolicyReportUtil.get_previous_stock_daily_info( stock_info, action_item.trade_watch_start_date, current_date_str) PolicyUtil.check_if_buy(stock_info.stock_id, stock_daily_info_list, trend_daily_info_list, action_item, action_item_policy, current_date_str, current_stock_daily_info, previous_stock_daily_info) else: assert len(action_item.buy_stock_action) == len( action_item.sell_stock_action) + 1 stock_daily_info_list = PolicyUtil.filter_stock_daily_info_list( stock_info, action_item_policy.sell.days_watch, current_date_str) trend_daily_info_list = PolicyUtil.filter_stock_daily_info_list( stock_info, action_item_policy.sell.trend.days_watch, current_date_str) if stock_daily_info_list: PolicyUtil.check_if_sell(stock_info.stock_id, stock_daily_info_list, trend_daily_info_list, action_item, action_item_policy, current_date_str, current_stock_daily_info) logging.debug("end try_trade_by_policy")
def test_get_the_stock_daily_info(self): stock_info = StockInfo() daily_info = stock_info.daily_info.add() daily_info.date = "20170101" daily_info = stock_info.daily_info.add() daily_info.date = "20170102" daily_info = stock_info.daily_info.add() daily_info.date = "20170105" self.assertTrue( PolicyReportUtil.get_the_stock_daily_info(stock_info, "20170101")) self.assertTrue( PolicyReportUtil.get_the_stock_daily_info(stock_info, "20170102")) self.assertTrue(not PolicyReportUtil.get_the_stock_daily_info( stock_info, "20170103")) self.assertTrue( PolicyReportUtil.get_the_stock_daily_info(stock_info, "20170105"))
def test_greater_policy_report_roi_top(self): left = PolicyReport() left.roi = 1.0 left.stock_sell_times = 2 left.stock_buy_times = 2 left.trade_profit_times = 2 right = PolicyReport() right.roi = 1.0 right.stock_sell_times = 2 right.stock_buy_times = 2 right.trade_profit_times = 2 self.assertTrue( PolicyReportUtil.greater_policy_report_roi(left, right) == 0) left.roi = 1.1 self.assertTrue( PolicyReportUtil.greater_policy_report_roi(left, right) < 0) left.roi = 1.0 left.stock_sell_times = 3 self.assertTrue( PolicyReportUtil.greater_policy_report_roi(left, right) < 0) left.stock_sell_times = 1 self.assertTrue( not PolicyReportUtil.greater_policy_report_roi(left, right) < 0) left.stock_sell_times = 2 left.stock_buy_times = 3 self.assertTrue( PolicyReportUtil.greater_policy_report_roi(left, right) < 0) left.stock_buy_times = 1 self.assertTrue( not PolicyReportUtil.greater_policy_report_roi(left, right) < 0) left.stock_buy_times = 2 left.trade_profit_times = 3 self.assertTrue( PolicyReportUtil.greater_policy_report_roi(left, right) < 0)
def filter_stock_daily_info_list(stock_info, days_watch, current_date_str): end_date = DatetimeUtil.from_date_str(current_date_str) result = [] for i in range(days_watch, 0, -1): the_date = end_date - datetime.timedelta(days=i) the_daily_info = PolicyReportUtil.get_the_stock_daily_info( stock_info, DatetimeUtil.to_datetime_str(the_date)) if the_daily_info: result.append(the_daily_info) return result
def test_get_cash_value_available(self): action_item = Person.StockPolicyActionsItem() action_item.cash_taken_in = 3001 action_item.trade_watch_start_date = "20170101" action_item.trade_watch_end_date = "20170102" buy_action = action_item.buy_stock_action.add() buy_action.date = "20170101" buy_action.at_price = 10 buy_action.volumn = 200 buy_action.stock_trade_cost = 1 self.assertEqual( 1000, PolicyReportUtil.get_cash_value_available(action_item))
def test_get_asset_value_out(self): stock_info = StockInfo() daily_info = stock_info.daily_info.add() daily_info.date = "20170101" daily_info.low = daily_info.high = daily_info.close = 10 daily_info = stock_info.daily_info.add() daily_info.date = "20170102" daily_info.low = daily_info.high = daily_info.close = 10.5 daily_info = stock_info.daily_info.add() daily_info.date = "20170105" daily_info.low = daily_info.high = daily_info.close = 10.1 action_item = Person.StockPolicyActionsItem() action_item.cash_taken_in = 5100 action_item.trade_watch_start_date = "20170101" action_item.trade_watch_end_date = "20170102" buy_action = action_item.buy_stock_action.add() buy_action.date = "20170101" buy_action.at_price = 10 buy_action.volumn = 200 buy_action.stock_trade_cost = 1 self.assertEqual( 5100 - 1 - 10 * 200 + 10.5 * 200 - 1, PolicyReportUtil.get_asset_value_out(stock_info, action_item)) action_item.trade_watch_end_date = "20170105" self.assertEqual( 5100 - 1 - 10 * 200 + 10.1 * 200 - 1, PolicyReportUtil.get_asset_value_out(stock_info, action_item)) sell_action = action_item.sell_stock_action.add() sell_action.date = "20170102" sell_action.at_price = 10.3 sell_action.volumn = 200 sell_action.stock_trade_cost = 1 self.assertEqual( 5100 - 1 - 10 * 200 + 10.3 * 200 - 1, PolicyReportUtil.get_asset_value_out(stock_info, action_item))
def test_get_previous_stock_daily_info(self): stock_info = StockInfo() daily_info = stock_info.daily_info.add() daily_info.date = "20170101" daily_info = stock_info.daily_info.add() daily_info.date = "20170102" daily_info = stock_info.daily_info.add() daily_info.date = "20170105" daily_info = stock_info.daily_info.add() daily_info.date = "20170106" daily_info = stock_info.daily_info.add() daily_info.date = "20170108" self.assertEqual( "20170102", PolicyReportUtil.get_previous_stock_daily_info( stock_info, "20170101", "20170105").date) self.assertEqual( None, PolicyReportUtil.get_previous_stock_daily_info( stock_info, "20170103", "20170105")) self.assertEqual( "20170105", PolicyReportUtil.get_previous_stock_daily_info( stock_info, "20170101", "20170106").date)
def test_build_watch_days(self): stock_info = StockInfo() daily_info = stock_info.daily_info.add() daily_info.date = "20170101" daily_info = stock_info.daily_info.add() daily_info.date = "20170102" daily_info = stock_info.daily_info.add() daily_info.date = "20170105" daily_info = stock_info.daily_info.add() daily_info.date = "20170106" action_item = Person.StockPolicyActionsItem() action_item.trade_watch_start_date = "20170103" action_item.trade_watch_end_date = "20170107" self.assertEqual( 2, PolicyReportUtil.build_watch_days(stock_info.daily_info, action_item))
def test_build_action_item_report(self): stock_info = StockInfo() daily_info = stock_info.daily_info.add() daily_info.date = "20170101" daily_info.low = daily_info.high = daily_info.close = 10 daily_info = stock_info.daily_info.add() daily_info.date = "20170102" daily_info.low = daily_info.high = daily_info.close = 10.5 daily_info = stock_info.daily_info.add() daily_info.date = "20170105" daily_info.low = daily_info.high = daily_info.close = 10.1 daily_info = stock_info.daily_info.add() daily_info.date = "20170106" daily_info.low = daily_info.high = daily_info.close = 9 daily_info = stock_info.daily_info.add() daily_info.date = "20170108" daily_info.low = daily_info.high = daily_info.close = 10.0 daily_info = stock_info.daily_info.add() daily_info.date = "20170109" daily_info.low = daily_info.high = daily_info.close = 10.9 daily_info = stock_info.daily_info.add() daily_info.date = "20170110" daily_info.low = daily_info.high = daily_info.close = 9.5 action_item = Person.StockPolicyActionsItem() action_item.cash_taken_in = 5100.0 action_item.trade_watch_start_date = "20170101" action_item.trade_watch_end_date = "20170102" buy_action = action_item.buy_stock_action.add() buy_action.date = "20170101" buy_action.at_price = 10 buy_action.volumn = 200 buy_action.stock_trade_cost = 1 report = PolicyReport() PolicyReportUtil.build_action_item_report(stock_info, action_item, report) self.assertEqual(1, report.stock_watch_days) self.assertEqual(5100, report.cash_taken_in) self.assertEqual(5100 - 10 * 200 - 1 + 10.5 * 200 - 1, report.cash_taken_out) self.assertEqual( float(report.cash_taken_out) / report.cash_taken_in, report.roi) self.assertEqual(1, report.stock_buy_times) self.assertEqual(0, report.stock_sell_times) self.assertEqual(1, report.trade_profit_times) self.assertEqual(0, report.trade_loss_times) self.assertEqual(1, report.stock_hold_days) self.assertEqual(1, report.stock_hold_profit_days) self.assertEqual(0, report.stock_hold_loss_days) self.assertEqual(report.stock_buy_times - report.stock_sell_times, report.stock_hold_no_sell_times) action_item.trade_watch_end_date = "20170105" PolicyReportUtil.build_action_item_report(stock_info, action_item, report) self.assertEqual(5100 - 10 * 200 - 1 + 10.1 * 200 - 1, report.cash_taken_out) self.assertEqual(report.stock_buy_times - report.stock_sell_times, report.stock_hold_no_sell_times) sell_action = action_item.sell_stock_action.add() sell_action.date = "20170102" sell_action.at_price = 10.2 sell_action.volumn = 200 sell_action.stock_trade_cost = 1 PolicyReportUtil.build_action_item_report(stock_info, action_item, report) self.assertEqual(2, report.stock_watch_days) self.assertEqual(5100, report.cash_taken_in) self.assertEqual(5100 - 10 * 200 - 1 + 10.2 * 200 - 1, report.cash_taken_out) self.assertEqual(report.cash_taken_out / report.cash_taken_in, report.roi) self.assertEqual(1, report.stock_buy_times) self.assertEqual(1, report.stock_sell_times) self.assertEqual(1, report.trade_profit_times) self.assertEqual(0, report.trade_loss_times) self.assertEqual(1, report.stock_hold_days) self.assertEqual(1, report.stock_hold_profit_days) self.assertEqual(0, report.stock_hold_loss_days) self.assertEqual(report.stock_buy_times - report.stock_sell_times, report.stock_hold_no_sell_times) sell_action.date = "20170102" sell_action.at_price = 9 sell_action.volumn = 200 sell_action.stock_trade_cost = 1 PolicyReportUtil.build_action_item_report(stock_info, action_item, report) self.assertEqual(2, report.stock_watch_days) self.assertEqual(5100, report.cash_taken_in) self.assertEqual(5100 - 10 * 200 - 1 + 9 * 200 - 1, report.cash_taken_out) self.assertEqual(report.cash_taken_out / report.cash_taken_in, report.roi) self.assertEqual(1, report.stock_buy_times) self.assertEqual(1, report.stock_sell_times) self.assertEqual(0, report.trade_profit_times) self.assertEqual(1, report.trade_loss_times) self.assertEqual(1, report.stock_hold_days) self.assertEqual(0, report.stock_hold_profit_days) self.assertEqual(1, report.stock_hold_loss_days) self.assertEqual(report.stock_buy_times - report.stock_sell_times, report.stock_hold_no_sell_times) buy_action = action_item.buy_stock_action.add() buy_action.date = "20170105" buy_action.at_price = 10.5 buy_action.volumn = 200 buy_action.stock_trade_cost = 1 action_item.trade_watch_end_date = "20170110" PolicyReportUtil.build_action_item_report(stock_info, action_item, report) self.assertEqual(6, report.stock_watch_days) self.assertEqual(5100, report.cash_taken_in) self.assertEqual( 5100 - 10 * 200 - 1 + 9 * 200 - 1 - 10.5 * 200 - 1 + 9.5 * 200 - 1, report.cash_taken_out) self.assertEqual(report.cash_taken_out / report.cash_taken_in, report.roi) self.assertEqual(2, report.stock_buy_times) self.assertEqual(1, report.stock_sell_times) self.assertEqual(0, report.trade_profit_times) self.assertEqual(2, report.trade_loss_times) self.assertEqual(5, report.stock_hold_days) self.assertEqual(1, report.stock_hold_profit_days) self.assertEqual(4, report.stock_hold_loss_days) self.assertEqual(report.stock_buy_times - report.stock_sell_times, report.stock_hold_no_sell_times)
def train(person, is_validate=False): logging.info("begin train, stock info size:%s, policy info size:%s", len(person.stock_info), len(person.policy_info)) for policy in person.policy_info: logging.info("begin train for policy_id:%s", policy.id) for stock_info in person.stock_info: if not stock_info.daily_info or stock_info.daily_info[ -1].low < policy.min_stock_price: continue logging.info( "begin train for stock_id:%s,policy_id:%s,stock_daily_info_size:%s", stock_info.stock_id, policy.id, len(stock_info.daily_info)) watch_days = max(policy.buy.days_watch, policy.sell.days_watch) trade_watch_date_list = PolicyUtil.get_trade_watch_date_list( stock_info.daily_info, watch_days, localconfig.max_watch_jump_times, localconfig.JUMPS_PER_WATCH) logging.debug("trade_watch_date_list:%s", trade_watch_date_list) for item in trade_watch_date_list: trade_watch_start_date_str, trade_watch_end_date_str = item action_item = person.action_items.add() action_item.cash_taken_in = person.cash_taken_in action_item.stock_id = stock_info.stock_id action_item.policy_id = policy.id action_item.trade_watch_start_date = trade_watch_start_date_str action_item.trade_watch_end_date = trade_watch_end_date_str PolicyUtil.build_policy_actions(stock_info, action_item, policy) PolicyReportUtil.build_action_item_report( stock_info, action_item, action_item.report) # clear memory now del action_item.buy_stock_action[:] del action_item.sell_stock_action[:] logging.info("end train for policy_id, stock_id") PolicyReportUtil.build_summary_policy_report_for_stock_policy( person, is_validate) del person.action_items[:] logging.info("end train for policy_id:%s", policy.id) PolicyReportUtil.build_summary_policy_report_for_policy( person, is_validate) PolicyReportUtil.build_summary_policy_report_for_policy_group( person, is_validate) PolicyReportUtil.build_summary_policy_report_for_stock_policy_group( person, is_validate) PolicyReportUtil.build_sort_report(person) # clear other empty del person.stock_info[:] del person.policy_info[:] PolicyReportUtil.print_summary(person) logging.info("end train") return
def check_if_buy(stock_id, stock_daily_info_list, trend_daily_info_list, action_item, action_item_policy, current_date_str, current_stock_daily_info, previous_stock_daily_info): the_low_price, the_high_price = current_stock_daily_info.low, current_stock_daily_info.high if len(action_item.sell_stock_action) < len( action_item.buy_stock_action): logging.debug("quit buy for wait sell") return assert len(action_item.buy_stock_action) == len( action_item.sell_stock_action) full_trend = PolicyUtil.get_flow_trend_cachable( stock_id, current_date_str, action_item_policy.buy.trend.days_watch, trend_daily_info_list, action_item_policy.buy.trend.trend_mode) if action_item_policy.buy.trend.growth_percent == localconfig.DEFAULT_CONFIG: if_continue = full_trend in localconfig.BUY_TREND_PERCENT.filter if localconfig.BUY_TREND_PERCENT.filter else True else: if_continue = action_item_policy.buy.trend.growth_percent == full_trend if not if_continue: return last_sequential_trend = PolicyPredictUtil.get_sequential_trend( trend_daily_info_list, action_item_policy.buy.trend.trend_mode) if action_item_policy.buy.trend.last_sequential_trend_count == localconfig.DEFAULT_CONFIG: if_continue = last_sequential_trend in localconfig.LAST_BUY_SEQUENTIAL_TREND_COUNT.filter if localconfig.LAST_BUY_SEQUENTIAL_TREND_COUNT.filter else True else: if_continue = action_item_policy.buy.trend.last_sequential_trend_count == last_sequential_trend if not if_continue: logging.debug( "ignore trend:%s vs %s", last_sequential_trend, action_item_policy.buy.trend.last_sequential_trend_count) return current_price = PercentPriceUtil.get_percent_price( stock_id, action_item_policy.buy.days_watch, current_date_str, stock_daily_info_list, action_item_policy.buy.at_percent) if current_price is None: logging.debug("quit buy for empty percent price") return if previous_stock_daily_info: current_price_percent = int(100.0 * current_price / previous_stock_daily_info.close) # NOTE: 这里进行了归一化, 需要与localconfig配合 current_price_percent = max(current_price_percent, 80) current_price_percent = min(current_price_percent, 120) if action_item_policy.buy.last_close_price_percent == localconfig.DEFAULT_CONFIG: if_continue = current_price_percent in localconfig.LAST_CLOSE_PRICE_PERCENT.filter if localconfig.LAST_CLOSE_PRICE_PERCENT.filter else True else: if_continue = action_item_policy.buy.last_close_price_percent == current_price_percent if not if_continue: logging.debug("quit buy for last_close_price_percent:%s", current_price_percent) return if current_price <= the_low_price: logging.debug( "quit buy for too low percent_price:%s < low_price:%s", current_price, the_low_price) return current_price = min(current_price, the_high_price) cash_value_left_to_buy = PolicyReportUtil.get_cash_value_available( action_item) logging.debug("cash value left:%s", cash_value_left_to_buy) if cash_value_left_to_buy <= 0: return if current_price < action_item_policy.min_stock_price: return stock_action = action_item.buy_stock_action.add() stock_action.date = current_date_str stock_action.at_price = current_price stock_action.volumn, stock_action.stock_trade_cost = PolicyUtil.get_volumn_and_trade_cost( cash_value_left_to_buy, current_price) stock_action.option_trade_cost = 0 logging.debug( "do buy stock, id:%s, date:%s, at_price:%s(%s-%s), volumn:%s", stock_id, stock_action.date, stock_action.at_price, the_low_price, the_high_price, stock_action.volumn)