Ejemplo n.º 1
0
    def __load_market_info(self):
        market_info = self.rh_session.market_info()
        if "opens_at" not in market_info or not market_info[
                "opens_at"] or "closes_at" not in market_info or not market_info[
                    "closes_at"]:
            market_info = self.rh_session.get_url_content_json(
                market_info["next_open_hours"])

        self.market_info = market_info
        # self.market_opens_at = datetime.now().replace(hour=8, minute=30, second=0, microsecond=0)  # utc_to_local(datetime.strptime(market_info["opens_at"], "%Y-%m-%dT%H:%M:%SZ"))
        self.market_opens_at = utc_to_local(
            datetime.strptime(market_info["opens_at"], "%Y-%m-%dT%H:%M:%SZ"))
        self.market_closes_at = utc_to_local(
            datetime.strptime(market_info["closes_at"], "%Y-%m-%dT%H:%M:%SZ"))

        current_time = datetime.now()
        if (current_time >= self.market_opens_at) and (current_time <
                                                       self.market_closes_at):
            self.is_market_open = True
        else:
            self.is_market_open = False

        log.debug(
            "market opens_at=%s, closes_at=%s, now=%s, is_market_open=%s" %
            (self.market_opens_at, self.market_closes_at, current_time,
             self.is_market_open))
Ejemplo n.º 2
0
    def _build_order_object(self, result, symbol=None):
        status = self._order_status_map[result["state"]]
        # log.debug(result)

        if not symbol:
            instrument = self.rh_session.get_url_content_json(result["instrument"])
            symbol = instrument["symbol"]

        order = Order(result["id"])
        order.status = status
        order.created = utc_to_local(datetime.strptime(result["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ"))
        order.updated = utc_to_local(datetime.strptime(result["updated_at"], "%Y-%m-%dT%H:%M:%S.%fZ"))

        order.stop = None
        order.limit = None
        if result["trigger"] == "stop":
            order.stop = float(result["stop_price"])

        if result["type"] == "limit":
            order.limit = float(result["price"])

        order.amount = int(float(result["quantity"]))
        if result["side"] == "sell":
            order.amount = -order.amount
        order.symbol = symbol
        order.filled = int(float(result["cumulative_quantity"]))
        if result["side"] == "sell":
            order.filled = -order.filled

        order.commission = float(result["fees"])
        order.rejected_reason = result["reject_reason"]
        order.time_in_force = result["time_in_force"]

        return order
Ejemplo n.º 3
0
    def _get_last_filled_order_by_side(self, security):
        latest_buy_order = None
        latest_sell_order = None
        order_data = self.rh_session.order_history()
        # log.info("order_data: %s" % order_data)
        if order_data and "results" in order_data:
            for result in order_data["results"]:
                status = self._order_status_map[result["state"]]
                if status not in [1]:  # or result["side"] != side:
                    # not open order
                    continue

                instrument = self.rh_session.get_url_content_json(
                    result["instrument"])
                symbol = instrument["symbol"]
                if security and security.symbol != symbol:
                    # not for the the security desired
                    continue

                if result["side"] == "buy":
                    if not latest_buy_order:
                        latest_buy_order = self._build_order_object(
                            result, symbol)
                        continue

                    updated = utc_to_local(
                        datetime.strptime(result["updated_at"],
                                          "%Y-%m-%dT%H:%M:%S.%fZ"))
                    if latest_buy_order.updated > updated:
                        continue

                    latest_buy_order = result

                if result["side"] == "sell":
                    if not latest_sell_order:
                        latest_sell_order = self._build_order_object(
                            result, symbol)
                        continue

                    updated = utc_to_local(
                        datetime.strptime(result["updated_at"],
                                          "%Y-%m-%dT%H:%M:%S.%fZ"))
                    if latest_sell_order.updated > updated:
                        continue

                    latest_sell_order = result

        return {"sell": latest_sell_order, "buy": latest_buy_order}
Ejemplo n.º 4
0
    def __load_profile_info(self):
        pos_infos = self.rh_session.positions()
        port_info = self.rh_session.portfolios()
        acct_info = self.rh_session.get_account()
        # log.info("pos_infos:%s" % pos_infos)
        # log.info("account_info:%s" % acct_info)
        # log.info("port_info:%s" % port_info)

        unsettled_funds = float(acct_info["unsettled_funds"])
        market_value = float(port_info["market_value"])
        equity = float(port_info["equity"])
        yesterday_equity = float(port_info["equity_previous_close"])
        uncleared_deposits = float(acct_info["uncleared_deposits"])
        cash_held_for_orders = float(acct_info["cash_held_for_orders"])
        cash = float(acct_info["cash"])
        total_cash = cash + unsettled_funds
        portfolio_value = equity
        buying_power = equity - market_value - cash_held_for_orders

        if not self._starting_cash:
            self._starting_cash = portfolio_value

        if not self._start_date:
            self._start_date = datetime.now()

        returns = 0
        if self._starting_cash and self._starting_cash > 0:
            returns = (portfolio_value -
                       self._starting_cash) / self._starting_cash
        long_position_value = 0
        short_position_value = 0
        unrealized_pl = 0
        positions = {}

        # log.info("pos: %s" % pos_infos["results"])
        if pos_infos and pos_infos["results"]:
            for result in pos_infos["results"]:
                amount = int(float(result["quantity"]))
                if amount == 0:
                    continue
                log.info("pos_infos:%s" % result)
                instrument = self.rh_session.get_url_content_json(
                    result["instrument"])
                symbol = instrument["symbol"]
                security = self.fetch_and_build_security(symbol,
                                                         sec_detail=instrument)
                # last_price = self.current(security, field="price")
                last_price = float(
                    self.rh_session.last_trade_price(symbol)[0][0])
                log.debug(last_price)
                # if not last_price:
                # Lets try again
                #    last_price = self.current(security, field="price")

                if not last_price and security in self._security_last_known_price:
                    last_price = self._security_last_known_price[security]

                self._security_last_known_price[security] = last_price

                created = utc_to_local(
                    datetime.strptime(result["created_at"],
                                      "%Y-%m-%dT%H:%M:%S.%fZ"))
                updated = utc_to_local(
                    datetime.strptime(result["updated_at"],
                                      "%Y-%m-%dT%H:%M:%S.%fZ"))
                cost_basis = float(result["average_buy_price"])
                position = Position(amount, cost_basis, last_price, created,
                                    updated)
                if "intraday_quantity" in result:
                    position.day_amount = int(
                        float(result["intraday_quantity"]))

                if "intraday_average_buy_price" in result:
                    position.day_cost_basis = int(
                        float(result["intraday_average_buy_price"]))

                positions[security] = position

                # position_value = position_value+(cost_basis*amount)
                if amount > 0:
                    unrealized_pl = unrealized_pl + ((last_price * amount) -
                                                     (cost_basis * amount))
                    long_position_value = long_position_value + (cost_basis *
                                                                 amount)
                else:
                    unrealized_pl = unrealized_pl + (
                        (cost_basis * np.abs([amount])[0]) -
                        (last_price * np.abs([amount])[0]))
                    short_position_value = long_position_value + (
                        cost_basis * np.abs([amount])[0])

        pnl = equity - uncleared_deposits - yesterday_equity  # unrealized_pl + unsettled_funds
        leverage = 0
        net_leverage = 0
        if portfolio_value > 0:
            leverage = (long_position_value +
                        short_position_value) / portfolio_value
            net_leverage = market_value / portfolio_value

        portfolio = Portfolio()
        portfolio.capital_used = np.abs([
            (short_position_value - long_position_value)
        ])[0]
        portfolio.cash = total_cash
        portfolio.pnl = pnl
        portfolio.positions = positions
        portfolio.portfolio_value = portfolio_value
        portfolio.positions_value = market_value
        portfolio.returns = returns
        portfolio.starting_cash = self._starting_cash
        portfolio.start_date = self._start_date

        self.context.portfolio = portfolio

        account = Account()
        # account.accrued_interest=acct_info
        account.available_funds = portfolio_value
        account.buying_power = buying_power
        account.cushion = total_cash / portfolio_value
        account.day_trades_remaining = float("inf")
        account.equity_with_loan = portfolio_value
        account.excess_liquidity = port_info["excess_margin"]
        account.initial_margin_requirement = float(
            acct_info["margin_balances"]["margin_limit"]
        ) if "margin_balances" in acct_info and "margin_limit" in acct_info[
            "margin_balances"] else 0
        account.leverage = leverage
        account.maintenance_margin_requirement = portfolio_value - float(
            port_info["excess_margin"])
        account.net_leverage = net_leverage
        account.net_liquidation = portfolio_value
        account.settled_cash = cash
        account.total_positions_value = market_value
        if "unallocated_margin_cash" in acct_info:
            account.unallocated_margin_cash = float(
                acct_info["unallocated_margin_cash"])

        self.context.account = account
Ejemplo n.º 5
0
    def _time_interval_processor(self):
        now = datetime.now()
        if now.weekday() not in [5, 6]:
            # if now.weekday() not in [6]:
            log.debug("In time interval processor")
            temp_datetime = datetime.now()
            self._active_datetime = temp_datetime.replace(second=0,
                                                          microsecond=0)

            market_open_temp = self.is_market_open
            self._current_security_bars = {}
            if not self._load_all_data():
                # Load Data Failed... we can't go further until we get fresh data... bad things can happend if algo operate with stale data.
                # Set reload data again in 1 minute.
                log.debug(
                    "Data retrieval was adnormal we'll check again next minute to try again "
                )
                _set_trigger_timer(
                    minute_interval=1,
                    callback_function=self._time_interval_processor)
                return schedule.CancelJob

            # update context status
            self.context.is_market_open = self.is_market_open
            if (not self._initialized
                    or not market_open_temp) and self.is_market_open:
                # if market was not open and is now open... initialize algo
                try:
                    if hasattr(self.active_algo, 'on_market_open'):
                        self.active_algo.on_market_open(
                            self.context, self.friar_data)

                        # self.active_algo.handle_data(self.context, self.friar_data)
                except Exception as inst:
                    log.error("Error occurred while invoking initialize: %s " %
                              inst)
                    traceback.print_exc()

            if self._data_frequency == "1d":
                # with this frequency, it's a market closed last update whenever this method is call
                self._market_closed_lastupdate = True
            elif self._data_frequency == "1h":
                minutes_after_open_time = self.market_opens_at + timedelta(
                    hours=1)
                minutes_after_open_time = minutes_after_open_time.replace(
                    minute=0, second=0, microsecond=0)
            elif self._data_frequency == "15m":
                minutes_after_open_time = self.market_opens_at + timedelta(
                    minutes=15)
                minutes_after_open_time = minutes_after_open_time.replace(
                    second=0, microsecond=0)
            elif self._data_frequency == "5m":
                minutes_after_open_time = self.market_opens_at + timedelta(
                    minutes=5)
                minutes_after_open_time = minutes_after_open_time.replace(
                    second=0, microsecond=0)
            else:
                minutes_after_open_time = self.market_opens_at + timedelta(
                    minutes=1)  # Adding one more call

            if market_open_temp and not self.is_market_open:
                # If market used to be open and at this update is now closed, we want to call handle_data one more time
                self._market_closed_lastupdate = True  # we want the algo to be called one more time.

            current_time = datetime.now()
            try:
                if (
                        self.is_market_open
                        and current_time >= minutes_after_open_time
                ) or self._market_closed_lastupdate:  # current_time < minutes_after_close_time:
                    self.active_algo.handle_data(self.context, self.friar_data)

                    if self._market_closed_lastupdate:
                        self._market_closed_lastupdate = False
            except Exception as e:
                log.error("Error occurred while invoking handle_data: %s " % e)
                traceback.print_exc()

        if self._data_frequency == "1d":
            direct_time = self.market_closes_at
            if datetime.now() >= direct_time:
                market_info = self.rh_session.get_url_content_json(
                    self.market_info["next_open_hours"])
                direct_time = utc_to_local(
                    datetime.strptime(market_info["closes_at"],
                                      "%Y-%m-%dT%H:%M:%SZ"))

            direct_time = direct_time + timedelta(
                minutes=5)  # wait 5 minutes after market closes
        elif self._data_frequency == "1h":
            if not self.is_market_open and datetime.now(
            ) < self.market_opens_at:
                direct_time = self.market_opens_at
            elif not self.is_market_open and datetime.now(
            ) > self.market_closes_at:
                market_info = self.rh_session.get_url_content_json(
                    self.market_info["next_open_hours"])
                direct_time = utc_to_local(
                    datetime.strptime(market_info["opens_at"],
                                      "%Y-%m-%dT%H:%M:%SZ"))
            else:
                direct_time = datetime.now() + timedelta(
                    hours=1)  # update every hour
                direct_time = direct_time.replace(minute=0,
                                                  second=0,
                                                  microsecond=0)
        elif self._data_frequency == "15m":
            if not self.is_market_open and datetime.now(
            ) < self.market_opens_at:
                direct_time = self.market_opens_at
            elif not self.is_market_open and datetime.now(
            ) > self.market_closes_at:
                market_info = self.rh_session.get_url_content_json(
                    self.market_info["next_open_hours"])
                direct_time = utc_to_local(
                    datetime.strptime(market_info["opens_at"],
                                      "%Y-%m-%dT%H:%M:%SZ"))
            else:
                now = datetime.now()
                multiples = int(now.minute / 15)
                diff = now.minute - (multiples * 15)
                direct_time = now + timedelta(minutes=(15 - diff))
                # direct_time = datetime.now() + timedelta(minutes=15)  # update every 15 minutes
                direct_time = direct_time.replace(second=0, microsecond=0)
        elif self._data_frequency == "5m":
            if not self.is_market_open and datetime.now(
            ) < self.market_opens_at:
                direct_time = self.market_opens_at
            elif not self.is_market_open and datetime.now(
            ) > self.market_closes_at:
                market_info = self.rh_session.get_url_content_json(
                    self.market_info["next_open_hours"])
                direct_time = utc_to_local(
                    datetime.strptime(market_info["opens_at"],
                                      "%Y-%m-%dT%H:%M:%SZ"))
            else:
                now = datetime.now()
                multiples = int(now.minute / 5)
                diff = now.minute - (multiples * 5)
                direct_time = now + timedelta(minutes=(5 - diff))
                # direct_time = datetime.now() + timedelta(minutes=5)  # update every 5 minutes
                direct_time = direct_time.replace(second=0, microsecond=0)
        else:
            direct_time = datetime.now() + timedelta(
                minutes=1)  # update every minute
            direct_time = direct_time.replace(second=0, microsecond=0)

        # log.debug("Interval Processing Done - Next Trigger %s" % direct_time)

        _set_trigger_timer(callback_function=self._time_interval_processor,
                           direct_time=direct_time)
        return schedule.CancelJob
Ejemplo n.º 6
0
def _load_quotes(symbol,
                 frequency,
                 interval,
                 period_factor,
                 period,
                 bar_count,
                 field,
                 wait_time=None):
    target_url = "https://finance.google.com/finance/getprices?i=" + str(
        interval) + "&p=" + str(
            period_factor) + period + "&f=d,o,h,l,c,v&q=" + symbol
    # log.debug(target_url)
    # data = urlopen(target_url, timeout=10)  # it's a file like object and works just like a file
    bars = None
    unix_date = None
    req = urllib.request.Request(target_url)
    with urllib.request.urlopen(req) as response:
        if wait_time:
            log.debug("About to sleep")
            time.sleep(wait_time)
        for line in response:  # files are iterable
            line = line.decode("utf-8").strip()
            # print (line)
            if not unix_date and not line.startswith("a"):
                continue

            if line.startswith("TIMEZONE_OFFSET"):
                print("timezone change: %s" % line)
                continue

            offset = 0
            (date, close, high, low, open, volume) = line.split(',')
            if date.startswith("a"):
                unix_date = int(date.replace("a", ""))
                offset = 0
            else:
                offset = int(date)

            quote_date = datetime.utcfromtimestamp(unix_date +
                                                   (offset * interval))
            if frequency == "1m" or frequency == "5m" or frequency == "15m" or frequency == "1h":
                quote_date = utc_to_local(quote_date)

            bar = pd.DataFrame(index=pd.DatetimeIndex([quote_date]),
                               data={
                                   'price': float(close),
                                   'open': float(open),
                                   'high': float(high),
                                   'low': float(low),
                                   'close': float(close),
                                   'volume': int(volume)
                               })
            # print(close)
            if bars is None:
                bars = bar
            else:
                bars = bars.append(bar)

    if bars is None:
        # log.warn("Unexpected, could not retrieve quote for security (%s) " % symbol)
        quote_date = datetime.now()
        quote_date = quote_date.replace(second=0, microsecond=0)
        bars = pd.DataFrame(index=pd.DatetimeIndex([quote_date]),
                            data={
                                'price': float("nan"),
                                'open': float("nan"),
                                'high': float("nan"),
                                'low': float("nan"),
                                'close': float("nan"),
                                'volume': int(0)
                            })
        # return bars

    bars = bars.tail(bar_count)
    if field:
        bars = bars[field]

    return bars