ヘビに睨まれたカエル

Pythonとオプショントレードで市場の恐怖に立ち向かっていきます。

なぜ先物売りじゃなくプット買いなのか

前回の記事で、株価の急落を待ち構えるのにプット買いが有効だという話を書きました。

robin29man-practice.hatenablog.com

株価が急落することを想定するなら先物売りでも良さそうですが、あえてプット買いを選択する理由は何でしょう?

プット買いのメリット

プット買いの方が有利な点は以下の2点です。

  1. 相場観が外れたときでも損失が限定である
  2. 急落時のボラティリティ上昇による利益の上乗せも見込める

もちろん先物売りの方が有利なケースもあって、株価は下がってもボラティリティは上昇しない(つまりジワジワ下げる)ケースでは先物売りのほうが利益が出やすいでしょう。 ただし、予想に反して上昇してしまった場合の損失は先物売りのほうが大きくなります。 結局のところ結果は相場によりけりではあるのですが、今相場が安定していて(ボラティリティが低い)、いつ来るか読めないけど、そろそろ来そうな株価の急落を待つケースでは、先物売りよりもプット買いの方に分があると感じています。

最後に

今回上げたプット買いのメリット2点について、次回以降詳しく書きたいと思います。

ただ、私の拙い文章では上手く伝えきれない部分もありますし、筆も遅いので、さらに詳しく効率よく知りたい方は、有料ですが下記の動画で学ばれることをお勧めいたします。 xn--kck0a1ce1ezepb4cxe.com

日経平均の暴落を待ち構える

株式投資をしている皆さん、日経平均の暴落にどういったイメージをお持ちでしょうか?

損失を生む・怖いといったマイナスイメージが先行する方が多いのではないでしょうか? 私も株をメインでやっていたころはそうでした。

 

しかし、オプション投資を始めてからは、大暴落は必ずしも怖いものではないと思うようになりました。

事前にそれに備えたポジションを取ることで、暴落時の保有株が出す損失をカバーしたり、カバーするどころか利益まで生んでしまう戦略を取ることが可能です。

 

そうした、オプションを用いて暴落を待ち構える戦略の一つがプットオプションの買いです。プットオプション日経平均が下がることで価格が上昇するもので、特に暴落が激しい場合には、ボラティリティの上昇による利益も得られます。

f:id:robin29man:20190412005553p:plain 

ところで、ここ数日は日経VI(ボラティリティを指数化したもの)がだいぶ低い水準まで来ましたね。嵐(=暴落)の前の静けさにも思えたり…しかもGWという長期連休も控えてるとなると、暴落に備えるにはいいタイミングのような気がするのは私だけでしょうか…?

 

オプションを用いた詳しい戦略は「日経VIを活用した日経225オプション戦略解説セミナー動画」にて紹介されています。

今回紹介したような、暴落に備えたプット買いはもちろん、その他いろいろな相場ごとに適したオプション戦略が紹介されています。

ご興味のある方は、暴落が来てしまう前に是非!!(笑)

 

オプションの本質的価値、時間的価値

今回は、既にオプションをご存知の方には、本当に基本の話です。(でも大事なこと)

オプションの本質的価値、時間的価値について。

例として、20000円のコールオプションの本質的価値、時間的価値はいくらか、について考えてみます。

 

  • ケース①
    今日がSQ日であるとき。(実際にはSQ日には売買できませんが、イメージとして。)
    この場合は、日経平均が20000円以上なら差額を受け取れます。一方、日経平均が20000円以下なら権利行使しなければよいので損益は0円。
    よって損益曲線としては下図のとおり。これがオプションの本質的価値と呼ばれるものです。

    f:id:robin29man:20190406064219p:plain

    20000コールオプションの本質的価値


  • ケース②
    SQ日まで残り1週間あるとき。
    この場合も、本質的価値としては上の考え方と同じになります。なぜならSQ日まで持ち越せば、上記のとおりの損益曲線になることが明らかなので。
    しかし、ケース①と異なるのは時間的価値も持つことです。例えば、今の日経平均が20000円として、SQ日にも20000円(もしくは それ以下)ならば本質的価値は0になると分かっていても、逆にSQ日までに上昇する可能性はあるわけで、であれば0円以上で買ってもいいかな、と思いませんか? これが時間的価値のイメージです。それがいくらになるかはSQ日までの残り日数や、市場の荒れ具合から計算されるのですが、今は仮に50円としましょう。
    じゃあ、今が19500円だとどうか?本質的価値が0円なのは変わらないですが、時間価値については50円より安くなりそうですね。SQ日に20000円以上になる可能性が低くなっていそうなので。同様に考えていけば、今の日経平均が20000円より下にあるほど時間価値は安くなることがイメージできると思います。反対に、今の日経平均が20000円より高い場合は、本質的価値が平坦でないために少しイメージしづらいかもしれませんが結局同じことです。20000円から離れるほど時間的価値は小さくなります。大きく離れていれば、その後SQ日までに多少動いたところで20000円を割る確率は低くなっていくので。
    と、いうことで時間的価値は、そのオプションの権利行使価格と日経平均が同じ価格の時に最も高く、そこから日経平均が離れるほど(上だろうと下だろうと)、安くなっていきます。
    で、結局どういうカーブになるかというと、下図のとおりとなります。
    ちゃんと計算方法があるんですが、それを説明しだすと今回の話からは飛躍しすぎるので、今回は省略します。

    f:id:robin29man:20190406064432p:plain

    20000コールオプションの時間的価値 (一例)

 

ここまで話した本質的価値と時間的価値の合計がオプションの価格となります。

実際に合計してみたうえでの議論は次回以降…

 

今回の話は下記でも触れられていますので、より詳しく知りたい方は読まれるとよいかと思います。(プレミアムはオプション価格のこと)

プレミアム | 北浜投資塾 - 大阪取引所(日本取引所グループ)
www.jpx.co.jp

Pythonで直近3か月分のSQ日と残存日数計算

前回までに、

  • 祝日をリスト形式で取得するプログラム

  • 対象限月を与えればSQ日を返してくれるプログラム

  • 特定の日付とSQ日を与えれば残存日数を返してくれるプログラム

を作成しました。今回は特定の日付だけ与えれば、そこから3限月を自動判別し、それらのSQ日および残存日数をまとめて取得する関数を作成します。

  1. どんな関数

    1. 特定の日付dateを与えると、そこから3限月分のSQ日と残存日数を辞書形式で取得する関数
  2. 関数が中でやってること

    1. dateが含まれる月から4ヶ月分を対象月とする。(最後に3ヶ月分に絞ります。この時点では、dateが今月のSQ日を過ぎてるかどうか判別できていないため。) → month_cand_list
    2. 各月のSQ日、残存日数を取得 → sq_date_cand_list, remaining_days_cand_list
    3. どの三ヶ月を選ぶか決める
      1. sq_date_cand_list[0]dateより後なら[0..2]を対象の3限月と判定し、一方sq_date_cand_list[0]dateより前なら[1..3]を対象の3限月と判定する。 → month_cand_list, sq_date_cand_list, remaining_days_cand_listを辞書型データのsq_remaining_dictとする。
  3. 結果

与えた日付によって正しい結果が返ってきているのが分かります。

今後はこれ使って東証終値のデータをいろいろ解析したいと思います。

PythonでSQ日、残存日数を自動計算

前回、営業日ベースの日数計算をするために、祝日をdatetime 形式のリスト形式で取得するモジュールを作りました。 robin29man-practice.hatenablog.com 今回は、それを使ってSQ日と残存日数(営業日ベース)を計算するモジュールを作ろうと思います。

  1. どんなモジュール

    1. 特定の日付dateおよび対象限月monthを与えると、SQ日と残存日数を返す関数
  2. 事前準備

    1. 前回作ったモジュールでholidaysを用意しておく。
  3. モジュールが中でやってること

    1. 対象限月のSQ日を取得
      1. (1~7日の間に必ず1つだけ金曜があるので)8日より後に来る最初の金曜が第2金曜と判断 → second_friday
      2. second_fridayが祝日なら、その一営業日前をSQ日と判断 → sq_date
      3. dateからsq _dateまでの残存日数を営業日ベースで計算。→ remaining_daysへ格納
  4. 結果 ちゃんと2019年5月限のSQ日、それから20190329起点の残存日数が計算できました!

次回は、この関数を使って、dateだけ与えれば、そこから3限月分のSQ日、残存日数を辞書形式で取得できるように拡張しようと思います。

Pythonで祝日(リスト形式)を取得する

何かと営業日ベースで計算する機会が多い(n営業日後、とか)ので、祝日をリスト形式で取得するモジュールを用意しておくことにしました。 Pythonにはworkdaysというライブラリがあり、土日を考慮した計算ならコレでできるのですが、祝日はworkdays関数の引数の一つとして自分でリストを与えてやる必要があるためです。

  • 事前準備

内閣府HP からsyukujitsu.csvを予めダウンロードしておく。 別にコレも都度プログラムでWebを参照するようにしてもいいのですが、2年分の祝日が乗っているので、2年に1回くらいなら手動ダウンロードでもいっか、と思いました。

syukujitsu.csvの中身はこんな感じ。1列目に月日、2列目に祝日の名称が書かれています。

国民の祝日・休日月日,国民の祝日・休日名称
2019/1/1,元日
2019/1/14,成人の日
2019/2/11,建国記念の日
2019/3/21,春分の日
2019/4/29,昭和の日
2019/4/30,休日
2019/5/1,休日(祝日扱い)
2019/5/2,休日
2019/5/3,憲法記念日
2019/5/4,みどりの日
2019/5/5,こどもの日
2019/5/6,休日
2019/7/15,海の日
2019/8/11,山の日
2019/8/12,休日
2019/9/16,敬老の日
2019/9/23,秋分の日
2019/10/14,体育の日(スポーツの日)
2019/10/22,休日(祝日扱い)
2019/11/3,文化の日
2019/11/4,休日
2019/11/23,勤労感謝の日
2020/1/1,元日
2020/1/13,成人の日
2020/2/11,建国記念の日
2020/2/23,天皇誕生日
2020/2/24,休日
2020/3/20,春分の日
2020/4/29,昭和の日
2020/5/3,憲法記念日
2020/5/4,みどりの日
2020/5/5,こどもの日
2020/5/6,休日
2020/7/23,海の日
2020/7/24,スポーツの日
2020/8/10,山の日
2020/9/21,敬老の日
2020/9/22,秋分の日
2020/11/3,文化の日
2020/11/23,勤労感謝の日

  • モジュール内でやること

    1. syukujitsu.csvの日付の行をリストで取得。
    2. daytime形式に変換。(np.vectorizeでリストにいっぺんに関数を適用できる)
    3. tolist()でリスト形式に戻しておく。(np.vectorizeするとarray形式になってしまうため)
  • プログラム

df_holidays = pd.read_csv("syukujitsu.csv", delimiter=",", encoding="SHIFT=JIS")
ser_holidays = df_holidays["国民の祝日・休日月日"].tolist()

ser_holidays = np.vectorize(dt.datetime.strptime)(ser_holidays, '%Y/%m/%d')

ser_holidays = ser_holidays.tolist()
ser_holidays

実行結果はこんな感じ。datetime形式のリストになってます。

[datetime.datetime(2019, 1, 1, 0, 0),
datetime.datetime(2019, 1, 14, 0, 0),
datetime.datetime(2019, 2, 11, 0, 0),
datetime.datetime(2019, 3, 21, 0, 0),
datetime.datetime(2019, 4, 29, 0, 0),
datetime.datetime(2019, 4, 30, 0, 0),
datetime.datetime(2019, 5, 1, 0, 0),
datetime.datetime(2019, 5, 9, 0, 0),
datetime.datetime(2019, 5, 10, 0, 0),
datetime.datetime(2019, 5, 4, 0, 0),
datetime.datetime(2019, 5, 5, 0, 0),
datetime.datetime(2019, 5, 6, 0, 0),
datetime.datetime(2019, 7, 15, 0, 0),
datetime.datetime(2019, 8, 11, 0, 0),
datetime.datetime(2019, 8, 12, 0, 0),
datetime.datetime(2019, 9, 16, 0, 0),
datetime.datetime(2019, 9, 23, 0, 0),
datetime.datetime(2019, 10, 14, 0, 0),
datetime.datetime(2019, 10, 22, 0, 0),
datetime.datetime(2019, 11, 3, 0, 0),
datetime.datetime(2019, 11, 4, 0, 0),
datetime.datetime(2019, 11, 23, 0, 0),
datetime.datetime(2020, 1, 1, 0, 0),
datetime.datetime(2020, 1, 13, 0, 0),
datetime.datetime(2020, 2, 11, 0, 0),
datetime.datetime(2020, 2, 23, 0, 0),
datetime.datetime(2020, 2, 24, 0, 0),
datetime.datetime(2020, 3, 20, 0, 0),
datetime.datetime(2020, 4, 29, 0, 0),
datetime.datetime(2020, 5, 3, 0, 0),
datetime.datetime(2020, 5, 4, 0, 0),
datetime.datetime(2020, 5, 5, 0, 0),
datetime.datetime(2020, 5, 6, 0, 0),
datetime.datetime(2020, 7, 23, 0, 0),
datetime.datetime(2020, 7, 24, 0, 0),
datetime.datetime(2020, 8, 10, 0, 0),
datetime.datetime(2020, 9, 21, 0, 0),
datetime.datetime(2020, 9, 22, 0, 0),
datetime.datetime(2020, 11, 3, 0, 0),
datetime.datetime(2020, 11, 23, 0, 0)]

次はこれ使って、SQ日や残存日数を自動計算するモジュール作る!!

Pythonで東証時系列データを自動取得

1. できるようになったこと

  • 東証に毎日upされるオプション価格データ(終値)のcsvファイルを取得する。
  • その際、ローカルにある最新データの日付を確認して、それ以降の日付ファイルを自動で取得する。

2. 学んだこと

2.1. request, zipfileモジュールの使い方

ネット上のzipファイルをDLして解凍する

2.2. globモジュールの使い方

ローカルフォルダに既にDL済みのファイル一覧を取得して、その中の最新日付ファイル名を取得。

2.3. datetimeモジュールの使い方

フォルダ内にあるファイルが"201902xx"の形式で日付を含むファイル名だったので、この形式のまま日付を扱っていたところ、8桁の数字として認識されてしまったため、繰り返し処理で2/28, 2/29, 2/30, 2/31 ...のデータを取得しようとしてErrorが出ていた。

対策としてdatetime形式に変換して扱うことにした。

2.4. try except構文

データがない日(休日)のデータを探しに行ったときのErrorで止まっていた。 try except構文を使ってError時は次の日付に移る仕様にした。

3. 完成形

datas = glob.glob("*.csv")
newest_date = datetime(int(datas[-1][3:7]),int(datas[-1][7:9]),int(datas[-1][9:11]))

today = datetime.today()

while today > newest_date:

    newest_date = newest_date + timedelta(days=1)
    newest_date_str = newest_date.strftime("%Y%m%d")
    
    try:
        # オプション理論価格等情報
        #    利用ガイド:http://www.jpx.co.jp/markets/derivatives/option-price/01.html
        #    一覧: http://www.jpx.co.jp/markets/derivatives/option-price/index.html
        url = "http://www.jpx.co.jp/markets/derivatives/option-price/data/%s.zip"
        file = "ose%stp"%newest_date_str

        r = requests.get(url%file)
        z = zipfile.ZipFile(io.BytesIO(r.content))
        z.extractall()
        colName = ("CODE","TYPE","MATURITY","STRIKE", "RSV", 
              "PUT_CODE", "PUT_PRICE", "PUT_RSV", "PUT_TPRICE", "PUT_VOLATILITY",
              "CALL_CODE","CALL_PRICE","CALL_RSV","CALL_TPRICE","CALL_VOLATILITY",
              "F225_PRICE", "Base_VOL")
        df_raw = pd.read_csv(file+".csv", names=colName,
                    converters = {'CODE' : strip,
                                  'TYPE' : strip})    
    except:
        continue
        
print("Finish!!")