From 859efd20acacff419a84aec58e60aad5f334cd59 Mon Sep 17 00:00:00 2001 From: NY Date: Fri, 23 May 2025 16:39:38 +0800 Subject: [PATCH] 1 --- poly/main.py | 25 +++++ poly/mainfr.py | 238 +++++++++++++++++++++++++++++++++++++++++++++++ test/aola.sqlite | Bin 28672 -> 28672 bytes 3 files changed, 263 insertions(+) create mode 100644 poly/main.py create mode 100644 poly/mainfr.py diff --git a/poly/main.py b/poly/main.py new file mode 100644 index 0000000..9e6926f --- /dev/null +++ b/poly/main.py @@ -0,0 +1,25 @@ +import requests +import json + +# API endpoint +url = "https://gamma-api.polymarket.com/markets" + +# Parameters +params = { + "clob_token_ids": "867120030737778362406620246392661182987264708958188075536191457143522877699" +} + +# Make the GET request +try: + response = requests.get(url, params=params) + response.raise_for_status() # Raise an error for bad status codes + + # Parse JSON response + market_data = response.json() + + # Pretty-print the JSON data + print("Market Data:") + print(json.dumps(market_data, indent=4, sort_keys=True)) + +except requests.exceptions.RequestException as e: + print(f"Error fetching market data: {e}") diff --git a/poly/mainfr.py b/poly/mainfr.py new file mode 100644 index 0000000..39aa336 --- /dev/null +++ b/poly/mainfr.py @@ -0,0 +1,238 @@ +import pandas as pd +import plotly.graph_objects as go +from plotly.subplots import make_subplots +from dash import Dash, dcc, html, Input, Output +from sqlalchemy import create_engine +from datetime import datetime + +# 数据库连接配置 +DB_CONFIG = { + 'host': '8.155.23.172', + 'port': 3306, + 'user': 'root2', + 'password': 'tG0f6PVYh18le41BCb', + 'database': 'elonX' +} +TABLE_NAME = 'poly_after2024' +db_uri = f"mysql+pymysql://{DB_CONFIG['user']}:{DB_CONFIG['password']}@{DB_CONFIG['host']}:{DB_CONFIG['port']}/{DB_CONFIG['database']}" +engine = create_engine(db_uri) + +# 第一步:提取用户的交易记录(从2024-01-01开始) +user_query = """ +select IF(maker_asset_id = 0, 'buy', 'sell') as sellorbuy, + maker_amount_filled/1000000 as maker_amount, + taker_amount_filled/1000000 as taker_amount, + maker_asset_id, taker_asset_id, + timestamp, IF(maker_asset_id = 0, taker_asset_id, maker_asset_id) as assetid +from poly_after2024 +where maker = '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b' and timestamp >= 1704085200 +union all +select IF(taker_asset_id = 0, 'buy', 'sell') as sellorbuy, + taker_amount_filled/1000000 as maker_amount, + maker_amount_filled/1000000 as taker_amount, + maker_asset_id, taker_asset_id, + timestamp, IF(maker_asset_id = 0, taker_asset_id, maker_asset_id) as assetid +from poly_after2024 +where taker = '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b' and timestamp >= 1704085200 +""" +user_df = pd.read_sql_query(user_query, engine) + +# 第二步:提取涉及的assetid的交易记录,计算价格 +asset_ids = user_df['assetid'].unique() +asset_query = f""" +select timestamp, maker_amount_filled/1000000 as maker_amount, taker_amount_filled/1000000 as taker_amount, + maker_asset_id, taker_asset_id, + IF(maker_asset_id = 0, taker_asset_id, maker_asset_id) as assetid +from poly_after2024 +where (IF(maker_asset_id = 0, taker_asset_id, maker_asset_id) in ({','.join([f"'{x}'" for x in asset_ids])})) +and timestamp >= 1704085200 +""" +asset_df = pd.read_sql_query(asset_query, engine) + +# 计算价格:金额/数量 +asset_df['price'] = 0.0 +for idx, row in asset_df.iterrows(): + if row['maker_asset_id'] == '0': + asset_df.at[idx, 'price'] = row['maker_amount'] / row['taker_amount'] + else: + asset_df.at[idx, 'price'] = row['taker_amount'] / row['maker_amount'] +asset_df['date'] = pd.to_datetime(asset_df['timestamp'], unit='s').dt.date +daily_prices = asset_df.groupby(['date', 'assetid'])['price'].mean().reset_index() + +# 第三步:计算用户持仓 +user_df['date'] = pd.to_datetime(user_df['timestamp'], unit='s').dt.date +holdings = {} # 记录持仓:{assetid: 数量} +daily_holdings = [] # 按天记录持仓和市值 +dates = pd.date_range(start='2024-01-01', end='2025-05-22', freq='D') + +for date in dates: + date = date.date() + day_trades = user_df[user_df['date'] <= date] + # 更新持仓 + for idx, trade in day_trades.iterrows(): + assetid = trade['assetid'] + amount = trade['maker_amount'] if trade['sellorbuy'] == 'buy' else -trade['maker_amount'] + holdings[assetid] = holdings.get(assetid, 0) + amount + if holdings[assetid] <= 0: # 持仓为0,移除 + del holdings[assetid] + # 计算市值 + total_value = 0 + asset_values = {} + for assetid, amount in holdings.items(): + price_data = daily_prices[(daily_prices['assetid'] == assetid) & (daily_prices['date'] <= date)] + if not price_data.empty: + latest_price = price_data.sort_values('date', ascending=False).iloc[0]['price'] + value = amount * latest_price + total_value += value + asset_values[assetid] = value + daily_holdings.append({'date': date, 'total_value': total_value, 'asset_values': asset_values}) + +# 转换为DataFrame +daily_holdings_df = pd.DataFrame(daily_holdings) + +# 第四步:饼图数据(默认显示整个时间段的市场占比) +market_share = user_df.groupby('assetid').apply( + lambda x: x[x['sellorbuy'] == 'buy']['taker_amount'].sum() +).reset_index(name='amount') +total_amount = market_share['amount'].sum() + +# 第五步:初始化Dash应用 +app = Dash(__name__) + +# 初始图表 +fig = make_subplots(rows=1, cols=2, specs=[[{"type": "pie"}, {"type": "scatter"}]], subplot_titles=("市场占比", "资产价值随时间变化")) + +# 饼图(初始) +fig.add_trace( + go.Pie( + labels=market_share['assetid'], + values=market_share['amount'], + hoverinfo='label+value', + textinfo='percent', + texttemplate='%{percent:.2%}', + marker=dict(colors=['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c']), + showlegend=False + ), + row=1, col=1 +) + +# 折线图 +fig.add_trace( + go.Scatter( + x=daily_holdings_df['date'], + y=daily_holdings_df['total_value'], + mode='lines+markers', + name='资产价值', + customdata=daily_holdings_df['asset_values'], + hovertemplate='日期: %{x}
总资产: %{y:.2f}' + ), + row=1, col=2 +) + +# 布局 +fig.update_layout( + title_text="交易员 0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b 资产分析", + showlegend=False, + height=500, + width=1000 +) + +# 饼图中心显示总金额 +fig.add_annotation( + text=f"${total_amount:,.2f}
总计", + x=0.18, y=0.5, + showarrow=False, + font=dict(size=16) +) + +# Dash布局 +app.layout = html.Div([ + dcc.Graph(id='main-graph', figure=fig), + dcc.Store(id='holdings-data', data=daily_holdings_df.to_dict('records')) # 存储持仓数据 +]) + +# 回调:当鼠标悬停在折线图上时,更新饼图 +@app.callback( + Output('main-graph', 'figure'), + Input('main-graph', 'hoverData'), + Input('holdings-data', 'data') +) +def update_pie_chart(hoverData, holdings_data): + # 恢复初始图表 + fig = make_subplots(rows=1, cols=2, specs=[[{"type": "pie"}, {"type": "scatter"}]], subplot_titles=("市场占比", "资产价值随时间变化")) + holdings_df = pd.DataFrame(holdings_data) + + # 折线图保持不变 + fig.add_trace( + go.Scatter( + x=holdings_df['date'], + y=holdings_df['total_value'], + mode='lines+markers', + name='资产价值', + customdata=holdings_df['asset_values'], + hovertemplate='日期: %{x}
总资产: %{y:.2f}' + ), + row=1, col=2 + ) + + # 如果没有hover数据,显示默认饼图 + if hoverData is None: + fig.add_trace( + go.Pie( + labels=market_share['assetid'], + values=market_share['amount'], + hoverinfo='label+value', + textinfo='percent', + texttemplate='%{percent:.2%}', + marker=dict(colors=['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c']), + showlegend=False + ), + row=1, col=1 + ) + fig.add_annotation( + text=f"${total_amount:,.2f}
总计", + x=0.18, y=0.5, + showarrow=False, + font=dict(size=16) + ) + else: + # 获取悬停的日期 + hover_date = hoverData['points'][0]['x'] + hover_date = pd.to_datetime(hover_date).date() + # 找到该日期的持仓数据 + holdings_row = holdings_df[holdings_df['date'] == hover_date] + if not holdings_row.empty: + asset_values = holdings_row.iloc[0]['asset_values'] + labels = list(asset_values.keys()) + values = list(asset_values.values()) + total_value = sum(values) + fig.add_trace( + go.Pie( + labels=labels, + values=values, + hoverinfo='label+value', + textinfo='percent', + texttemplate='%{percent:.2%}', + marker=dict(colors=['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c']), + showlegend=False + ), + row=1, col=1 + ) + fig.add_annotation( + text=f"${total_value:,.2f}
总计", + x=0.18, y=0.5, + showarrow=False, + font=dict(size=16) + ) + + fig.update_layout( + title_text="交易员 0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b 资产分析", + showlegend=False, + height=500, + width=1000 + ) + return fig + +# 运行Dash应用 +if __name__ == '__main__': + app.run_server(debug=True) \ No newline at end of file diff --git a/test/aola.sqlite b/test/aola.sqlite index 3bf664c63ce26b7ec66f346cb91081c3165e0c17..0743ea85224da565896c3e4c12be1f24c8ff706e 100644 GIT binary patch delta 186 zcmZp8z}WDBae@>RU-d*8Cm^{ofmx2xaC3^>0!L;;hNY9)6B3xeF)W?fXf5b(%w}!M zpltkfQzH;PU)nMGbdt2Ok%h6cp@DI6aiLk6VPaBcaWRnA1v7NvDqW4(O!XNQb)QXN r@U(3zNS~agg|cyZE~XxclFhb>I-GpkU~LQx2yHANZJVcMWw8PP);mR~ delta 77 zcmZp8z}WDBae@>R@3VW!R8dX1&+-6jJA{66A~siUE6G%sKd$mWKY+# gNt2##m@;{NqByTnnGq1_KAYS0a^cR+)3UNy0c><1Z~y=R