相場商売

トレーディングビジネスあれこれ

15章

Tickモジュール

Tickについては本の発売時とはだいぶ状況が変わっている部分で、
7月22日の後と前ではTickが違い、
また銘柄別でもTopix100の銘柄とそれ以外でTickが異なっている。

そのため正確に作るには、引数を価格だけではなく、
価格と日付と銘柄コードを取る必要が出てくる。

だが今回は変更されてまだすぐだし、
検証の大部分は過去のTickサイズで検証するということなので
本の内容に忠実に作ることにする。

roundメソッドだけ、pythonに組み込み関数として使われているので
my_roundと名前を変えた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import math

# 呼値モジュール
# 呼値単位に合わせて値段を上下させたり丸めたりする

# 呼値単位
def size(price):
    if price <= 3000:
        return 1
    elif 3000 < price <= 5000:
        return 5
    elif 5000 < price <= 30000:
        return 10
    elif 30000 < price <= 50000:
        return 50
    elif 50000 < price <= 300000:
        return 100
    elif 300000 < price <= 500000:
        return 500
    elif 500000 < price <= 3000000:
        return 1000
    elif 3000000 < price <= 5000000:
        return 5000
    elif 5000000 < price <= 30000000:
        return 10000
    elif 30000000 < price <= 50000000:
        return 50000
    elif 50000000 < price:
        return 100000

# 半端な数字を上の呼び値に切り上げ
# 半端でなければ何もしない
def ceil(price):
    tick_size = size(price)
    if price % tick_size == 0:
        return price
    else:
        return truncate(price) + tick_size

# 半端な数字を下の呼び値に切り下げ
# 半端でなければ何もしない        
def truncate(price):
    return math.floor(price - price % size(price))
    
# 上か下、どちらか近い方に丸める
# 半端でなければ何もしない
def my_round(price):
    tick_size = size(price)
    if price % tick_size * 2 >= tick_size:
        return ceil(price)
    else:
        return truncate(price)
        
# 何ティックか足す
def up(price, tick = 1):
    for i in range(0, tick):
        price += size(price)
    return ceil(price)

# 何ティックか引く
def down(price, tick = 1):
    price = truncate(price)
    for i in range(0, tick):
        price -= size(price)
    return price
            
if __name__ == '__main__':    
    print(size(100))    #=> 1
    print(size(2999))   #=> 1
    print(size(3000))   #=> 1
    print(size(3001))   #=> 5
    print(size(4000))   #=> 5
    print(size(5100))   #=> 10
    print(size(30000))  #=> 10
    print(size(30050))  #=> 50

    print(truncate(99.99))  #=> 99
    print(truncate(3004))   #=> 3000
    print(truncate(3006))   #=> 3005

    print(ceil(99.99))      #=> 100
    print(ceil(3004))       #=> 3005
    print(ceil(3006))       #=> 3010

    print(my_round(99.99))     #=> 100
    print(my_round(99.49))     #=> 99
    print(my_round(3004))      #=> 3005
    print(my_round(3002))      #=> 3000

    print(up(100))          #=> 101
    print(up(100, 3))       #=> 103
    print(up(2999, 1))      #=> 3000
    print(up(2999, 2))      #=> 3005
    print(up(3000))         #=> 3005

    print(down(100))        #=> 99
    print(down(100, 3))     #=> 97
    print(down(3005, 1))    #=> 3000
    print(down(3005, 2))    #=> 2999
    print(down(3000))       #=> 2999
    print(down(3001))       #=> 2999