プログラミングのすすめ 第六歩 は、今までの windows プログラミングと JavaScript とを合わせて、ある程度目的を持ってちょっとは使い物になるものを作ろうと思います。
そこで、最近 FXを始めたこともあり、毎日のFXの損益をグラフにするプログラムを作っていこうと思います。
会員数は国内最大級の180万人を突破!【paters】プロジェクト
線香 ギフト 贈答用 日本香堂 宇野千代の線香 特撰淡墨の桜 8小箱塗箱入 お線香 お供え 喪中見舞い 喪中はがき お歳暮 新盆見舞い 初盆 お盆 お供え物 お中元 お彼岸 進物線香 供物 微煙
名付けて ”プロジェクト FX損益総計グラフ” です。
FXの約定履歴からデータをダウンロードし、次のように毎日の建玉損益を集計します。
| 9/1 | 9/2 | 9/5 | 9/6 | 9/7 | 9/8 | 9/9 | 9/10 | 9/13 | 9/14 | 9/15 | 9/16 | 9/17 | 9/20 | 9/21 | 9/22 | 9/23 | 9/24 | 9/27 | 9/28 | 9/29 | 9/30 |
| 1000 | 4500 | 3880 | -2100 | 3000 | -5300 | -2100 | 300 | 3410 | 3420 | -2010 | 210 | 450 | 990 | 1240 | -3100 | 3010 | -1000 | 2050 | -300 | 20 | 3570 |
このデータを元に次の様なグラフを作るのが目的です。

約定履歴のCSV形式データの処理
データの形態を知る
どこのFX会社でも、WEBのFX取引ツールから 約定履歴が .csv形式等でダウンロード出来ると思います。
データを集計する上では、ダウンロードした データがどのような形なのかを調べる必要があります。
まず、約定履歴で 9/1~9/30 の期間を指定して、決済のみの 売買を CSV出力して ダウンロードしました。CSV出力では、次の様にそれぞれの項目がカンマ[,]で区切られています。
| “通貨ペア”,”売買”,”区分”,”数量(Lot)”,”約定レート”,”建玉損益(円)”,”スワップ”,”決済損益(円)”,”注文日時”,”約定日時”,”注文番号”,”円転レート”,”取引手数料”,”建玉損益” |
| “AUD/JPY”,”買”,”決済”,”1″,”93.938″,”1,000″,”0″,”1,000″,”2022/09/30 17:44:45″,”2022/09/30 17:50:27″,”126000006050495″,”-“,”0″,”\1,000” |
| “AUD/JPY”,”売”,”決済”,”1″,”94.07″,”1,600″,”0″,”1,600″,”2022/09/30 17:21:51″,”2022/09/30 17:21:56″,”126000006042192″,”-“,”0″,”\1,600” |
| “AUD/JPY”,”売”,”決済”,”1″,”94.044″,”1,020″,”0″,”1,020″,”2022/09/30 11:40:31″,”2022/09/30 11:51:56″,”126000006041309″,”-“,”0″,”\1,020” |
6番目の建玉損益 と 10番目の約定日時を取り出して、日毎の合計を計算するプログラムをVBのコンソールアプリで作ります。
ダウンロードした9月の約定履歴データは、TradeRecordList9.csv という名前で \SumByDay という ディレクトリに置いてあります。
C:\WINDOWS\system32>cd \SumbyDay
C:\SumByDay>dir
ドライブ C のボリューム ラベルは Windows7_OS です
ボリューム シリアル番号は D97B-6C70 です
C:\SumByDay のディレクトリ
2022/10/09 16:50 <DIR> .
2022/10/09 16:50 <DIR> ..
2022/10/09 16:25 23,112 TradeRecordList9.csv
1 個のファイル 23,112 バイト
2 個のディレクトリ 19,265,359,872 バイトの空き領域
それでは、早速 プログラム作りを始めましょう。新たに使うVBの関数等は、各項目の最初に記してあります。
約定履歴データのファイルを読み込む
StreamReader() , ReadLine() , Do Until / Loop
まずTradeRecordList9.csv を読み込むVBプログラムを作ります。Visual Studio 2022 で コンソールアプリの作成で始めます。
Imports System
Imports System.Diagnostics.Eventing
Imports System.IO
Module Program
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
Debug.WriteLine(line1)
Loop
sr.Close()
End Sub
End Module
それでは、新しく記述したコードの解説を致します。

新たに記述したコードは7行目~12行目です。






デバッグの開始 で実行してみます。

今回の処理には関係ないのですが、一応 直して置きます。このような文字化けの対策については、プログラミングのすすめ 第三歩 をご参照下さい。
ファイル TradeRecordList9.csv を一旦 適当な editor で読み込み、 UTF-8 BOM属性付き で保存しなおします。
再実行結果

行から必要なデータを取り出す
String() , Split()
次は読み込んだ1行のデータからカンマで区切られた建玉損益(6番目)と約定日時(10番目)のデータのみを取り出します。
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim ret As String()
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, ",")
Debug.WriteLine(ret(5))
Loop
sr.Close()
End Sub新しく記述したコードの解説をします。



デバッグの開始 で実行してみます。

該当部分の行データを見てみましょう。最後から8行目の “2 と出たところの1行です。
"AUD/JPY","売","決済","1","95.127","2,400","0","2,400","2022/09/01 20:50:38","2022/09/01 20:51:13","126000005050844","-","0","\2,400"“AUD/JPY”,“売”,“決済”,“1”,“95.127”,“2,400″,“0”,”2,400″, 確かにカンマ(,)で区切って6番目は “2 です。
“2,400” は 建玉損益が 2,400円 ということなのですが、1,000円以上は三桁毎に , が入るので カンマ(,)だけで区切った場合は不都合です。ということで、データをよくみると ”,” を区切り文字にすると問題なく行きそうです。
ダブルクォーテーション(“) をSplit関数の区切り文字に使いたい
ダブルクォーテーション(“) を区切り文字にしたい時は、区切り文字を定義する (“) の中に “” と二個続けて記述することで可能となります。従って “,” を区切りとしたいときは ret = Split(line1, “””,”””) と記述します。
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim ret As String()
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Debug.WriteLine(ret(5))
Loop
sr.Close()
End Sub実行結果は

約定日時も正しく取り出せているかどうか見てみましょう。
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim ret As String()
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Debug.WriteLine(ret(9))
Loop
sr.Close()
End Sub
ここまで、今回のプロジェクトの説明とデータの読み込み、必要なデータの取り出し方について解説してきました。
抽出データの整形
Replace() , Substring() , If / then / else / End if
次は、抽出した 建玉損益 、 約定日時 を処理し易い様に整形します。
建玉損益は、[680] , [-1,100] , [2,400] , [800] のような形で得られますが、 1,000円以上の数字に 3桁ごとにカンマ[,] がふられています。このまま JavaScript に渡すとエラーになります。 [,] は取り除く必要があります。
約定日時については、その日ごとに約定した建玉損益を合計するのが目的ですので、約定日時は 09/01 のように 月/日 だけで十分です。これを考慮して、抽出した 建玉損益・約定日時 を整形します。
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim ret As String()
Dim Soneki As String
Dim MonthDay As String
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Soneki = ret(5).Replace(",", "")
If Len(ret(9)) > 10 Then
MonthDay = ret(9).Substring(5, 5)
Else
MonthDay = ret(9)
End If
Debug.WriteLine(Soneki + " " + MonthDay)
Loop
sr.Close()
End Sub更新したコードについて解説致します。




デバッグの開始 で実行します。

最初の行にタイトルが入っているので、If 文で 約定日時のデータ値が10桁以下の時は、Substring関数を通さないようにしていたのですが、最初の行をダミーで読み込んで飛ばせば、いいことなのでコードを次のように変更しました。
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim dummy As String = sr.ReadLine()
Dim ret As String()
Dim Soneki As String
Dim MonthDay As String
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Soneki = ret(5).Replace(",", "")
' If Len(ret(9)) > 10 Then
MonthDay = ret(9).Substring(5, 5)
' Else
' MonthDay = ret(9)
'End If
Debug.WriteLine(Soneki + " " + MonthDay)
Loop
sr.Close()
End Sub
毎日の建玉損益の合計
ToString()
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim dummy As String = sr.ReadLine()
Dim ret As String()
Dim Soneki As String
Dim MonthDay As String
Dim PrevDay As String = "FirstDay"
Dim DaySum As Integer
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Soneki = ret(5).Replace(",", "")
MonthDay = ret(9).Substring(5, 5)
If PrevDay = MonthDay Or PrevDay = "FirstDay" Then
PrevDay = MonthDay
DaySum = DaySum + Soneki
Else
Debug.WriteLine(PrevDay + " Sum " + DaySum.ToString)
DaySum = Soneki
PrevDay = MonthDay
End If
Debug.WriteLine(Soneki + " " + MonthDay)
Loop
Debug.WriteLine(PrevDay + " Sum " + DaySum.ToString)
sr.Close()
End Sub追加したコードの解説を致します。



デバッグの開始 で実行します。

合計だけの表示で実行しました。

次は、結果をファイルに出力します。
結果のファイル出力
StreamWriter() , WriteLine()
Sub Main(args As String())
Dim sr As StreamReader = New StreamReader("\SumByDay\TradeRecordList9.csv")
Dim sw As StreamWriter = New StreamWriter("\SumByDay\TradeSumByDay.txt", False)
Dim dummy As String = sr.ReadLine()
Dim ret As String()
Dim Soneki As String
Dim MonthDay As String
Dim PrevDay As String = "FirstDay"
Dim DaySum As Integer
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Soneki = ret(5).Replace(",", "")
MonthDay = ret(9).Substring(5, 5)
If PrevDay = MonthDay Or PrevDay = "FirstDay" Then
PrevDay = MonthDay
DaySum = DaySum + Soneki
Else
Debug.WriteLine(PrevDay + " " + DaySum.ToString)
sw.WriteLine(PrevDay + " " + DaySum.ToString)
DaySum = Soneki
PrevDay = MonthDay
End If
Loop
Debug.WriteLine(PrevDay + " " + DaySum.ToString)
sw.WriteLine(PrevDay + " " + DaySum.ToString)
sr.Close()
sw.Close()
End Sub新たに追加したコードの説明を致します。



デバッグの開始 で実行してみます。
デバッグ窓の表示は以前と変わりませんが、\SumByDay\TradeSumByDay.txt が作成されている筈です。
コマンドプロンプトを立ち上げてチェックしてみましょう。
C:\SumByDay>dir
ドライブ C のボリューム ラベルは Windows7_OS です
ボリューム シリアル番号は D97B-6C70 です
C:\SumByDay のディレクトリ
2022/10/12 21:30 <DIR> .
2022/10/12 21:30 <DIR> ..
2022/10/12 21:28 58,504,498 SumByDay.exe
2022/10/09 21:42 19,314 TradeRecordList9.csv
2022/10/12 21:30 195 TradeSumByDay.txt
3 個のファイル 58,524,007 バイト
2 個のディレクトリ 14,082,400,256 バイトの空き領域
C:\SumByDay>type TradeSumByDay.txt
09/30 6780
09/29 2950
09/28 9940
09/15 -7600
09/14 -960
09/08 -7860
09/07 -12180
09/06 2160
09/05 4090
09/03 -150
09/02 550
09/01 3100
C:\SumByDay>ファイルの中身も正しいようです。
実行可能ファイルを単一ファイルとして発行する
Visual Studio 2022 での最後の作業です。 作成した プロジュクト SumByDay の 実行可能ファイルを発行します。
そのままで発行すると、 exe と dll の二つのファイルが出来て この二つのファイルがないと正しく実行できません。
exe ファイルだけで実行可能とするため、発行前に次の作業を実施します。













ここまで、実行可能ファイルを単一で発行する方法を解説してきました。
折角作ったexe ファイルですが、今のままだと汎用性に欠けます。次のステップで約定データのファイル名や置いてあるパスをパラメータで渡して実行できるような形に変えたいと思います。
ファイルのパス、ファイル名をパラメータ(引数)で渡す
String.Length , System.Environment.CurrentDirectory , For / Next
Sub Main(args As String())
Dim fpath As String
Dim fname As String
Dim file_path_name As String()
If args.Length = 0 Then
fpath = System.Environment.CurrentDirectory + "\"
fname = "TradeRecordList.csv"
Else
file_path_name = Split(args(0), "\")
fpath = file_path_name(0) + "\"
For i = 1 To file_path_name.Length - 2
fpath = fpath + file_path_name(i) + "\"
Next
fname = file_path_name(file_path_name.Length - 1)
End If
Dim sr As StreamReader = New StreamReader(fpath + fname)
Dim sw As StreamWriter = New StreamWriter("TradeSumByDay.txt", False)
Dim dummy As String = sr.ReadLine()
Dim ret As String()
Dim Soneki As String
Dim MonthDay As String
Dim PrevDay As String = "FirstDay"
Dim DaySum As Integer
Do Until sr.EndOfStream
Dim line1 As String = sr.ReadLine()
ret = Split(line1, """,""")
Soneki = ret(5).Replace(",", "")
MonthDay = ret(9).Substring(5, 5)
If PrevDay = MonthDay Or PrevDay = "FirstDay" Then
PrevDay = MonthDay
DaySum = DaySum + Soneki
Else
Debug.WriteLine(PrevDay + " " + DaySum.ToString)
sw.WriteLine(PrevDay + " " + DaySum.ToString)
DaySum = Soneki
PrevDay = MonthDay
End If
Loop
Debug.WriteLine(PrevDay + " " + DaySum.ToString)
sw.WriteLine(PrevDay + " " + DaySum.ToString)
sr.Close()
sw.Close()
End Sub新たに追加したコードの説明を致します。








デバッグで引数を渡すには
それでは、実行してみましょう。 Visual Studio の デバッグで引数を渡すには デバッグ・プロパティに引数をセットします。

デバッグ プロパティは、以下のメニューの下にある窓の右側の小さな逆三角をクリックしても出ます。


パラメータ(引数)でファイルパス、ファイル名を渡しての処理とVisual Studio でのデバッグでの引数の渡し方についてご説明しました。
ここまで、約定履歴データをサマリーして日ごとの合計を得る EXE ファイルの作成について解説きてしました。ここで少し気になるのが、データが新しい日付け順(09/30 ~)になっていることです。出来れば 09/01 ~ にしたいですね。 それは、DOS コマンドの sort を使えば簡単にできるのですが、Visual Basic のプログラム内から DOS コマンドを発行するのはややこしいので、後でバッチファイルで実施することとします。
VB 実行ファイル + DOS コマンド SORT の バッチ・ファイル
テキスト・エディターで次のコードを書いて SumByDay.bat というファイル名で SumByDay.exe があるディレクトリに保存します。バッチ・ファイルに引数を渡すと %1 に入ります。従って、それはそのまま exe に渡されます。
@echo off
SumByDay.exe %1
sort <TradeSumByDay.txt >TradeSumByDayS.txt
同じディレクトリには、ディフォルトのファイル名のデータファイルがあります。
C:\SumByDay>dir
ドライブ C のボリューム ラベルは Windows7_OS です
ボリューム シリアル番号は D97B-6C70 です
C:\SumByDay のディレクトリ
2022/10/16 18:06 <DIR> .
2022/10/16 18:06 <DIR> ..
2022/10/16 17:17 <DIR> sep
2022/10/16 15:51 73 SumByDay.bat
2022/10/16 17:20 58,504,498 SumByDay.exe
2022/10/09 21:42 19,314 TradeRecordList.csvSumByDay.bat を引数なしで実行してみます。
C:\SumByDay>SumByDay.bat
C:\SumByDay>dir
ドライブ C のボリューム ラベルは Windows7_OS です
ボリューム シリアル番号は D97B-6C70 です
C:\SumByDay のディレクトリ
2022/10/16 18:16 <DIR> .
2022/10/16 18:16 <DIR> ..
2022/10/16 17:17 <DIR> sep
2022/10/16 15:51 73 SumByDay.bat
2022/10/16 17:20 58,504,498 SumByDay.exe
2022/10/09 21:42 19,314 TradeRecordList.csv
2022/10/16 18:16 147 TradeSumByDay.txt
2022/10/16 18:16 147 TradeSumByDayS.txt
5 個のファイル 58,524,179 バイト
3 個のディレクトリ 22,002,925,568 バイトの空き領域
C:\SumByDay>type TradeSumByDayS.txt
09/01 3100
09/02 550
09/03 -150
09/05 4090
09/06 2160
09/07 -12180
09/08 -7860
09/14 -960
09/15 -7600
09/28 9940
09/29 2950
09/30 6780
TradeSumByDay.txt が作成され、それをソートした TradeSumByDayS.txt が出来ました。
これで約定履歴データをJavaScript に渡せる状態に出来ました。次は、このデータを元にJavaScript でグラフを作って行きます。それは、プログラミングのすすめ 第七歩 でやって行きます。
Xserverドメイン
お名前.com
Xserverビジネス
ロリポップ!なら大人気のWordpressも簡単インストール!
あなたもWordPressでブログデビューしちゃおう!!
映画シン・エバンゲリオン劇場版を観るなら<U-NEXT>
【DMM FX】口座開設のお申込みはこちら


コメント