def close(self, dt: datetime, price: float, comment: str = ""): """ ポジションを閉じます。 """ self._is_closed = True self._close_time = dt self._close_price = price self._close_comment = comment closing_eargs = EventArgs({ "position": self, "exec_price": self._close_price }) self._on_closing(closing_eargs) self._exec_close_price = closing_eargs.params["exec_price"] self._on_closed(EventArgs({"position": self})) self._logger.debug( "position_closed: action={}, exec_price={}, exec_amount={}, comment={}" .format(self.close_action, self.exec_close_price, self.exec_order_amount, self.close_comment))
def open(self, dt: datetime, action: str, price: float, amount: float, comment: str = "", limit_price: float = None, stop_price: float = None): """ ポジションを開きます。 """ self._open_time = dt self._open_action = action self._open_price = price self._order_amount = amount self._open_comment = comment self._limit_price = limit_price self._stop_price = stop_price opening_eargs = EventArgs({ "position": self, "exec_price": self._open_price, "exec_amount": self._order_amount, "cancel": False }) self._on_opening(opening_eargs) if opening_eargs.params["cancel"]: self._is_canceled = True return self._exec_open_price = opening_eargs.params["exec_price"] self._exec_order_amount = opening_eargs.params["exec_amount"] self._is_opened = True self._on_opened(EventArgs({"position": self})) self._logger.debug( "position_opened: action={}, exec_price={}, exec_amount={}, comment={}" .format(self.open_action, self.exec_open_price, self.exec_order_amount, self.open_comment))
def go_next(self) -> bool: """ 次のローソク足を取得する Returns ------- bool 取得に成功した場合True、失敗した場合False """ # バックテストモードの場合 if self._backtest_mode: # ティックデータが存在しない場合 if len(self._sequential_prices) == 0: if self._datetime_cursor < self._datetime_to: # ローソク足の取得範囲を計算する self._datetime_cursor += timedelta( minutes=Period.to_minutes(self._period)) range_from = self._datetime_cursor - timedelta( minutes=Period.to_minutes(self._period) * (self._cache_bar_count - 1)) range_to = self._datetime_cursor # ローカルDB、もしくはサーバーからローソク足を取得する self._ohlcs = self._get_ohlcs_from_local_or_server( self._currency_pair, self._period, range_from, range_to) # より下位のローソク足を取得する detail_range_from = self._ohlcs["times"][-1] detail_range_to = self._ohlcs["times"][-1] + timedelta( minutes=Period.to_minutes(self._period)) - timedelta( minutes=1) detail_ohlcs = self._get_ohlcs_from_local_or_server( self._currency_pair, Period.zoom_period(self._period, 4), detail_range_from, detail_range_to) # より下位のローソク足をティックデータに変換する for i, x in enumerate(detail_ohlcs["times"]): self._sequential_prices.append( detail_ohlcs["opens"][i]) if detail_ohlcs["closes"][i] > detail_ohlcs["opens"][i]: self._sequential_prices.append( detail_ohlcs["lows"][i]) self._sequential_prices.append( detail_ohlcs["highs"][i]) else: self._sequential_prices.append( detail_ohlcs["highs"][i]) self._sequential_prices.append( detail_ohlcs["lows"][i]) self._sequential_prices.append( detail_ohlcs["closes"][i]) self._sequential_prices[0] = self._ohlcs["opens"][-1] self._sequential_prices[self._sequential_prices.index( max(self._sequential_prices) )] = self._ohlcs["highs"][-1] self._sequential_prices[self._sequential_prices.index( min(self._sequential_prices) )] = self._ohlcs["lows"][-1] self._sequential_prices[-1] = self._ohlcs["closes"][-1] # ティックデータで最新のローソク足の価格を更新する self._ohlcs["opens"][-1] = self._sequential_prices[0] self._ohlcs["highs"][-1] = self._sequential_prices[0] self._ohlcs["lows"][-1] = self._sequential_prices[0] self._ohlcs["closes"][-1] = self._sequential_prices[0] self._sequential_prices.pop(0) # ローソク足更新イベントを実行する self._on_ohlc_updated(EventArgs()) return True else: return False # ティックデータが存在する場合 else: # ティックデータで最新のローソク足の価格を更新する if self._sequential_prices[0] > self._ohlcs["highs"][-1]: self._ohlcs["highs"][-1] = self._sequential_prices[0] if self._sequential_prices[0] < self._ohlcs["lows"][-1]: self._ohlcs["lows"][-1] = self._sequential_prices[0] self._ohlcs["closes"][-1] = self._sequential_prices[0] self._sequential_prices.pop(0) # ローソク足更新イベントを実行する self._on_ohlc_updated(EventArgs()) # リアルタイムモードの場合 else: # ローソク足の取得範囲を計算する self._datetime_cursor = datetime.now() self._to_datetime = self._datetime_cursor range_from = self._datetime_cursor - timedelta( minutes=Period.to_minutes(self._period) * (self._cache_bar_count - 1)) range_to = self._datetime_cursor # サーバーが過去のローソク足を返す場合の対策 try_count = 0 previous_time = None if "times" in self._ohlcs: previous_time = self._ohlcs["times"][-1] while True: # サーバーからローソク足を取得する self._ohlcs = self._get_ohlcs_from_server( self._currency_pair, self._period, range_from, range_to) try_count += 1 if previous_time is None \ or (previous_time is not None and self._ohlcs["times"][-1] >= previous_time): break else: print("server response time is wrong.") if try_count > 100: raise Exception("server response time is wrong.") time.sleep(1.0) # ローソク足更新イベントを実行する self._on_ohlc_updated(EventArgs()) return True