Λάδι Βιώσας

http://profile.hatena.ne.jp/kenkitii/

Pythonで簡易銘柄スクリーニング

最近、ピアキャストにも飽きてきて、株価のチェックが趣味になってきました。あちこちのサイトをみたり、omega chart を使ってスクリーニングしてみたりと、色々遊んでるわけですが、もうちょっとこうなんていうか、自由にいろいろできるようにならんもんかなぁ、と思い始めたので、ちょっとしたスクリプトを書いてみました。

  • stock.py
#! -*- coding: cp932 -*-
import sys, os
from subprocess import Popen, call
from datetime import datetime, timedelta
import urllib2

class Storage(dict):
    def __getattr__(self, key): 
        if self.has_key(key): 
            return self[key]
        raise AttributeError, repr(key)
    def __setattr__(self, key, value): 
        self[key] = value
    def __repr__(self):     
        return '<Storage ' + dict.__repr__(self) + '>'

class Stocks(dict):
    path_to_dat = "dat"

    def __init__(self):
        self._make_dict()

    def _execute(self, cmd):
        status = True
        try:
            ret = call(cmd, shell=True)
            if ret < 0:
                print >>sys.stderr, "The child process was exited by signal.", -ret
                status = False
        except OSError, e:
            print >>sys.stderr, "failed to execute.:", e
            status = False
        return status

    def _download(self, date):
        filename = "t%s.csv" % date.strftime("%y%m%d")
        if not self.path_to_dat in os.listdir("."):
            os.mkdir(self.path_to_dat)
            
        if filename in os.listdir(self.path_to_dat):
            return True

        cmd = "curl -O --silent http://souba-data.com/data_day/%sd/%s_%sd/T%s.lzh" % (
            date.strftime("%Y"),
            date.strftime("%y"),
            date.strftime("%m"),
            date.strftime("%y%m%d"))

        if not self._execute(cmd):
            return False
            
        cmd = "lha eq T%s.lzh" % date.strftime("%y%m%d")
        if not self._execute(cmd):
            return False

        self._execute("mv t%s.csv dat/" % date.strftime("%y%m%d"))
        self._execute("rm T%s.lzh" % date.strftime("%y%m%d"))
        return True
    
    def _make_dict(self):
        yesterday = datetime.today() - timedelta(1)
        while yesterday.weekday() == 5 or yesterday.weekday() == 6:
            yesterday = yesterday - timedelta(1)
            
        filename = "T%s.csv" % yesterday.strftime("%y%m%d")
        if not self._download(yesterday):
            print >>sys.stderr, "Error: failed to download stock data."
            sys.exit(1)
        
        dat = open(os.path.join(self.path_to_dat, filename)).read()
        
        markets = {'東証1部': 'T1', '東証2部': 'T2', 'ヘラクレス': 'H', '大証ヘ': 'H',
                   'JAQ': 'J', '大証1部': 'O1', '大証2部': 'O2', '東証マ': 'M',}
        markets_rss = {'東証1部': 'T', '東証2部': 'T', 'ヘラクレス': 'OJ', '大証ヘ': 'OJ',
                       'JAQ': 'Q', '大証1部': 'OS', '大証2部': 'OS', '東証マ': 'T', }

        for line in dat.strip().split("\n"):
            columns = line.strip().split(",")
            #2007/10/10,1001,11,1001 日経225,17231,17255,17146,17178,1693630000,東証1部
            #1          2    3  4              5     6     7     8     9          10
            if columns[9] in ['外国', '名古1部', '名古2部', '名証セ']:
                continue
            if columns[1] == '1005':
                continue

            self[int(columns[1])] = Storage({
                'description': unicode(columns[3][5:],'cp932').encode('utf-8'),
                'market': markets[columns[9]],
                'opening_price': int(columns[4]),
                'high_price': int(columns[5]),
                'low_price': int(columns[6]),
                'closing_price': int(columns[7]),
                'volume': float(columns[8]),
                'rss_code': "%s.%s" % (str(columns[1]), markets_rss[columns[9]])})
  • 必要なもの

lhaを呼び出しているので、sudo port install lha しといてください。あ、言い忘れましたが、Macで動作チェックをしています。スクリプトの中で、curlとlhaを呼び出していますが、ここらへん修正すれば windowsでも動くと思います。たぶん。


で、、、こんな感じで使えます。指定した銘柄の、昨日の4本値と出来高を取得できます。

>>> import stock
>>> s = stock.Stocks()
>>> s[4755]
<Storage {'high_price': 57500, 'volume': 197372.0, 'description': '\x8ay\x93V', 'low_price': 53000, 'opening_price': 53500, 'rss_code': '4755.Q', 'closing_price': 57500, 'market': 'J'}>
>>> print s[4755].description
楽天
>>> s[4755].closing_price
57500
>>> 
>>> for code, v in s.items():
...   if 0 < v.closing_price < 200:
...     print v.description
... 
中川無線
さが美
ラオックス
ステラG
・・・(以下略)

スクリーニングなら omega chartで色々出来るんですが、まぁpythonでやってみたかったと。。。台風来てて暇だし。。。というか、omega chartの拡張の書き方がよくわからず挫折気味です。