小白量化彩票实战(1)彩票分析及爬虫双色球彩票开奖数据
彩票选号码有两类:一是自主组号,二是软件算号。
1、自主组号。主要用自己认为的吉祥号,例如生日或有特殊意义,特殊感觉的号码。但是这些选出的号码多于彩票号码,,就需要依赖程序软件进行条件过滤和缩水投注。
2、软件算号。主要通过计算机统计,利用大数定理,概率统计,以及深度学习等工具,进行电脑选号。
如果直接选出中大奖的号码,因为概率太低,例如双色球中奖概率1700多万分支一,基本不可能。但是我们分析开奖号码条件。
一等奖:6+1
二等奖:6
三等奖:5+1
四等奖:5、4+1
五等奖:4、3+1
六等奖:2+1、1+1、0+1
我们发现只要中蓝球,至少会得5元。因此我们以蓝号为中奖目标。但是蓝号有16个号,中奖概率为1/16。
一注彩票2元钱,假设我们一期开奖投注2注4元钱,投注2个蓝号,如果任意一个选中,我们就获得5元,赢利5-4=1元钱。
如何能够选2个蓝号,就能中5元钱。
首先要会“舍得”,不要每期都投注,这样你必败在大数定律中,因为长期统计,每个蓝号出现的几率,无限接近1/16,彩票机构就是赚大多数投注错的人的钱。
写《战胜庄家》的索普是如何赌场赚钱的?1960年代初,一位名叫索普(Edward Thorp)的美国数学家利用刚出现不久的计算机找到了21点游戏中的机会,发展出一套通过计牌(card counting)打败赌场的方法。索教授理论付诸实践,用自己的计牌法连连大胜赌场。
索普计牌法的原理并不难。 先讲讲21点的规则:玩家和庄家(赌场)对赌,看谁手中牌的点数之和更接近(但不能超过)21点。 10,J,Q,K都算十点,2至9 按各自点数计算,A可以算1点也可以算11点。 例如下面的一手牌可以算8点,也可以算18点。
牌局开始,玩家和庄家各发两张牌,庄家的牌一明一暗(例如下图)。 然后玩家先做决定:可以抓牌,做加倍等特殊行动,或在任何时候选择“停”。如果玩家超过21点(爆牌)就直接输了,否则“停”后轮到庄家行动。 庄家不能“见机行事”,只能按固定规则:手中的牌达到17点或以上必须“停”,否则必须抓。最后双方比谁的牌更接近21点。
此外还有个特殊规定:一张A和一张十点牌(10,J,Q,K)叫“黑杰克”(Blackjack),拿到者直接取胜。 如果玩家拿到黑杰克,可赢取1.5倍筹码。庄家拿到黑杰克只能赢取1倍筹码。
很明显,21点游戏中庄家和玩家各有优势。 庄家的优势在“后发制人”:玩家如果先爆牌,庄家可以不战而胜。而玩家的优势在于灵活机动,可以根据自己的牌和庄家暴露的那张牌决定战术。此外,黑杰克3:2的赔率也有利于玩家。
十点牌和A越多,出现黑杰克的机会越多,也越容易爆牌,玩家“机动灵活”的优势更有价值。 反之,3,4,5,6等小牌越多,爆牌的可能性越小,对庄家比较有利。索普时代的21点多用1副或2副扑克牌,当牌刚洗好时,赌场占据0.5%左右的概率优势。 妙处在于,随着牌局进行,某些时候大牌和A的比例会变高,概率会转为对玩家有利。 索普战胜赌场的方法就是:通过计牌估算概率,当形势有利时下大赌注!
读者要学会读文抽象:只有对自己有利的情况下才下注。
既然双色球蓝号概率只有1/16,我们什么时候去买呢?
我们对彩票篮球号码提取特征,蓝号可以分大小号,1-8大号,9-16小号。又可以分奇偶号。号码大小号和奇偶号出现的概率为1/2,因此根据大数定理,奇号和大号不会持续连出。
假定奇号和大号连出3期,我们蓝球可以选择偶数小号来买。我们只能选2,4,6,8号等4个号。仍然超出我们选择的范围,我们再提取特征,余三(即除3的余数,0,1,2),同样依赖大数定理,同样的模式出现只有1/3的概率,他们连出就要排排除。
假定我们发现有三期大号,奇数,余三2连出,排除后,我们的选择只有:4,6号。是不是满足了我们的要求。
假定前面3期开奖号如下,大号,奇数,余三2连出:
02 03 13 18 20 31, 11
06 10 13 25 26 32, 11
06 09 16 18 22 29, 11
我们蓝号选择只有:4,6号,我们选了这2个号投注,出现奖号“02 03 07 08 17 22, 15”没有买中。蓝15是大号,奇号,余三0,因此根据大数定理排除了蓝6,只剩蓝4号投注了。
我们再次投注2注蓝4,结果开奖“07 09 14 26 30 31, 04”,我们获利10-4-4=2元。
你会说,哪有那么巧,确实那么巧,上面5期是双色球2021001-2021005的开奖号。
假如是1/2几率赢后投注翻倍的游戏,例如比大小,想赢就要采用“马丁策略”,只压大或小单向,亏钱后,压注翻倍,只要本金足够多,赢1次,就全赢。
如果赢率只有40%的几率的游戏,本金有限,怎么够最佳自己投注呢?这就要使用“凯利公式”。
形势有利时如何下注很需要技巧。押太少了浪费机会,押太多了“牺牲”的风险大增。 什么才是不多不少的合适赌注呢? 1956年,科学家凯利(John Kelly)就此发表了论文,提出了著名的凯利公式。
f* = (bp - q) / b
其中,f* = 投注金额占总资金的比例,p = 获胜的概率,q = 失败的概率,q = 1-p,b = 赔率。
例如在轮盘赌中押单个数字,b = 35,押红黑,b = 1。
凯利公式指明了风险控制的至关重要性:即便是正期望值的游戏也不能押太大的赌注。 从数学上讲,押注资金比例超过了凯利值,长期的赢钱速度反而下降。 举个极端的例子,如果你每手都押上全部资金,那么不管你赢过多少钱,只要输一次就立刻破产。正所谓:辛辛苦苦几十年,一夜回到解放前。
投资和投注是一门科学,如同玩游戏。假定你玩帝国时代或者星际争霸游戏,你打算把游戏中金钱全部造兵,去赌一把去分胜负?还是想造农民来种田挖矿?
把投资看作游戏,你会感觉赚钱很容易。感觉赚钱很容易,是从战略上来说的。从整体上来说,要轻视它。从每一局部来说,要重视它。亏钱会让你心痛,任何投资莫过如此。
后面文章,以双色球为例,介绍如何通过小白量化金融模块来分析彩票。
我们先用Python爬虫数据,获取全部双色球彩票数据。下面给出双色球爬虫代码。
import requests
from bs4 import BeautifulSoup
# 发起请求
basic_url = 'http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
response = requests.get(basic_url, headers=headers, timeout=10)
response.encoding = 'utf-8'
htm = response.text
# 解析内容
soup = BeautifulSoup(htm, 'html.parser')
# 获取页数信息
page = int(soup.find('p', attrs={
"class": "pg"}).find_all('strong')[0].text)
url_part = 'http://kaijiang.zhcw.com/zhcw/html/ssq/list'
ssq=''
ssqhm=[]
for i in range(1, page+1):
url = url_part + '_' + str(i) + '.html'
res = requests.get(url, headers=headers, timeout=10)
res.encoding = 'utf-8'
context = res.text
soups = BeautifulSoup(context, 'html.parser')
if soups.table is None:
continue
elif soups.table:
table_rows = soups.table.find_all('tr')
for row_num in range(2, len(table_rows)-1):
row_tds = table_rows[row_num].find_all('td')
ems = row_tds[2].find_all('em')
result = row_tds[0].string +', '+ row_tds[1].string +', '+ems[0].string+' '+ems[1].string+' '+ems[2].string+' '+ems[3].string+' '+ems[4].string+' '+ems[5].string+', '+ems[6].string
td2 = row_tds[3].find_all('strong')
ss=td2[0].string
ss=ss.replace(',','')
result=result+','+ss
td3 = row_tds[4].find_all('strong')
result=result+','+td3[0].string
td4 = row_tds[5].find_all('strong')
result=result+','+td4[0].string
ssq=result+'\n'+ssq
print(result)
def save_to_file(content):
with open('ssq.txt', 'w', encoding='utf-8') as f:
f.write(content + '\n')
save_to_file(ssq)
采集结果保存到ssq.txt文件中了。
2020-12-31, 2020134, 02 09 10 20 22 26, 01,399565532,48,275
2021-01-03, 2021001, 02 03 13 18 20 31, 11,411170524,10,126
2021-01-05, 2021002, 06 10 13 25 26 32, 11,374374440,10,185
2021-01-07, 2021003, 06 09 16 18 22 29, 11,360514540,5,136
2021-01-10, 2021004, 02 03 07 08 17 22, 15,396531778,2,208
2021-01-12, 2021005, 07 09 14 26 30 31, 04,359757108,14,76
2021-01-14, 2021006, 06 08 22 24 25 26, 01,367900704,10,194
2021-01-17, 2021007, 02 04 12 21 25 32, 16,389232822,3,104
2021-01-19, 2021008, 01 05 07 14 18 33, 07,358122646,4,86
2021-01-21, 2021009, 02 04 07 24 25 32, 13,367324734,4,57
2021-01-24, 2021010, 01 04 11 19 32 33, 05,394795416,7,129
2021-01-26, 2021011, 05 10 16 23 27 33, 14,358439884,18,228
2021-01-28, 2021012, 03 06 14 18 20 26, 01,365486356,17,218
2021-01-31, 2021013, 06 09 12 16 27 31, 06,403024326,17,169
2021-02-02, 2021014, 04 15 21 25 29 33, 06,365029152,3,96
2021-02-04, 2021015, 06 14 16 26 28 29, 07,373264066,6,93
2021-02-07, 2021016, 03 08 09 13 15 18, 10,447622614,16,192
2021-02-21, 2021017, 09 15 18 29 32 33, 02,442443732,6,116
2021-02-23, 2021018, 02 08 14 23 25 32, 06,352299530,3,128
我们使用小白量化,必须使用pandas的DataFrame 对象来用仿通达信公式统计分析,一次我们再把ssq.txt文件改为容易处理的ssq.csv格式,下面给出程序。
import math
import datetime as dt
import pandas as pd
import numpy as np
import random
df=pd.read_csv('ssq.txt' , encoding= 'gbk',header=None)
df.rename(columns={
0:'date', 1:'qh', 2:'hh',3:'lh',4:'tz',5:'j1',6:'j2'}, inplace = True)
df['h1']=[int(x.strip().split(' ')[0]) for x in df.hh.astype(str)]
df['h2']=[int(x.strip().split(' ')[1]) for x in df.hh.astype(str)]
df['h3']=[int(x.strip().split(' ')[2]) for x in df.hh.astype(str)]
df['h4']=[int(x.strip().split(' ')[3]) for x in df.hh.astype(str)]
df['h5']=[int(x.strip().split(' ')[4]) for x in df.hh.astype(str)]
df['h6']=[int(x.strip().split(' ')[5]) for x in df.hh.astype(str)]
df['sumh']=df['h1']+df['h2']+df['h3']+df['h4']+df['h5']+df['h6']
df.to_csv('ssq.csv' , encoding= 'gbk')
print(df)
处理后的结果如下:
date qh hh lh ... h4 h5 h6 sumh
0 2003-02-23 2003001 10 11 12 13 26 28 11 ... 13 26 28 100
1 2003-02-27 2003002 04 09 19 20 21 26 12 ... 20 21 26 99
2 2003-03-02 2003003 01 07 10 23 28 32 16 ... 23 28 32 101
3 2003-03-06 2003004 04 06 07 10 13 25 3 ... 10 13 25 65
4 2003-03-09 2003005 04 06 15 17 30 31 16 ... 17 30 31 103
5 2003-03-13 2003006 01 03 10 21 26 27 6 ... 21 26 27 88
6 2003-03-16 2003007 01 09 19 21 23 26 7 ... 21 23 26 99
小白量化彩票模块演示:
import math
import datetime as dt
import pandas as pd
import numpy as np
import HP_cp as hcp #小白量化彩票模块
##排列型彩票
print('福彩3D的中奖概率:',1/hcp.cfpl(r=3))
print('福彩3D的全部号码:\n',hcp.qplh2(m=3))
print('福彩双色球的中奖号码总数:',hcp.zh(r=6,n=33)*16)
print('随机福彩双色球5注号码:')
for i in range(5):
for h in hcp.randhm(r=6,m=33,n=1):
print(h,end=' ')
print(' + ',hcp.randone(m=10,n=1))
#获取本地ssq.csv双色球数据
df=pd.read_csv('ssq.csv' , encoding='gbk')
print(df)
程序运行结果:
福彩3D的中奖概率: 0.001
福彩3D的全部号码:
['000', '001', '002', '003', '004', '005', '006', '007', '008', '009', '010', '011', '012', '013', '014', '015', '016', '017', '018', '019', '020', '021', '022'
...
福彩双色球的中奖号码总数: 17721088
随机福彩双色球5注号码:
4 10 12 15 25 29 + 7
3 8 13 16 22 23 + 4
2 4 9 13 25 33 + 9
4 11 19 20 26 33 + 10
1 3 7 21 27 28 + 1
Unnamed: 0 date qh ... h5 h6 sumh
0 0 2003-02-23 2003001 ... 26 28 100
1 1 2003-02-27 2003002 ... 21 26 99
2 2 2003-03-02 2003003 ... 28 32 101
3 3 2003-03-06 2003004 ... 13 25 65
后面文章将介绍彩票特征分析,统计,仿通达信指标分析,深度学习以及过滤和缩水等技术。
请点赞本文,你的鼓励是我写作的动力!
请持续关注我的博客,我的进步,就是你的进步!