証券会社のFX部門でつけた知識を詰め込んだプログラムを構築します。FXは楽して勝てる!?
SQLobjectのSELECTがどうも忘れっぽいのでメモ
今回使用するテーブルは↓


class Price(SQLObject):
  date = DateCol()
  urrency = StringCol()
  open = FloatCol()
  high = FloatCol()
  low = FloatCol()
  close = FloatCol()


何も指定しないで取得するには・・・
peeps = Price.select()


指定して取得するには・・・
peeps = Price.select(Price.q.date == "2006-06-11")


複数の指定をして取得するには・・・
peeps = Price.select(AND(Price.q.date == "2006-06-11",Price.q.currency == "USD/JPY"))


昇順や降順を指定して取得するには・・・
昇順
peeps = Price.select(Price.q.date == "2006-06-11",orderBy = Price.q.date)
降順
peeps = Price.select(Price.q.date == "2006-06-11",orderBy = -Price.q.date)


とりあえずこんな感じかな。
あとはSELECTぢゃないけどついでにメモ


データの追加は・・・
Price(date = "2006-06-11",
    currency = "USD/JPY",
    open = 120.95,
    high = 121.82,
    low = 120.76,
    close = 121.71)



データの更新は・・・
内容が見れるように変数に代入してから
for n in peeps:
  n.currency = "EUR/JPY"


SELECTを代入した変数をリストかforとかで代入すれば内容が見れるようになる。


データの削除は・・・
Price.delete(1)

引数にはidをしていする。
idとは↓のテーブル名の次の数字
(データの内容)Price 1 date='datetime.date(200...)' currency='USD/JPY'・・・
その3ではDBを作成まで完成していて今回は作成したDBにデータを格納します。
日曜には出来てたんだけど更新するの忘れてしまって始めに作った奴をちょっと変えちゃったけど格納するところは変えてないので気にしないw


# -*- coding:Shift_JIS -*-

from table import Price
from sqlobject import *

def save_price(data):
  dir = "D|\data\price.db"
  connection_string = 'sqlite:/' + dir
  connection = connectionForURI(connection_string)
  sqlhub.processConnection = connection
  Price(date = data[0],
     currency = data[1],
     open = data[2],
     high = data[3],
     low = data[4],
     close = data[5])
  connection.cache.clear()
if __name__ == '__main__':
  save_price(data)


dataにはDBのフォーマットのデータを設定してsave_priceに渡してあげればOK。


connection.cache.clear()


最後のこれはキャッシュをクリアしてるみたいです。
詳しい事はわかんないけどpythonの消費メモリが増えちゃうけど、これをつけると早くなるみたい。
DBを作成するのにsqlobjectを使ってみたけど、簡単だけど難しいからメモ。

ドキュメントはここにあります。今回かなり参考にさせてもらいました。
http://ymasuda.jp/python/sqlobject/doc_0.7/SQLObject.html


まずは、テーブルの定義


class Price(SQLObject):
  date = DateCol()
  currency = StringCol()
  open = FloatCol()
  high = FloatCol()
  low = FloatCol()
  close = FloatCol()


SQL文の代わりにSQLObjectのサブクラスを定義してPrice.createTable()すれば完成。

次にデータベースへの接続


dir = "絶対パス"
connection_string = 'sqlite:/' + dir
connection = connectionForURI(connection_string)
sqlhub.processConnection = connection


普通にやっただけぢゃエラーになってしまいます。
上で紹介したドキュメントをにもありますが絶対パスを指定する時にWindowsのドライブレターの後ろの:を|に変換しておくこと。
つまり「C:」じゃなくて「C|」ぢゃないとダメです。
今回は取得したレートを保存する作業に入ります。
保存先としてSQLiteのデータベースを作成することにしました。PythonではSQLObjectというモジュールで簡単にテーブルの定義やDBの接続が出来ます。

格納したいデータは日付と通貨ペアと4本値


# -*- coding:Shift_JIS -*-

from sqlobject import *
dir = "D|\data\price.db"

class Price(SQLObject):
  """テーブルの定義"""
  date = DateCol()
  currency = StringCol()
  open = FloatCol()
  high = FloatCol()
  low = FloatCol()
  close = FloatCol()

def making_DB():
  """テーブル作成"""
  Price.createTable()

if __name__ == '__main__':
#DB接続
  connection_string = 'sqlite:/' + dir
  connection = connectionForURI(connection_string)
  sqlhub.processConnection = connection
  making_DB()


これだけでDB作成は終わり。
次回は作成したDBにデータを格納します。
その1の続き。
分析などで過去分は必須。でも前回は指定した日付の4本値だけを取得するだけだったので今回は範囲を指定してその範囲の4本値を取得するようにする。



# -*- coding:Shift_JIS -*-

import re
import urllib2
from BeautifulSoup import BeautifulSoup

url = "http://money.www.infoseek.co.jp/MnForex/fxlast/?fx=F1001"

def print_rate(sy,sm, sd, ey, em, ed):
  op = "&sy=%s&sm=%s&sd=%s&ey=%s&em=%s&ed=%s&k=d" % (sy,sm, sd, ey, em, ed)
  req = url + op
  save = 0
  while req != None:
    bs = BeautifulSoup(urllib2.urlopen(req))
    data = bs.findAll("tr", align="right")
    for tr in data:
      rate = tr.findAll("td")
      print tr.th.string, rate[1].string, rate[2].string, rate[3].string, rate[0].string
    next = bs.findAll("a", href=re.compile('/MnForex/fxlast/(.*)'))
    next = next[-1].get('href', None)
    if next.find(op) == -1:
      req = None
    elif save > int(next[next.find("st=") + 3:]):
      req = None
    else:
      save += 50
      req = url + next

print print_rate(2005, 10, 15, 2007, 10, 25)



直感的に作ってしまったがなんともかっこ悪いw
こんなコード載せるのもどうかと思うがメモなので気にしない。さすがに1度といえど実行する際は修正しないとな。