ファンダメンタルデータを連続で取得する(その2)

Pocket

今回は、TradeStationの標準のファンダメンタルデータ取得のインジケーターを改変してファンダメンタルデータを連続で取得できるアプリケーションの作成の続きです。(その2)
※今回のプログラムは、TradeStationの標準インジケーターのソースコードを改変したものです。


まず最初にグローバルなスコープに定義する変数と定数を定義します。以下のようにコードの最初のところに定義してください。

ソースを説明します。

行数 内容
1 無限ループ検出を切ります。EasyLanguageでは指定時間プログラム側に制御が戻っていない場合は無限ループでなくても無限ループとしてシステムエラーでプログラムを落としてしまいます。
2~5 階層の深いクラスを使う時に冗長な名前を書かないための定義です。
6 変数定義です。
FQP:ファンダメンタル取得用オブジェクトです。
LoadStatus:処理の状態を管理する変数で何をしているかを表す”Status”と、いま処理している場所を表す”Position”があります。
FundamentalInfo:取得したデータを格納する辞書型の変数です。
GetStockCode:取得する必要がある銘柄コードです。
7 定数の定義を始める予約語です。
8 会計基準を表す定数です。詳しくは、ファンダメンタルデータを取得するインジケーターを解析するを参照してください。
9 ファンダメンタルデータの期間を表す定数です。
10 単独決算の数値か連結決算の数値かを表す定数です。
11 どこまで遡ってデータを取得するかを表す定数です。
12 取得するファンダメンタルデータのキー文字列です。
13 LoadStatusのStatusの1つで、処理前の状態を表す定数です。
14 LoadStatusのStatusの1つで、処理開始の状態を表す定数です。
15 LoadStatusのStatusの1つで、データ更新待ちの状態を表す定数です。

“Status”について補足すると、ボタンが押されると、”LoadStatusStart”の状態になって、銘柄コードを設定してデータの更新待ちの状態になると、”LoadStatusLoading”になり、更新データを受け取って処理すると、再び、”LoadStatusStart”になって、次の銘柄をロードします。全ての銘柄が取得し終わると、”LoadStatusBefore”になります。データは、”FundamentalInfo”に格納されて、該当データのキー文字列が存在しない場合だけ、”GetStockCode”に入ってデータの取得が行われます。

次にボタン押下時のコードです。

コードを説明します。

行数 内容
1 ボタンクリック時のイベントから自動的に挿入されたボタン押下時に実行されるメソッドの開始を表します。
2 関数の中だけで使うローカル変数です。
inputFile:入力ファイルのオブジェクトです。
line:ファイルから1行読み出した後に、カンマで区切って内容を受け取るVector配列です。
item:1行の中で各データがコロン(:)繋ぎで格納されているので、コロンで区切って受け取るためのVector配列です。
counter:ループカウンタもしくは、データを数えるための変数です。
fundData:グローバルな位置に定義されているデータ辞書(FundamentalInfo)は辞書の中に辞書が入っています。その辞書を格納するためのテンポラリ用の辞書です。
3 関数の開始を表します。
4 コメントです。
5 処理中にもう1度ボタンが押された場合の判定です。処理を中断します。
6 if文の開始を表します。
7 辞書の初期化などの初期処理を実行する関数を呼び出します。関数のコードは後ほど掲載します。
8 処置中断時に取得済データをファイルに書き込みます。関数のコードは後ほど掲載します。
9 処理が中断されたことをユーザに知らせます。
10 ボタンのキャプションを元に戻します。
11 ロード処理には進まずに関数を抜けます。
12 if文の終了を表します。
13~14 コメントと空行です。
15 辞書の初期化などの初期処理を実行する関数を呼び出します。関数のコードは後ほど掲載します。
16 ファンダメンタルデータ取得用オブジェクトが初期化されているか判定します。
17 if文の開始を表します。
18 オブジェクトを生成(初期化)します。
19 データのキー文字列を設定します。
20 リアルタイムをOFFにします。このフラグが処理にどう影響を与えるのか、わかりませんが、とりあえずここではOFFにして問題ありません。
21 タイムゾーンを設定します。
22 データ更新時のコールバック関数を定義します。
23 ステータス更新時のコールバック関数を定義します。データ取得時のエラー発生をキャッチするためです。
24 if文の終了を表します。
25~26 空行とコメントです。
27 例外キャッチの開始を表します。tryの中で例外が発生した場合は、Catchに飛びます。ファイルが存在しなかった場合に例外が発生したのでtryを入れました。本来はファイルの存在を確認してから存在していれば開くのが普通だとは思いますが、ファイルの存在を確認する命令が確認できませんでした。
28 finallyでファイルを閉じているので、ファイルを開く前にNULLで初期化して確実に判定できるようにします。
29 ファイルを開きます。前回処理データなので、初回は存在していないはずです。
30 ファイルの終了を判定します。ファイルが終了位置に達していない場合はbeginの中が処理されます。
31 ファイルを1行読んで、カンマで区切ってlineに格納します。
32 テンポラリ辞書を初期化します。
33 読み込んだ行の2個目以降の項目数分だけループさせます。
34 for文の開始を表します。
35 ファイルから取得したカンマ区切りの項目をさらにコロン(:)で区切ります。データとしては、”CR_OP:10000000″というように入っている想定です。
36 正しくコロンで区切られたデータかどうか(区切った後のデータ数が2であること)を判定しています。
37 1番目の項目をキーとして、2番目の項目をデータとして格納します。データはとりあえず文字列として格納しています。
38 for文の終了を表します。
39 作成したローカル変数の辞書データをグローバルな辞書データに格納します。辞書の中に辞書がある形です。
40 while文の終了を表します。ここまでで例外が発生した場合はプログラムが落ちずにキャッチされます。
41 例外をキャッチするための書き方です。例外キャッチは、tryとcatchとfinallyがセットになっています。finallyはないこともあります。ここでは汎用的な例外クラスですべての例外をキャッチしています。例外の種類によって後続の処理を変えたい場合は例外クラスを細かく(exceptionクラスの派生クラス)指定します。”ex”にメッセージなどが格納されます。
42 例外処理が発生した場合の処理です。ここでは何もしません。
43 例外の発生有無にかかわらず処理をすることを書くところです。
44 ここではfinallyでファイルをクローズします。ファイルを開く前に例外が発生する可能性もゼロではないので、開かれているかどうか判定します。
45 ファイルを閉じます。
46~48 try文の終了と空行とコメントです。
49 銘柄コードの取得に使用するファイルをオープンします。ファイルの説明は下記のコラムに書いています。
50 ヘッダーは使わないので、1行読み込んで飛ばしています。
51 ファイルの終了位置に達していなければwhileの中の処理を実行します。
52 1行分読み込んでカンマで区切ってVector型の変数に格納します。
53 4番目(配列はゼロから始まっているので(3))の項目が”市場第1部(国内株)”であれば処理します。今回は東証1部の銘柄を処理対象にします。
54 空の辞書型の配列を初期化します。
55 該当の銘柄コードがグローバルの辞書データ内に存在しているか判定しています。
56 存在していない場合は挿入します。少し上の処理で”StockFile.txt”を読み込んでいますが、そのファイルに存在しているデータは上の処理で既に格納されているので飛ばされます。”StockFile.txt”に存在していない場合に銘柄コードだけ設定して中身は空の辞書データが作成されます。
57~58 if文とwhile文の終了を表します。
59 ファイルを閉じます。
60~61 空行とコメントです。
62 作成したグローバルな辞書データを最初から参照します。
63 for文の開始を表します。
64 辞書データの中の辞書データを取り出します。
65 辞書データに指定したファンダメンタルデータが格納されているか判定します。
66 ファンダメンタルデータが存在しない場合は、データを取得する必要があるので取得用の配列に銘柄コードを追加します。
67~69 for文の終了と空行とコメントです。
70 取得対象の配列にデータがあるか判定します。
71 if文の開始を表します。
72 ステータス表示用のラベルを更新します。
73~74 データ取得をコントロールするタイマーを開始して有効にします。
75 処理開始後に再度ボタンがクリックされた場合は、データ取得を中止するため、ボタンのキャプションを”中止”に変更する。
76 ステータスを更新します。
77~79 if文の終了とelse文とelse文の開始を表します。
80 取得対象の銘柄がない場合はステータス表示用のラベルに、その旨書き込んで取得用のタイマーを開始させずに終了する。
81~82 else文の終了と関数の終了を表します。
COLUMN 銘柄コード参照用データについて
上場している企業の銘柄コードを取得するために、エクセルファイルの読み込みで紹介したJPXのホームページからダウンロードできるデータを使用します。このエクセルファイルをそのまま使ってもいいのですが、4000行近いデータをエクセルで読み込むとかなり時間がかかります。なので、CSVデータに変換します。名前を付けて保存でファイルの種類をCSV(カンマ区切り)を選択して保存します。そのまま保存するとShift-JISという文字コードで保存されると思います。このShift-JISのファイルをEasyLanguageで読み込むと漢字が読めなかったので、UTF-8に変更しています。エクセルのバージョンによっては、UTF-8のCSVが選択できるようですが、選択できない場合は適宜別のテキストエディタなどを使って文字コードを変更してください。ここではファイル名を”data_j_utf8.csv”としています。Shift-JISは日本語を使うために開発された文字コードで、数値や英字は1バイトですが、漢字などの全角文字は2バイトで表現します。UTF-8は世界的な文字コードの標準規格ですが、数値や英字などはShift-JISと変わりませんが、漢字などは3バイトで表現します。Shift-JISの方が歴史は古いですが、Unicodeという新しい規約で世界中のすべての文字を統一したコード体系で扱おうという試みが始まりました。当初は2バイトで収めたい要望があったようでUTF-16というすべての文字を2バイトで表すコード体系が考えられましたが、アジア圏で使われている漢字の数の多さで破綻して3バイト体系のUTF-8の方が主流になっていきました。

コードの説明が長くなったので、続きのコードは次回にします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です