資金管理(ピラミッド法)

カミさんとシステムトレードの話をしていて、資金管理がいかに大切かを話していたのだけど、そもそも本当に効果があるのか自分でも自信がなかったので、簡単に試してみた。

以前、聞きかじった手法は

  • 賭け金の初期値は五枚
  • 勝ったら一枚減らす
  • 負けたら一枚増やす
  • 最大枚数(九枚)または最小枚数(一枚)になったら初期値に戻す

というもの。

いま調べてみたらダランベールのバリエーションの一つであるピラミッドという手法らしい。

適当にOCamlで書いてみる。

open Printf

let play max_play init_bet max_bet min_bet =
    Random.self_init();
    let rec loop i bet sum =
        if i >= max_play then sum
        else (
            let next_bet, updated_sum =
                match Random.bool() with
                (* win *)
                | true ->
                    printf "win:  bet [%d] -> " bet;
                    let next_bet =
                        if bet > min_bet then bet - 1 else init_bet in
                        (next_bet, sum + bet)
                (* lose *)
                | false ->
                    printf "lose: bet [%d] -> " bet;
                    let next_bet =
                        if bet < max_bet then bet + 1 else init_bet in
                        (next_bet, sum - bet) in
            printf "sum [%d]\n" updated_sum;
            loop (i + 1) next_bet updated_sum
        ) in
    loop 0 init_bet 0

let _ =
    printf "total:[%d]\n" (play 20 5 9 1)

これを動かしてみるとこんな感じ。

:!ocaml invest.ml
win:  bet [5] -> sum [5]
lose: bet [4] -> sum [1]
win:  bet [5] -> sum [6]
lose: bet [4] -> sum [2]
win:  bet [5] -> sum [7]
win:  bet [4] -> sum [11]
lose: bet [3] -> sum [8]
lose: bet [4] -> sum [4]
lose: bet [5] -> sum [-1]
lose: bet [6] -> sum [-7]
win:  bet [7] -> sum [0]
win:  bet [6] -> sum [6]
win:  bet [5] -> sum [11]
lose: bet [4] -> sum [7]
lose: bet [5] -> sum [2]
lose: bet [6] -> sum [-4]
lose: bet [7] -> sum [-11]
lose: bet [8] -> sum [-19]
win:  bet [9] -> sum [-10]
win:  bet [8] -> sum [-2]
total:[-2]

何回かやってみると、-30〜30あたりを行ったり来たりしていて優位性がなさそう…

じゃあ回数を増やしてみようということで、

  :
  :
let multiplay max_play =
    let rec loop i result_list =
        if i >= max_play then result_list
        else loop (i + 1) ((play 20 5 9 1) :: result_list) in
    loop 0 []

let _ = 
    let max_play = 100000 in
    let result_list = multiplay max_play in
    let sum = List.fold_left (fun ans x -> ans + x) 0 result_list in
    let ave = (float_of_int sum) /. (float_of_int max_play) in
    printf "ave:[%f]\n" ave

としてみると…

:!ocaml invest.ml
ave:[-0.140100]

:!ocaml invest.ml
ave:[0.054160]

:!ocaml invest.ml
ave:[-0.110570]

:!ocaml invest.ml
ave:[0.342800]

としょぼい。標準偏差も見なくていいや…

う〜〜〜ん、資金管理って効果があるのかなぁ。ちょっと不安になってきた。