{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from datetime import datetime\n", "from dao.Database import Database\n", "from data_model import MysqlConfig, OddsJamOrder, OddsjamBet" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "\n", "def get_oddsjam_order_data_from_db()->List:\n", " config_file_path = 'config\\mysql_config.json'\n", " mysql_config = MysqlConfig.parse_file(config_file_path)\n", " dao = Database(mysql_config)\n", "\n", " select_query = \"SELECT * FROM bet.oddsjam_order where bet_status in ('won', 'lost');\"\n", " raw_data_list = dao.fetchall(query=select_query)\n", " order_data_list = [OddsJamOrder(**data).model_dump() for data in raw_data_list]\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "simulation_data = get_oddsjam_order_data_from_db()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "db_df = pd.DataFrame(order_data_list)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def get_benefit(row):\n", " home_or_away = row['home_or_away']\n", " price = row[f'{home_or_away}_price'] / 100\n", " if row['outcome'] == -1:\n", " return -1\n", " if price >= 0:\n", " return price \n", " else:\n", " return 1 / abs(price) \n", " \n", "db_df['outcome'] = db_df['bet_status'].apply(lambda x: 1 if x == 'won' else -1)\n", "db_df['benefit'] = db_df.apply(get_benefit, axis=1)\n", "db_df['date'] = db_df['start_timestamp'].apply(lambda x: datetime.fromtimestamp(x // 1000).strftime(\"%Y-%m-%d\"))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def get_odds(row):\n", " home_or_away = row['home_or_away']\n", " price = row[f'{home_or_away}_price'] / 100\n", " if price >= 0:\n", " return price\n", " else:\n", " return 1 / abs(price) " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "db_df['odds2'] = db_df.apply(get_odds, axis=1)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.5232254542910955" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df['odds2'].mean()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bet_status\n", "lost 19316\n", "won 8249\n", "dtype: int64" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df.groupby('bet_status').size()" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.4551825216755248" ] }, "execution_count": 130, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[db_df['bet_status'].isin(['won', 'lost'])]['benefit'].mean()" ] }, { "cell_type": "code", "execution_count": 149, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1477.1127282023094" ] }, "execution_count": 149, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[['home_price', 'away_price', 'home_or_away', 'bet_status', 'benefit']]['benefit']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 1780.000000\n", "mean 1.165759\n", "std 0.338662\n", "min 0.359712\n", "25% 0.909091\n", "50% 1.080000\n", "75% 1.360000\n", "max 4.000000\n", "Name: odds2, dtype: float64" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[(db_df['market_width'] <= 25) & (db_df['market_width'] >= 20)]['odds2'].describe()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bet_status\n", "lost 1231\n", "won 1080\n", "dtype: int64" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[(db_df['market_width'] <= 25) & (db_df['market_width'] >= 20)].groupby(['bet_status']).size()" ] }, { "cell_type": "code", "execution_count": 171, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.4764044943820225" ] }, "execution_count": 171, "metadata": {}, "output_type": "execute_result" } ], "source": [ "848 / (848+932)" ] }, { "cell_type": "code", "execution_count": 170, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0318921348314607" ] }, "execution_count": 170, "metadata": {}, "output_type": "execute_result" } ], "source": [ "848 / (848+932) * (1.166 + 1)" ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 5902.000000\n", "mean 2.026751\n", "std 1.825651\n", "min 0.166667\n", "25% 1.020000\n", "50% 1.430000\n", "75% 2.200000\n", "max 25.000000\n", "Name: odds2, dtype: float64" ] }, "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[db_df['bet_status'] == 'won']['odds2'].describe()" ] }, { "cell_type": "code", "execution_count": 157, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "count 13439.000000\n", "mean 4.082506\n", "std 3.955954\n", "min 0.235294\n", "25% 1.500000\n", "50% 2.700000\n", "75% 5.400000\n", "max 35.000000\n", "Name: odds2, dtype: float64" ] }, "execution_count": 157, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_df[db_df['bet_status'] == 'lost']['odds2'].describe()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "raw_df = pd.read_excel('PEV 3.11-10.26.xlsx', sheet_name='原始数据')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "\n", "data_df = db_df.copy()\n", "data_df = data_df[data_df['market_width'] <= 25]\n", "data_df = data_df[data_df['market_width'] >= 20]\n", "# data_df = data_df[data_df['selected_sportsbook'] == '1XBet']\n", "data_df['investment'] = 1" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "odds_df = data_df.groupby('date').agg({'odds2': 'mean'}).reset_index()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "name": "lost", "type": "bar", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 11, 96, 138, 109, 190, 99, 289, 62, 89, 98, 50 ], "yaxis": "y" }, { "name": "won", "type": "bar", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 12, 113, 94, 79, 178, 88, 284, 59, 56, 80, 37 ], "yaxis": "y" }, { "mode": "markers+lines", "name": "平均赔率", "type": "scatter", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 1.1965734109952426, 1.2294773511597243, 1.3513840696836157, 1.209601147300343, 1.1063211834713325, 1.2904563185996685, 1.0492181007177963, 1.2070565768132386, 1.154097538043856, 1.1587947147909168, 1.2470557464128864 ], "yaxis": "y2" } ], "layout": { "barmode": "group", "legend": { "title": { "text": "Variables" } }, "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "Comparison of Two Variables Across Categories" }, "xaxis": { "title": { "text": "日期" } }, "yaxis": { "title": { "text": "金额" } }, "yaxis2": { "overlaying": "y", "side": "right", "title": { "text": "收益率" } } } } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import plotly.graph_objects as go\n", "\n", "\n", "\n", "df = pd.pivot_table(data_df, index=['date'], columns=['bet_status'], aggfunc='size', fill_value=0).reset_index()\n", "df = df.sort_values(by='date')\n", "date_x = df['date'].tolist()\n", "# 创建Plotly图形对象\n", "fig = go.Figure()\n", "\n", "cols = df.columns[1:]\n", "for col in cols:\n", " y_data = df[col].tolist()\n", " # 添加第一个变量的数据\n", " fig.add_trace(go.Bar(\n", " x=date_x,\n", " y=y_data,\n", " name=col,\n", " # marker_color='indianred' # 设置颜色\n", " yaxis='y1'\n", " ))\n", "\n", "fig.add_trace(go.Scatter(\n", " x=odds_df['date'],\n", " y=odds_df['odds2'],\n", " mode='markers+lines',\n", " name='平均赔率',\n", " yaxis='y2'\n", "))\n", "\n", "# 更新布局\n", "fig.update_layout(\n", " barmode='group', # 将柱状图设置为并排显示\n", " title='Comparison of Two Variables Across Categories',\n", " xaxis=dict(title='日期'),\n", " yaxis=dict(title='金额'),\n", " yaxis2=dict(title='收益率', overlaying='y', side='right'),\n", " legend_title='Variables'\n", ")\n", "fig.show()" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idbet_idgame_idaway_bet_namehome_bet_nameaway_no_vig_pricehome_no_vig_priceaway_pricehome_priceaway_sportsbooks...sportsbook_orderidhome_or_awaystart_timestampselected_sportsbookbet_statusoutcomebenefitdateodds2investment
1edge:10012-40335-2024-08-31:1st_half_team_tota...edge:10012-40335-2024-08-31:1st_half_team_tota...10012-40335-2024-08-31Oud-Heverlee Leuven Under 0.5Oud-Heverlee Leuven Over 0.5102.85-102.85-110.0-102.0[FanDuel, DraftKings]...Nonehome1725129900000Bovadawon10.9803922024-09-010.9803921
9edge:10012-40335-2024-08-31:total_goals:over_2...edge:10012-40335-2024-08-31:total_goals:over_2...10012-40335-2024-08-31Under 2.5Over 2.5-101.35101.35-102.0105.0[Bodog, Bovada]...Nonehome1725129900000BetOnlinelost-1-1.0000002024-09-011.0500001
15edge:10035-41288-2024-08-31:total_goals:over_2...edge:10035-41288-2024-08-31:total_goals:over_2...10035-41288-2024-08-31Under 2.5Over 2.5-121.90121.90-134.0124.0[FanDuel]...Nonehome1725129000000BetOnlinewon11.2400002024-09-011.2400001
19edge:10068-27381-24-35:point_spread:northweste...edge:10068-27381-24-35:point_spread:northweste...10068-27381-24-35Tulsa -37.5Northwestern State +37.5100.40-100.40105.0-110.0[betPARX, BetRivers]...Noneaway1724976000000betPARXlost-1-1.0000002024-08-301.0500001
25edge:10068-27381-24-35:total_points:over_53_5:...edge:10068-27381-24-35:total_points:over_53_5:...10068-27381-24-35Under 53.5Over 53.5132.39-132.39122.0-130.0[DraftKings]...Nonehome1724976000000betPARXwon10.7692312024-08-300.7692311
26edge:10068-27381-24-35:total_points:over_53:un...edge:10068-27381-24-35:total_points:over_53:un...10068-27381-24-35Under 53Over 53109.70-109.70110.0-110.0[betPARX, BetRivers]...Noneaway1724976000000betPARXlost-1-1.0000002024-08-301.1000001
27edge:10068-27381-24-35:total_points:over_54_5:...edge:10068-27381-24-35:total_points:over_54_5:...10068-27381-24-35Under 54.5Over 54.5114.29-114.29105.0-114.0[Fanatics]...Nonehome1724976000000betPARXwon10.8771932024-08-300.8771931
28edge:10068-27381-24-35:total_points:over_54:un...edge:10068-27381-24-35:total_points:over_54:un...10068-27381-24-35Under 54Over 54122.41-122.41112.0-122.0[DraftKings]...Nonehome1724976000000BetRiverswon10.8196722024-08-300.8196721
30edge:10068-27381-24-35:total_points:over_55:un...edge:10068-27381-24-35:total_points:over_55:un...10068-27381-24-35Under 55Over 55-112.29112.29-110.0110.0[BookMaker]...Noneaway1724976000000BookMakerlost-1-1.0000002024-08-300.9090911
32edge:10068-27381-24-35:total_points:over_56:un...edge:10068-27381-24-35:total_points:over_56:un...10068-27381-24-35Under 56Over 56-104.24104.24-112.0105.0[DraftKings]...Nonehome1724976000000betPARXwon11.0500002024-08-301.0500001
\n", "

10 rows × 50 columns

\n", "
" ], "text/plain": [ " id \\\n", "1 edge:10012-40335-2024-08-31:1st_half_team_tota... \n", "9 edge:10012-40335-2024-08-31:total_goals:over_2... \n", "15 edge:10035-41288-2024-08-31:total_goals:over_2... \n", "19 edge:10068-27381-24-35:point_spread:northweste... \n", "25 edge:10068-27381-24-35:total_points:over_53_5:... \n", "26 edge:10068-27381-24-35:total_points:over_53:un... \n", "27 edge:10068-27381-24-35:total_points:over_54_5:... \n", "28 edge:10068-27381-24-35:total_points:over_54:un... \n", "30 edge:10068-27381-24-35:total_points:over_55:un... \n", "32 edge:10068-27381-24-35:total_points:over_56:un... \n", "\n", " bet_id game_id \\\n", "1 edge:10012-40335-2024-08-31:1st_half_team_tota... 10012-40335-2024-08-31 \n", "9 edge:10012-40335-2024-08-31:total_goals:over_2... 10012-40335-2024-08-31 \n", "15 edge:10035-41288-2024-08-31:total_goals:over_2... 10035-41288-2024-08-31 \n", "19 edge:10068-27381-24-35:point_spread:northweste... 10068-27381-24-35 \n", "25 edge:10068-27381-24-35:total_points:over_53_5:... 10068-27381-24-35 \n", "26 edge:10068-27381-24-35:total_points:over_53:un... 10068-27381-24-35 \n", "27 edge:10068-27381-24-35:total_points:over_54_5:... 10068-27381-24-35 \n", "28 edge:10068-27381-24-35:total_points:over_54:un... 10068-27381-24-35 \n", "30 edge:10068-27381-24-35:total_points:over_55:un... 10068-27381-24-35 \n", "32 edge:10068-27381-24-35:total_points:over_56:un... 10068-27381-24-35 \n", "\n", " away_bet_name home_bet_name \\\n", "1 Oud-Heverlee Leuven Under 0.5 Oud-Heverlee Leuven Over 0.5 \n", "9 Under 2.5 Over 2.5 \n", "15 Under 2.5 Over 2.5 \n", "19 Tulsa -37.5 Northwestern State +37.5 \n", "25 Under 53.5 Over 53.5 \n", "26 Under 53 Over 53 \n", "27 Under 54.5 Over 54.5 \n", "28 Under 54 Over 54 \n", "30 Under 55 Over 55 \n", "32 Under 56 Over 56 \n", "\n", " away_no_vig_price home_no_vig_price away_price home_price \\\n", "1 102.85 -102.85 -110.0 -102.0 \n", "9 -101.35 101.35 -102.0 105.0 \n", "15 -121.90 121.90 -134.0 124.0 \n", "19 100.40 -100.40 105.0 -110.0 \n", "25 132.39 -132.39 122.0 -130.0 \n", "26 109.70 -109.70 110.0 -110.0 \n", "27 114.29 -114.29 105.0 -114.0 \n", "28 122.41 -122.41 112.0 -122.0 \n", "30 -112.29 112.29 -110.0 110.0 \n", "32 -104.24 104.24 -112.0 105.0 \n", "\n", " away_sportsbooks ... sportsbook_orderid home_or_away \\\n", "1 [FanDuel, DraftKings] ... None home \n", "9 [Bodog, Bovada] ... None home \n", "15 [FanDuel] ... None home \n", "19 [betPARX, BetRivers] ... None away \n", "25 [DraftKings] ... None home \n", "26 [betPARX, BetRivers] ... None away \n", "27 [Fanatics] ... None home \n", "28 [DraftKings] ... None home \n", "30 [BookMaker] ... None away \n", "32 [DraftKings] ... None home \n", "\n", " start_timestamp selected_sportsbook bet_status outcome benefit \\\n", "1 1725129900000 Bovada won 1 0.980392 \n", "9 1725129900000 BetOnline lost -1 -1.000000 \n", "15 1725129000000 BetOnline won 1 1.240000 \n", "19 1724976000000 betPARX lost -1 -1.000000 \n", "25 1724976000000 betPARX won 1 0.769231 \n", "26 1724976000000 betPARX lost -1 -1.000000 \n", "27 1724976000000 betPARX won 1 0.877193 \n", "28 1724976000000 BetRivers won 1 0.819672 \n", "30 1724976000000 BookMaker lost -1 -1.000000 \n", "32 1724976000000 betPARX won 1 1.050000 \n", "\n", " date odds2 investment \n", "1 2024-09-01 0.980392 1 \n", "9 2024-09-01 1.050000 1 \n", "15 2024-09-01 1.240000 1 \n", "19 2024-08-30 1.050000 1 \n", "25 2024-08-30 0.769231 1 \n", "26 2024-08-30 1.100000 1 \n", "27 2024-08-30 0.877193 1 \n", "28 2024-08-30 0.819672 1 \n", "30 2024-08-30 0.909091 1 \n", "32 2024-08-30 1.050000 1 \n", "\n", "[10 rows x 50 columns]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_df.head(10)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "status date active inactive\n", "0 2024-01-01 2 1\n", "1 2024-01-02 1 1\n", "2 2024-01-03 0 1\n" ] } ], "source": [ "import pandas as pd\n", "\n", "# 示例数据\n", "data = {\n", " 'date': ['2024-01-01', '2024-01-01', '2024-01-01', '2024-01-02', '2024-01-02', '2024-01-03'],\n", " 'status': ['active', 'inactive', 'active', 'active', 'inactive', 'inactive']\n", "}\n", "\n", "df = pd.DataFrame(data)\n", "\n", "# 将日期列转换为日期类型\n", "df['date'] = pd.to_datetime(df['date'])\n", "\n", "# 使用 pivot_table 进行聚合\n", "result = pd.pivot_table(df, values='status', index=['date'], columns=['status'], aggfunc='size', fill_value=0).reset_index()\n", "\n", "print(result)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "bet_status date lost won\n", "0 2024-08-26 11 12\n", "1 2024-08-27 96 113\n", "2 2024-08-28 138 94\n", "3 2024-08-29 109 79\n", "4 2024-08-30 190 178\n", "5 2024-08-31 99 88\n", "6 2024-09-01 289 284\n", "7 2024-09-02 62 59\n", "8 2024-09-03 89 56\n", "9 2024-09-04 98 80\n", "10 2024-09-05 50 37\n", "Index(['date', 'lost', 'won'], dtype='object', name='bet_status')\n" ] } ], "source": [ "import pandas as pd\n", "\n", "\n", "\n", "# 使用 pivot_table 进行聚合\n", "result = pd.pivot_table(data_df, index=['date'], columns=['bet_status'], aggfunc='size', fill_value=0).reset_index()\n", "\n", "print(result)\n", "print(result.columns)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datestatus
02024-01-01active
12024-01-01inactive
22024-01-01active
32024-01-02active
42024-01-02inactive
52024-01-03inactive
\n", "
" ], "text/plain": [ " date status\n", "0 2024-01-01 active\n", "1 2024-01-01 inactive\n", "2 2024-01-01 active\n", "3 2024-01-02 active\n", "4 2024-01-02 inactive\n", "5 2024-01-03 inactive" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "年化夏普率: -1.4002737338136018\n", "ROI: -0.011875712320100193\n" ] } ], "source": [ "def clac_closing_balance(day_benefit_list, pre_balance=1000, pre_benefit=0):\n", " closing_balance_list = []\n", " for i, benefit in enumerate(day_benefit_list):\n", " closing_balance = pre_balance + pre_benefit / 3 + benefit * 2 / 3\n", " closing_balance_list.append(closing_balance)\n", " pre_balance = closing_balance\n", " pre_benefit = benefit\n", " return closing_balance_list\n", "\n", "def calc_in_transit_funds_ratio(daily_investment_list, closing_balance_list, start_closing_balance=1000):\n", " assert len(daily_investment_list) == len(closing_balance_list)\n", " ratio_list = []\n", " for i, daily_investment in enumerate(daily_investment_list):\n", " if i == 0:\n", " ratio = daily_investment / start_closing_balance\n", " else:\n", " ratio = daily_investment / closing_balance_list[i-1]\n", " ratio_list.append(ratio)\n", " return ratio_list\n", "\n", "\n", "init_balance = 1000\n", "res_df = data_df.groupby('date').agg({'investment':'sum', 'benefit':'sum'}).rename(columns={'investment':'当日投入', 'benefit':'日收益'}).reset_index()\n", "res_df['日收益率'] = res_df['日收益'] / res_df['当日投入']\n", "res_df['累计收益'] = res_df['日收益'].cumsum()\n", "res_df['累计投入'] = res_df['当日投入'].cumsum()\n", "res_df['累计收益率'] = res_df['累计收益'] / res_df['累计投入']\n", "\n", "day_benefit_list = res_df['日收益'].tolist()\n", "closing_balance_list = clac_closing_balance(day_benefit_list=day_benefit_list, pre_balance=init_balance)\n", "res_df['日末余额(1.6天结算)'] = closing_balance_list\n", "\n", "daily_investment_list = res_df['当日投入'].tolist()\n", "res_df['在途资金比例'] = calc_in_transit_funds_ratio(daily_investment_list=daily_investment_list, closing_balance_list=closing_balance_list, start_closing_balance=init_balance)\n", "annualized_sharpe_ratio = res_df['日收益'].sum() / init_balance / res_df['日收益率'].std() * ((365 / len(res_df))**0.5)\n", "print(f'年化夏普率: {annualized_sharpe_ratio}')\n", "roi = res_df['日收益'].sum() / res_df['当日投入'].sum()\n", "print(f'ROI: {roi}')" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "name": "日末余额", "type": "bar", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 1002.6656885456886, 1029.320085562455, 1031.6353596927408, 1014.877157613626, 1004.9262841780602, 1010.5006139053265, 1012.8869095027875, 1015.040231362553, 997.2052265455578, 980.6588565360646, 974.1046903384964 ], "yaxis": "y" }, { "mode": "markers+lines", "name": "日收益率", "type": "scatter", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 0.17384925297968776, 0.1817336321334136, -0.06688902311428041, -0.09243710870965964, -0.01694897264848009, 0.06139093881401034, -0.0037706970033483623, 0.035622210587666514, -0.19936311011066554, -0.058234435568632774, -0.053429707249929806 ], "yaxis": "y2" }, { "mode": "markers+lines", "name": "累计收益率", "type": "scatter", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 0.17384925297968776, 0.18095199109662177, 0.05703148399117068, 0.013933178120379116, 0.0027913825488691288, 0.01187018704065157, 0.00683522830064485, 0.008667540166362694, -0.006075589985235103, -0.010250173849373946, -0.011875712320100193 ], "yaxis": "y2" }, { "mode": "markers+lines", "name": "在途资金比例", "type": "scatter", "x": [ "2024-08-26T00:00:00", "2024-08-27T00:00:00", "2024-08-28T00:00:00", "2024-08-29T00:00:00", "2024-08-30T00:00:00", "2024-08-31T00:00:00", "2024-09-01T00:00:00", "2024-09-02T00:00:00", "2024-09-03T00:00:00", "2024-09-04T00:00:00", "2024-09-05T00:00:00" ], "y": [ 0.023, 0.20844435227771982, 0.22539150187983306, 0.1822349323660187, 0.3626054613992025, 0.1860833007795684, 0.5670456723281954, 0.11946052305029518, 0.1428514806800882, 0.1784988638864379, 0.08871586629758899 ], "yaxis": "y2" } ], "layout": { "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "日末余额(1.6天结算) 和 累计收益率 折线图" }, "xaxis": { "title": { "text": "日期" } }, "yaxis": { "title": { "text": "金额" } }, "yaxis2": { "overlaying": "y", "side": "right", "tickformat": ".1%", "title": { "text": "收益率" } } } } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import plotly.graph_objects as go\n", "from plotly.subplots import make_subplots\n", "\n", "\n", "\n", "res_df['日期'] = pd.to_datetime(res_df['date'])\n", "\n", "fig = go.Figure()\n", "fig.add_trace(go.Bar(\n", " x=res_df['日期'],\n", " y=res_df['日末余额(1.6天结算)'],\n", " name='日末余额',\n", " yaxis='y1'))\n", "\n", "for col in ['日收益率', '累计收益率', '在途资金比例']:\n", " fig.add_trace(go.Scatter(\n", " x=res_df['日期'],\n", " y=res_df[col],\n", " mode='markers+lines',\n", " name=col,\n", " yaxis='y2'))\n", "\n", "\n", "\n", "fig.update_layout(\n", " title='日末余额(1.6天结算) 和 累计收益率 折线图',\n", " xaxis=dict(title='日期'),\n", " yaxis=dict(title='金额'),\n", " yaxis2=dict(title='收益率', overlaying='y', side='right', tickformat='.1%'),\n", ")\n", "\n", "fig.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 基于market width 进行分层, 然后计算年华夏普率值, 进行资金配比" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
outcomecount
0-1.039838
41.037469
20.02804
1-0.5164
30.591
\n", "
" ], "text/plain": [ " outcome count\n", "0 -1.0 39838\n", "4 1.0 37469\n", "2 0.0 2804\n", "1 -0.5 164\n", "3 0.5 91" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "raw_df.groupby('outcome').agg({'away_team': 'count'}).rename(columns={'away_team': 'count'}).reset_index().sort_values(by='count', ascending=False)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.1811803969722776" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "raw_df['odds EU'].mean()" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "37.78343433288728" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1.01**365" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" } }, "nbformat": 4, "nbformat_minor": 2 }