def send(self, action): for event in self._events_container[self._context.trading_dt]: if event.event_type == EVENT.BAR: event.action = action self._split_and_publish(event) self._split_and_publish(Event(EVENT.SETTLEMENT)) tracker = self._context.tracker reward = tracker._portfolio_current_bar_returns[-1] info = {} info["returns_mean"] = tracker._returns_mean[-1] info["unit_sharpe_ratio"] = tracker._unit_sharpe_ratio[-1] info["draw_down"] = tracker._draw_down[-1] info["max_draw_down"] = tracker._max_draw_down[-1] info["profit_and_loss"] = tracker._portfolio_current_bar_pnl[-1] if self._context.trading_dt == self.available_trading_dts[-1]: is_done = True else: is_done = False if is_done: pass else: next_trading_dt = self._context.get_next_trading_dt() self._context.update_time(calendar_dt=next_trading_dt, trading_dt=next_trading_dt) return reward, is_done, info
def events(self, trading_dts): event_container = {} for trading_dt in trading_dts: events_within_bar = (Event(EVENT.BEFORE_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt), Event(EVENT.BAR, calendar_dt=trading_dt, trading_dt=trading_dt), Event(EVENT.AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) #yield events_within_bar event_container[trading_dt] = events_within_bar return event_container
def submit_order(self, order): if order.position_effect == POSITION_EFFECT.MATCH: raise TypeError("unsupported position_effect {}".format( order.position_effect)) account = self._context.get_account(order.order_book_id) self._context.event_bus.publish_event( Event(EVENT.ORDER_PENDING_NEW, account=account, order=order)) if order.is_final(): return if self._context.frequency == '1d' and not self._match_immediately: self._delayed_orders.append((account, order)) return self._open_orders.append((account, order)) order.active() self._context.event_bus.publish_event( Event(EVENT.ORDER_CREATION_PASS, account=account, order=order)) if self._match_immediately: self._match()
def __init__(self, data_source, look_backward_window=1, mode="rl", starting_cash={"STOCK": 1000000}, commission_multiplier=1, min_commission=5, tax_multiplier=1) -> None: self.look_backward_window = look_backward_window self.mode = mode self.starting_cash = starting_cash self.commission_multiplier = commission_multiplier self.min_commission = min_commission self.tax_multiplier = tax_multiplier self._context = Context(look_backward_window=look_backward_window) #set data_source self._context.set_data_source(data_source) #set event_source event_source = SimulationEventSource() self._context.set_event_source(event_source) #set broker broker = SimulationBroker(self._context) self._context.set_broker(broker) # transaction_cost decider transaction_cost_decider = CNStockTransactionCostDecider( commission_multiplier=commission_multiplier, min_commission=min_commission, tax_multiplier=tax_multiplier) self._context.set_transaction_cost_decider("CS", transaction_cost_decider) # setup account and portfolio portfolio = Portfolio(starting_cash=starting_cash, init_positions={}) self._context.set_portfolio(portfolio) # setup a tracker to record key info tracker = Tracker(self._context) self._context.set_tracker(tracker) self._context.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT)) #setUP executor if mode == "rl": self._executor = RLExecutor(self._context) else: self._executor = Executor(self._context) # user strategy user_strategy = Strategy(self._context)
def cancel_order(self, order): account = self._context.get_account(order.order_book_id) self._env.event_bus.publish_event( Event(EVENT.ORDER_PENDING_CANCEL, account=account, order=order)) order.mark_cancelled( "{order_id} order has been cancelled by user.".format( order_id=order.order_id)) self._env.event_bus.publish_event( Event(EVENT.ORDER_CANCELLATION_PASS, account=account, order=order)) try: self._open_orders.remove((account, order)) except ValueError: try: self._delayed_orders.remove((account, order)) except ValueError: pass
def after_trading(self, __): for account, order in self._open_orders: order.mark_rejected( "Order Rejected: {order_book_id} can not match. Market close.". format(order_book_id=order.order_book_id)) self._env.event_bus.publish_event( Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=order)) self._open_orders = self._delayed_orders self._delayed_orders = []
def _match(self, order_book_id=None): order_filter = None if order_book_id is None else lambda a_and_o: a_and_o[ 1].order_book_id == order_book_id for account, order in filter(order_filter, self._open_orders): self._get_matcher(order.order_book_id).match(account, order, open_auction=False) final_orders = [(a, o) for a, o in self._open_orders if o.is_final()] self._open_orders = [(a, o) for a, o in self._open_orders if not o.is_final()] for account, order in final_orders: if order.status == ORDER_STATUS.REJECTED or order.status == ORDER_STATUS.CANCELLED: self._env.event_bus.publish_event( Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=order))
def match(self, account, order, open_auction): if not (order.position_effect in self.SUPPORT_POSITION_EFFECTS and order.side in self.SUPPORT_SIDES): raise NotImplementedError order_book_id = order.order_book_id deal_price = self._deal_price_decider(order_book_id, order.side) fill = order.unfilled_quantity ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction) price = deal_price trade = Trade.__from_create__(order_id=order.order_id, price=price, amount=fill, side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount) trade._commission = self._context.get_trade_commission(trade) trade._tax = self._context.get_trade_tax(trade) order.fill(trade) self._turnover[order.order_book_id] += fill self._context.event_bus.publish_event( Event(EVENT.TRADE, account=account, trade=trade, order=order)) if order.type == ORDER_TYPE.MARKET and order.unfilled_quantity != 0: reason = "Order Cancelled: market order {order_book_id} volume {order_volume} is larger than 25% percent of current bar volume, fill {filled_volume} actually".format( order_book_id=order.order_book_id, order_volume=order.quantity, filled_volume=order.filled_quantity, ) order.mark_cancelled(reason)
def before_trading(self, _): for account, order in self._open_orders: order.active() self._env.event_bus.publish_event( Event(EVENT.ORDER_CREATION_PASS, account=account, order=order))
def _rl_events(self, trading_dts): event_container = {} for i, trading_dt in enumerate(trading_dts[:-1]): events_within_bar = [] events_within_bar.append( Event(EVENT.BAR, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_BAR, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.PRE_AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.PRE_SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) next_trading_dt = trading_dts[i + 1] events_within_bar.append( Event(EVENT.PRE_BEFORE_TRADING, calendar_dt=next_trading_dt, trading_dt=next_trading_dt)) events_within_bar.append( Event(EVENT.BEFORE_TRADING, calendar_dt=next_trading_dt, trading_dt=next_trading_dt)) events_within_bar.append( Event(EVENT.POST_BEFORE_TRADING, calendar_dt=next_trading_dt, trading_dt=next_trading_dt)) events_within_bar.append( Event(EVENT.PRE_BAR, calendar_dt=next_trading_dt, trading_dt=next_trading_dt)) event_container[trading_dt] = events_within_bar return event_container
def __init__(self, data_source, look_backward_window=1, mode="non-rl", starting_cash={"STOCK": 1000000}, commission_multiplier=1, min_commission=5, tax_multiplier=1) -> None: self.look_backward_window = look_backward_window self.mode = mode self.starting_cash = starting_cash self.commission_multiplier = commission_multiplier self.min_commission = min_commission self.tax_multiplier = tax_multiplier self._context = Context(look_backward_window=look_backward_window) #set mode self._context.set_mode(mode) #set data_source self._context.set_data_source(data_source) #set event_source event_source = SimulationEventSource() self._context.set_event_source(event_source) #set broker broker = SimulationBroker(self._context) self._context.set_broker(broker) # transaction_cost decider transaction_cost_decider = CNStockTransactionCostDecider( commission_multiplier=commission_multiplier, min_commission=min_commission, tax_multiplier=tax_multiplier) self._context.set_transaction_cost_decider("CS", transaction_cost_decider) # setup account and portfolio portfolio = Portfolio(starting_cash=starting_cash, init_positions={}) self._context.set_portfolio(portfolio) #setUP executor if mode == "rl": self._executor = RLExecutor(self._context) else: self._executor = Executor(self._context) # user strategy user_strategy = Strategy(self._context) # setup a tracker to record key info tracker = Tracker(self._context) self._context.set_tracker(tracker) self._context.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT)) self._context.update_time( calendar_dt=self._context.available_trading_dts[0], trading_dt=self._context.available_trading_dts[0]) # action and observation space self.action_space = gym.spaces.Box( 0, 1, shape=(len(data_source.order_book_ids_index), ), dtype=np.float32) # include cash # get the state space from the data min and max if look_backward_window == 1: self.observation_space = gym.spaces.Box( low=-np.inf, high=np.inf, shape=(len(data_source.order_book_ids_index), len(data_source.feature_list)), dtype=np.float32) else: self.observation_space = gym.spaces.Box( low=-np.inf, high=np.inf, shape=(len(data_source.order_book_ids_index), look_backward_window, len(data_source.feature_list)), dtype=np.float32)
def events(self, trading_dts): event_container = {} #for trading_dt in trading_dts[:-1]: for i, trading_dt in enumerate(trading_dts): #events_within_bar = ( Event(EVENT.BEFORE_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt), # Event(EVENT.BAR, calendar_dt=trading_dt, trading_dt=trading_dt), # Event(EVENT.AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt) # ) events_within_bar = [] events_within_bar.append( Event(EVENT.PRE_BEFORE_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.BEFORE_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_BEFORE_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.PRE_BAR, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.BAR, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_BAR, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.PRE_AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_AFTER_TRADING, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.PRE_SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) events_within_bar.append( Event(EVENT.POST_SETTLEMENT, calendar_dt=trading_dt, trading_dt=trading_dt)) #yield events_within_bar event_container[trading_dt] = events_within_bar return event_container