예제 #1
0
 def _position_repository_position_opening(self, sender: object,
                                           eargs: EventArgs):
     """
     リポジトリでポジションを開くときに発生します。
     """
     position = eargs.params["position"]
     position_repository = eargs.params["position_repository"]
     exec_price, exec_amount, cancel = self._on_position_opening(
         position, position_repository)
     eargs.params["exec_price"] = exec_price
     eargs.params["exec_amount"] = exec_amount
     eargs.params["cancel"] = cancel
예제 #2
0
 def _position_repository_position_closing(self, sender: object,
                                           eargs: EventArgs):
     """
     リポジトリでポジションを閉じるときに発生します。
     """
     position = eargs.params["position"]
     position_repository = eargs.params["position_repository"]
     exec_price = self._on_position_closing(position, position_repository)
     eargs.params["exec_price"] = exec_price
예제 #3
0
 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))
예제 #4
0
 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))
예제 #5
0
 def _on_position_closed(self, sender: object, eargs: EventArgs):
     """
     ポジションクローズイベントを発生させます。
     """
     eargs.params["position_repository"] = self
     self._position_closed_eventhandler.fire(eargs)
예제 #6
0
 def _on_position_opening(self, sender: object, eargs: EventArgs):
     """
     ポジションオープニングイベントを発生させます。
     """
     eargs.params["position_repository"] = self
     self._position_opening_eventhandler.fire(eargs)
예제 #7
0
    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