本文目录导读:

我理解您想了解如何用Python分析必发指数(Betfair指数)的变化,必发指数反映了市场资金流向和价格变动,是博彩市场的重要参考指标,下面我提供一个完整的分析框架和代码示例。
必发指数分析的核心维度
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
import requests
class BetfairIndexAnalyzer:
"""
必发指数变化分析器
"""
def __init__(self, match_data):
"""
初始化分析器
match_data: 包含时间戳、主胜、平局、客胜等数据
"""
self.df = pd.DataFrame(match_data)
self.df['timestamp'] = pd.to_datetime(self.df['timestamp'])
self.df = self.df.sort_values('timestamp')
def calculate_basic_indicators(self):
"""
计算基础指标
"""
# 指数变化率(每分钟变化)
self.df['home_change'] = self.df['home_odds'].diff()
self.df['draw_change'] = self.df['draw_odds'].diff()
self.df['away_change'] = self.df['away_odds'].diff()
# 累计变化
self.df['home_cumsum'] = self.df['home_change'].cumsum()
self.df['draw_cumsum'] = self.df['draw_change'].cumsum()
self.df['away_cumsum'] = self.df['away_change'].cumsum()
# 波动率(滚动标准差)
self.df['home_volatility'] = self.df['home_odds'].rolling(window=10).std()
self.df['away_volatility'] = self.df['away_odds'].rolling(window=10).std()
return self.df
def detect_market_moves(self, threshold=0.02):
"""
检测市场大幅波动
threshold: 波动阈值(2%)
"""
moves = []
for i in range(1, len(self.df)):
home_pct_change = (self.df['home_odds'].iloc[i] - self.df['home_odds'].iloc[i-1]) / self.df['home_odds'].iloc[i-1]
away_pct_change = (self.df['away_odds'].iloc[i] - self.df['away_odds'].iloc[i-1]) / self.df['away_odds'].iloc[i-1]
if abs(home_pct_change) > threshold or abs(away_pct_change) > threshold:
moves.append({
'timestamp': self.df['timestamp'].iloc[i],
'home_odds': self.df['home_odds'].iloc[i],
'away_odds': self.df['away_odds'].iloc[i],
'home_pct_change': home_pct_change,
'away_pct_change': away_pct_change
})
return pd.DataFrame(moves)
def analyze_correlation(self):
"""
分析各赔率之间的相关性
"""
correlation_matrix = self.df[['home_odds', 'draw_odds', 'away_odds']].corr()
return correlation_matrix
def generate_signals(self):
"""
生成交易信号
"""
signals = []
# 信号1: 连续大幅下降(主力资金介入)
for i in range(5, len(self.df)):
home_5min_change = (self.df['home_odds'].iloc[i] - self.df['home_odds'].iloc[i-5]) / self.df['home_odds'].iloc[i-5]
if home_5min_change < -0.05: # 5分钟下降超过5%
signals.append({
'timestamp': self.df['timestamp'].iloc[i],
'type': 'STRONG_BUY_HOME',
'reason': f'主胜赔率5分钟下降{abs(home_5min_change)*100:.1f}%',
'odds': self.df['home_odds'].iloc[i]
})
# 信号2: 反向趋势(指数异常)
if abs(home_5min_change) > 0.03 and abs(self.df['home_odds'].iloc[i] - self.df['home_odds'].mean()) > 2 * self.df['home_odds'].std():
signals.append({
'timestamp': self.df['timestamp'].iloc[i],
'type': 'ABNORMAL_SIGNAL',
'reason': '异常波动检测',
'odds': self.df['home_odds'].iloc[i]
})
return pd.DataFrame(signals)
def visualize_analysis(self):
"""
可视化分析结果
"""
fig, axes = plt.subplots(3, 1, figsize=(12, 10))
# 图1: 赔率走势
axes[0].plot(self.df['timestamp'], self.df['home_odds'], label='主胜', color='blue')
axes[0].plot(self.df['timestamp'], self.df['draw_odds'], label='平局', color='gray')
axes[0].plot(self.df['timestamp'], self.df['away_odds'], label='客胜', color='red')
axes[0].set_xlabel('时间')
axes[0].set_ylabel('赔率')
axes[0].legend()
axes[0].set_title('必发指数走势图')
# 图2: 累计变化
axes[1].plot(self.df['timestamp'], self.df['home_cumsum'], label='主胜累计变化', color='blue')
axes[1].plot(self.df['timestamp'], self.df['draw_cumsum'], label='平局累计变化', color='gray')
axes[1].plot(self.df['timestamp'], self.df['away_cumsum'], label='客胜累计变化', color='red')
axes[1].axhline(y=0, linestyle='--', color='black', alpha=0.5)
axes[1].set_xlabel('时间')
axes[1].set_ylabel('累计变化')
axes[1].legend()
axes[1].set_title('赔率累积变化趋势')
# 图3: 波动率
axes[2].plot(self.df['timestamp'], self.df['home_volatility'], label='主胜波动率', color='blue')
axes[2].plot(self.df['timestamp'], self.df['away_volatility'], label='客胜波动率', color='red')
axes[2].set_xlabel('时间')
axes[2].set_ylabel('波动率')
axes[2].legend()
axes[2].set_title('赔率波动率分析')
plt.tight_layout()
plt.show()
def export_report(self):
"""
导出分析报告
"""
report = {
'basic_stats': self.df[['home_odds', 'draw_odds', 'away_odds']].describe(),
'market_moves': self.detect_market_moves(),
'signals': self.generate_signals(),
'correlations': self.analyze_correlation()
}
return report
# 示例数据生成和测试
def generate_sample_data():
"""
生成示例数据(模拟真实数据)
"""
np.random.seed(42)
timestamps = pd.date_range(start='2024-01-01 19:00', end='2024-01-01 20:00', freq='1min')
# 模拟赔率变化
home_odds = np.random.normal(2.00, 0.02, len(timestamps))
draw_odds = np.random.normal(3.30, 0.02, len(timestamps))
away_odds = np.random.normal(3.50, 0.02, len(timestamps))
# 模拟市场突变动(20分钟时出现异常)
home_odds[15:25] -= 0.15
away_odds[15:25] += 0.1
return {
'timestamp': timestamps,
'home_odds': home_odds,
'draw_odds': draw_odds,
'away_odds': away_odds
}
# 使用示例
if __name__ == "__main__":
# 生成示例数据
sample_data = generate_sample_data()
# 创建分析器
analyzer = BetfairIndexAnalyzer(sample_data)
# 计算基础指标
df = analyzer.calculate_basic_indicators()
print("基础数据统计:")
print(df.describe())
# 检测市场波动
moves = analyzer.detect_market_moves()
print("\n检测到的大幅波动:")
print(moves)
# 生成交易信号
signals = analyzer.generate_signals()
print("\n交易信号:")
print(signals)
# 相关性分析
correlations = analyzer.analyze_correlation()
print("\n赔率相关性矩阵:")
print(correlations)
# 可视化分析
analyzer.visualize_analysis()
# 导出完整报告
report = analyzer.export_report()
print("\n分析报告已生成")
关键分析维度详解
市场情绪指标
def market_sentiment(self):
"""
计算市场情绪:赔率变化的方向性和强度
"""
sentiment = 0
if self.df['home_odds'].iloc[-1] < self.df['home_odds'].iloc[0]:
sentiment += 1 # 主胜被看好
if self.df['away_odds'].iloc[-1] < self.df['away_odds'].iloc[0]:
sentiment -= 1 # 客胜被看好
# 考虑变化速度
home_speed = (self.df['home_odds'].iloc[-1] - self.df['home_odds'].iloc[0]) / len(self.df)
away_speed = (self.df['away_odds'].iloc[-1] - self.df['away_odds'].iloc[0]) / len(self.df)
return {
'sentiment': sentiment,
'home_speed': home_speed,
'away_speed': away_speed
}
资金流分析
def analyze_money_flow(self):
"""
基于赔率变化估算资金流向
"""
# 赔率下降通常意味着资金流入
home_flow = -self.df['home_odds'].pct_change().fillna(0)
away_flow = -self.df['away_odds'].pct_change().fillna(0)
# 计算累计资金流
self.df['home_cum_flow'] = home_flow.cumsum()
self.df['away_cum_flow'] = away_flow.cumsum()
return self.df
异常检测算法
def anomaly_detection(self, window=30):
"""
使用移动平均和标准差检测异常
"""
self.df['home_ma'] = self.df['home_odds'].rolling(window=window).mean()
self.df['home_std'] = self.df['home_odds'].rolling(window=window).std()
# 找出超出2个标准差的点
anomalies = self.df[abs(self.df['home_odds'] - self.df['home_ma']) > 2 * self.df['home_std']]
# 过滤掉NaN
anomalies = anomalies.dropna(subset=['home_ma'])
return anomalies
实战技巧建议
- 数据采集频率:高频数据建议使用30秒到1分钟间隔,低频可用5分钟
- 时间窗口:重点关注开赛前30分钟到1小时的变化
- 组合信号:不要单独依赖单一指标,结合多个指标判断
- 历史对比:与相似赛事的历史数据进行对比分析
- 实时监控:建立实时监控系统,设置预警阈值
这个框架可以帮助您系统分析必发指数的变化规律,发现市场趋势和异常情况,您可以根据实际需求扩展功能,比如添加机器学习预测模型或更复杂的交易策略。