2008年2月16日土曜日

システムトレード

FX&日経225先物 システムトレード実践テクニックの本を買った。
Click証券であればシステム的には完全自動売買が可能となるので
試してみようかな。。。
以前、ちょっと試しましたが実践したらすぐバグをみつけそれ以来
止めてしまいました。

本はまだ、途中ですがシステムの検証(バックテスト)はエクセルを使って
やっているようです。OpenOfficeのスプレッドシートもそれなりに
使えますが、やっぱエクセルと比べると見劣りします。

ubuntuならやっぱゴリゴリとスクリプトで検証すべきでしょう

2008年2月13日水曜日

ネットワーク理論3

3万人にアクセスしスクリプトも順調に動作していましたが、
mixiに足あとのつけすぎと怒られました。

自分から30693人時点での結果です。

隔たり次数 0 人数 1
隔たり次数 1 人数 38
隔たり次数 2 人数 365
隔たり次数 3 人数 3716
隔たり次数 4 人数 26573

隔たり次数が2で365人というのは自分の友達は他人の友達という
ことで結構友人がかぶっているのではないかと思います。

この後の推移を見たかったのですがここで止めときます。
おそらくmixiもスモールワールドなんだと思いますが、
実証できなくて残念。

2008年2月12日火曜日

weather hack

天気予報で降水確率が40%以上だったら、傘忘れないでね〜メールを
携帯に送るスクリプトを作りました。

天気予報データからXMLでデータを取得する。
自分の住まいのエリアの1日分の降水確率で40%以上があれば
予報データを組み立て携帯へ送信する。

携帯へはgmailを利用。gmailerというrubyのライブラリが必要です。

後は、crontab or タスクリストへ朝自動で起動する用にしておくだけです。
rubyなのでサクッとできました。

require 'net/http'
require 'gmailer'
require 'rexml/document'

host="www.drk7.jp"
path="/weather/xml/14.xml"

user="gmailのID"
pass="gmailのパスワード"
cellphone="携帯のアドレス"

#降水確率の基準値 メール送るか送らないか
RAINFALL_RATE=40

resp = ""
Net::HTTP.version_1_2

Net::HTTP.start(host, 80) {|http|
response = http.get(path)
if response.code != "200"
raise HttpError, "Http Conection Error."
end
resp = response.body
}

send_flag=false

body = "傘!!\n"
body << "神奈川県東部\n"
doc = REXML::Document.new(resp)
doc.elements.each("./weatherforecast/pref/area/info") do |item|
if item.attributes["date"] == Time.now.strftime("%Y/%m/%d")
#and doc.elements.each("./weatherforecast/pref/area").attributes["id"] == "東部"
body << item.text("weather") + "\n"
body << "降水確率\n"
4.times do |i|
period = item.get_elements("./rainfallchance/period")[i].text
hour = item.get_elements("./rainfallchance/period")[i].attributes["hour"]
body << "#{hour} #{period}\n"
begin
send_flag = true if period.to_i >= RAINFALL_RATE
rescue
end
end
body << item.text("weather_detail") + "\n"
# 西部をスキップする
break
end
end

puts body

if send_flag
GMailer.connect(user, pass) do |g|
g.send(
:to => cellphone,
:subject => "weather hack",
:body => body)
end
end


メールのイメージ
傘!!
神奈川県東部
くもり時々雨
降水確率
00-06 --
06-12 60
12-18 50
18-24 30
北の風のちやや強く海上では後北の風強くくもり朝から昼過ぎ雨

2008年2月10日日曜日

FX@ターミナル


Click証券が提供するFXトレード用のWEB API自作クライアントが実際に
使えるようになりました。現在は成行約定、成行決済、IFO注文、レート取得、
建玉取得だけできます。Click証券のWebページからトレードするよりはすばやく
トレードできます。
Rubyのカーセスの勉強にもなりました。

2008年2月9日土曜日

ネットワーク理論2

mixiへ再びアクセスできるようになりました。
隔たり次数がすぐに上がってしまうバグもあったので修正しました。

mixiのユーザ件数は1000万くらいだったので、スクリプトを途中で
止めた場合に内容をダンプする機能を付け加えました。

あと、アクセスする間隔は2秒が最適のようです。
メモリーが最後まで足りるかは?です。すべてのユーザにアクセスする
には先が長そうです。

途中経過(6千人程度)です。
隔たり次数 0 人数 1
隔たり次数 1 人数 38
隔たり次数 2 人数 365
隔たり次数 3 人数 3716
隔たり次数 4 人数 1832
全人数 5952

list.yaml
"自分のMIXIのID": 
:url: http://mixi.jp/show_friend.pl
:flag: false
:depth: 0


スクリプト
require 'rubygems'
require 'mechanize'
require "yaml"

username = '<メールアドレス>'
password = '<パスワード>'

agent = WWW::Mechanize.new
page = agent.get('http://mixi.jp/')
form = page.forms[0]
form.fields.find {|f| f.name == 'email'}.value = username
form.fields.find {|f| f.name == 'password'}.value = password
form.fields.find {|f| f.name == 'next_url'}.value = '/home.pl'
page = agent.submit(form, form.buttons.first)


def url()
a = nil; id = ""
$list.each do |k,i|
if i[:flag] == false
if a == nil
a = i; id = k
end
if a[:depth] > i[:depth]
a = i
id = k
end
end
end
id
end

def set(id, url, depth)
if !$list.key?(id)
a={:url=>url,:depth=>depth,:flag=>false}
$list[id] = a
end
end

def output_data
result = {}

$list.each do |k,v|
depth = v[:depth]
if result.key?(depth)
result[depth] += 1
else
result[depth] = 1
end
size = v[:list].size if v[:list] != nil
puts "#{k} #{size} #{v[:flag]} #{depth}"
end

result.each do |k,v|
puts "隔たり次数 #{k} 人数 #{v}"
end
puts "全人数 #{$list.size}"
end

$list = YAML::load(File.open("list.yaml").read)

Signal.trap('INT') do
output_data()
YAML.dump($list, File.open("list.yaml", 'w'))
exit 0

end

while (id = url()) != nil
$list[id][:list] = []
depth = $list[id][:depth] + 1
diarylist = agent.get($list[id][:url])
diarylist.links.each do |link|
if link.href =~ /show_friend.pl\?id\=(\d+)/
friend_id = $1.to_s
url = "http://mixi.jp/" + link.href
$list[id][:list] << $1
set(friend_id, url, depth)
end
end
$list[id][:flag] = true
puts "#{id} size #{$list.size}"

#中間報告
output_data() if rand(50) == 20
sleep 2
end

output_data()



本はこれです。

ネットワーク理論

ネットワーク理論の本を読んでます。

新ネットワーク思考—世界のしくみを読み解く(LINKED: The New Science of Networks)

有名なのはケビン・ベーコンゲームというものでケビン・ベーコンと他のハリウッド俳優は
少なくとも2人の共演者で繋がっているという法則。これはハリウッドの世界だけでなく
世界中の人々もすくなくとも6人の友人で繋がっている。自分と福田総理、自分とアフリカの
誰かとも6人の友人を通じてその人にたどり着けるというもの。
これは6次の隔たりと呼ばれています。

そこで思ったのがmixiはどうなってるんだろう?何次の隔たり?
スクリプトを作って検証しようと思いました。

require 'rubygems'
require 'mechanize'

username = '<メールアドレス>'
password = '<パスワード>'

agent = WWW::Mechanize.new
page = agent.get('http://mixi.jp/')
form = page.forms[0]
form.fields.find {|f| f.name == 'email'}.value = username
form.fields.find {|f| f.name == 'password'}.value = password
form.fields.find {|f| f.name == 'next_url'}.value = '/home.pl'
page = agent.submit(form, form.buttons.first)

$list={}
h={}
h[:url] = 'http://mixi.jp/list_friend.pl'
h[:flag] = false
h[:depth] = 0
$list["mixiのid"] = h

def url()
res=nil
$list.each do |k,i|
if i[:flag] == false
i[:flag] = true
return k
end
end
nil
end

def set(id, url, depth)
if !$list.key?(id)
a={:url=>url,:depth=>depth,:flag=>false}
$list[id] = a
end
end

while (id = url()) != nil
#break if $list.size > 100

$list[id][:list] = []
depth = $list[id][:depth] + 1
diarylist = agent.get($list[id][:url])
diarylist.links.each do |link|
if link.href =~ /show_friend.pl\?id\=(\d+)/
friend_id = $1.to_s
url = "http://mixi.jp/" + link.href
$list[id][:list] << $1
set(friend_id, url, depth)
else
# puts "not mutch"
end
sleep 1
end
puts "size #{$list.size}"
end

result = {}

$list.each do |k,v|
depth = v[:depth]
if result.key?(depth)
result[depth] += 1
else
result[depth] = 1
end
size = v[:list].size if v[:list] != nil
puts "#{k} #{size} #{v[:flag]} #{depth}"
end

result.each do |k,v|
pust "隔たり #{k} 人数 #{v}"
end


結果はアクセスし過ぎで接続不可になってしまいました。
sleepの時間を調節しないとダメみたいです。

間隔を空けない連続的なページの遷移・更新を頻繁におこなわれていることが見
受けられましたので、一時的に操作を停止させていただきます。申し訳ございま
せんが、しばらくの間お待ちください。

2008年2月4日月曜日

SG アラブファンド

今日、ソシエテゼネラルのSG アラブファンドを購入したので、
基準価格を取得するスクリプトを作成しました。
これをcrontab(windows ならタスク)で自動起動させ結果を
gmailで飛ばすとかなり便利です。rubyではgmailerという
ライブラリがすでにあります。
私はこれで毎朝、携帯に全投資信託の基準価格を送信して
一喜一憂しております。

実行時はソースファイルをsjisで保存。
ruby sg.rb

ソース sg.rb
require 'uri'
require 'net/http'

$KCODE="s"


class HttpError < StandardError; end

class Sg

SG_URL = 'http://www.sgam.co.jp/html/kagaku01.htm'
attr_reader :day, :value, :diff

def initialize
@data = self.get(SG_URL)
self.parse
end


def get( url, query=nil )



target_uri = URI.parse( url )

resp_data=nil

path = target_uri.path

if query != nil

path = path + '?' + query

end



Net::HTTP.version_1_2

Net::HTTP.start(target_uri.host, 80) {|http|
req = Net::HTTP::Get.new(path)
response = http.request(req)

if response.code != "200"

raise HttpError, "Http Conection Error."

end
resp_data = response.body
}

if resp_data == nil

raise HttpError, "Http Receive Error."

end

resp_data

end

def parse

regex = %r{

<!--Date-->
¥s+([\d\/]+)
¥s+現在</font></p>
¥s+</td>
¥s+</tr>
¥s+</table>

}xs
# 日付を取得
@day = $1 if @data =‾ regex

regex = %r{
<tr>
¥s+<td>¥s<a¥shref=141005_arab_m.html¥starget=¥'_top¥'>SG¥sアラブ株式ファンド</a>¥s</td>
¥s+<td¥salign=center¥snowrap>¥s([¥d¥,]+)¥s</td>
¥s+<td¥salign=center¥snowrap>¥s([¥d¥-¥+]+)¥s</td>
¥s+<td¥salign=center¥snowrap>¥s[¥d¥,]+¥s</td>
¥s+</tr>
}xs

# 日付を取得
if @data =~ regex
@value = $1; @diff = $2
else
raise "ERROR 解析失敗"
end

end

end

if __FILE__ == $0
sg = Sg.new
puts "SG ARAB #{sg.day} #{sg.value} #{sg.diff}"

end


実行結果
$ ruby sg.rb
SG ARAB 2008/2/4 10,029 25

2008年2月2日土曜日

ターミナルでFXトレード


ターミナルからClick証券の発注を行うプログラムを作成しました。
画像はgnome-terminalをキャプチャーしたものです。
テスト中でレートはClick証券のLocal APIサーバより取得してます。

RubyのCursesを使って画面を制御。数秒間隔で外為レートと自分の
建玉一覧を取得します。発注はコマンドで行えるように実装しました。
下のようなイメージでプライスオーダー(po)、買い(logn)の意味です。
rateはオプションで指定可。
> po long [rate]

通貨指定は環境変数のような扱いにしてます。set PAIR=USDJPYで変更できる
ようにしたい。まだ、実装はできてないですが。
もっと簡単に取引出来るようにしたい。リストで注文の候補をだしリスト番号の1を
コマンド入力すると発注の要求をだす感じで。。。

RubyのCursesは始めて使ってみたのですが結構苦戦しました。カーソルの
制御の仕方にてこずりました。
GUIがいろいろとある中、あえてカーセスを使ってみました。少し新鮮かも。

干し芋のリスト