XBRL

2009-08-16

EDINET サイトを firewatir で自動閲覧しデータダウンロードする

firewatir の使い方が分かったので、EDINET サイトから XBRL データをダウンロードする ruby スクリプトを書いてみた。
- http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/watir/edinet/edint-download.rb?view=markup&revision=93&root=ruby-xbrl
> View of /trunk/Edinet/tools/watir/edinet/edint-download.rb - ruby-XBRL - SourceForge.JP

# firefox の download 動作の設定を
#     "ダイアログを開かずに 特定フォルダ以下に保存する"
# ようにしておくことが必要。

20090816firewatir

XBRLデータは、これで完全に download することができそうだ。
PDF データもダウンロードしたかったが、こちらは まだ完全にはできていない。
PDF ダウンロード時に 別window がひらくのだが、これを close する方法が不明...
20ファイルまでは download されるのだが、それ以上は 別window がひらかなくなり、download もされない。
(エラーにはならないので、XBRL データの download は それ以降も問題な実行はされる)

これで、SEC と EDINET の 最新 XBRL データを集めることができるようになったことになる。
次は これらのファイルを簡易検索して download できるようなサービスを sinatra でつくる予定。

| | コメント (0) | トラックバック (0)

2009-08-13

jquery で SEC の RSS を web ブラウザで表示する。

RSS リーダーをつかえば、RSS 閲覧はできる。
でも RSS リーダーを使わずに web ブラウザ画面に 直接 SEC の RSS を表示させてみた。
http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/rss.html?root=ruby-xbrl&view=log

20090813secrss_2
設置方法:
*  rss.htm, jquery/, jquery-plugin/ を httpサーバーの document エリアに置く。
  例:MacOSX の場合
        ~/Sites/ や  /Users/youichikato/Sites

    jquery は以下から download できる。
      http://docs.jquery.com/Downloading_jQuery#Download_jQuery
    jFeed は以下から download できる。
      http://plugins.jquery.com/project/jFeed 

外部サイトの RSS データを取得するための jFeed に含まれている proxy.php を利用する。
php が動作するように http サーバーの設定をすることも必要。
proxy.php の設置場所に合わせて、rss.html 中のproxy.php のパスの変更もすること。
// 現状は、jFeed 中のproxy.php を直に指定している。

| | コメント (0) | トラックバック (0)

2009-08-10

sinatra + haml + sass + jquery (その2)

20090810ciksearcher

http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/?root=ruby-xbrl
を更新した。

更新内容は、submit ボタンに disabeld 制御を追加した事だ。
検索条件が空の場合にsubmit ボタンを 無効にし、そうでないときにボタンを有効にするようにした。

これは、jquery に本を買ってきて、selector や イベントに処理関数を割り当てる方法を勉強した成果である。

| | コメント (0) | トラックバック (0)

2009-08-09

sinatra + haml + sass + jquery

20090809sinatra

SEC の SIC コードの検索 web アプリを sinatra で作成している。
favicon.ico の設定、jquery の tablesorter, pager の組み込みもできるようになった。

http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/?root=ruby-xbrl

つぎのいずれの方法でも起動できる。

$ jruby web-app.rb    // このあと ブラウザで http:;pcalhost:4567 にアクセス
$ ruby web-app.rb   // このあと ブラウザで http:;pcalhost:4567 にアクセス
$ rackup config.ru   // このあと ブラウザで http:;pcalhost:9292 にアクセス

この後は SIC, CIK コードの検索アプリ/Restful サービスとして完成をさせていこう。

| | コメント (0) | トラックバック (0)

2009-08-03

SIC コード検索を sinatra + haml で

20090803sicsearch

先日は SEC サイトの SIC コード全体を取得するプログラムを作ったが、
取得データの検索をする web アプリを sinatra + haml で作成してみた。
http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/?root=ruby-xbrl
(ruby web-app.rb として走らせる)

favicon.ico の表示ができるようにする、
jquery で、検索結果表のソートをできるようにする、
SIC, CIK の両方の検索を可能にする、
などの機能も追加していく予定。

| | コメント (0) | トラックバック (0)

2009-08-01

sqlitel3 から mysql5 に変更したら

sqlite3 での DB 作成時間、検索時間は使用に耐えないので、
利用する DB を sqlite3 から mydql5 に変えてみた。

 DataMapper.setup(:default, "sqlite3://#{File.dirname(File.expand_path(__FILE__))}/db.sqlite3")

    DataMapper.setup(:default, "mysql://root:root@localhost/dm_test")
に変更するだけ。
ただし、  コンソールから Database を作成しておく必要がある。
    $ mysql -u root -p
    > create database dm_test;
    > quit

しかし、走らせるといくつかエラーが発生した。

その1:
======
$ ruby XbrlDatamap.rb file init

  Incorrect date value: '-4712-01-01' for column 'period_instant'  のエラーが出た。
対処:
  Date.new => Date.today
に変更。
Date 値に対するチェックが sqlite3 は甘いみたいだ。

その2:
======
$ ruby sample00.rb -i /Users/youichikato/work/www/EDGAR/data/*/*/*-*[0-9].xml

   Data too long for column 'val' at row 1 (MysqlError) のエラーがでた。
対処:
fact の DataMap 定義
  property :val, Text
  =>
  property :val, String, :length => 4096
デフォルトの文字列の長さの扱いが sqlite3 と mysql では異なってる?

上記変更後の DB 作成は
364.710000   9.420000 374.130000 (465.242776)
約 8 分!
sqlite3 の 25 倍の速さ!

NetIncomeLoss 科目の検索も
  2.040000   0.040000   2.080000 (  2.368310)
と 2 秒程度で、sqlite3 の 8 倍の速さ!

変更したソースコードは 以下に commit 済み。
http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/datamap/?root=ruby-xbrl

つぎは、この検索機能を sinatra で web アプリに仕立てる予定。
(jruby でも動作するようにするのは、その後だな...)

| | コメント (0) | トラックバック (1)

2009-07-31

解決:libxml-ruby/datamapper は不安定?

次の2つの情報を net 上で得た。
- http://osdir.com/ml/lang.ruby.modules.libxml.devel/2008-07/msg00094.html
> Re: [ libxml-Bugs-8337 ] Opening many files causes: msg#00094 lang.ruby.modules.libxml.devel

GC.start をファイルオープン前に呼ぶと良いらしい。

- http://www.iteray.com/archives/133
> libxml-ruby problems on Mac OS X | Iteray

sudo bash
ARCHFLAGS='-arch i386' gem install -r libxml-ruby -- --build-flags --with-opt-lib=/opt/local/lib
のようにして、libxml-ruby を insutall すると良いらしい。

これらをおこなったところ、やっと SEC で zip 公開されている XBRL データの
全インスタンスをDB 格納できた。
(ただし、 901491/000110465908020683/pzza-20071230.xml.org は
mlns:pzza="http://www.pzza.com\"
=>
mlns:pzza="http://www.pzza.com"
へ書き換えをして、XML 処理時にエラーが発生しないようにした)

$ ruby sample00.rb -i /Users/youichikato/work/www/EDGAR/data/*/*/*-*[0-9].xml

"facts:    190135"
"units:    1644"
"contexts: 10574"
インスタンスファイル数:658 ファイル
DB 作成: 約3 時間30分 (12259秒)
DB (b.sqlite3) のサイズ   89MB

NetIncomeLoss の検索(925箇所): 15 秒

sqlite3 ではちょっと遅いな。
Mysql5 で試してみようと思う。

| | コメント (0) | トラックバック (4)

2009-07-29

libxml-ruby/datamapper は不安定?

大量のxml を libxml でパース、datamapper で保持しようとするとエラーになる。
しかも 同じ条件で走らせてもエラーの発生状況がまちまち...

$ ruby sample00.rb -i /Users/youichikato/work/www/EDGAR/data/*/*/[Aa]*[0-9].xml
"--- init DB"
reading 1:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000075/atg-20080331.xml
reading 2:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000130/atg-20080630.xml
reading 3:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000144/atg-20080930.xml
reading 4:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415509000014/atg-20081231.xml
reading 5:    /Users/youichikato/work/www/EDGAR/data/1004155/000114036108003746/agl-20071231.xml
reading 6:    /Users/youichikato/work/www/EDGAR/data/1091587/000104746909002416/abb-20081231.xml
reading 7:    /Users/youichikato/work/www/EDGAR/data/1310243/000114036108015489/anr-20080331.xml
reading 8:    /Users/youichikato/work/www/EDGAR/data/1310243/000131024308000026/anr-20080630.xml
reading 9:    /Users/youichikato/work/www/EDGAR/data/1310243/000131024309000008/anr-20081231.xml
reading 10:    /Users/youichikato/work/www/EDGAR/data/2969/000095012308012951/apd-20080630.xml
reading 11:    /Users/youichikato/work/www/EDGAR/data/4281/000119312507209888/aa-20070630.xml
reading 12:    /Users/youichikato/work/www/EDGAR/data/4281/000119312507233651/aa-20070930.xml
reading 13:    /Users/youichikato/work/www/EDGAR/data/4281/000119312508072455/aa-20071231.xml
reading 14:    /Users/youichikato/work/www/EDGAR/data/4281/000119312508107986/aa-20080331.xml
./parseritem.rb:22: [BUG] Segmentation fault
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9]

Abort trap
$ ruby sample00.rb -i /Users/youichikato/work/www/EDGAR/data/*/*/[Aa]*[0-9].xml
"--- init DB"
reading 1:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000075/atg-20080331.xml
reading 2:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000130/atg-20080630.xml
reading 3:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415508000144/atg-20080930.xml
reading 4:    /Users/youichikato/work/www/EDGAR/data/1004155/000100415509000014/atg-20081231.xml
reading 5:    /Users/youichikato/work/www/EDGAR/data/1004155/000114036108003746/agl-20071231.xml
reading 6:    /Users/youichikato/work/www/EDGAR/data/1091587/000104746909002416/abb-20081231.xml
reading 7:    /Users/youichikato/work/www/EDGAR/data/1310243/000114036108015489/anr-20080331.xml
reading 8:    /Users/youichikato/work/www/EDGAR/data/1310243/000131024308000026/anr-20080630.xml
reading 9:    /Users/youichikato/work/www/EDGAR/data/1310243/000131024309000008/anr-20081231.xml
./parseritem.rb:20:in `parse': undefined method `child' for -532922715:Fixnum (NoMethodError)
    from sample00.rb:53:in `read_data'
    from sample00.rb:139
    from /opt/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    from sample00.rb:108

ruby1.9 で試そうと思ったが、ruby1.9 では dm-more のインストールでエラーが...
$ sudo gem1.9 install dm-more
... 省略...
ferret.c:297: error: ‘struct RString’ has no member named ‘len’
make: *** [ferret.o] Error 1
... 省略...

$ sudo gem1.9 install ferret
ferret.c:297: error: ‘struct RString’ has no member named ‘len’
make: *** [ferret.o] Error 1

うーん、どうする?

$ port list ruby ruby19
ruby                           @1.8.7-p174     lang/ruby
ruby19                         @1.9.1-p129     lang/ruby19
$ port list libxml2
libxml2                        @2.7.3          textproc/libxml2
そういえば、なに別のものを ports, gem でインストールしたもので、
お前がつかっている libxml2 の version は古い とかいわれたことがあったなぁ。
でも port でいれた libxml2 でなく、/usr/lib/libxml2.dylib が使われていることまでわかったことがあった。port でいれた libxml2 を リンクさせることはできず、あきらめていた。
今回の現象も 古い libxml2 が使われてしまっているせいだろうか...

| | コメント (0) | トラックバック (0)

2009-07-27

Datamapper で XBRL データ情報の一部を DB に変換

XBRL データの instans の情報の一部をDatamapper で DB 保存し、
条件検索をするプログラムを試作してみた。

ruby でのソースコード一式は以下にある。
- http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/datamap/?root=ruby-xbrl
> Index of /trunk/Edinet/tools/datamap - ruby-XBRL - SourceForge.JP

実行例を示す。
14 ファイルを処理し、それぞれインスアンの科目数の検索、"NetIncomeLoss" 科目の検索
を行ってみている。
最初は、DB 登録を行う。(時間がかかる)
2回目は作成済みDB を参照して検索をする。(時間はかからない)

$ ruby sample00.rb  -h
Usage: sample00 [options]
    -m                               use memory db
    -i                               init db

$ ruby sample00.rb -i /Users/youichikato/work/www/EDGAR/data/*/*/msft*[0-9].xml
"--- init DB"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312505193215/msft-20050630.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312506128216/msft-20060331.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312506205609/msft-20060630.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312506235137/msft-20060930.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312507039978/msft-20061231.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312507116258/msft-20070331.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312507221457/msft-20070630.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312507253878/msft-20070930.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312507259490/msft-20070930.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312508031558/msft-20071231.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml"
"reading /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml"
"instances: 14"
0: /Users/youichikato/work/www/EDGAR/data/789019/000119312505193215/msft-20050630.xml
    1119, 5, 149
1: /Users/youichikato/work/www/EDGAR/data/789019/000119312506128216/msft-20060331.xml
    779, 4, 131
2: /Users/youichikato/work/www/EDGAR/data/789019/000119312506205609/msft-20060630.xml
    1188, 5, 195
3: /Users/youichikato/work/www/EDGAR/data/789019/000119312506235137/msft-20060930.xml
    409, 4, 56
4: /Users/youichikato/work/www/EDGAR/data/789019/000119312507039978/msft-20061231.xml
    650, 4, 86
5: /Users/youichikato/work/www/EDGAR/data/789019/000119312507116258/msft-20070331.xml
    669, 4, 117
6: /Users/youichikato/work/www/EDGAR/data/789019/000119312507221457/msft-20070630.xml
    1060, 5, 111
7: /Users/youichikato/work/www/EDGAR/data/789019/000119312507253878/msft-20070930.xml
    438, 5, 62
8: /Users/youichikato/work/www/EDGAR/data/789019/000119312507259490/msft-20070930.xml
    449, 3, 77
9: /Users/youichikato/work/www/EDGAR/data/789019/000119312508031558/msft-20071231.xml
    846, 3, 135
10: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml
    849, 3, 147
11: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml
    1447, 5, 167
12: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml
    706, 5, 110
13: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml
    903, 5, 155
"facts:    11512"
"units:    60"
"contexts: 1698"
"---- Search http://xbrl.us/us-gaap/2008-03-31:NetIncomeLoss --"
"----        http://xbrl.us/us-gaap/2008-01-31:NetIncomeLoss --"
  1: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            8,168,000,000 2004-06-30
  2: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           12,254,000,000 2005-06-30
  3: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           12,599,000,000 2006-06-30
  4: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           14,065,000,000 2007-06-30
  5: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           17,681,000,000 2008-06-30
  6: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,289,000,000 2007-09-30
  7: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,707,000,000 2007-12-31
  8: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,388,000,000 2008-03-31
  9: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,297,000,000 2008-06-30
10: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,478,000,000 2006-09-30
11: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,626,000,000 2006-12-31
12: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,926,000,000 2007-03-31
13: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,035,000,000 2007-06-30
14: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,141,000,000 2005-09-30
15: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,653,000,000 2005-12-31
16: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,977,000,000 2006-03-31
17: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,828,000,000 2006-06-30
18: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml            4,289,000,000 2007-09-30
19: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml            4,373,000,000 2008-09-30
20: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            4,707,000,000 2007-12-31
21: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            4,174,000,000 2008-12-31
22: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            8,996,000,000 2007-12-31
23: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            8,547,000,000 2008-12-31
24: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml           11,030,000,000 2007-03-31
25: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml           13,384,000,000 2008-03-31
26: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml            4,926,000,000 2007-03-31
27: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml            4,388,000,000 2008-03-31
65.380000  31.090000  96.470000 (142.322403)

$ ruby sample00.rb /Users/youichikato/work/www/EDGAR/data/*/*/msft*[0-9].xml
"--- open DB"
"instances: 14"
0: /Users/youichikato/work/www/EDGAR/data/789019/000119312505193215/msft-20050630.xml
    1119, 5, 149
1: /Users/youichikato/work/www/EDGAR/data/789019/000119312506128216/msft-20060331.xml
    779, 4, 131
2: /Users/youichikato/work/www/EDGAR/data/789019/000119312506205609/msft-20060630.xml
    1188, 5, 195
3: /Users/youichikato/work/www/EDGAR/data/789019/000119312506235137/msft-20060930.xml
    409, 4, 56
4: /Users/youichikato/work/www/EDGAR/data/789019/000119312507039978/msft-20061231.xml
    650, 4, 86
5: /Users/youichikato/work/www/EDGAR/data/789019/000119312507116258/msft-20070331.xml
    669, 4, 117
6: /Users/youichikato/work/www/EDGAR/data/789019/000119312507221457/msft-20070630.xml
    1060, 5, 111
7: /Users/youichikato/work/www/EDGAR/data/789019/000119312507253878/msft-20070930.xml
    438, 5, 62
8: /Users/youichikato/work/www/EDGAR/data/789019/000119312507259490/msft-20070930.xml
    449, 3, 77
9: /Users/youichikato/work/www/EDGAR/data/789019/000119312508031558/msft-20071231.xml
    846, 3, 135
10: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml
    849, 3, 147
11: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml
    1447, 5, 167
12: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml
    706, 5, 110
13: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml
    903, 5, 155
"facts:    11512"
"units:    60"
"contexts: 1698"
"---- Search http://xbrl.us/us-gaap/2008-03-31:NetIncomeLoss --"
"----        http://xbrl.us/us-gaap/2008-01-31:NetIncomeLoss --"
  1: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            8,168,000,000 2004-06-30
  2: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           12,254,000,000 2005-06-30
  3: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           12,599,000,000 2006-06-30
  4: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           14,065,000,000 2007-06-30
  5: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml           17,681,000,000 2008-06-30
  6: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,289,000,000 2007-09-30
  7: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,707,000,000 2007-12-31
  8: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,388,000,000 2008-03-31
  9: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,297,000,000 2008-06-30
10: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,478,000,000 2006-09-30
11: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,626,000,000 2006-12-31
12: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            4,926,000,000 2007-03-31
13: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,035,000,000 2007-06-30
14: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,141,000,000 2005-09-30
15: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            3,653,000,000 2005-12-31
16: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,977,000,000 2006-03-31
17: /Users/youichikato/work/www/EDGAR/data/789019/000119312508162828/msft-20080630.xml            2,828,000,000 2006-06-30
18: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml            4,289,000,000 2007-09-30
19: /Users/youichikato/work/www/EDGAR/data/789019/000119312508215214/msft-20080930.xml            4,373,000,000 2008-09-30
20: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            4,707,000,000 2007-12-31
21: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            4,174,000,000 2008-12-31
22: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            8,996,000,000 2007-12-31
23: /Users/youichikato/work/www/EDGAR/data/789019/000119312509054006/msft-20081231.xml            8,547,000,000 2008-12-31
24: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml           11,030,000,000 2007-03-31
25: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml           13,384,000,000 2008-03-31
26: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml            4,926,000,000 2007-03-31
27: /Users/youichikato/work/www/EDGAR/data/789019/000119312508089475/msft-20080331.xml            4,388,000,000 2008-03-31
  1.930000   0.200000   2.130000 (  2.225345)
ntsitm298093:datamap youichikato$

| | コメント (0) | トラックバック (0)

2009-07-25

SEC の cik, sic の一覧

SEC で配布されている XBRL データには、cik, sic という企業のID 番号や、業種ID 番号が含まれている。
それらの番号の一覧表を、ruby の hash として取得するプログラムを作ってみた。

http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/?root=ruby-xbrl
  get-cik.rb
  get-sic.rb

run させると こんな風になる。 (ruby1.9 でも動作します)
$ ruby get-sic.rb
reading... http://www.sec.gov/info/edgar/siccodes.htm
445
save to sic.yml
445
  0.240000   0.060000   0.300000 (  1.614466)
ntsitm290106:sec youichikato$ ruby get-sic.rb
reading... http://www.sec.gov/info/edgar/siccodes.htm
Data count = 445
save to sic.yml
Data count = 445
  0.240000   0.070000   0.310000 (  1.797561)

$ ruby get-cik.rb
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-123.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-a.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-b.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-c.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-d.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-e.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-f.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-g.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-h.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-i.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-j.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-k.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-l.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-m.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-n.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-o.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-p.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-q.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-r.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-s.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-t.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-uv.htm
reading... http://www.sec.gov/divisions/corpfin/organization/cfia-wxyz.htm
Data count = 11506
save to cik.yml
Data count = 11506
  4.960000   0.490000   5.450000 ( 38.125122)

| | コメント (0) | トラックバック (0)

2009-07-23

なぜか rackup から treemap へ辿りついた

- http://www.rubyinside.com/make-any-ruby-object-rack-friendly-with-rackable-2088.html
> Make any Ruby object Rack-friendly with Rackable

上の記事を読んで、rackup  の使い方を調べた。
しsて そこから いろいろ辿って、treemap と その利用アプリを知る事ができた。
Disk Inventory X は便利だ。これを web ベースで動作させたいなぁ。

- http://labs.unoh.net/2007/05/rackweb.html
> ウノウラボ Unoh Labs: RackでWebアプリのWebサーバー依存を無くす

- http://mono.kmc.gr.jp/~yhara/d/?date=20081013#p01
> [ruby][mac] Ruby treemap gem を使って、ディスク使用量を二次元グラフ化するスクリプトを書いた - Greenbear Diary (2008-10-13)

- http://www.derlien.com/
> Disk Inventory X

- http://www.cs.umd.edu/hcil/treemap-history/index.shtml
> Treemaps for space-constrained visualization of hierarchies

XBRL の Dimension 情報を Treemap 風に interective に表示/ナビゲートしている例は既にあるのだろうか?

| | コメント (0) | トラックバック (0)

2009-07-21

XBRL を datamapper で処理する試作

datamapper で XBRL データを保持する試作をしてみた。
まずは instance データ中の情報の一部だけを 変換する例をつくり、
どの程度の速度が出るかをみてみよう。

10000 項目のデータ (10 インスタンスがそれぞれ 10 コンテキスト * 100 科目を持つ) を作り、ちょっとした検索を行う。

以下が、ソースコードと実行結果例だが、速度的にはちょっと遅いかもしれない。
検索は、致命的に遅い訳ではないので、今後 実装を進めていこうと思う。

$ cat samler.rb

require 'rubygems'
require 'dm-core'
require 'dm-more'
require 'dm-types'
require 'pp'
require 'benchmark'

NUM_INSTANCE = 10
NUM_CONTEXT = 10
NUM_FACT_PER_CONTEXT = 100

class Xbrlinstance
  include DataMapper::Resource
  property :id, Integer, :serial => true

  property :fpath, String

  has n, :units
  has n, :contexts
  has n, :facts
  has n, :footnotes
end

class Unit
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance
  has n, :facts

  property :name, String
  property :measure, String
  property :numerator, String
  property :denominator, String
end

class Context
  include DataMapper::Resource
  property :id, Integer, :serial => true

  belongs_to :xbrlinstance
  has n, :facts

  property :name, String
  property :identifier, String
  property :period_startDate, Date, :default => nil
  property :period_endDate,  Date, :default => nil
  property :period_instant,  Date, :default => nil
  property :period_forever,  Boolean, :dafault => false

  property :senario, Text   # not yet impl
  property :segment, Text   # not yet impl
end

class Footnote
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance

  property :val, Text     # not yet impl
end

class Fact
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance

  property :element, String
  property :val, Text

  belongs_to :context   # @contxtRef
  belongs_to :unit      # @unitRef

  def inspect
    super.to_s +
      " contextRef='#{Context.all('id' => self.context_id)[0].name.to_s}'" +
      " unitRef='#{Unit.all('id' => self.unit_id)[0].name.to_s}'" +
      " val='#{val}'\n"
  end
end

def generate_data
  # instance を登録
  1.upto(NUM_INSTANCE) do |i|
    inst = Xbrlinstance.find_or_create(:fpath => "A-#{i}.xml")
    u1 = inst.units.build(:name => "unit-01", :measure => "measure")

    # fact を登録
    1.upto(NUM_CONTEXT) do |j|
      c = inst.contexts.build(:name => "context-#{j}", :period_instant => Date.new)

      1.upto(NUM_FACT_PER_CONTEXT) do |k|
        f = inst.facts.build(:element => "foo:bar-#{k}", :val => "#{i*10000 + j*1000 + k}")
        u1.facts << f
        c.facts << f
      end
    end
    inst.save
  end
end

def usage
  puts "usage: ruby #{__FILE__} [mem | file [init]]"
  exit(0)
end

usage if ARGV.size == 0

puts Benchmark.measure {

  while ARGV.size > 0
    opt = ARGV.shift
    if (opt == "mem")
      puts "--- using memory"
      DataMapper.setup(:default, 'sqlite3::memory:''')
      puts "--- init data"
      DataMapper.auto_migrate!
      generate_data()
    elsif (opt == "file")
      puts "--- using file"
      DataMapper.setup(:default, "sqlite3://#{   File.dirname(File.expand_path(__FILE__))}/db.sqlite3")
      opt2 = ARGV.shift
      if (opt2 == nil)
        puts "--- open exist data"
        DataMapper.auto_upgrade!
      elsif (opt2 == "init")
        puts "--- init data"
        DataMapper.auto_migrate!
        generate_data()
      else
        usage
      end
    else
      usage
    end
  end

  # pp Xbrlinstance.first('id' => '2')
  # pp Xbrlinstance.all

  pp Unit.all('name' => 'unit-01').size
  pp Unit.all('xbrlinstance.fpath' => 'A-5.xml', 'name' => 'unit-02').size

  pp Context.all.size
  pp Context.all('xbrlinstance.fpath' => 'A-5.xml').size

  pp Fact.all.size
  pp Fact.all('unit.name' => 'unit-01').size
  pp Fact.all('xbrlinstance.fpath' => 'A-5.xml').size
  pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'context.name' => 'context-9').size
  pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'element' => 'foo:bar-5').size
  pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'element' => 'foo:bar-5', 'context.name' => 'context-2').size
}

# ------- 実行結果例 -----
# ruby sample.rb file init
#  ...
#  31.190000  13.210000  44.400000 ( 73.532679)
# -----------------------------------------------
# $ ruby sample.rb
# "file"
# --- using file
# --- open exist data
# 10
# 0
# 100
# 10
# 10000
# 10000
# 1000
# 100
# 10
# 1
#   1.280000   0.020000   1.300000 (  1.311618)
# -----------------------------------------------
# ruby sample.rb mem
# ...
# 24.110000   0.180000  24.290000 ( 24.516180)
# -----------------------------------------------

| | コメント (0) | トラックバック (0)

2009-07-19

SEC サイトから XBRL データを一括ダウンロード

http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/SimpleCrawler/examples/download_xbrl.rb?view=markup&revision=71&root=ruby-xbrl
として、 SEC サイトから XBRL データを一括 download する例を置いた。

http://www.sec.gov/Archives/edgar/xbrldata.tar.gz  として、March 23, 2009 時点の全データが配布されているが、
それ以降のデータは RSS から拾ってくるかなどして補充していく必要がある。
RSS からの XBRL データ download は大分 前に書いているけど。
 http://sourceforge.jp/projects/ruby-xbrl/svn/view/trunk/Edinet/tools/sec/read-rss.rb?view=markup&revision=32&root=ruby-xbrl

兎も角、SEC のデータを集める手段は確立できた。
次の作業は これを Detaouse 化することだ。
(数値情報/非数値データの検索、XML データそのものの取出し, ruby オブジェクトとしての取出し)
を web-service/RESTFull で提供できればと思っている。

EDINET サイトからも XBRLデータを 一括 download しようと思ってが、
mecahanize は javascript を処理できないらしい。
# そもそも EDINET サイトからの XBRLデータ取得が SEC サイトのように簡単
# にできるようになっていない事が問題と思うけど。

| | コメント (0) | トラックバック (0)

2009-05-17

jruby + swing で EDINET2009 タクソノミを閲覧(その9)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)

EDINET サイトで、XBRL データを download する場合、一度に複数企業のデータを指定できる。
その場合 1 つの zip の複数企業データが含まれれる。
そのような zip の対しても csv ファイルを全企業分 生成できるようにした。

2企業のデータを含む zip の処理例を示す。
$ ruby edinet2csv.rb ../../sample2009-edinet/XBRL_20090517_155420.zip > 1.csv
(このプログラムは jruby と ruby のどちらでも動作する)

出力結果を openoffice で開いてみる。
2009051701
2009051702

| | コメント (0) | トラックバック (0)

2009-05-10

jruby + swing で EDINET2009 タクソノミを閲覧(その8)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)

- zip ファイルを扱う
- 簡易表示テンプレートの追加

20090510edinetinstance01 20090510edinetinstance02 20090510edinetinstance03 20090510edinetinstance04
EDINET サイトから download する XBRLデータは、zip 圧縮されています。
アプリケーション画面への Drop, [file] - [open]で この zip ファイルそのもの処理できるようにしました。
(アプリ側で、./temp/ 以下に zip を自動解凍し、そのファイルに対して処理をするようにしただけ)
本当は、xbrl データ (*.xbrl, *.zip) などの URL を webブラウザから drop できたらと考えていたが、
EDINET サイトでの XBRL データ参照は、URL で簡単に 指し示せるようになっていないのであった....

今 書籍 財務マネジメントの基本と原則 を読んでいます。
この書籍中の BS, PL, CF, 基本値 の表示を得るようなテンプレートをつくりました。
書籍では、株発行数、株価も指標としていますので、次は これらの値を web サービスなどで取得して表中に表示したいと思う。

| | コメント (0) | トラックバック (0)

2009-05-07

jruby + swing で EDINET2009 タクソノミを閲覧(その7)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)
メニュー構築の実装を整理し、同時にツールバーも付けました。
ツールバーは表示位置を左、右へ移動したり、フロート表示にすることもできます。
20090505edinetinstance00
20090505edinetinstance01
20090505edinetinstance02

| | コメント (0) | トラックバック (0)

2009-05-06

jruby + swing で EDINET2009 タクソノミを閲覧(その6)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)
EDINET の表示テンプレートだけでなく、ユーザー定義の表示テンプレートを
適用することができるようにしました。
次のスクリーンショットは、 バランスシートの概要だけを表示する
テンプレートを指定している様子です。

20090505edinetinstance

memo.txt には、TODO を記載しています。

現時点では、jrubyc して classfile 化しての実行ができない、
Netbeans6.5 下での debug 実行ができない 等の問題も抱えています。

| | コメント (0) | トラックバック (0)

2009-05-04

jruby + swing で EDINET2009 タクソノミを閲覧(その5)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)

タブシート表示にした。
 左画面のインスアンス値タブは、シート名を企業名にした。
 右画面は、タクソノミ情報と、表示適用テンプレート一覧にした。
   表示適用テンプレート一覧上では、ダブルクリックで表示テンプレートを切り替えられる。
いまは 未だ用意していないが、ユーザー定義のテンプレートの追加も考えている。
20090504edinetinstance00 20090504edinetinstance01

| | コメント (0) | トラックバック (0)

2009-05-02

jruby + swing で EDINET2009 タクソノミを閲覧(その4)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
更新しました。(jruby + swing)
文字列検索機能を追加しました。
Edinetinstance20090502

tree 部、table 部中の文字列(部分一致、大文字/小文字を区別) で検索し、
一致する行が選択状態になります。
// 正規表現での検索、インクリメンタル検索にするなど いろいろな発展バリエーションは考えられるが、まずは 固定文字列の一括検索だけ。

ツリー部を折り畳んでいても、一致する行があれば、自動的に展開されて表示される。(これは JXTreeTabel 自体が持っている機能動作)

| | コメント (0) | トラックバック (0)

2009-04-26

jruby + swing で EDINET2009 タクソノミを閲覧(その3)

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
の EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラムを
また 更新しました。
負値を赤表示にするとか、合計値は、上辺に線を引くとか...
20090426edinetinstance
次は、表示データ中の検索機能、csv/Excel での保存機能、http://  データの扱い etc... を追加したい。

| | コメント (0) | トラックバック (0)

2009-04-25

jruby + swing で EDINET2009 タクソノミを閲覧(その2)


http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinetinstance.rb?root=ruby-xbrl&view=log
として EDINET 2009 のインスタンス情報を GUI で閲覧できるプログラム を登録しました。(jruby 1.2.0 で開発してます)

20090425edinetinstance

http://homepage2.nifty.com/youichi_kato/video/2009-04-25-edinetinstance.swf
として、1分ほどの動画を置いています。
# 動画の作成は、jing ( http://www.jingproject.com/ ) を使いました。

| | コメント (0) | トラックバック (1)

2009-04-18

jruby + swing で EDINET2009 タクソノミを閲覧

http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/edinettree.rb?root=ruby-xbrl&view=log
として、EDINET 2009 のタクソノミ情報を GUI で閲覧できるプログラム登録しました。
Edinettree

これは EDINET サイトにある EXCEL のタクソノミ情報を閲覧しているだけです。
この情報を ruby で扱い、かつ GUI で表示する練習です。
これを発展させて、インスタンスファイルの情報を 表示内容に付加するなどが可能なはずです。

この folder にある main.rb は、インスタンスファイルから
 (科目ID, コンテキスト、値) を 取得できるプログラムです。 
次は、この main.rb プログラムの GUI 化をする予定です。
(フィアルを Drag&Drop したら、treetable 形式で、 科目を階層表示 context/値を table 表示する)

| | コメント (0) | トラックバック (0)

2009-03-14

EDINET 2009 のタクソノミ作成がよくわからない

- http://www.fsa.go.jp/search/20090309/tguide20090309.pdf
> 企業別タクソノミ作成ガイドライン
の 58 ページの  "8-8 ラベルの追加について" に次の文がある。

> 別記事業において一般商工業タクソノミに用意されている勘定科目を使用する場合、既存のラベルでは業法等と不整合になる場合があります。その場合、業種毎に用意されたラベルロールのうち適切なものに、新規にラベルを追加することができます(この場合でも既存のラベルを上書きすることはできないことに留意してください)。

うーん、よくわからないなぁ。
具体的にはどんな記述を ラベルリンクベースファイルに追加すればいいんだろう?

上書きというのは prohibited で priority を高くした arc を定義したうえで、
別の arc で 別定義を書くということだよな。(多分)

では、追加という場合は、prohibited な arc で既存 arc を無効にせずに、
単に 別定義を書けばよいということなのか?
そして、arcrole に既存のものとは異なる指定をして、
表示リンクでは、arcrol でどのラベルを使うかを指定させるということなのか?

http://svn.sourceforge.jp/view/trunk/Edinet/tools/misc/add-label.rb?view=markup&root=ruby-xbrl
として、リンクベースファイルに定義を追加する実験の途中コードを置いてみた。

ラベル文字列を定義する場合と、既存のレベル文字列を流用する場合の
両方を考慮しないといけないよね。
サンプルインスタンスに、ラベルの追加例があると嬉しいのだが...

| | コメント (0) | トラックバック (0)

2009-03-12

ruby でEDINETの2009年のXBRLサンプルデータをCSV化

昨年 、2008 年の EDINET の XBRLサンプルデータを CSV 化するプログラムを作成した。
今日は、これをもとに 2009 年版のサンプルデータを CSV化するプログラムを作った。
こんな感じの CSV が一瞬で得られる。
Edinet2009samplecsv
プログラム
- http://svn.sourceforge.jp/view/trunk/Edinet/lib/src2009/?root=ruby-xbrl
プログラムが参照するデータ
- http://svn.sourceforge.jp/view/trunk/Edinet/lib/edinet-2009-03-01/?root=ruby-xbrl
EDINET のサンプルデータ
- http://svn.sourceforge.jp/view/trunk/Edinet/sample2009-03-09/?root=ruby-xbrl

このプログラムは、インスタンスデータのみを解析する。
タクソノミー情報は、EDINETサイト ( http://www.fsa.go.jp/search/20090309.html ) で提供されている 勘定科目リスト (タクソノミー設計書) の情報を流用して利用している。

| | コメント (0) | トラックバック (0)

2009-03-09

ruby で DSL (その2)

http://svn.sourceforge.jp/view/trunk/Edinet/tools/parser/?root=ruby-xbrl
に parser_schema.rb を commit した。

この中では、メイン処理は次のようになっている。

  xml = '../data/td-net/081220090203088072/tdnet-qcedjpfr-33500-2008-11-30-01-2009-02-20.xsd'

  xsd = Xsd.new.parse(xml)

  if xsd.has_element?('ResearchAndDevelopmentExpense_Div_OperatingRevenue_OneYearDelta')
    pp xsd.ResearchAndDevelopmentExpense_Div_OperatingRevenue_OneYearDelta
  end

ここで指定している xsd ファイルでは、1つの element だけが定義されている。
そして このプログラムからの出力は、こんなふうになる。

#<Element:0x07fe66c
@id=
  :"tdnet-qcedjpfr-33500_ReversalOfAccumulatedImpairmentLossOnLeasedAssetsOpeCF",
@name=:ReversalOfAccumulatedImpairmentLossOnLeasedAssetsOpeCF,
@nillable=:true,
@periodtype=:duration,
@substitutiongroup=:"xbrli:item",
@type=:"xbrli:monetaryItemType">

つまり、このプログラムでは、
xsd ファイルを処理して、あるインスタンスを得るのだが、
そのインスタンスは、
 1. xsd ファイル中で定義された element 名を名前に持つ method が定義されている。
   2. その method の返値は、 Element というクラスのインスタンスであり、
  該当する element の属性を保持している。
のである。

いまは、タクソノミーの import 処理をしていないし、
各種リンクベースも処理していない。
でも、これらを クラスの多重継承、複合として処理し、
かつ、XBRL インスタンスファイルの対しても行うなら、
XBRL文書から ruby クラス/インスタンスを生成できたことになる。

| | コメント (0) | トラックバック (0)

2009-02-28

ruby-xbrl に commit

業務がいそがしくて、全然 作業がすすんでいないが、
ruby-xbrl をすこしだけ update した。

http://svn.sourceforge.jp/view/trunk/Edinet/?root=ruby-xbrl  に
  - XBRLデータのスキャン (import を辿る) の実験コード。
  - RSpec の使い方の例
を cimmit。

RSpec の使い方の例 は、
  - http://japan.zdnet.com/blog/yoshimi/2008/02/22/entry_27016449/
  > RSpecチュートリアルやってみる - 吉見和也(Kazuya Yoshimi) - ZDNet Japan
を読んで、自分でもやってみた結果だ。

| | コメント (0) | トラックバック (0)

2009-01-26

XBRL ファイルの リンクをたどる (その2)

前に XBRL インスタンスデータから ファイル import 関係ツリーを作ることをした。
今度は、ファイル自体をローカルファイルに保存し、2回目からは ネット経由しないでデータアクセスするようなプログラムを作ってみた。

ソースコードは後で示すとして、実行例をまず 示そう。

$ ruby filescan.rb
"3740c8e0eedfad9f135dd69f9296f709"
"readed  100 files. 17439149 bytes."
  3.910000   2.450000   6.360000 (149.429177)

$ ruby filescan.rb
"3740c8e0eedfad9f135dd69f9296f709"
"readed  100 files. 17439149 bytes."
  1.190000   0.060000   1.250000 (  1.255830)

これは microsoft データを読んでみたものだ。
読み込みデータ全体の MD5 値、ファイル数, byte 総数と、benchmark 値を表示している。
2 回目の実行は、1.2 秒だ!

ソースを示そう。(150 行ほどある)

$ cat filescan.rb

# 2009-01-25 katoy
#  Scaw and cache all importd file for XBRL-instnce data.

require 'rubygems'
require 'xml/libxml'
require 'open-uri'
require 'pathname'
require 'pp'
require 'benchmark'
require 'md5'
require 'set'

class FileCache
  CACHE = './cache'   # Cache Folder. 末尾に / は付けない。

  attr_reader :md5
  attr_reader :count
  attr_reader :size
  attr_reader :readed

  def initialize
    @md5 = MD5.new
    @count = 0
    @size = 0
    @readed = Set.new
  end

  def visit(path, dir = '')
    from_path = Utils::normalize_path(path, dir)
    return if @readed.include?(from_path)

    parent = Utils::parent(from_path)
    data = ""

    if from_path.index('http:/') != 0
      cache_file = from_path
      open(cache_file) { |src| data = src.read }
    else
      # ネット上ファイルの場合
      cache_file = CACHE + from_path.gsub('http:/', '/http')   
      # キャッシュから読み込む
      if File.exists?(cache_file)
        open(cache_file) { |src| data = src.read }
      else
        # 読み込んでから、キャッシュにも保存する
        Utils::multi_mkdir(File::dirname(cache_file))  if !File.exists?(File::dirname(cache_file))
        open(from_path) { |src|
          data = src.read
          open(cache_file, "w") { |dest| dest.write(data) }
        }
      end
    end

    @readed << from_path
    @md5.update(data)
    @count += 1
    @size += data.length

    reader = nil

    begin
      reader = XML::Reader.new(data)
      while 1 == reader.read
        href = nil
        name = "#{reader.namespace_uri}:#{reader.local_name}"
        case name
        when 'http://www.w3.org/2001/XMLSchema:import'
          href = reader['schemaLocation']
        when 'http://www.xbrl.org/2003/linkbase:schemaRef'
          href = reader['xlink:href']
        when 'http://www.xbrl.org/2003/linkbase:linkbaseRef'
          href = reader['xlink:href']
        end

        if href != nil
          to_path = Utils::normalize_path(href, parent)
          visit(to_path, parent)
        end
      end
    rescue
      puts "---- error reading #{from_path} (#{cache_file})"
      exit 1
    ensure
      reader.close if reader != nil
      reader = nil
    end
  end
end

class Utils
  def self.cleanpath(path)
    Pathname.new(path).cleanpath
  end

  def self.parent(full_path)
    p = full_path.rindex('/') - 1
    full_path[0..p]
  end

  def self.multi_mkdir(mkpath)
    path = ''
    mkpath.split('/').each do |f|
      path.concat(f)
      Dir.mkdir(path) unless path == '' || File.exist?(path)
      path.concat('/')
    end
  end

  def self.normalize_path(path, dir='')
    if path.index('http://') == 0
      uri = URI.parse(path)
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    elsif dir.index('http://') == 0
      uri = URI.parse("#{dir}/#{path}")
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    else
      path = path[5.. path.length] if path.index('file:') == 0
      dir = File::expand_path('.') if dir == ''
      full_path = Utils::cleanpath(File::expand_path(path, dir))
    end

    full_path.to_s
  end
end

# See http://www.sec.gov
# SEC - adobe
# pat = "http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml"
# SEC - microsoft
pat = "http://www.sec.gov/Archives/edgar/data/789019/000119312508215214/msft-20080930.xml"

# pat = "file:/Users/youichikato/work/www/xbrl.org/XBRL-CONF/Common/instance/397-00-ConsistentInstance-valid.xbrl"
# pat = "/Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl"
# pat = "/Users/youichikato/NetBeansProjects/ruby-xbrl/Edinet/sample/**/*.xbrl"
# pat = "data/X99001-000/jpfr-asr-X99001-000-2008-03-31-01-2008-06-27.xbrl"
# pat = ARGV[0]

puts Benchmark.measure {
  fscan = FileCache.new

  if pat == nil
    puts "--No specified XBRL instance."
    exit 1
  elsif pat.index('http:') == 0
    full_path = Utils::normalize_path(pat)
    fscan.visit(full_path)
  else
    Dir.glob(pat).each do |f|
      full_path = Utils::normalize_path(f)
      fscan.visit(full_path)
    end
  end

  pp fscan.md5.hexdigest
  pp "readed  #{fscan.count} files. #{fscan.size} bytes."
}

ファイル読み込みが、この程度の処理時間で済むなら、どの言語で処理しても人間にとっては大差は無いかもしれない。

| | コメント (0) | トラックバック (0)

2009-01-12

XBRL ファイルの リンクをたどる

libxml-ruby を使って、XBRL データを読み込む事にした。
(REXML は動作が遅いらしいので)

以前に、XBRLインスタンスファイルを指定すると、
そこからの参照ファイルの Tree 状態をコンソールに表示するものを作った。

今回、REXML -> libxml に書き換えてみた。
(実は 以前のプログラムでは、参照をすべて辿れていなかったことも気がついた)

$ cat filetree.rb

# 2009-01-10 katoy
#   Show imported tree list for XBRL-instnce data.

require 'rubygems'
require 'xml/libxml'
require 'open-uri'
require 'pathname'
require 'pp'
require 'yaml'
require 'benchmark'

class FileTree
  YAML_NAME = 'links.yaml'

  attr_reader :links    # from_url => [to_url, ...] のハッシュ

  def initialize
    @links = { }
#   if File.exist?(YAML_NAME)
#     @links = YAML.load_file(YAML_NAME)
#   end
  end

#  def save_links
#    @links.reject!{ |k, v| k.index("http") != 0 }
#    File.open( YAML_NAME, 'w' ) do |f|
#      YAML.dump( @links, f )
#    end
#  end

  def generate(path, dir = '')
    from_path = Utils::normalize_path(path, dir)
    parent = Utils::parent(from_path)

    if @links[from_path] != nil
      puts "------- skip #{from_path}"
      return
    end

    reader = nil

    begin
      reader = XML::Reader.file(from_path)
      while 1 == reader.read
        href = nil
        name = "#{reader.namespace_uri}:#{reader.local_name}"
        case name
        when 'http://www.w3.org/2001/XMLSchema:import'
          href = reader['schemaLocation']
        when 'http://www.xbrl.org/2003/linkbase:schemaRef'
          href = reader['xlink:href']
        when 'http://www.xbrl.org/2003/linkbase:linkbaseRef'
          href = reader['xlink:href']
        end

        if href != nil
          to_path = Utils::normalize_path(href, parent)
          generate(to_path, parent)
          @links[from_path] = [] if @links[from_path] == nil
          @links[from_path] << to_path
        end
      end
    rescue
      puts "---- error reading #{to_path}"
    ensure
      reader.close if reader != nil
    end
  end

  def print_tree(path, indent=0)

    return if @links[path] == nil
    @links[path].each do |f|
      puts "#{' ' * (4*indent)}#{f}"
      print_tree(f, indent + 1)
    end
  end

end

class Utils
  def self.cleanpath(path)
    Pathname.new(path).to_s
  end

  def self.parent(full_path)
    p = full_path.rindex('/') - 1
    full_path[0..p]
  end

  def self.normalize_path(path, dir='')

    if path.index('http://') == 0
      uri = URI.parse(path)
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    elsif dir.index('http://') == 0
      uri = URI.parse("#{dir}/#{path}")
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    else
      path = path[5.. path.length] if path.index('file:') == 0
      dir = File::expand_path('.') if dir == ''
      full_path = Utils::cleanpath(File::expand_path(path, dir))
    end

    full_path
  end
end

# See http://www.sec.gov
# SEC - adobe
# pat = "http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml"
# SEC - microsoft
# pat = "http://www.sec.gov/Archives/edgar/data/789019/000119312508215214/msft-20080930.xml"

# pat = "397-00-ConsistentInstance-valid.xbrl"
# pat = "file:/Users/youichikato/work/www/xbrl.org/XBRL-CONF/Common/instance/397-00-ConsistentInstance-valid.xbrl"
# pat = "/Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl"
# pat = "/Users/youichikato/NetBeansProjects/ruby-xbrl/Edinet/sample/**/*.xbrl"
pat = ARGV[0]

  puts Benchmark.measure {
  ftree = FileTree.new

  if pat.index('http:') == 0
    full_path = Utils::normalize_path(pat)
    ftree.generate(full_path)
    ftree.print_tree(full_path)
  else
    Dir.glob(pat).each do |f|
      full_path = Utils::normalize_path(f)
      ftree.generate(full_path)
      ftree.print_tree(full_path)
    end
  end
#  ftree.save_links
}

$ ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829.xsd
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_pre.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_cal.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_def.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_lab.xml
     ... 省略
                            http://www.xbrl.org/2003/xl-2003-12-31.xsd
                                http://www.xbrl.org/2003/xlink-2003-12-31.xsd
                            http://www.xbrl.org/2003/xlink-2003-12-31.xsd
  4.520000   0.900000   5.420000 (371.585711)

最後の行は benchmak ライブラリーのよるものだ。ここでは 370 秒かかったことがしめされている。

参照ファイルの数(重複も)が多いことが分かる。( Tree 表示の行数は3000 行ほどになる)
また、この処理時間の遅さは、ほとんど ネットアクセスによるものとおもわれる。
(一度 読み込みをしたファイルは、再度 読み込まない工夫はしてあるが)

実用的なものにするには、次のような工夫をすることが考えられる。
  1. ネット経由でアクセスしたファイルは、キャッシュフォルダーの保持し、次回からはキャッシュしたファイルへアクセスする。
     (ブラウザのキャッシュフォルダと同じ考え)
  2. ネット上ファイルの内容は基本的に変化しないはずなので、 ファイル上ファイルについての 解析した参照情報は
     永続化保持して、再利用するようにする。

ここでは、2 番の方法を実装してみよう。

つまり @links を yaml で保持する。
ソースコード中の
   initialize の変更と
   ファイルの最後の save 呼び出し
を追加するだけだ。
# 実は上で示したコードでは、その部分はコメントにしてあった。
この変更を加えると 一回目の実行は遅いが、2回目はもちろん 劇的に速くなる。

$  ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
  4.810000   0.950000   5.760000 (382.223170)
$  ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
  0.050000   0.020000   0.070000 (  0.109030)

ここでは、File からの import 情報だけを永続化して再利用したが、
XBRL の他の情報も同様の方法で永続化することも可能だろう。

XBRL データの処理の関門はいくつかある。
1. ファイルの参照を辿らないと完全な情報を得ることができない。
2. xlink, Xpointer を処理する必要がある。

でも、すべての情報を得る必要がないケースもある。
( (科目ID, コンテキスト、値) の組を得るだけなら、インスタンスファイルだけの処理で十分だ)

#インスアンスファイルを libxml をつかって処理する例は、作成済み。
# 数日中に 別途 投稿する予定である。

ファイル参照をすべて辿るのは、基本的には上に示した方法 (130 行程度) で可能なことがわかった。
次は、Xlinkm Xpointer をつかっている 各種のリンクベースファイルを処理することを行おう。

| | コメント (0) | トラックバック (0)

2008-11-24

xml を別の xml 形式に変換するには?(その2)

汎用的なものはみつけられず。
ともかく、XBRL インスタンスの書き換え専用の ruby スクリプトを書いてみた。

$ cat toSimpleXbrl.rb
# 2008-11-23 katoy
# XBRL インスタンスの 科目タグを書き換える。
#   <foo:bar ...> <==> <item prefix='foo' local_name='bar' ...>
#

require 'rubygems'
require "rexml/document"
require 'open-uri'
require 'pp'

#----------------------
class XBRL
  def self.to_simple(doc)

    doc.elements.each do |elem|
      elem.elements.each do |c| 
        to_simple_tree(c)
      end
    end
  end

  def self.to_simple_tree elem

    prefix = elem.prefix
    return if prefix == 'xlink' or prefix == 'link'

    name = elem.name
    return if name == "context" or name == "unit"

    to_simple_element(elem)
    elem.elements.each do |e|
      name = e.name
      to_simple_tree(e)   
    end
  end

  def self.to_simple_element elem
    type = elem.node_type
    if type != :comment and type != :text
      name = elem.name
      elem.add_attributes( { 'prefix' => elem.prefix, 'local_name' => elem.local_name } )
      elem.name = :item
    end
  end

  #----------------------
  def self.to_xbrl(doc)

    doc.elements.each do |elem|
      elem.elements.each do |c|
        to_xbrl_tree(c)
      end
    end
  end

  def self.to_xbrl_tree elem
    to_xbrl_element(elem)
    elem.elements.each do |e|
      to_xbrl_tree(e)   
    end
  end

  def self.to_xbrl_element elem
    type = elem.node_type
    if type != :comment and type != :text   

      if elem.name == nil  # c.name == 'item' ではひかっからない、何故?
        elem.name = "#{elem.attribute('prefix')}:#{elem.attribute('local_name')}"
        elem.delete_attribute("prefix")
        elem.delete_attribute("local_name")
      end
    end
  end
end

def execute doc
  org_xml = doc.to_s

  XBRL::to_simple(doc)
  simple_xml = doc.to_s

  XBRL::to_xbrl(doc)
  xbrl_xml = doc.to_s

  # puts f
  if org_xml != xbrl_xml or simple_xml == xbrl_xml
    puts "--- Error #{f} ------"
    doc.write( File.new('1.org.xml', 'w'))
    File.new('1.simple.xml', 'w').write simple_xml
    File.new('1.xbrl.xml', 'w').write xbrl_xml
    exit
  end

  temp = REXML::Document.new simple_xml
  temp.write( File.new('1.simple.xml', 'w'), 4 )

  temp = REXML::Document.new org_xml
  temp.write( File.new('1.org.xml', 'w'), 4 )

end

# local file
pat = "/Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl"
# pat = "397-00-ConsistentInstance-valid.xbrl"

# SEC - adobe
# pat = "http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml"

count = 0

if pat.index('http:') == 0
  uri = URI.parse(pat)
  doc = REXML::Document.new uri.read
  execute doc
  count += 1
else
  Dir.glob(pat).each do |f|
    doc = REXML::Document.new File.open(f)
    execute doc
    count += 1
  end
end
puts "-- Checked #{count} files in #{pat}"

$ ruby toSimpleXbrl.rb
-- Checked 69 files in /Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl

念のために実行後に 1.org.xml (変換前の XBRL), 1.simple.xml(変換後の XBRL)を出力している。

$ diff 1*
21c21
<     <tx:A decimals='0' contextRef='ctx0' unitRef='u1'>
---
>     <item local_name='A' prefix='tx' decimals='0' contextRef='ctx0' unitRef='u1'>
23,24c23,24
<     </tx:A>
<     <tx:B decimals='0' contextRef='ctx0' unitRef='u1'>
---
>     </item>
>     <item local_name='B' prefix='tx' decimals='0' contextRef='ctx0' unitRef='u1'>
26,27c26,27
<     </tx:B>
<     <tx:C decimals='0' contextRef='ctx0' unitRef='u1'>
---
>     </item>
>     <item local_name='C' prefix='tx' decimals='0' contextRef='ctx0' unitRef='u1'>
29,30c29,30
<     </tx:C>
<     <tx:D decimals='0' contextRef='ctx0' unitRef='u1'>
---
>     </item>
>     <item local_name='D' prefix='tx' decimals='0' contextRef='ctx0' unitRef='u1'>
32c32
<     </tx:D>
---
>     </item>

ローカルファイルだけでなく、SEC サイトのデータも扱える。
// 今は、ソース中の pat で、処理対象ファイルを指定するので、適宜 編集すること。

$ time ruby toSimpleXbrl.rb
-- Checked 69 files in /Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl

real    0m1.131s
user    0m1.030s
sys    0m0.088s

$ time ruby toSimpleXbrl.rb
-- Checked 1 files in http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml

real    0m5.754s
user    0m3.301s
sys    0m0.250s

| | コメント (0) | トラックバック (0)

2008-11-23

xml を別の xml 形式に変換するには?

xml を別の xml 形式に変換するには?

xml を別の xml 形式に変換するには XSLT という方法がある。
でも、XSLT は使いにくい。
(本当に単純な変換ならよいけど。
ちょっと複雑な条件判定、繰り返しのような処理をしようとすると、保守困難なコードになってしまう)

XSLT のような機能を ruby でうまく記述できる DSL な例はないのかなぁ。

# 具体的に考えている利用シーンは、XBRL データの変換だ。
# XBRLそのものの XML 形式は複雑すぎる。
# もっと、Object マッピングしやすい XML に変換してから処理をしたいのだ。
# XBRL のインスタンスデータ中の 各項目が <a:item...> のようにデータ作成側の好き勝手な タグになっているなんて... orz
# (xsd で タグ名をデータ作成者が自由に定義できることの意義は理解できるけど...)
#
# これを <item prefix="a", name="item"...> のように情報量を保ったまま
# 書き換えてしまえば、既存のxml-object マッピングライブラリーで処理しやすくなる。

| | コメント (0) | トラックバック (0)

2008-11-04

XBRL-API を試す(その2)

XBRLAPI で遊んでみている。
へんなところや疑問があったので、sourceforge.net にバグ報告、フォーラム投稿をした。
http://sourceforge.net/projects/xbrlapi/

フォーラム投稿(HELP)には、すぐに返信が来た。素晴らしい。

XBRLAPI はまだまだ開発途中のようだ。
XBRL が本当に世界中で有効されるのは、XBRL 処理のライブラリーが Opensource で
提供されることが必須と思っている。

// XML パーサーが 各種言語で ライブラリーとして自由に利用可能なのと同じように。
//その上でどんなアプリを作るかの競争になっていくべきだろう。

| | コメント (0) | トラックバック (0)

2008-11-02

XBRL-API を試す

XBRL-API (revison 302) には、
org.xbrlapi.examples.load.Load として、
XBRL インスタンスを読み込み、
  - presentation リンクの内容、
  - instance の context, unit, item, footnote 一覧
を表示するサンプルプログラムがある、

これを
-Xmx300m -Djava.library.path=/Users/youichikato/work/www/dbxml-2.4.16/install/lib
-database /Users/youichikato/work/www/xbrlapi-bdbxml
-container xbrlapiContainer
-cache /Users/youichikato/work/www/xbrlapi-cache
http://www.sec.gov/Archives/edgar/data/789019/000119312508215214/msft-20080930.xml
の様なパラメータを指定して、microsoft の XBRLデータで実行させてみた。

最初の実行では、190 秒 かかった。
2回目は、14 秒
この プログラムでは、一度目で解析した情報は dbxml に保持しているため、
2回目以降はデータの読み込み、解析をしないですませている為だ。

macosx 10.5 で、 dbxml をつかって xbrlapi を動作させるのは少し苦労した。
なぜか java 1.6 では エラーがでてしまうのだ。
   Exception in thread "main" java.lang.UnsatisfiedLinkError ...

http://forums.oracle.com/forums/thread.jspa?messageID=2459042
を参考にして、 java 1.5 で dbxml, xbrlapi を compile することで、動作させることができた。

dbxml は ruby からも使えるようなので、ATOKダイレクト と組み合わせることで、財務情報アクセスのためのツールが作れそうな気がする。
ATOKダイレクトで [企業名、科目名、コンテキスト] をインクリメンタル指定させながら検索して入力できるようにするのだ。
Excel でのセル値入力の場面や、財務関係レポート中で数値を引用する場面で利用できそうだ。
1つの数値を返すだけでなく、いっそのこと ATOK から csv 形式、Office ソフトの xml 形式、htmlでのTable 形式の文字列で、表として複数値を返すようにしてしまえば、XBRLデータの活用頻度が飛躍的に高まる気がする。

| | コメント (2) | トラックバック (0)

2008-08-03

SEC の XBRL データの取得

SEC ( http://www.sec.gov/ ) で公開される アメリカの XBRL データを ダウンロードする ruby スクリプトを書いてみた。
公開データの追加状況は RSS で取得できるので、それを読んで新しいデータをダウンロードするようにした。
http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/tools/sec/read-rss.rb?rev=26&root=ruby-xbrl&view=auto

こんな感じに使う。

$ ruby read-rss.rb X    // 不正パラメータを指定して簡易ヘルプを表示させた
usage: ruby read-rss.rb [n]
     n: SEC の n 日以内の新しい XBRL ダータをダウンロードする。
        指定省略した場合 7
     データは ./Archies/edgar/... に保存される。

$ ruby read-rss.rb 10
downlaod 2 corp(s)
AMEDISYS INC : 100% |oooooooooooooooooooooooooooooooooooooooo| ETA:  00:00:00
SAFEWAY INC (: 100% |oooooooooooooooooooooooooooooooooooooooo| ETA:  00:00:00
$
$ tree  // ダウンロードデータを確認
.
|-- Archives
|   `-- edgar
|       `-- data
|           |-- 86144
|           |   `-- 000119312508160373
|           |       |-- 0001193125-08-160373.txt
|           |       |-- d8k.htm
|           |       |-- swy-20080614.xml
|           |       |-- swy-20080614.xsd
|           |       |-- swy-20080614_cal.xml
|           |       |-- swy-20080614_lab.xml
|           |       `-- swy-20080614_pre.xml
|           `-- 896262
|               `-- 000119312508160221
|                   |-- 0001193125-08-160221.txt
|                   |-- amed-20080630.xml
|                   |-- amed-20080630.xsd
|                   |-- amed-20080630_cal.xml
|                   |-- amed-20080630_lab.xml
|                   |-- amed-20080630_pre.xml
|                   |-- d8k.htm
|                   `-- g42936tx1logo.jpg
`-- read-rss.rb

| | コメント (0) | トラックバック (0)

2008-06-07

ActiveRecord を 単独で使う例

http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/tools/ar/?root=ruby-xbrl
として,
 ActiveRecord を 単独で使う例
を置きました。
これは、EDINET データを RDB に保存するための練習コードです。
(java で RDB にアクセスするのに比べて簡単だなぁ)

| | コメント (0) | トラックバック (0)

2008-05-18

バランスシートの簡易グラフ表示

財務諸表の中の1つのバランスシートのおおまかな様子を図示する
プログラムを試作しました。
これは [[流動資産、固定資産], [流動負債、固定負債、資金]]をパーセント表示するものです。
出力書式は png とsvg です。
Bs_3

画像生成には cairo ライブラリーを利用しました。(sudo gem install cairo でインストールすること)

ファイナンス系の web ページ, web-service や EDINET から バランスシートの上記の値を取得することは簡単だ。それらを図示するのに使おうと思っています。

以下の ruby でのソースコードを示します。

$ cat graph_bs.rb
# See http://jp.rubyist.net/magazine/?0019-cairo
#     http://d.hatena.ne.jp/miyamuko/20070518/p1
#     http://ashitani.jp/wiki/index.rb?p=rcairo

# 2008-05-18 katoy

require "rubygems"
require 'cairo'

def draw(surface, graph_data)
  context = Cairo::Context.new(surface)

  width = graph_data[:width] * 1.0
  height = graph_data[:height] * 1.0
  font_size = graph_data[:font_size] * 1.0
  offset_x = font_size * 1.5
  offset_y = font_size * 0.5
  context.set_font_size(font_size)
  context.select_font_face("Sans")

  colors = [
    [[0.0, 0.9, 0.0], [0.0, 0.9, 0.9], [0.9, 0.0, 0.0]],
    [[0.9, 0.0, 0.0], [0.9, 0.9, 0.0], [0.9, 0.9, 0.9]],
    [[0.0, 0.9, 0.0], [0.5, 0.9, 0.5], [0.5, 0.9, 0.0]],
  ]
  col_num = graph_data[:data].size

  graph_data[:data].each_with_index do |col, i|
    total = col.to_a.inject(0){|t, a| t += a}
    sub_total = 0
    col.each_with_index do |val, j|

      d0 = 1.0 * sub_total / total * height
      d1= 1.0 * (sub_total + val) / total * height
      w0 = 1.0 * width / col_num * i
      w1 = 1.0 * width / col_num * (i + 1)

      context.fill do
        color = colors[ i % 3][j]
        context.set_source_rgb(color[0],color[1],color[2])
        context.rectangle(w0.round, d0.round, w1.round, d1.round)
      end

      context.stroke do
        context.set_source_rgb(0, 0, 0)  # black
        context.set_line_width(1)
        context.move_to(w0, d1)
        context.line_to(w1, d1)
      end
      # text
      context.set_source_rgb(0, 0, 0)  # black
      p = 100.0 * val / total
      c = height * 0.5 * (sub_total + (sub_total + val)) / total
      w = 0.5 * (w0 + w1)
      context.move_to(w.round - offset_x, c + offset_y)
      text = "#{"%.1f" % p} %"
      context.show_text(text)

      sub_total += val
    end
  end

  context.set_source_rgb(0, 0, 0)  # black
  context.set_line_width(1)
  # vertical line
  context.stroke do
    context.move_to(0, 0)
    context.line_to(0, height)

    (1..col_num).each do |i|
      w0 = 1.0 * width / col_num * i
      context.move_to(w0.round - 1, 0)
      context.line_to(w0.round - 1, height)
    end
  end

  # horizontal line
  context.stroke do
    context.move_to(0, 0)
    context.line_to(width, 0)
  end
end

def output(graph_data, file_name)
  width = graph_data[:width] * 1.0
  height = graph_data[:height] * 1.0

  # PNG 出力
  format = Cairo::FORMAT_ARGB32
  Cairo::ImageSurface.new(format, width, height) do |surface|
    draw(surface, graph_data)
    surface.write_to_png("#{file_name}.png")
  end

  # SVG 出力
  Cairo::SVGSurface.new("#{file_name}.svg", width, height) do |surface|
    draw(surface, graph_data)
  end
end

width = 100
height = 120
font_size = 10
rs = 100  # 流動資産の金額
ks =  60  # 固定試算の金額
rf =  70  # 流動負債の金額
kf =  50  # 固定負債の金額
si = (rs + ks) - (rf + kf)  # 残りは資金

graph_data = {:width => width, :height => height, :font_size => 12,
              :data => [[rs, ks], [rf, kf, si]]}

output(graph_data, "bs")

| | コメント (0) | トラックバック (0)

2008-05-10

MSN サイトのファイナンシャルデータを ruby でアクセス(その2)

プログラムを更新しました。

- http://sourceforge.jp/forum/forum.php?forum_id=14849
> > MSN マネーサイトの財務諸表ページから csv を得る

ネストしている項目の処理が変だったのも修正しました。

| | コメント (0) | トラックバック (0)

2008-05-08

MSN サイトのファイナンシャルデータを ruby でアクセス

http://jp.moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol=JP:7974&lstStatement=Balance&stmtView=Ann
任天堂の財務諸表の概要が MSN のファイナンシャルサイトで閲覧できる。

これは HTML なので、ruby でアクセスして、 cvs 形式で保存するようにしてみた。
ソースは subversion に commit してある。(このプログラムは EDINT, XBRL データを扱っていないけど...)
http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/tools/msn-finance.rb?rev=22&root=ruby-xbrl&view=markup

最近、財務諸表の読み方の本が沢山 出版されている。
MSN サイトのデータを CSV にすれば、Excel の取り込んだりすることが可能となる。
そうして、書籍を読みながら沢山の企業のデータで手を使って分析をしてみると、知識が身につくと思う。

任天堂のデータを csv にして、それを NeoOffice で読み込んだスクリーンショットを示す。

Msnfinance01 Msnfinance02

| | コメント (0) | トラックバック (0)

2008-04-20

ruby で XBRL データの処理をしよう(その3)

ruby-XBRL に次の機能を実装したものを commit しました。
- http://sourceforge.jp/forum/forum.php?forum_id=14656
> > SourceForge.JP: EDINETインスタンス -> CSV 機能を実装

EDINET のサンプルインスタンスを指定すると、科目、コンテキスト毎の値が CSV 書式で出力されます。

$ ruby main.rb
../sample/X99002-000/jpfr-q1r-X99002-000-2008-06-30-01-2008-08-08.xbrl
, , CurrentQuarterConsolidatedInstant, Prior1YTDConsolidatedDuration, CurrentYTDConsolidatedDuration, Prior1QuarterConsolidatedInstant, DocumentInfo, Prior1YearConsolidatedInstant, Prior2YearConsolidatedInstant
, , 2008-06-30, 2007-04-01 - 2007-06-30, 2008-04-01 - 2008-06-30, 2007-06-30, 2008-08-08, 2008-03-31, 2007-03-31
jpfr-t-cte:OrdinaryIncome, 経常利益, , 15000000000, 15000000000, , , ,
jpfr-t-cte:IntangibleAssets, 無形固定資産, 5000000000, , , , , 5000000000,
jpfr-t-cte:CostOfSales, 売上原価, , 70000000000, 70000000000, , , ,
jpfr-t-cte:AllowanceForDoubtfulAccountsIOAByGroup, 貸倒引当金, -1000000000, , , , , -1000000000,
jpfr-t-cte:NotesAndAccountsPayableTrade, 支払手形及び買掛金, 2000000000, , , , , 2000000000,
... 以下省略 ...

出力された csv を NeoOffice で表示させたときのスクリーンショットを示します。
Rubyxbrl2008042001 Rubyxbrl2008042002 Rubyxbrl2008042003_2
この版では、インスタンスファイル中の科目順で表示していますが、
EDINET の業種別タクソノミ設計書に記載されている 表情報に従って順番や合計関係を加味して出力すれば、
より財務諸表に近い出力を得る事も可能なはずです。

| | コメント (0) | トラックバック (0)

2008-04-17

edinetlabe.rb を更新

http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/tools/?root=ruby-xbrl
の edinetlabe.rb というスクリプトを更新しました。

前回の commit ソースでは、単に
    prefix:local から csv の列内容を得る
だけでした。
csv ファイルには、各シート毎の情報が連結されて保持されています。
シートの数/名前、シート毎に 項目の順番/合計関係を取得できるようにしました。
run させたときの出力はこんな感じになります。

$ ruby edinetlabel.rb
=====================================
貸借対照表(投資信託受益証券)
貸借対照表
   資産の部
      流動資産
         預金
         金銭信託
         コール・ローン
         抵当証券
         金銭債権
         約束手形
         信託受益権
         受益証券発行信託の受益証券
         株式

    . . . 省略 . . .

   経常損益の部
      営業損益の部
         営業収入
            営業収入
"貸借対照表(学校法人)"
["-", "貸借対照表", nil, nil, "連結貸借対照表[標準]\n連結貸借対照表、タイトル項目[冗長]", "四半期貸借対照表[標準]\n四半期貸借対照表、タイトル項目[冗長]", "四半期連結貸借対照表[標準]\n四半期連結貸借対照表、タイトル項目[冗長]", "中間貸借対照表[標準]\n中間貸借対照表、タイトル項目[冗長]", "中間連結貸借対照表[標準]\n中間連結貸借対照表、タイトル項目[冗長]", "Balance sheets", nil, "貸借対照表、タイトル項目", "jpfr-t-cte", "BalanceSheetsAbstract", nil, "xbrli:stringItemType", nil, "xbrli:item", "instant", nil, "TRUE", "TRUE", "0"]
["A", "固定資産", nil, "固定資産合計[合計]", nil, nil, nil, nil, nil, "Noncurrent assets", nil, "固定資産", "jpfr-t-cte", "NoncurrentAssets", "[合計]", "xbrli:monetaryItemType", nil, "xbrli:item", "instant", "debit", "FALSE", "TRUE", "3"]
["A", "教育研究用機器備品", nil, nil, nil, nil, nil, nil, nil, "Educational research instrument and equipment", nil, "教育研究用機器備品、学校法人", "jpfr-t-edu", "EducationalResearchInstrumentAndEquipmentEDU", nil, "xbrli:monetaryItemType", nil, "xbrli:item", "instant", "debit", "FALSE", "TRUE", "4"]
$

| | コメント (0) | トラックバック (0)

2008-04-14

edinetlabe.rb を登録

http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/tools/?root=ruby-xbrl
に edinetlabe.rb というスクリプトを登録しました。
( https://sourceforge.jp/projects/ruby-xbrl/news/ のプロジェクトニュースも参照してください)

これは、EDINET タクソノミの設計情報 xsl
  http://www.fsa.go.jp/singi/edinet/20080208.html の EXCEL勘定科目リスト (EXCEL:3,350K)
の内容を取得するというものです。

実際には、この xsl データを NeoOffice で開いて csv で保存し直して、それを ruby でアクセスをしています。

EDINET タクソノミの xsd, xml の解釈をせずに、この 設計情報と EDINET インスタンスデータだけからできることがいくつもあると思います。

| | コメント (0) | トラックバック (0)

2008-04-13

xbrlcopy.rb を登録

sourceforge.jp の ruby-XBRL に次のニュースを投稿しました。

- https://sourceforge.jp/forum/forum.php?forum_id=14599
> > xbrlcopy.rb を登録

まずは、EDINETのデータファイルの名前変更ツールを作ってみました。

sourceforge.jp のプロジェクト作成直後から、作業時間が取れずにいましたが、
今後は、作業時間が取れそうです。

EDINET データを個人が簡単に閲覧したり、データ抽出して比較/分析をするためのフリーなツールが充実していくことで、XBRLを意識せずに多くの人がXBRLの恩恵を受けることができると思っています。

| | コメント (0) | トラックバック (0)

2008-03-29

XBRL を ruby ソースに変換するってどう?

XBRL データを ruby ソースに変換してしまうと良いのではないか? と考え始めている。
ともかく XBRL データを DOM で扱うのは面倒なのだ!

XBRLの本家サイトにあるサンプルデータを使って、考えていることを以下に示していこう。
# ここでは手書きで ruby コードを起こしているが、本当はプログラムで自動変換をさせることになる。

使用したデータは
- http://www.xbrl.org/SpecRecommendations/
   2.1 Conformance Suite (Candidate Recommendation 3)   March 5, 2007
   Full Test Suite zip ( http://www.xbrl.org/2007/XBRL-CONF-CR3-2007-03-05.zip )
   XBRL-CONF-CR3-2007-03-05/Common/397-00-ConsistentInstance-valid.xbrl
                                   397-ABC.xsd
                                   397-ABC-calculation.xml

この3ファイルに相当する ruby ソースをつくる。
  1. XBRl 汎用のクラス定義
  2. 397-ABC.xsd, 397-ABC-calculation.xml に対応するクラス定義
  3. 397-00-ConsistentInstance-valid.xbrl の対応するクラス定義

1. XBRl 汎用のクラス定義

$ cat XbrlBase.rb

#----------------------
class XbrlElement
  attr_reader :name, :id, :type, :substutionGroup, :nillable, :periodType

  def initialize(name, id, type, substutionGroup, nillable, periodType)
    @name = name
    @id = id
    @type = type
    @substutionGroup = substutionGroup
    @nillable = nillable
    @periodType = periodType
  end
end

class XbrlCalculation
  attr_reader :arcs

  def initialaize(arcs)
    @arcs = arcs
  end
end

class CalculationArc
  attr_reader :arcrole, :from, :to, :weight
  def initialaize(arcsrole, from, to, weight)
    @arcsrole = arcrole
    @from = from
    @to = to
    @weight = weight
  end
end

class XbrlInsntance
  attr_reader :xsd
  attr_reader :items, :contexts, :units

  def initialize(items, contexts, units)
    @items = items
    @contexts = contexts
    @units = units
  end
end
#--- End of File ---


2. 397-ABC.xsd, 397-ABC-calculation.xml に対応するクラス定義

まず、xsd ファイルと xml を示す。
$ cat 397-ABC.xsd
<?xml version="1.0"?>
<!-- XBRL 2.1 Tests -->
<!-- Copyright 2003 XBRL International Inc.  See www.xbrl.org/legal.  All Rights Reserved. -->
<schema targetNamespace="http://xbrl.example.com/397/ABC"
  xmlns:abc="http://xbrl.example.com/397/ABC"
  xmlns="http://www.w3.org/2001/XMLSchema"
  xmlns:xbrli="http://www.xbrl.org/2003/instance"
  xmlns:link="http://www.xbrl.org/2003/linkbase"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  elementFormDefault="qualified">

        <import namespace="http://www.xbrl.org/2003/instance"
          schemaLocation="../lib/xbrl-instance-2003-12-31.xsd"/>

  <annotation>
    <appinfo>
      <link:linkbaseRef xlink:type="simple"
                        xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase"
                        xlink:href="397-ABC-calculation.xml" />      
    </appinfo>
  </annotation>

        <element  name="A"
            id="A"
            type="xbrli:monetaryItemType"
            substitutionGroup="xbrli:item"
            nillable="true"
            xbrli:periodType="instant"/>

        <element  name="B"
            id="B"
            type="xbrli:monetaryItemType"
            substitutionGroup="xbrli:item"
            nillable="true"
            xbrli:periodType="instant"/>

        <element  name="C"
            id="C"
            type="xbrli:monetaryItemType"
            substitutionGroup="xbrli:item"
            nillable="true"
            xbrli:periodType="instant"/>

</schema>

$ cat 397-ABC-calculation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2005 XBRL International Inc.  See www.xbrl.org/legal.  All Rights Reserved. -->
<linkbase xmlns="http://www.xbrl.org/2003/linkbase"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          >

        <calculationLink xlink:type="extended" xlink:role="http://www.xbrl.org/2003/role/link">

                <loc xlink:type="locator" xlink:href="397-ABC.xsd#A" xlink:label="summationItem" />
                <loc xlink:type="locator" xlink:href="397-ABC.xsd#B" xlink:label="contributingItem" />
                <loc xlink:type="locator" xlink:href="397-ABC.xsd#C" xlink:label="contributingItem" />

    <!-- A = B + C -->
                <calculationArc xlink:type="arc"
                    xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item"
                    xlink:from="summationItem"
                    xlink:to="contributingItem"
                    weight="1"/>

  </calculationLink>

</linkbase>

これに対応する ruby ソースを次に示す。
$ cat ABC_xsd.rb
require 'XbrlBase'

#-------- 397-ABC.xsd ----------
class A < XbrlElement
  def A.inst
    A.new("A", "A", :monetaryItemType, :item, true, :instant)
  end
end

class B < XbrlElement
  def B.inst
    B.new("B", "B", :monetaryItemType, :item, true, :instant)
  end
end

class C < XbrlElement
  def C.inst
    ans = C.new("C", "C", :monetaryItemType, :item, true, :instant)
  end
end

#----- 397-ABC-calculation.xml ---
class ABC_Calc < XbrlCalculation
  def inst
    arc = CalculationArc.new("http://www.xbrl.org/2003/arcrole/summation-item",
                             :summationItem, :contributingItem, 1)
    arcs = [arc]
    ABC_Calc.new(arcs)
  end
end

3. 397-00-ConsistentInstance-valid.xbrl の対応するクラス定義

まず、XBRL データを示す。
$ cat 397-00-ConsistentInstance-valid.xbrl
<?xml version="1.0"?>
<!-- Copyright 2005 XBRL International Inc.  See www.xbrl.org/legal.  All Rights Reserved. -->
<xbrl xmlns="http://www.xbrl.org/2003/instance"
      xmlns:link="http://www.xbrl.org/2003/linkbase"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:abc="http://xbrl.example.com/397/ABC"
      xmlns:iso4217="http://www.xbrl.org/2003/iso4217"
      >

        <link:schemaRef xlink:href="397-ABC.xsd" xlink:type="simple"/>

  <!-- A = B + C -->
        <abc:B contextRef="c1" unitRef="u1" precision="INF">1</abc:B>
        <abc:C contextRef="c1" unitRef="u1" precision="INF">2</abc:C>
        <abc:A contextRef="c1" unitRef="u1" precision="INF">3</abc:A>

        <context id="c1">
                <entity>
                        <identifier scheme="www.example.com">example</identifier>
                </entity>
                <period>
                        <instant>2003-03-31</instant>
                </period>
        </context>

        <unit id="u1">
                <measure>iso4217:USD</measure>
        </unit>

</xbrl>

これに対応する ruby ソースを示す。
$ cat sample01-instance.rb

require 'ABC_xsd'
require 'pp'

#-------- 397-00-ConsistentInstance-valid.xbrl -----------
class Sample01Instance < XbrlInsntance
  @links = [:calc => ABC_Calc.new]

  def Sample01Instance.inst
    items = []
    items << {:element => B.inst, :val =>1, :presoson =>:INF , :contextRef => :c1, :unitRef =>:u1}
    items << {:element => C.inst, :val =>2, :presoson =>:INF , :contextRef => :c1, :unitRef =>:u1}
    items << {:element => A.inst, :val =>3, :presoson =>:INF , :contextRef => :c1, :unitRef =>:u1}

    contexts = {}
    contexts[:c1] = {:entity => "example", :period => "2003-03-31"}

    units = {}
    units[:u1] = :iso4217_USD

    Sample01Instance.new(items, contexts, units)
  end
end

#---- Main ----
if __FILE__ == $0

inst = Sample01Instance.inst

  inst.items.each {|item|
    contextRef = item[:contextRef]
    period = inst.contexts[contextRef][:period]
    puts "#{item[:element].name}   #{item[:val]} [#{period}]"
  }
end
#--- End of File ---

これには, 科目の名前、値、コンテキストを列挙するアプリも追加してある。
この最後のソースを走らせてみれば、次のようになる。

$ ruby sample01-instance.rb
B   1 [2003-03-31]
C   2 [2003-03-31]
A   3 [2003-03-31]

erb を利用するなどすれば、HTML の表形式で出力することも可能だろう。

XBRL データが表現してことを ruby クラス/オブジェクトとして表現しているので、
ruby の機能をつかって柔軟なデータ処理が可能となる。
上記 XBRL では、XBRL 共通の xsd, xml が実際には参照されているが、その 部分の ruby ソース化はしていない。
実際には、すべての xsd, xml を ruby ソースに変換する必要がある。
そうしておけば、XBRL データ中からの XBRL/EDINT の共通フィアルへ参照は、
ruby 中では 単なる require 文に置換することができる。

インスタンス編集は、ruby オブジェクトの変更と同一視することもでき、エディタでの編集補完機能や、
プログラム実行時のリフレクションなどをつかって編集をするなんてことが可能になる。

| | コメント (0) | トラックバック (0)

2008-02-10

プログラマーの為の XBRL という記事を書き始めました。

プログラマーの為の XBRL という記事を書き始めました。
http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi/trunk/Edinet/lecture/000-begin.txt?rev=4&root=ruby-xbrl&view=auto

netbeans6.0.1/ruby/jruby を使ってプログラミングして行く予定です。
(netbeans から commti する時に コメントとして日本語を書いたら
  svn: Can't convert string from native encoding to 'UTF-8':
とのエラーになった...どうすれば解消できるのか?)

| | コメント (0) | トラックバック (0)

2008-01-20

sourceforge.jp へ netbenas からの svn アクセスができない

netbeans6 から sourceforge.jp に ソースを登録しようとしたが、エラーがでて import できない。("Connection closed unexpectedly")

コマンドラインで実行すれば、import できた。
$ svn import . svn+ssh://katoy@svn.sourceforge.jp/svnroot/ruby-xbrl/trunk -m 'Initial import to Subversion'

import できたので netbeans6 から checkout を試みるが、これもダメ。
しかたないので、再度、コマンドラインで checkout した。

$ svn checkout svn+ssh://katoy@svn.sourceforge.jp/svnroot/ruby-xbrl/trunk .

コマンドラインでは、 ssh login もうまくいく。
$ ssh -l katoy -i ~/.ssh/id_dsa shell.sourceforge.jp

netbeans6 での subversion でのダイアログでは次のように設定している。
何が悪いのかなぁ。

Repository URL:  svn+ssh://katoy@svn.sourceforge.jp/svnroot/ruby-xbrl
Tunnel Command:  ssh -l katoy -i ~/.ssh/id_dsa

開発者としてでなく、

Repository URL:  http://svn.sourceforge.jp/svnroot/ruby-xbrl/trunk

として、アクセスすれば、netbeasns6 から checkout  はできるのだが。

| | コメント (0) | トラックバック (1)

2008-01-19

XBRLインスタンス作成Tool があるのを知った

http://sourceforge.jp/projects/goingxbrl/
> ...
XBRLインスタンス作成Tool kit for RDBは、XBRLタクソノミーをRDBに展開し、SQLとmethodのコールでXBRLインスタンスを作成することができます。
> ...
なんてものがあることを知った。(java)
RDB アクセスを ActiveRecored にして、ruby や jruby と組み合わせて使えるかな?

| | コメント (0) | トラックバック (0)

2008-01-16

ruby で XBRL データの処理をしよう(その2)

sourceforge.jp に project ページができました。

  https://sourceforge.jp/projects/ruby-xbrl

----- 返信メールから引用 ----

Sourceforge Admin <sf-admin@sourceforge.jp>    
2008/01/15 8:48
Your project registration for SourceForge has been approved.

Project Full Name:  ruby-XBRL
Project Unix Name:  ruby-xbrl
CVS Server:         cvs.sourceforge.jp
Project Page:       https://sourceforge.jp/projects/ruby-xbrl
Project Admin Page: https://sourceforge.jp/project/admin/?group_id=3311

Your project registration for SourceForge has been approved.

---- ここまで -----

承認メールの返信は1時間ほどで届いていたのか。素早いな。

他の project の ファイル構成、wiki 書き方 などを参考にして、
どんどんと 更新をしていきた い。

| | コメント (0) | トラックバック (0)

2008-01-15

ruby で XBRL データの処理をしよう

http://ja.wikipedia.org/wiki/XBRL
という 財務諸表 のための xml の仕様があります。
日本では、EDINET ( http://ja.wikipedia.org/wiki/EDINET ) として利用が開始されます。

このデータを利用するための オープンソースは少ないです。
sourceforge.net で XBRL で検索したら、12 件がヒットするだけ。

- http://sourceforge.net/search/?words=xbrl&sort=registration_date&sortdir=desc&offset=0&type_of_search=soft&pmode=0&form_cat=18
> > SourceForge.net: Software Search

そこで、 sourceforge.jp に "ruby-xbrl" として、プロジェクト登録の申請をしました。
ここでは、 ruby で、 XBRL/EDINET のデータを表示する為のアリブラリーと、
それを利用したアプリケーションを作っていこうと思います。(ライセンスは GRL で)
個人投資家が XBRL データを有効利用できるためのツールを作成できればと思っています。
# 興味がある方は、連絡を。一緒に作業をしていきたいです。

soruceforge のプロジェクト登録が承認されしだい、活動を開始したい。
現時点での手持ちソースと実行例を以下に示します。

「main.rb」をダウンロード

「xbrl.rb」をダウンロード

「myyaml.rb」をダウンロード

$ ruby main.rb
B:c1=1
C:c1=2
A:c1=3

これは、
- http://www.xbrl.org/frontend.aspx?clk=SLK&val=100
> > Welcome to XBRL
にある
  http://www.xbrl.org/2007/XBRL-CONF-CR3-2007-03-05.zip
というデータ中の XBRL-CONF-CR3-2007-03-05/Common/instance/397-00-ConsistentInstance-valid.xbrl
という XBRL データを処理して 項目名と値を表示している という実行例です。
(処理ファイル名は現状はソース埋め込み。 See main.rb )

これは、私が netbeasn6 をつかって最初の作成した ruby プログラムでもあります。
書き方が下手なせいもあり、370 行ほどあるが、netbeasn6 のような IDE を利用することで
ソースコード編集、debug が比較的 楽にできました。
テストコードと、ドキュメント用コメントも徐々に書いていこうと思っています。

rails での利用、xfy/xvcd での利用も視野に入れたいと考えています。

# myyaml.rb のコードは
# http://d.hatena.ne.jp/Rommy/20061229/1167406811
#   - 日本語をto_yamlするとエンコードされてしまう問題を安直な方法で解決する
# のコードを流用しています。
# sourceforge 登録時は、削除 or 自作のものへの置き換えをします。

| | コメント (0) | トラックバック (0)