def _init_files(self, log_dir): self.fills_file = open(os.path.join(log_dir, 'fills.csv'), 'w') self.orders_file = open(os.path.join(log_dir, 'orders.csv'), 'w') self.pnl_file = open(os.path.join(log_dir, 'pnl.csv'), 'w') self.fills_file.write(Fill.get_header() + '\n') self.orders_file.write(OrderCommon.get_header() + '\n') self.pnl_file.write('timestamp,symbol,pnl,cum_pnl\n')
def print_output_files(self, input_args): if self.log_dir is None: raise ValueError("asked to print results, but log_dir is None") print("printing results to " + self.log_dir) fills_file = open(os.path.join(self.log_dir, 'fills.csv'), 'w') orders_file = open(os.path.join(self.log_dir, 'orders.csv'), 'w') pnl_file = open(os.path.join(self.log_dir, 'pnl.csv'), 'w') pars_used_file = open(os.path.join(self.log_dir, 'parameters_used'), 'w') summary_file = open(os.path.join(self.log_dir, 'summary'), 'w') fills_file.write(Fill.get_header() + '\n') orders_file.write(OrderCommon.get_header() + '\n') for f in self.fills_hist: # type: Fill fills_file.write(f.to_line() + '\n') for o in self.order_hist: # type: OrderCommon orders_file.write(o.to_line() + '\n') pnl_file.write('time,symbol,pnl,cum_pnl\n') for s in self.SYMBOLS: sum = 0 for p in self.closed_positions_hist[s]: # type: PositionSim sum += p.realized_pnl pnl_file.write(','.join([str(p.current_timestamp.strftime('%Y-%m-%dT%H:%M:%S')), s.name, str(p.realized_pnl), str(sum)]) + '\n') pars_used_file.write(str(input_args)) pars_used_file.write("") summary_file.write(self.summary.to_str()) pars_used_file.close() pnl_file.close() fills_file.close() orders_file.close() summary_file.close()
def _execute_order(self, order: OrderCommon) -> Fill: assert self.tick_num < len(self.ohlcv) if order.status != OrderStatus.Pending and not order.is_open(): raise ValueError("expected order to be opened, but got " + str(order.status) + ". Order = \n" + order.get_header() + "\n" + str(order)) current_candle = self.current_candle() current_time = current_candle.name # pd.Timestamp high = current_candle.high low = current_candle.low open = current_candle.open close = current_candle.close position = self.positions[order.symbol] # type: PositionSim current_qty = position.signed_qty qty_fill = qty_to_close = outstanding_qty = None crossed = False if order.type is OrderType.Market: crossed = True price_fill = self._estimate_price() qty_fill = order.signed_qty elif order.type is OrderType.Limit: price_fill = order.price max_qty_fill = order.leaves_qty * order.side() # clip fill if (open <= order.price <= close) or (close <= order.price <= open): qty_fill = max_qty_fill elif high == low == order.price: qty_fill = round(0.5 * max_qty_fill) else: if low < order.price < high: if order.is_sell(): factor = max((high - order.price) / (high - low), 0.50001) assert factor >= 0 else: factor = max((low - order.price) / (low - high), 0.50001) assert factor >= 0 qty_fill = round(factor * max_qty_fill) if qty_fill is not None: crossed = True else: raise ValueError("order type " + str(order.type) + " not supported") if not crossed: return None # type: Fill if position.is_open and position.would_change_side(qty_fill): qty_to_close = float(sign(qty_fill)) * min(abs(current_qty), abs(qty_fill)) outstanding_qty = qty_fill - qty_to_close if order.fill(qty_fill) or order.type == OrderType.Market: order.status = OrderStatus.Filled order.fill_price = price_fill if order.price is not None and ((open <= order.price <= close) or (close <= order.price <= open)): assert order.status == OrderStatus.Filled fee = self.FEE[order.type] if outstanding_qty: position = self._update_position(order.symbol, qty=qty_to_close, price=price_fill, leverage=self.leverage[order.symbol], current_timestamp=current_time, fee=fee) assert not position.is_open position = self._update_position(order.symbol, qty=outstanding_qty, price=price_fill, leverage=self.leverage[order.symbol], current_timestamp=current_time, fee=fee) assert position.is_open else: self._update_position(order.symbol, qty=qty_fill, price=price_fill, leverage=self.leverage[order.symbol], current_timestamp=current_time, fee=fee) fill = Fill(order=order, qty_filled=qty_fill, price_fill=price_fill, fill_time=current_time, fill_type=FillType.complete if (order.status == OrderStatus.Filled) else FillType.partial) self.fills_hist += [fill] self.active_orders = drop_closed_orders_dict(self.active_orders) if self.can_call_handles: order.tactic.handle_fill(fill) return fill