LoginSignup
3
2

More than 1 year has passed since last update.

PDF(SBI証券、くりっく株365、取引残高報告書)からCSV(テキスト)を作成する

Last updated at Posted at 2020-10-20

2022-09-07 使い方の改善。setwd()、getwd()
2020-02-12 v0.3.3 SBI証券、仕様変更(x6:証拠金の残高が削除されたための対応)
2020-12-28 v0.3.2 バグ修正(ページ下部の明細抽出もれ、x座標のソート)
2020-10-14 .txt → .csv
2020-10-12 Rパッケージ化
#

はじめに


世界の株価指数に投資することが出来る金融商品として、
くりっく株365があります。

上場CFD(東京金融取引所に上場する株価指数証拠金取引)ですが、
 個人だと申告分離課税、
 法人だと総合課税と、
確定申告をしなければなりません。

毎月の取引残高報告書に基づいて申告するのですが、
SBI証券の場合、PDFなのですよ。

これを手作業で集計するのが面倒なので、

PDF、取引残高報告書のうち(2頁〜)証拠金入出金明細書を
CSV(テキスト)にします。

これを会計ソフトと税務ソフト(eTaxの①預貯金)反映させることを目的としています。

#

注意点

テスト不足です。
・複数頁にまたがる場合は、どうだろう。。  → 修正済み
・未使用と思われる列にデータがあると、誤動作するでしょう。
#

想定PDF


7列の表ですが、
摘要(3列)と備考(7列)にはデータが無いと想定しています。

2020-10-20 18.39のイメージ.jpeg
#

使い方(パッケージ版)


githubにパッケージを作ったのでインストールしてください。
準備.r
library( devtools ) # install.packages("devtools")
install_github("nt1969m/sbitools") #面倒な事を聞かれたら、3: Noneで、  

PDFのあるファイルパスを指定、実行

CSV作成.R
# setwd() ※PDFのあるディレクトリーを設定
    # R本体の場合、  「メニュー」 → 「その他」 → 「作業ディレクトリの変更」
    # RStudioの場合、「メニュー」→「Session」→「Set Working Directory」→「Choose Directory」
d <- getwd()
library(sbitools) 
dummy <- CFD( d ) # ファイルが作成されます。PDFのあるディレクトリーに、

CSVファイル(証拠金入出金明細書.csv)が作られたはず。

(コンティンジェンシー・プラン)
もしもの場合、
SBI証券がPDFの仕様を変更した(無意識も含めて)ことにより、
うまく動かない場合、
設定ファイルを作って下さい。
(PDFのあるディレクトリーを指定。dを設定の上で)

設定変更.R
  d <- "./inst/extdata/"  # (例)PDFのあるディレクトリー
  spec <- data.frame( matrix( NA ,0 ,4 ) )
  colnames( spec ) <- c("h1","h2","x1","x4")
  spec[1,1:2] <- c("証拠金入出金明細書","受渡日")
  spec[1,3:4] <- c(25,488) # <------ ここをいじってみる
  save( spec ,file=file.path( d,"specCFD.Rda" ) )

specCFD.Rdaというファイルが作成されると、
デフォルト設定ではなく、
特注設定で実行します。

いじる箇所は以下
3列"x1":受渡日の先頭ポジション
4列"x4":減少の最終ポジション(減少と増加の判定に使用)

#↓過去の出来事
#

使い方(ソース直書き版)

使い方.R
source(	"PDF_CFD_SBI.R"	) 
	# PDFのあるディレクトリーを指定
d <- file.path( ... ,"B_0988_SBI証券" ,"CFD" )

出入 <- CFD.main( d )

csvファイル(証拠金入出金明細書.txt)が作成される。

PDF_CFD_SBI.R
	# pdfデータをインポートするため
library( pdftools )	# install.packages("pdftools")

CFD.main <- function( d ) {
		print( d )
	CFD <- CFD.init()	# ファイル別
	files	<- dir( d ,pattern=".pdf$" ,ignore.case=T )
	for( f in files) {
		p <- pdf_info( file.path( d ,f ) )$pages
		df <-	pdf_data( file.path( d ,f ) )
			print( c( f , p ) )
		CFD <- rbind( CFD ,CFD.pdf( df ,p ) )
	}
	csv <- CFD.fin( CFD )
	f <- file.path( d ,"証拠金入出金明細書.txt" )	
	write.csv( csv ,file=f )	
	print( f )
	
return( csv )
}
print( c( "CFD.main()" ,CFD.main ) )

CFD.pdf <- function( df ,p ) {
	CFD <- CFD.init()	# PDF別
	for( i in 1:p ) {  # i <- 2
		print( i )
		df_p <- sapply( df[[ i ]] ,"[" )  [ ,c("x","y","text") ]  
		x <- as.integer( df_p[ ,"x" ] )
		y <- as.integer( df_p[ ,"y" ] )

		h1 <- subset( df_p ,df_p[,"text"] == "証拠金入出金明細書" )
		h1_y <- as.integer( h1[,"y"] )
		if ( nrow( h1 ) == 0 ) next
		print( h1 )

		h2 <- subset( df_p ,df_p[,"text"] == "受渡日" )
		h2_y <- as.integer( h2[,"y"] )
		m <- df_p[ y > h2_y , ]
		r <- subset( m, m[ ,"x"] == 25 )
		CFD <- rbind(CFD ,CFD.line( m ,r ) )
	}
return( CFD )
}
print( c( "CFD.pdf()" ,CFD.pdf ) )

CFD.line <- function( m ,r ) {
	CFD <- CFD.init()	
	for( j in 1:nrow( r ) ) {  
		CFD[ j ,1 ] <- r[ j,"text"]	
		 <- subset( m ,m[ ,"y" ]==r[ j , "y" ] )
		CFD[ j ,2 ] <- [ 2,"text"]	
		if( as.integer( [ 3,"x"] ) <= 488 ) {
			CFD[ j ,4 ] <- [ 3,"text"]
		} else {
			CFD[ j ,5 ] <- [ 3,"text"]
		}	
		CFD[ j ,6 ] <- [ 4,"text"]
			# 想定外かも?
		switch( ( nrow(  ) - 4 ) 
		,"1" = {
			print(  ) 
			}	
		)
	}
return( CFD )
}
print( c( "CFD.line()" ,CFD.line ) )

CFD.fin <- function( 出入 ) {
	出入[ ,1] <- gsub( "/" ,"-" ,出入[ ,1] )
	出入[ ,4] <- as.integer( gsub( "," ,"" ,出入[ ,4] ) )
	出入[ ,5] <- as.integer( gsub( "," ,"" ,出入[ ,5] ) )
	出入[ ,6] <- as.integer( gsub( "," ,"" ,出入[ ,6] ) )
	print( paste0("証拠金の増減=" ,sum( 出入[ ,5] ,na.rm=T ) - sum( 出入[ ,4] ,na.rm=T ) ) ) 

return( 出入 )
}
print( c( "CFD.fin()" ,CFD.fin ) )

CFD.init <- function( n=1 ) {
			# 列数
	df <- data.frame( matrix( NA ,0 ,7 ) )
			# 列名
	colnames( df ) <- c(
	 "受渡日="			# 列1
	,"区分="		# 列2
	,"摘要="			# 列3
	,"証拠金の減少="	 #,"証拠金の減少(円)="		# 列4
	,"証拠金の増加=" #,"証拠金の残高(円)="		# 列5
	,"証拠金の残高="	 #,"証拠金の残高(円)="		# 列6
	,"備考="		# 列7
	)
	switch( n
	, "1" =  {		# (2頁〜)証拠金入出金明細書
		#	print( sapply( df ,mode ) )
		}
	)
return( df )
}
print( c( "CFD.init()" ,CFD.init ) )
#
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2