Beispiel #1
0
def populate_stocks():
    non_crypto_exchanges = Exchanges.query.filter(
        Exchanges.is_crypto == False, Exchanges.priority != None).all()
    crypto_exchanges = Exchanges.query.filter(
        Exchanges.is_crypto == True, Exchanges.priority != None).all()

    exchanges = {
        "stock": {
            "exchange": non_crypto_exchanges,
            "name": {
                "displaySymbol": "display_symbol",
                "description": "name"
            },
            "search": lambda ex: search(query="exchange", arg=ex)
        },
        "crypto": {
            "exchange":
            crypto_exchanges,
            "name": {
                "description": "name",
                "displaySymbol":
                "currency",  # please review, unsure if this is a good idea
            },
            "search":
            lambda ex: search(query="exchange", arg=ex, stock_type="crypto")
        },
    }

    exchange_stocks = []
    heapq.heapify(exchange_stocks)
    for ex_type, exchange_dict in exchanges.items():
        for exchange in exchange_dict["exchange"]:
            payload = exchange_dict["search"](exchange.code)
            df = pd.DataFrame.from_records(payload)
            df["exchange"] = exchange.code
            df["type"] = ex_type
            df.rename(columns=exchange_dict["name"], inplace=True)
            if ex_type == 'crypto':
                df['display_symbol'] = df.currency
            heapq.heappush(exchange_stocks, (exchange.priority, {
                exchange: df
            }))

    stocks_df = pd.read_sql(
        Stock.query.with_entities(Stock.symbol).subquery(), db.session.bind)
    while exchange_stocks:
        num_stocks, stock_dict = heapq.heappop(exchange_stocks)
        ex, df = stock_dict.popitem()

        df = df[~df.symbol.isin(stocks_df.symbol)]

        if len(df):
            bulk_add_from_df(df, db, Stock)
Beispiel #2
0
def get_watchlist(user: User):
    watchlist_list = []
    for item in user.watchlist.watchlist_items:
        watchlist_list.append({
            "symbol":
            item.stock.symbol,
            "name":
            item.stock.name,
            "date_added":
            item.date_added.timestamp(),
            **search(query="quote",
                     arg=item.stock.symbol,
                     stock_type=item.stock.type)
        })
    return {"watchlist": watchlist_list}
Beispiel #3
0
def portfolio_value(user: User, use_stored=False, average_mode="moving"):
    balance = all_stocks_balance(user)
    avgs = average_price(user, mode=average_mode)

    p_value = []

    if use_stored:
        quote = (Stock.query.with_entities(
            Stock.symbol, Stock.last_quote).filter(
                Stock.symbol.in_(list(balance.keys()))).all())
        balance_df = pd.DataFrame.from_dict(balance,
                                            orient="index",
                                            columns=["quantity"])
        quote_df = pd.DataFrame(quote, columns=["symbol", "current"])
        quote_df.set_index(["symbol"], inplace=True)
        portfolio_df = balance_df.join(quote_df)

        portfolio_df["value"] = portfolio_df.current * portfolio_df.quantity
        p_value = (portfolio_df.reset_index().rename(columns={
            "index": "symbol"
        }).to_dict(orient="records"))

    else:
        for stock, quant in balance.items():
            quote = search("quote", stock)
            current = quote["c"]
            previous = quote["pc"]
            p_value.append(
                dict(
                    symbol=stock,
                    quantity=quant,
                    current=current,
                    previous=previous,
                    value=current * quant,
                ))
    for entry in p_value:
        for trade_type, stock_statistics in avgs.items():
            entry[trade_type] = {}
            if entry["symbol"] in stock_statistics:
                entry[trade_type] = stock_statistics[entry["symbol"]]
        entry["return"] = entry["value"] - entry["buy"]["total"]

    return p_value
Beispiel #4
0
def calculate_all_portfolios_values(query_limit=60, ):
    # First, query only the stocks that are in users portfolios
    portfolio_stocks = Stock.query.join(Portfolio, Stock.portfolios).all()
    allowance_per_call = S_PER_MIN / query_limit

    processing_start = time.time()
    # Time logic is to limit our calls per minute to the bandwidth available
    # Get current quote price for the portfolio stocks
    for stock in portfolio_stocks:
        start_t = time.time()

        quote = search("quote", stock.symbol)

        stock.last_quote = quote["c"]
        stock.last_quote_time = datetime.now()

        end_t = time.time()
        duration = end_t - start_t
        pause_time = allowance_per_call - duration

        if pause_time > 0:
            time.sleep(pause_time)
    db.session.commit()
    # For every user, create a portfolio price entry and commit it to the db
    all_users = User.query.all()
    for user in all_users:
        portfolio = portfolio_value(user, use_stored=True)
        if not portfolio:
            continue

        portfolio_df = pd.DataFrame.from_records(portfolio, )
        investment_value = portfolio_df["value"].sum()
        cash_balance = user.portfolio.balance

        portfolioprice = PortfolioPrice(
            close_balance=cash_balance,
            investment_value=investment_value,
        )

        user.portfolio.portfolioprice.append(portfolioprice)

        db.session.commit()
Beispiel #5
0
    def get(self):
        args = candle_parser.parse_args()
        args["symbol"] = args["symbol"].upper()
        current_unix_time = datetime.datetime.now().timestamp()

        if not args["from"]:
            args["from"] = int(current_unix_time -
                               datetime.timedelta(weeks=1).total_seconds())

        if not args["to"]:
            args["to"] = int(current_unix_time)

        if not args["resolution"]:
            args["resolution"] = "60"

        candle = search(query="candle", arg=args)
        if candle["s"] == "no_data":
            return {
                "message":
                "Symbol not found or data unavailable for that resolution, "
                "check inputs and try again."
            }, 404

        return candle, 200
Beispiel #6
0
def simulate(date_from=None,
             date_to=None,
             query_limit=60,
             user=None,
             start_hour=21,
             start_minute=30):
    # First, query only the stocks that are in users portfolios
    if user is None:
        portfolio_stocks = Stock.query.join(Portfolio, Stock.portfolios).all()
    else:
        portfolio_stocks = user.portfolio.stocks
    allowance_per_call = S_PER_MIN / query_limit

    if date_to is None:
        date_to = datetime.now(timezone.utc)

    date_to = get_query_time(date_to, start_hour, start_minute)

    if date_from is None:
        date_from = int((date_to - timedelta(weeks=4).total_seconds()))

    date_from = get_query_time(date_from, start_hour, start_minute)

    if date_from > date_to:
        raise ValueError(
            "date_from must be a date at least 1 day before date_to. Check your inputs."
        )
    elif date_to - date_from < timedelta(days=1).total_seconds():
        raise ValueError(
            "date_from must be a date at least 1 day before date_to. Check your inputs."
        )

    processing_start = time.time()
    # Time logic is to limit our calls per minute to the bandwidth available
    # Get current quote price for the portfolio stocks

    symbols = [s.symbol for s in portfolio_stocks]
    first_query_flag = True
    for symbol in symbols:
        start_t = time.time()

        arg = {
            "symbol": symbol,
            "resolution": "D",
            "to": date_to,
            "from": date_from,
        }

        quote = search(query="candle", arg=arg)

        if first_query_flag:
            stock_price = pd.DataFrame(columns=pd.MultiIndex.from_product(
                [symbols, ["quote", "quantity"]]),
                                       index=quote["t"])
            first_query_flag = False

        stock_price.loc[:, (symbol, "quote")] = quote["c"]

        end_t = time.time()
        duration = end_t - start_t
        pause_time = allowance_per_call - duration

        if pause_time > 0:
            time.sleep(pause_time)

    # For every user, create a portfolio price entry and commit it to the db
    if user is None:
        all_users = User.query.all()
    else:
        all_users = [user]

    for user in all_users:
        stock_balance = all_stocks_balance(user)
        if not portfolio_stocks:
            continue
        portfolio_stock_symbols = list(stock_balance.keys())
        user_stocks = stock_price[portfolio_stock_symbols]
        for stock, quantity in stock_balance.items():
            user_stocks.loc[:, (stock, "quantity")] = quantity

        investment_values = user_stocks.groupby(axis=1,
                                                level=0).prod().sum(axis=1)
        cash_balance = user.portfolio.balance

        payload_df = pd.DataFrame()
        payload_df["timestamp"] = investment_values.index
        payload_df["investment_value"] = investment_values.values
        payload_df["close_balance"] = cash_balance

        payload_df[
            "total_value"] = payload_df.close_balance + payload_df.investment_value

        return payload_df.to_dict("records")