MATLABで競艇の解析を始めよう（有名な買い方をしてみよう）

# MATLAB ボートレースの９個目の記事です。
　[これ](https://qiita.com/teruqii/items/cd6e390cff80d6686c69)の続きです。９回も書いたので、そろそろ儲かるといいですね！
　前にどっかで蛭子買いとかを書いたけどそういうのじゃなくて、もっと時系列を考えた買い方をしてみましょう。

## いろいろな買い方をバーチャルでやってみよう。
　とりあえず、世の中にある古典的な手法を試してみよう。いろいろ試すので、[８回目の記事](https://qiita.com/teruqii/items/cd6e390cff80d6686c69)のデータは保存しておくといいです。MATLAB の保存は save コマンドで、TR_2019.mat みたいに保存されます。

```matlab
save TR_all TR_2019
save fanbook Person
```

読み込みは load ですね。

```matlab
load TR_all
load fanbook
```


# マーチンゲール法

　有名で簡単な方法です！外れたら２倍の金額を掛けていくという方法です。

1回目：100円　はずれ
2回目：200円　はずれ
3回目：400円　はずれ
4回目：800円　あたり！　→　配当３倍で 2400円ゲット（900円の利益）
　　　↓
1回目の100円からやり直し。

場が変わると時系列がややこしくなるので、どこかの場を決めて2019年のデータでやってみよう！

## 芦屋で、２連単１－２を買う。

　当てなきゃいかんので、３連単じゃなくて２連単にしてみよう。なんとなく芦屋で 2019/1/1 の 1R から 100円ではじめるとして、プログラムは簡単。

```matlab
%% 芦屋を抜こう
R21 = TR_2019(TR_2019.Place == "芦屋",:);

%% マーチンゲール
cnt = 1;
result = 0;

for n = 1:height(R21)
    if R21.exacta(n) == "12"
        result(end+1) = result(end) + cnt(end) * R21.exacta_d(n) - cnt(end) * 100;
        cnt(end+1) = 1;
    else
        result(end+1) = result(end) - cnt(end) * 100;
        cnt(end+1) = cnt(end) * 2;
    end
end

result(1) = [];

plot(datenum(R21.YYYYMMDD,'yyyymmdd'),result)
datetick('x','yyyymmdd')
```

結果↓↓↓

![ashiya.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475339/456443c5-4613-da3a-4989-1d40fc592f91.png)

12月に930億円儲かりました！が、よく見てみると11月に331億の負債を抱えております。
（X軸の737800って値は、加工を忘れて西暦0年1月0日からの経過日数を丸めたものなので気にしないで。。）

### もしも1日12レースが全部外れると、いくら負けるのか。
　コマンドで確認。

```matlab
>> cumsum(2.^(0:11))'*100

ans =

         100
         300
         700
        1500
        3100
        6300
       12700
       25500
       51100
      102300
      204700
      409500
```

40万円！

### そして、芦屋の最大ベットはいくらだったんだろうか・・・

max(cnt)*100 が最大のベット額です。

```matlab
>> max(cnt)*100

ans =

   53687091200
```

29連敗で2^29！
11月のどっかのレースに536億円も突っ込んでる・・・

こんなに賭けるとオッズが動いて 1.0 倍になっちゃうのでダメですね。（そもそもそんなにお金がない。）


## 芦屋のせいかもしれないから、いろんな場でやってみよう。

　成績が悪いのは芦屋のせいにするとして、こんなプログラムを実行！

```matlab
%% 全場
Place = unique(categorical(TR_2019.Place));
Res = {};
for m = 1:length(Place)
    cnt = 1;
    result = 0;
    
    RR = TR_2019(TR_2019.Place == Place(m),:);
    for n = 1:height(RR)
        if RR.exacta(n) == "12"
            result(end+1) = result(end) + cnt(end) * RR.exacta_d(n) - cnt(end) * 100;
            cnt(end+1) = 1;
        else
            result(end+1) = result(end) - cnt(end) * 100;
            cnt(end+1) = cnt(end) * 2;
        end
    end
    
    result(1) = [];
    
    Res{m} = [datenum(RR.YYYYMMDD,'yyyymmdd'),result'];
end

for m = 1:length(Place)
    plot(Res{m}(:,1),Res{m}(:,2))
    datetick('x')
    hold on
    Rmin(m,1) = min(Res{m}(:,2));
    Rend(m,1) = Res{m}(end,2);
end
disp([char(Place) repmat(':',24,1) num2str(Rmin) ,repmat('  ',24,1), num2str(Rend)])
```

↓↓↓ 表示される結果（場：一番負けてたときの額 ,   2019/12/31の額の順で表示）
（プロットも出るけど省略）

```
三国 :  -3435466303520     4124085770380
下関 :  -4775293393050     7597635785790
丸亀 :  -1717461124720      681865268070
住之江:  -6868548609000     5026954670250
児島 :    -12932906780       78255103180
唐津 :      -281654930         494649880
多摩川:-439802038224070  4090326557994720
大村 :   -429497217130     4081424658760
宮島 :  -3435957639420    18929682358650
尼崎 :   -136096464350      596068294490
常滑 :  -2077543733480     7199599703680
平和島: -13592300283830     7296894575700
徳山 :       -48404300         608844120
戸田 :  -3422469258120    30763761466410
桐生 : -54969530832510    57763477827280
江戸川:  -1706406693520    13264273184600
津  :  -1715088302520     1033692166330
浜名湖:  -6862590672900    19421761275680
琵琶湖:   -858995958100     7407761073810
福岡 :     -4119332260       90515597680
芦屋 :    -33101058900       93064134940
若松 :   -181534055800     2131960434410
蒲郡 :   -846713042360     6904781857170
鳴門 :   -159767455990      570498286060
```

全部、年末にはプラスになってるけど、負けが大きすぎてダメだね！
多摩川に至っては、439兆円も負けて国家予算を超えておる。

## ２連単の１－２が悪いのかもしれん。
　こういう方法って配当の期待値が２倍くらいだったら 50% 近く当てないとダメなんですが、1-2 だと 19% くらいでした。３連複にして３点くらい買ってみようかな。

　３連複の 1=2=3, 1=2=4, 1=3=4 の３つで 41% くらいなので、これで児島でやってみよう。
3点なので、300円→ 600円 → 1200円 → 2400円 → ... と増えます。

```matlab
R = TR_2019(TR_2019.Place == "児島",:);

cnt = 1;
result = 0;
numbet = 300;

for n = 1:height(R)
    if R.trio(n) == "123" || R.trio(n) == "124" || R.trio(n) == "134"
        result(end+1) = result(end) + cnt(end) * R.trio_d(n) - cnt(end) * numbet;
        cnt(end+1) = 1;
    else
        result(end+1) = result(end) - cnt(end) * numbet;
        cnt(end+1) = cnt(end) * 2;
    end
end

result(1) = [];

figure(1)
plot(datenum(R.YYYYMMDD,'yyyymmdd'),result')
datetick('x','yyyymmdd')
disp([min(result), result(end)])
```

↓↓↓ 結果。

![kojima.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475339/28b129b1-c3ae-b21a-3307-d64e3a9cf6b0.png)

-29万円のときはあるけど、87万円プラスですね。
たまたまかもしれないので、この通りに買おう！とかしないように。


# グランマーチンゲール法

　負けたら２倍じゃなくて、２倍＋１にしたり、３倍したりするとかがグランマーチンゲールと呼ばれる手法らしいです。

　2n+1 の場合、当たるまで 100円 → 300円 → 700円 → 1500円 → ... ですね。
1点買いで1日12レース全部負けると、総投資額は・・・

```matlab
>> cumsum(cumsum(2.^(0:11)))'*100

ans =

         100
         400
        1100
        2600
        5700
       12000
       24700
       50200
      101300
      203600
      408300
      817800
```

81万円！

何個かプログラム書いてみたけど、大体破産してたので省略・・・
別の手法を見てみよう。

# ダランベール法
　負けたらカウントを１つ増やして、勝ったら１つ減らすやり方です。

1回目：100円　はずれ
2回目：200円　はずれ
3回目：300円　はずれ
4回目：400円　あたり！　→　配当３倍で 1200円ゲット
5回目：300円　あたり！　→　配当３倍で 900円ゲット
6回目：200円　はずれ
7回目：300円　はずれ

という感じ。1日全部負けても7800円x点数だから破産することはなさそうですね。

これは儲かるのでしょうか。３連複３点でやってみよう。

```matlab
Place = unique(categorical(TR_2019.Place));

for m = 1:length(Place)
    R = TR_2019(TR_2019.Place == Place(m),:);
    
    cnt = 1;
    result = 0;
    nb = 300;
    
    for n = 1:height(R)
        if R.trio(n) == "123" || R.trio(n) == "124" || R.trio(n) == "134"
            result(end+1) = result(end) + cnt(end) * R.trio_d(n) - cnt(end) * nb;
            cnt(end+1) = max(cnt(end) - 1,1);
        else
            result(end+1) = result(end) - cnt(end) * nb;
            cnt(end+1) = cnt(end) + 1;
        end
    end
    
    result(1) = [];
    
    figure(1)
    hold on
    plot(datenum(R.YYYYMMDD,'yyyymmdd'),result)
    datetick('x','yyyymmdd')
    disp([R.Place{1} ,':', num2str(min(result)),'  ', num2str(result(end))])
end
legend(Place)
```

↓↓↓　結果。

![dara.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475339/e9fa74a0-fb0b-416a-7440-d60836228614.png)

みんな緩やかに損をしていく。。

# ココモ法
　[フィボナッチ数列](https://qiita.com/teruqii/items/0abb8f2bad841b6a0272)を使った方法で、負けたらその時に賭けた額と、その前に賭けた額を足していく手法です。1-1-2-3-5-8-13-21-... のあれですね。

1回目：100円　はずれ
2回目：100円　はずれ
3回目：200円　はずれ
4回目：300円　はずれ
5回目：500円　はずれ
6回目：800円　はずれ
5回目：1300円　あたり！　→　配当３倍で 4200円ゲット
6回目：100円　はずれ
7回目：100円　はずれ

```matlab
Place = unique(categorical(TR_2019.Place));

for m = 1:length(Place)
    R = TR_2019(TR_2019.Place == Place(m),:);
     
    cnt = 1;
    result = 0;
    reset = true;
    nb = 300;
    
    for n = 1:height(R)
        if R.trio(n) == "123" || R.trio(n) == "124" || R.trio(n) == "134"
            result(end+1) = result(end) + cnt(end) * R.trio_d(n) - cnt(end) * nb;
            cnt(end+1) = 1;
            reset = true;
        else
            result(end+1) = result(end) - cnt(end) * nb;
            if reset
                cnt(end+1) = 1;
                reset = false;
            else
                cnt(end+1) = cnt(end) + cnt(end-1);
            end
        end
    end
    
    result(1) = [];
    cnt(1) = [];
    
    figure(1)
    hold on
    plot(datenum(R.YYYYMMDD,'yyyymmdd'),result)
    datetick('x','yyyymmdd')
    disp([R.Place{1} ,':', num2str(min(result)),'  ', num2str(result(end))])
end
legend(Place)
```

グラフは省略。下関と桐生と福岡がプラス。

```
三国:-693920  -690430
下関:-601290  1636830
丸亀:-350210  -337940
住之江:-137980  -130410
児島:-112350  -110120
唐津:-572910  -572910
多摩川:-601110  -546410
大村:-2032260  -2032260
宮島:-190810  -161870
尼崎:-3846110  -2243680
常滑:-667510  -662700
平和島:-1410190  -1410190
徳山:-170050  -160980
戸田:-1948730  -1637590
桐生:-358590  488480
江戸川:-1074960  -1074960
津:-678080  -627320
浜名湖:-672670  -78090
琵琶湖:-529090  -306480
福岡:-1486530  45610
芦屋:-307170  -307170
若松:-1266520  -578320
蒲郡:-385970  -210090
鳴門:-708950  -702910
```

マーチンゲールよりも負債額も現実的な感じですけど、この３点買いだとイマイチですね。


# 他にもあるけど、長くなったのでこのくらいに。。

　金丸法とかモンテカルロ法とかありますけど大体似たようなプログラムで書けますので、やってみたい人はトライしてみてね。あとは、何回目かの記事でも書いたように、全レース買うとろくな事にならないので、人で絞ったりレースの特徴で絞ったりしましょう。

　例えば、下関で3号艇がA1の選手の時だけココモ法を使って、３連複 1=2=3 の１点買いをするとして、

```matlab
R = TR_2019(TR_2019.Place == "下関",:);

cnt = 1;
result = 0;
reset = true;
yyyymmdd = [];
nb = 100;

for n = 1:height(R)
    if Person.Class(Person.NameNo == (R(n,:).fin_name(R.frame(n,:)==3))) == "A1"  % ← ここに条件を追加。
        if R.trio(n) == "123"
            result(end+1) = result(end) + cnt(end) * R.trio_d(n) - cnt(end) * nb;
            cnt(end+1) = 1;
            reset = true;
        else
            result(end+1) = result(end) - cnt(end) * nb;
            if reset
                cnt(end+1) = 1;
                reset = false;
            else
                cnt(end+1) = cnt(end) + cnt(end-1);
            end
        end
        yyyymmdd(end+1) = datenum(R.YYYYMMDD(n),'yyyymmdd');
    end
end

result(1) = [];
cnt(1) = [];

figure(1)
hold on
plot(yyyymmdd,result)
datetick('x','yyyymmdd')
disp([R.Place{1} ,':', num2str(min(result)),'  ', num2str(result(end))])
```


![shimo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475339/b17e9e13-914a-4a76-73fe-2869c781b2d1.png)

2019年だと53万円くらいプラスなので、いい結果ですね！（右肩上がりのグラフはいいね。）
ただ、実際にやると連敗中に心が折れてしまいそう。。