def setUp(self): self.start_time = time.time() # Establish data base API and setup mock data self.engine = engine self.requests_session = requests.Session() s3_cache.flushall() rds.flushall() reset_db() os.system("mysql -h db -uroot main < mockdata.sql") for i in range(len(USER_DATA)): user_id = i + 1 rds.set(f"{PLAYER_RANK_PREFIX}_{user_id}", STARTING_ELO_SCORE) rds.set(f"{THREE_MONTH_RETURN_PREFIX}_{user_id}", 0)
def serialize_and_pack_rankings(): cutoff_time = datetime_to_posix(dt.utcnow() - DateOffset(months=3)) with engine.connect() as conn: user_df = pd.read_sql(""" SELECT user_id, rating, username, profile_pic, n_games, total_return, basis, sr.timestamp FROM stockbets_rating sr INNER JOIN ( SELECT game_id, MAX(id) AS max_id FROM game_status WHERE status = 'finished' AND timestamp >= %s GROUP BY game_id ) gs ON gs.game_id = sr.game_id INNER JOIN ( SELECT id, username, profile_pic FROM users ) u ON u.id = sr.user_id """, conn, params=[cutoff_time]) indexes_df = pd.read_sql(""" SELECT user_id, rating, imd.username, imd.profile_pic, n_games, total_return, basis, sr.timestamp FROM stockbets_rating sr INNER JOIN ( SELECT game_id, MAX(id) AS max_id FROM game_status WHERE status = 'finished' AND timestamp >= %s GROUP BY game_id ) gs ON gs.game_id = sr.game_id INNER JOIN ( SELECT symbol, `name` AS username, avatar AS profile_pic FROM index_metadata ) imd ON sr.index_symbol = imd.symbol """, conn, params=[cutoff_time]) df = pd.concat([user_df, indexes_df]) df["basis_times_return"] = df["total_return"] * df["basis"] total_basis_df = df.groupby("username", as_index=False)["basis"].sum().rename(columns={"basis": "total_basis"}) df = df.merge(total_basis_df, on="username").sort_values(["username", "timestamp"]) stats_df = df.groupby("username", as_index=False).agg({"user_id": "first", "rating": "last", "profile_pic": "first", "n_games": "last", "basis_times_return": "sum", "total_basis": "first"}) stats_df["three_month_return"] = stats_df["basis_times_return"] / stats_df["total_basis"] del stats_df["basis_times_return"] del stats_df["total_basis"] stats_df.sort_values("rating", ascending=False, inplace=True) stats_df = stats_df.where(pd.notnull(stats_df), None) update_player_rank(stats_df) rds.set(PUBLIC_LEADERBOARD_PREFIX, json.dumps(stats_df.to_dict(orient="records")))
def make_redis_mocks(): for i, _ in enumerate(MOCK_DATA["users"]): user_id = int(i + 1) rds.set(f"{PLAYER_RANK_PREFIX}_{user_id}", STARTING_ELO_SCORE) rds.set(f"{THREE_MONTH_RETURN_PREFIX}_{user_id}", 0) serialize_and_pack_rankings() game_ids = [3, 6, 7, 8] for game_id in game_ids: init_game_assets(game_id) serialize_and_pack_games_per_user_chart() # TODO: This is a quick hack to get the admin panel working in dev. Fix at some point df = make_games_per_user_data() chart_json = make_chart_json(df, "cohort", "percentage", "game_count") s3_cache.set(f"{ORDERS_PER_ACTIVE_USER_PREFIX}", json.dumps(chart_json))
def calculate_and_pack_game_metrics(game_id: int, start_time: float = None, end_time: float = None): for user_id in get_active_game_user_ids(game_id): return_ratio, sharpe_ratio = calculate_metrics(game_id, user_id, start_time, end_time) rds.set(f"{RETURN_RATIO_PREFIX}_{game_id}_{user_id}", return_ratio) rds.set(f"{SHARPE_RATIO_PREFIX}_{game_id}_{user_id}", sharpe_ratio) if check_single_player_mode(game_id): for index in TRACKED_INDEXES: df = get_index_portfolio_value_data(game_id, index, start_time, end_time) index_return_ratio = portfolio_return_ratio(df) index_sharpe_ratio = portfolio_sharpe_ratio(df, RISK_FREE_RATE_DEFAULT) rds.set(f"{RETURN_RATIO_PREFIX}_{game_id}_{index}", index_return_ratio) rds.set(f"{SHARPE_RATIO_PREFIX}_{game_id}_{index}", index_sharpe_ratio)
def test_db_helpers(self): dummy_symbol = "ACME" dummy_name = "ACME CORP" symbol_id = add_row("symbols", symbol=dummy_symbol, name=dummy_name) # There's nothing special about primary key #27. If we update the mocks this will need to update, too. self.assertEqual(symbol_id, 27) acme_entry = query_to_dict("SELECT * FROM symbols WHERE symbol = %s", dummy_symbol)[0] self.assertEqual(acme_entry["symbol"], dummy_symbol) self.assertEqual(acme_entry["name"], dummy_name) user_id = add_row("users", name="diane browne", email="*****@*****.**", profile_pic="private", username="******", created_at=time.time(), provider="twitter", resource_uuid="aaa") rds.set(f"{PLAYER_RANK_PREFIX}_{user_id}", STARTING_ELO_SCORE) rds.set(f"{THREE_MONTH_RETURN_PREFIX}_{user_id}", 0) new_entry = get_user_information(user_id) self.assertEqual(new_entry["name"], "diane browne") game_id = add_row("games", creator_id=1, title="db test", game_mode="multi_player", duration=1_000, buy_in=0, benchmark="return_ratio", side_bets_perc=0, invite_window=time.time() + 1_000_000_000_000) add_row("game_status", game_id=game_id, status="pending", users=[1, 1], timestamp=time.time()) new_entry = get_game_info(game_id) self.assertEqual(new_entry["title"], "db test")
def setup_new_user(name: str, email: str, profile_pic: str, created_at: float, provider: str, resource_uuid: str, password: str = None) -> int: user_id = add_row("users", name=name, email=email, username=None, profile_pic=profile_pic, created_at=created_at, provider=provider, password=password, resource_uuid=resource_uuid) requester_friends_ids = get_requester_ids_from_email(email) for requester_id in requester_friends_ids: add_row("external_invites", requester_id=requester_id, invited_email=email, status="accepted", timestamp=time.time(), type="platform") invite_friend(requester_id, user_id) # seed public rank and 3-month return add_row("stockbets_rating", user_id=user_id, index_symbol=None, game_id=None, rating=STARTING_ELO_SCORE, update_type="sign_up", timestamp=time.time(), n_games=0, total_return=0, basis=0) rds.set(f"{PLAYER_RANK_PREFIX}_{user_id}", STARTING_ELO_SCORE) rds.set(f"{THREE_MONTH_RETURN_PREFIX}_{user_id}", 0) return user_id
def update_player_rank(df: pd.DataFrame): for i, row in df.iterrows(): if row["user_id"]: rds.set(f"{PLAYER_RANK_PREFIX}_{int(row['user_id'])}", row["rating"]) rds.set(f"{THREE_MONTH_RETURN_PREFIX}_{int(row['user_id'])}", row["three_month_return"])
def set_cache_price(symbol, price, timestamp): rds.set(symbol, f"{price}_{timestamp}")