出力ファイルを複数作るには、プログラムの高速化

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
datte123
記事: 19
登録日時: 9年前

出力ファイルを複数作るには、プログラムの高速化

#1

投稿記事 by datte123 » 9年前

[1] 質問文
 [1.1] 私は今、金融商品の取引データを分析したくてプログラムを書いています
 [1.2] それぞれの銘柄のコード(会社の番号)のフォルダに入っている日付のついたcsvファイルを読み込んで、処理を行っています。
ファイルは銘柄コードのフォルダ内に20120104.csv,20120105.csv…という風にあります。

現在下記に示した、コードのようにcsvファイルの内容を読み込んである特定の行の時、その行の特定の列の数字を合計して1日の集計結果として出力し、それを1年分行っています。
これを複数の銘柄にわたって行っています。

今困っているのは、現在のコードだと出力ファイルが1つになってしまうことです。
希望は銘柄コード+文字列.csv(例えば、銘柄コードが6501だとすると、6501_market.csv)のように出力ファイルを銘柄ごとに分けたいのです。

もう一つは、現在のコードだとかなり処理に時間がかかっているので何か効率化する方法はないのでしょうか?

(読み込むcsvファイルは104列、行は銘柄やその日によってまちまちですが最大で60万行くらいかと思います)

[2] 環境  
 [2.1] OS : Windows,
 [2.2] コンパイラ名 : Visual C++ 2010

[3] その他
C言語は先輩のコードを必要なところを直す程度しかやったことはありません。

コード:

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>		
#include <direct.h>
#include <string.h>
#include <math.h>

#define CSV_MAX 600000
#define MEIGARA_MAX 320
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300

typedef struct{
	int time;int zss;double dpp;int gbp[8], gap[8];
	long int gbv[9],gav[9],blmt[9],almt[9], xv;
	double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];
	long int bmkt; 
	long int amkt; 
	int b_movement;
	int a_movement;
	long int bbook[8];
	long int abook[8];
	int period; 
	long double blmt_prob[8];
	long double almt_prob[8];
	int hh;int mm;			
	int yakujou;			
	int timesec;
	int es;	
	int blmt_canc[9];int almt_canc[9];
	int cpb;
	int cpa;
	int exc;
	int esr;
	int bclmt[9],aclmt[9];

	long int mkt_i;	
	long int mkt_m;	

	long int allgbv, allgav;
	long int allblmt, allalmt;	
	long int allbclmt, allaclmt;



}table;

table t[CSV_MAX];

int main() {

	//struct table t[CSV_MAX];
	FILE *fp;
	FILE *output;

	output = fopen("result.csv", "w");
	fclose(output);

	long int i;
	int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2;
	int ban;
	char f_fullname_new[64]="new/";

	//2013用
	int syou;
	int ctp;
	int ccc; 
	int h, jj, kk,qq,jjj,kkk;	

	char temp[100];
	long int itayose_time;	
	long int oohike_time;	
	int basyo;		
	int day;
	int y,buyy,selly;
	long int y_ryou,buy_y_ryou,sell_y_ryou,itayose_y_ryou;
	long int Lkk00,Lkk01,Lkk02;

	char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
	int amari,counthh,countmm;/*時刻読み込み用*/
	c = 0;  i = 0;  // ban = 0;  counthh = 0;  countmm = 0;  amari=0;
	f_num=0;

	if ((fp = fopen("list03.csv", "r")) == NULL) {
		printf("list file can't open!!\n");
		exit(EXIT_FAILURE);
	}
	while ((c = getc(fp)) != EOF) {
		if (c == '\n') {
			i=0;
			f_num++;
			continue;
		}
		f_name[f_num][i++] = c;
	}

	fclose(fp);

	for (mn=0; mn<f_num; mn++) {

		hiduke = 0;//ban = 0;

		/*銘柄ごとパラメータ初期化用------------------------------------------------------------------*/
	
		day =0;
		for (y=START_YEAR; y<=STOP_YEAR; y++){
			for (m=1; m<=12; m++){

				for (d=1; d<=31; d++){


					sprintf(temp, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
					printf("%s\n",temp);
					//getchar();
					if ( (fp = fopen(temp, "r")) == NULL )  {	
						continue;
					}
					day = day+1;

/*日ごと変数初期化 ------------------------------------------------------------------------------------------------------------------*/
					for (i = 50; i < CSV_MAX; i++) {
						t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
						t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
						t[i].hh = 0;t[i].mm = 0;
						t[i].b_movement = 0;t[i].a_movement = 0;
						t[i].yakujou = 0;
						t[i].mkt_m = 0; t[i].mkt_i = 0;
						t[i].timesec = 0;
						for (j = 0; j < 8; j++) {
							t[i].gbp[j] = 0;t[i].gap[j] = 0;
							t[i].bbook[j] = 0;t[i].abook[j] = 0;
							t[i].bclmt[j] = 0; t[i].aclmt[j] =0;

							for(k=0;k<100;k++){
							t[i].pxv[k][j]=0;	t[i].dpxv[k][j]=0;
							}
						}
						//デプスはoverの分も表示されるようになったため
						for(j =0; j < 9; j++){
							t[i].gbv[j] =0; t[i].gav[j]=0;
							t[i].blmt[j] =0; t[i].almt[j]=0;
							t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
						}

						t[i].es=0;
						t[i].cpa=0;t[i].cpb=0;
						t[i].esr=0;
						t[i].allgbv=0; t[i].allgav=0;
						t[i].allblmt=0; t[i].allalmt=0;
						t[i].allbclmt=0; t[i].allaclmt=0;
					}
					y = buyy = selly =0;
					y_ryou = buy_y_ryou = sell_y_ryou = itayose_y_ryou =0;
					Lkk00=Lkk01=Lkk02=0;
					/* to table from file ------------------------------------------------------------------------------------------------------------------*/
					//それぞれの値を決定する
					i = 0;
					n = 0;
					while ((c = getc(fp)) != EOF) {
						
						if (c == ',') {	  /* Kugiri */
							n=n+1;	//date の何列目かをカウントする変数
							if(n == 10){//秒が読み終えたときに秒を時分に結合する
								t[i].time=t[i].time*100;
								t[i].time=t[i].time+t[i].timesec;
							}
							if(n ==4 ){
								if(t[i].exc==21){
									break;
								}
							}
						}
						else if (c == '\n'){n = 0;i++;}	//1行分読み込んだら初期化
						else {
							switch (n) {
								case 7:
									t[i].time = t[i].time * 10 + (c - '0');		break;
								case 9:
									t[i].timesec = t[i].timesec*10+(c-'0');		break;
								case 0:
									t[i].yakujou = t[i].yakujou * 10 +(c-'0');	break;
								case 11:
									t[i].dpp = t[i].dpp * 10 + (c - '0');	break;
								case 12:
									t[i].xv = t[i].xv*10 + (c - '0');		break;
								case 13:	
									t[i].es = t[i].es * 10 + (c - '0');		break;
								case 3:
									t[i].exc = t[i].exc * 10 + (c - '0');	break;
								case 14:	
									t[i].esr = t[i].esr * 10 + (c - '0');	break;
								default :
									if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
									else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
									else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
									else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
									break;
							}
						}	
					}

					fclose(fp);																									
					row = i;	/*i=CSV_MAX*/

// ------------------------------------------------------------------------------------------------------------------
					for(i = 0; i<1;i++){
						basyo=t[i].exc;
					}
					
					for(i = 0; i< row; i++ ) {		
						if ( t[i].yakujou ==1){
							if(t[i].es == 16){			
								t[i].amkt = t[i].xv;
							}else if(t[i].es == 48){	
								t[i].bmkt = t[i].xv;
							}else if(t[i].es == 1){		
								t[i].mkt_i=t[i].xv;
								if(t[i].time<=113000){	
									itayose_time=i;
								}
							}else{						
								t[i].mkt_m=t[i].xv;
							}
							if(t[i].esr >= 0){
								if(t[i].time==150000){
									oohike_time=i+2;
								}
							}
						}
					}
					
//-------------------------------------------------------------------------------
					
					for ( i = 0 ; i < oohike_time ; i++){

		//回数と量を合計
						if(t[i].yakujou == 1){
							y +=1;
							Lkk00=y_ryou;
							y_ryou=Lkk00+t[i].xv;
							if(t[i].es==16){
								selly +=1;
								Lkk01=sell_y_ryou;
								sell_y_ryou=Lkk01+t[i].xv;
							}
							else if(t[i].es == 48){
								buyy +=1;
								Lkk02=buy_y_ryou;
								buy_y_ryou=Lkk02+t[i].xv;}
							else if(t[i].es == 1){
								itayose_y_ryou += t[i].xv;}
							Lkk00=Lkk01=Lkk02=0;
						}
					}

/*-------------------------------------------------------------------*/
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv");	//ファイルへ出力 
					output = fopen(f_fullname_new,"a");
					if (output == NULL)
					{
						printf ("Error opening file");
						getchar();
						exit (1);
					}
					else
					{	fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
							,
							f_name[mn],y, m/10, m%10, d/10, d%10,y,selly,buyy,y_ryou,sell_y_ryou,buy_y_ryou,itayose_y_ryou
						);
					}
					fclose (output);					

				}//日ごと
			}//月ごと
		}//年ごと
	}

}//main
最後に編集したユーザー datte123 on 2014年9月01日(月) 23:59 [ 編集 2 回目 ]

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#2

投稿記事 by へにっくす » 9年前

突っ込みどころ満載ですね。

・main関数一つはやめてください。関数化ってできますか?
・変数名を単純にしすぎです。
・コメントが少なすぎです。struct tableの内容も全然コメントされていないですよね・・・掲示したソースの処理の流れを箇条書きに記述することができますか?
・インデントはしっかり行いましょう。たとえコメントでもそれを疎かにすると、悩む種になりかねません。
・ファイル読み込みでfscanf/fgets/freadのいずれかを使わずgetcを使っている理由はなんですか?それこそがファイルアクセスに時間がかかっているところですが。

まずは上記でできるところから直してみてください。
とくにmain関数一つなのは駄目です。大ざっぱでよいので、関数に分けてみてください。
(今のソースですと高速化云々より、まずはきちんとしたプログラムを組めるようにするのが先だと思います)
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#3

投稿記事 by datte123 » 9年前

関数化というのは例えば、加算するところを関数として作っておいて、その関数に引数を渡して答えだけそこで返すものですよね?今回のコードではどこの部分を関数化した方がいいのでしょうか?例えば回数と量を合計するところとかですか?

提示したソースの処理の流れは、
list.csvから処理したい銘柄コードを読み込む
読み込んだ銘柄コードのフォルダの中にあるcsvファイルを日付順に開く
1列目の値をt.yakujouに4列目の値をt.excに…使用する列の値をそれぞれ別の変数に代入する
その日のcsvの最後まで行ったら、まずその日の成行注文全てを買と売に分類する
区切りとなる時間を探して変数に代入する
1から最後の行までt.yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
そのファイル(1日)の加算した合計をmarket_canc.csvに出力する
これを1年間分繰り返す
箇条書きってこういう感じでいいのでしょうか?

ファイル読み込みでgetcを使っているのは引き継いだものをそのまま使っているからです。
前にfgetsを使用しようとやってみたのですが、何が原因かわからず、そのままgetcを使っています。

コード:

#include "stdafx.h"
#pragma warning(disable:4996)	//警告無効

#include <stdio.h>
#include <stdlib.h>		
#include <direct.h>
#include <string.h>
#include <math.h>

#define CSV_MAX 500000
#define MEIGARA_MAX 320
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300

typedef struct{
	int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
	long int gbv[9],gav[9],blmt[9],almt[9], xv;
	double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
	long int bmkt; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文*/
	long int amkt; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文*/
	int b_movement; /*買い気配値のTickの移動分*/
	int a_movement; /*売り気配値のTickの移動分*/
	long int bbook[8]; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文の合計*/
	long int abook[8]; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文の合計*/
	int period; /*時間区切り*/
	long double blmt_prob[8];	/*買い指値注文確率*/
	long double almt_prob[8];
	int hh;int mm;			/*hh=時間(例 09時,14時) mmは分*/
	int yakujou;			//その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
	int timesec;	//秒用
	int es;	//約定種別
	int blmt_canc[9];int almt_canc[9]; //キャンセル
	int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
	int cpa;//売り最良気配値の変化用フラグ
	int exc;//上場場所
	int esr;//約定レコード
	int bclmt[9],aclmt[9];//キャンセル注文流入量

	long int mkt_i;	//板寄せ時点での出来高
	long int mkt_m;	//買い売りどちらの成行き注文か判断できないものを格納する

	long int allgbv, allgav;	//その時の全気配量(overを含む)
	long int allblmt, allalmt;	//その時の全指値注文量
	long int allbclmt, allaclmt;	//その時の全キャンセル量


}table;

table t[CSV_MAX];

int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
 
    output = fopen("result.csv", "w");
    fclose(output);
 
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2;
    int ban;
    char f_fullname_new[64]="new/";
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char temp[100];
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int y,buyy,selly;//約定回数,買/売
    long int y_ryou,buy_y_ryou,sell_y_ryou,itayose_y_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数

	char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
	int amari,counthh,countmm;/*時刻読み込み用*/
	c = 0;  i = 0;  // ban = 0;  counthh = 0;  countmm = 0;  amari=0;
	f_num=0;

	if ((fp = fopen("list.csv", "r")) == NULL) {
		printf("list file can't open!!\n");
		exit(EXIT_FAILURE);
	}
	while ((c = getc(fp)) != EOF) {
		if (c == '\n') {
			i=0;
			f_num++;
			continue;
		}
		f_name[f_num][i++] = c;
	}

	fclose(fp);

	for (mn=0; mn<f_num; mn++) {

		hiduke = 0;//ban = 0;

		/*銘柄ごとパラメータ初期化用------------------------------------------------------------------*/
		for(i=0;i<24;i++){
			for(j=0;j<9;j++){
				blmt_flow_ichiji[i][j]=0;	almt_flow_ichiji[i][j]=0;
				blmt_canc_ichiji[i][j]=0;	almt_canc_ichiji[i][j]=0;
				blmt_flow_ave24[i][j]=0;	almt_flow_ave24[i][j]=0;
				blmt_canc_ave24[i][j]=0;	almt_canc_ave24[i][j]=0;
			}
		}
	
		day =0;
		for (y=START_YEAR; y<=STOP_YEAR; y++){
			for (m=1; m<=12; m++){

				for (d=1; d<=31; d++){


					sprintf(temp, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
					printf("%s\n",temp);
					//getchar();
					if ( (fp = fopen(temp, "r")) == NULL )  {	
						continue;
					}
					day = day+1;

/*日ごと変数初期化 ------------------------------------------------------------------------------------------------------------------*/
					for (i = 50; i < CSV_MAX; i++) {
						t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
						t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
						t[i].hh = 0;t[i].mm = 0;
						t[i].b_movement = 0;t[i].a_movement = 0;
						t[i].yakujou = 0;
						t[i].mkt_m = 0; t[i].mkt_i = 0;
						t[i].timesec = 0;
						for (j = 0; j < 8; j++) {
							t[i].gbp[j] = 0;t[i].gap[j] = 0;
							t[i].bbook[j] = 0;t[i].abook[j] = 0;
							t[i].bclmt[j] = 0; t[i].aclmt[j] =0;

							for(k=0;k<100;k++){
								t[i].pxv[k][j]=0;	t[i].dpxv[k][j]=0;
							}
						}
						//デプスはoverの分も表示されるようになったため
						for(j =0; j < 9; j++){
							t[i].gbv[j] =0; t[i].gav[j]=0;
							t[i].blmt[j] =0; t[i].almt[j]=0;
							t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
						}

						t[i].es=0;
						t[i].cpa=0;t[i].cpb=0;
						t[i].esr=0;
						t[i].allgbv=0; t[i].allgav=0;
						t[i].allblmt=0; t[i].allalmt=0;
						t[i].allbclmt=0; t[i].allaclmt=0;
					}
					yakujou = buyyakujou = sellyakujou =0;
					yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
					Lkk00=Lkk01=Lkk02=0;
/* to table from file ------------------------------------------------------------------------------------------------------------------*/
//それぞれの値を決定する
					i = 0;
					n = 0;
					while ((c = getc(fp)) != EOF) {
						
						if (c == ',') {		/* Kugiri */
							n=n+1;			//date の何列目かをカウントする変数
							if(n == 10){	//秒が読み終えたときに秒を時分に結合する
								t[i].time=t[i].time*100;
								t[i].time=t[i].time+t[i].timesec;
							}
							if(n ==4 ){
								if(t[i].exc==21){
									break;
								}
							}
						}
						else if (c == '\n'){n = 0;i++;}	//1行分読み込んだら初期化
						else {
							switch (n) {
								case 7:
									t[i].time = t[i].time * 10 + (c - '0');		break;
								case 9:
									t[i].timesec = t[i].timesec*10+(c-'0');		break;
								case 0:
									t[i].yakujou = t[i].yakujou * 10 +(c-'0');	break;
								case 11:
									t[i].dpp = t[i].dpp * 10 + (c - '0');	break;
								case 12:
									t[i].xv = t[i].xv*10 + (c - '0');		break;
								case 13:	
									t[i].es = t[i].es * 10 + (c - '0');		break;
								case 3:
									t[i].exc = t[i].exc * 10 + (c - '0');	break;
								case 14:	
									t[i].esr = t[i].esr * 10 + (c - '0');	break;
								default :
									if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
									else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
									else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
									else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
									break;
							}
						}	
					}

					fclose(fp);																									
					row = i;	/*i=CSV_MAX*/

// ------------------------------------------------------------------------------------------------------------------
					for(i = 0; i<1;i++){
						basyo=t[i].exc;
					}
					//成行注文の種類分け,区切りの時間を探す
					for(i = 0; i< row; i++ ) {		
						if ( t[i].yakujou ==1){
							if(t[i].es == 16){			
								t[i].amkt = t[i].xv;
							}else if(t[i].es == 48){	
								t[i].bmkt = t[i].xv;
							}else if(t[i].es == 1){		
								t[i].mkt_i=t[i].xv;
								if(t[i].time<=113000){	
									itayose_time=i;
								}
							}else{						
								t[i].mkt_m=t[i].xv;
							}
							if(t[i].esr >= 0){
								if(t[i].time==150000){
									oohike_time=i+2;
								}
							}
						}
					}
					
//-------------------------------------------------------------------------------
					
					for ( i = 0 ; i < oohike_time ; i++){

		//回数と量を合計
						if(t[i].yakujou == 1){
							yakujou +=1;
							Lkk00=yakujou_ryou;
							yakujou_ryou=Lkk00+t[i].xv;
							if(t[i].es==16){
								sellyakujou +=1;
								Lkk01=sell_yakujou_ryou;
								sell_yakujou_ryou=Lkk01+t[i].xv;
							}
							else if(t[i].es == 48){
								buyyakujou +=1;
								Lkk02=buy_yakujou_ryou;
								buy_yakujou_ryou=Lkk02+t[i].xv;}
							else if(t[i].es == 1){
								itayose_yakujou_ryou += t[i].xv;}
							Lkk00=Lkk01=Lkk02=0;
						}
					}

/*-------------------------------------------------------------------*/
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv");	//ファイルへ出力 
					output = fopen(f_fullname_new,"a");
					if (output == NULL)
					{
						printf ("Error opening file");
						getchar();
						exit (1);
					}
					else
					{	fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
							,
							f_name[mn],y, m/10, m%10, d/10, d%10,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
						);
					}
					fclose (output);					

				}//日ごと
			}//月ごと
		}//年ごと
	}
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#4

投稿記事 by へにっくす » 9年前

No.3のコードで、109~116行目の追加と、165~166行目で変数名の変更をしているようですが、コンパイルエラーになってます。
以下、VS2012 Expressでコンパイルした結果。

コード:

1>------ ビルド開始: プロジェクト: ***, 構成: Debug Win32 ------
1>  .cpp
1>.cpp(111): error C2065: 'blmt_flow_ichiji' : 定義されていない識別子です。
1>.cpp(111): error C2065: 'almt_flow_ichiji' : 定義されていない識別子です。
1>.cpp(112): error C2065: 'blmt_canc_ichiji' : 定義されていない識別子です。
1>.cpp(112): error C2065: 'almt_canc_ichiji' : 定義されていない識別子です。
1>.cpp(113): error C2065: 'blmt_flow_ave24' : 定義されていない識別子です。
1>.cpp(113): error C2065: 'almt_flow_ave24' : 定義されていない識別子です。
1>.cpp(114): error C2065: 'blmt_canc_ave24' : 定義されていない識別子です。
1>.cpp(114): error C2065: 'almt_canc_ave24' : 定義されていない識別子です。
1>.cpp(165): error C2065: 'yakujou' : 定義されていない識別子です。
1>.cpp(165): error C2065: 'buyyakujou' : 定義されていない識別子です。
1>.cpp(165): error C2065: 'sellyakujou' : 定義されていない識別子です。
1>.cpp(166): error C2065: 'yakujou_ryou' : 定義されていない識別子です。
1>.cpp(166): error C2065: 'buy_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(166): error C2065: 'sell_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(166): error C2065: 'itayose_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(251): error C2065: 'yakujou' : 定義されていない識別子です。
1>.cpp(252): error C2065: 'yakujou_ryou' : 定義されていない識別子です。
1>.cpp(253): error C2065: 'yakujou_ryou' : 定義されていない識別子です。
1>.cpp(255): error C2065: 'sellyakujou' : 定義されていない識別子です。
1>.cpp(256): error C2065: 'sell_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(257): error C2065: 'sell_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(260): error C2065: 'buyyakujou' : 定義されていない識別子です。
1>.cpp(261): error C2065: 'buy_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(262): error C2065: 'buy_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(264): error C2065: 'itayose_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'yakujou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'sellyakujou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'buyyakujou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'yakujou_ryou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'sell_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(281): error C2065: 'buy_yakujou_ryou' : 定義されていない識別子です。
1>.cpp(282): error C2065: 'itayose_yakujou_ryou' : 定義されていない識別子です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
コンパイルできないソースは掲示しないでください。最低限の礼儀ですよ。
(コンパイルできない環境なのであれば、前もって書いてください・・・orz)
また、

コード:

#pragma warning(disable:4996)   //警告無効
この追記も行っているようですが、これはやらない方が賢明ですよ。これは単に警告を出さないってだけで、問題を解決したわけじゃないですからね?

さて、本題ですが。
datte123 さんが書きました:関数化というのは例えば、加算するところを関数として作っておいて、その関数に引数を渡して答えだけそこで返すものですよね?今回のコードではどこの部分を関数化した方がいいのでしょうか?例えば回数と量を合計するところとかですか?
全部です。まあ、処理の流れを書いてくれましたが、これに番号を振ってみます。

(1) list.csvから処理したい銘柄コードを読み込む
(2) 読み込んだ銘柄コードのフォルダの中にあるcsvファイルを日付順に開く
(3) 1列目の値をt.yakujouに4列目の値をt.excに…使用する列の値をそれぞれ別の変数に代入する
(4) その日のcsvの最後まで行ったら、まずその日の成行注文全てを買と売に分類する
(5) 区切りとなる時間を探して変数に代入する
(6) 1から最後の行までt.yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
(7) そのファイル(1日)の加算した合計をmarket_canc.csvに出力する
(8) これを1年間分繰り返す

さてここから考えると、まずは(1)だけ関数化できますね
(2)で日付順に開いて、(3)~(7)を行いますので、(3)~(7)を関数化できそうかな?
(8)はどこにかかるのか不明ですが…予測ですが(2)~(7)すべてにかかるのでしょうか。

上記で間違いないのであれば、(1)と(3)~(7)、2つの関数をまず作るべきですね。
そして、同じような処理があれば、さらに関数化するのです。
個人的には一つの関数が100行以上になっているのは何かしら冗長な部分が必ずあると思っています。
まあでもその前に、肝心のコードには、その処理の流れに関するコメントを記載してくれていないので、
今度はコードに上記の番号で構いませんので処理の流れのコメントを追加してくれませんか。
tableのコメントは素晴らしいのに・・・処理の流れを書かないなんて変ですよ。

コード:

// (1) list.csvから処理したい銘柄コードを読み込む START
 ;
// (1) list.csvから処理したい銘柄コードを読み込む END
// (2) 読み込んだ・・・
という感じに。それが終わったら、ソースを掲示してください。
そのあとに関数化に挑戦しましょう。
※もちろん処理の流れとコードで合っていないと分かったのであれば、直さないといけません。
 これは自分の思ってることと、実際に書いているコードとの検証にもなるので重要なことです。
オフトピック
インデントのそろえるのもやってくれているようですが、不完全です。
たとえコメントでも、インデントはちゃんとそろえてくださいと書いたはずですよ。
(No.3のコードで言うと、133、168、169、218、245、249、269行目ですね。
そもそも関数化ができてれば行頭から書く必要がないのです)
【追記】
datte123 さんが書きました:ファイル読み込みでgetcを使っているのは引き継いだものをそのまま使っているからです。
前にfgetsを使用しようとやってみたのですが、何が原因かわからず、そのままgetcを使っています。
引き継いだソースなのですね。だからとりあえずgetcのままと。
ということは、C言語の標準関数をうまく使えないということですね。
関数化が終わったら、その話に行きましょう。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#5

投稿記事 by datte123 » 9年前

処理の流れをコメントしました。処理がもう一つありましたので(9)としてついかしました。
関数化に関しては下記のようなほんとに基本しかやったことないので、どこを調べたら(1),(3)~(7)ができそうですか?

コード:

#include <stdio.h>

int add( int x, int y ) {
    int z;
    z = x + y;
    return z;
}

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 320
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文*/
    long int amkt; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文*/
    int b_movement; /*買い気配値のTickの移動分*/
    int a_movement; /*売り気配値のTickの移動分*/
    long int bbook[8]; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文の合計*/
    long int abook[8]; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文の合計*/
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
 
    output = fopen("result.csv", "w");
    fclose(output);
 
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
    char f_fullname_new[64]="new/";
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char temp[100];
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;  // ban = 0;  counthh = 0;  countmm = 0;  amari=0;
    f_num=0;
	//(9)(1)~(8)を複数の会社に対して行う
	//(1)list.csvから処理したい証券コード1銘柄を読み込む
    if ((fp = fopen("list.csv", "r")) == NULL) {
        printf("list file can't open!!\n");
        exit(EXIT_FAILURE);
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
 
    fclose(fp);
	//(1)終了
	
    for (mn=0; mn<f_num; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く
                    sprintf(temp, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    printf("%s\n",temp);

                    if ( (fp = fopen(temp, "r")) == NULL )  {   
                        continue;
                    }
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く終了
                    day = day+1;

					//(3)1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する 
                    for (i = 50; i < CSV_MAX; i++) {
                        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
                        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
                        t[i].hh = 0;t[i].mm = 0;
                        t[i].b_movement = 0;t[i].a_movement = 0;
                        t[i].yakujou = 0;
                        t[i].mkt_m = 0; t[i].mkt_i = 0;
                        t[i].timesec = 0;
                        for (j = 0; j < 8; j++) {
                            t[i].gbp[j] = 0;t[i].gap[j] = 0;
                            t[i].bbook[j] = 0;t[i].abook[j] = 0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
                            for(k=0;k<100;k++){
                                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
                            }
                        }
                        //デプスはoverの分も表示されるようになったため
                        for(j =0; j < 9; j++){
                            t[i].gbv[j] =0; t[i].gav[j]=0;
                            t[i].blmt[j] =0; t[i].almt[j]=0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
                        }
 
                        t[i].es=0;
                        t[i].cpa=0;t[i].cpb=0;
                        t[i].esr=0;
                        t[i].allgbv=0; t[i].allgav=0;
                        t[i].allblmt=0; t[i].allalmt=0;
                        t[i].allbclmt=0; t[i].allaclmt=0;
                    }
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;

					
                    i = 0;
                    n = 0;
                    while ((c = getc(fp)) != EOF) {
                        
                        if (c == ',') {     /* Kugiri */
                            n=n+1;          //date の何列目かをカウントする変数
                            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                                t[i].time=t[i].time*100;
                                t[i].time=t[i].time+t[i].timesec;
                            }
                            if(n ==4 ){
                                if(t[i].exc==21){
                                    break;
                                }
                            }
                        }
                        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
                        else {
                            switch (n) {
                                case 7:
                                    t[i].time = t[i].time * 10 + (c - '0');     break;
                                case 9:
                                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                                case 0:
                                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                                case 11:
                                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                                case 12:
                                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                                case 13:    
                                    t[i].es = t[i].es * 10 + (c - '0');     break;
                                case 3:
                                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                                case 14:    
                                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                                default :
                                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                                    break;
                            }
                        }   
                    }
					//(3)1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する 終了
                    fclose(fp);                                                                                                 
                    row = i;    /*i=CSV_MAX*/
 
                    for(i = 0; i<1;i++){
                        basyo=t[i].exc;
                    }
                    //(4)(5) 成行注文の種類分け,区切りの時間を探す------------------------------------------------------
                    for(i = 0; i< row; i++ ) {      
                        if ( t[i].yakujou ==1){
                            if(t[i].es == 16){          
                                t[i].amkt = t[i].xv;
                            }else if(t[i].es == 48){    
                                t[i].bmkt = t[i].xv;
                            }else if(t[i].es == 1){     
                                t[i].mkt_i=t[i].xv;
                                if(t[i].time<=113000){  
                                    itayose_time=i;
                                }
                            }else{                      
                                t[i].mkt_m=t[i].xv;
                            }
                            if(t[i].esr >= 0){
                                if(t[i].time==150000){
                                    oohike_time=i+2;
                                }
                            }
                        }
                    }
                    //(4)(5)終了
					
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する------------------------------------------------------------------------------
                    for ( i = 0 ; i < oohike_time ; i++){
 
                        if(t[i].yakujou == 1){
                            yakujou +=1;
                            Lkk00=yakujou_ryou;
                            yakujou_ryou=Lkk00+t[i].xv;
                            if(t[i].es==16){
                                sellyakujou +=1;
                                Lkk01=sell_yakujou_ryou;
                                sell_yakujou_ryou=Lkk01+t[i].xv;
                            }
                            else if(t[i].es == 48){
                                buyyakujou +=1;
                                Lkk02=buy_yakujou_ryou;
                                buy_yakujou_ryou=Lkk02+t[i].xv;}
                            else if(t[i].es == 1){
                                itayose_yakujou_ryou += t[i].xv;}
                            Lkk00=Lkk01=Lkk02=0;
                        }
                    }
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する 終了
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する--------------------------------------------------------------------------------------
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
                    output = fopen(f_fullname_new,"a");
                    if (output == NULL)
                    {
                        printf ("Error opening file");
                        getchar();
                        exit (1);
                    }
                    else
                    {   fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
                            ,
                            f_name[mn],y, m/10, m%10, d/10, d%10,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
                        );
                    }
                    fclose (output);                    
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する 終了
                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#6

投稿記事 by へにっくす » 9年前

今度はコンパイルエラーになりませんでした。
また、インデントも直されていますね。
(267行目のfprintfが変ですが、まあ許容範囲です ^^;)
ありがとうございます。

では本題。
datte123 さんが書きました:処理の流れをコメントしました。処理がもう一つありましたので(9)としてついかしました。
関数化に関しては下記のようなほんとに基本しかやったことないので、どこを調べたら(1),(3)~(7)ができそうですか?
(9)を増やしたのですね。階層化すると以下のような感じでしょうか。
dixq_net_forum_3_t15541_image_1.png
流れをイメージするとこんな感じ
dixq_net_forum_3_t15541_image_1.png (22.99 KiB) 閲覧数: 12359 回
ちゃんとそれぞれ(1)~(9)に対し、開始と終了がコメントされていますね。okですが、普通は、終了の後はすぐ開始があるものです。
たとえば(2)の終了の後の

コード:

day=day+1;
は何?
こういう処理があると、(1)~(9)の他にまだ別の処理がある!ということになり、NGです。
(4)(5)がいっしょなのも変ですね。いっしょなのであれば、一つにするべきです。
あるいは、(4)と(5)の処理を明確にすべきです。
それを踏まえてもう一度処理の流れを考えてみてください。

それと(1)に対しては、処理として独立してるのは明白なので、
とりあえずこれを関数化しましょうか。
関数化するには、入力/出力/戻り値を考える必要があります。
入力/出力は引数で定義します。
戻り値は関数でreturnするときの値です。
定義の仕方は、

コード:

戻り値の型 関数名(引数)
{
    // なんかの処理
    return 戻り値;
}
の形式で定義します。そういう意味では、main関数もその仲間ですね。
int main()
となっているので
入力:なし
出力:なし
戻り値:int型
となります。
あなたが挙げてくれたadd関数に関して言えば、
入力:int x
入力:int y
出力:なし
戻り値:int型
となります。
入力/出力に関しては、引数の型で表すのでいくつでもよいですが、戻り値の型に関しては一つだけです。
オフトピック
(複数の項目を戻り値の型としたい場合は構造体として1つにした型を返します。
まあこれは入力/出力の型に対しても言えることですが・・・)
さあこれを踏まえて、まず(1)の入力/出力/戻り値を考えてみてください。
そうですね、銘柄のリストを読み込むのですから、meigara_list_readという関数名にしましょうか。
(ほかに分かりやすい関数名があったらそちらでもよいです。適当なreadとかでは駄目ですよ)

(1)~(9)の再考(再考したソースを掲示してくださいね)と、(1)に対する入力/出力/戻り値ができたら、
関数化の修正に入ります。
オフトピック
私がログインする時間帯は朝と夜なので、そのへんはご了承願います。
(来週から平日はそんなに応えられないかもしれないので予めお知らせしておきます・・・)
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#7

投稿記事 by datte123 » 9年前

指摘されたdayの部分については、色々処理を追加していた名残で、消し忘れた部分で今回の処理では全く使っていない部分です。
(今回提示したコードは色々追加していた部分を省いて基本的な処理だけにしたものなので)

(1)の関数化
入力:list.csv
出力:なし?
戻り値:f_name[](銘柄コードが入った配列)
このように考えて、単純に関数化?してみましたが、戻り値が配列なので、これって複数の戻り値ってことですよね?ということはこのままではダメなんですよね?

コード:

char meigara_list_read(char x){
	if((fp = fopen("x","r")) == NULL){
		printf("list file can't open!!\n");
		exit(EXIT_FAILURE);
	}
	while ((c = getc(fp)) != EOF) {
		if(c == '\n'){
			i=0;
			f_num++;
			continue;
		}
		f_name[f_num][i++] = c;
	}
	return f_name[]
}

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文*/
    long int amkt; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文*/
    int b_movement; /*買い気配値のTickの移動分*/
    int a_movement; /*売り気配値のTickの移動分*/
    long int bbook[8]; /*論文(指値注文の執行確率)の定義とは違う = 買い成行注文の合計*/
    long int abook[8]; /*論文(指値注文の執行確率)の定義とは違う = 売り成行注文の合計*/
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
 
    output = fopen("result.csv", "w");
    fclose(output);
 
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
    char f_fullname_new[64]="new/";
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char temp[100];
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	
	//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力
    if ((fp = fopen("list.csv", "r")) == NULL) {
        printf("list file can't open!!\n");
        exit(EXIT_FAILURE);
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
 
    fclose(fp);
	//(1)終了
	//(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<f_num; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く
                    sprintf(temp, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    printf("%s\n",temp);

                    if ( (fp = fopen(temp, "r")) == NULL )  {   
                        continue;
                    }
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く終了
                    //day = day+1;	

					//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する 
                    for (i = 0; i < CSV_MAX; i++) {
                        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
                        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
                        t[i].hh = 0;t[i].mm = 0;
                        t[i].b_movement = 0;t[i].a_movement = 0;
                        t[i].yakujou = 0;
                        t[i].mkt_m = 0; t[i].mkt_i = 0;
                        t[i].timesec = 0;
                        for (j = 0; j < 8; j++) {
                            t[i].gbp[j] = 0;t[i].gap[j] = 0;
                            t[i].bbook[j] = 0;t[i].abook[j] = 0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
                            for(k=0;k<100;k++){
                                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
                            }
                        }
                        //デプスはoverの分も表示されるようになったため
                        for(j =0; j < 9; j++){
                            t[i].gbv[j] =0; t[i].gav[j]=0;
                            t[i].blmt[j] =0; t[i].almt[j]=0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
                        }
 
                        t[i].es=0;
                        t[i].cpa=0;t[i].cpb=0;
                        t[i].esr=0;
                        t[i].allgbv=0; t[i].allgav=0;
                        t[i].allblmt=0; t[i].allalmt=0;
                        t[i].allbclmt=0; t[i].allaclmt=0;
                    }
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;

					
                    i = 0;
                    n = 0;
                    while ((c = getc(fp)) != EOF) {
                        
                        if (c == ',') {     /* Kugiri */
                            n=n+1;          //date の何列目かをカウントする変数
                            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                                t[i].time=t[i].time*100;
                                t[i].time=t[i].time+t[i].timesec;
                            }
                            if(n ==4 ){
                                if(t[i].exc==21){
                                    break;
                                }
                            }
                        }
                        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
                        else {
                            switch (n) {
                                case 7:
                                    t[i].time = t[i].time * 10 + (c - '0');     break;
                                case 9:
                                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                                case 0:
                                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                                case 11:
                                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                                case 12:
                                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                                case 13:    
                                    t[i].es = t[i].es * 10 + (c - '0');     break;
                                case 3:
                                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                                case 14:    
                                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                                default :
                                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                                    break;
                            }
                        }   
                    }
					//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する 
                    fclose(fp);                                                                                                 
                    row = i;    /*i=CSV_MAX*/
					//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
                    for(i = 0; i<1;i++){
                        basyo=t[i].exc;
                    }
					//(4)初めの行のt[i].excの値をbasyoに保存する 終了
                    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
                    for(i = 0; i< row; i++ ) {
						if(t[i].exc != basyo){	//場所が違ったらその日は終了
							break;
						}
                        if ( t[i].yakujou ==1){
                            if(t[i].es == 16){          
                                t[i].amkt = t[i].xv;
                            }else if(t[i].es == 48){    
                                t[i].bmkt = t[i].xv;
                            }else if(t[i].es == 1){     
                                t[i].mkt_i=t[i].xv;
                                if(t[i].time<=113000){  
                                    itayose_time=i;
                                }
                            }else{                      
                                t[i].mkt_m=t[i].xv;
                            }
                            if(t[i].esr >= 0){
                                if(t[i].time==150000){
                                    oohike_time=i+2;
                                }
                            }
                        }
                    }
                    //(5)終了
					
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する------------------------------------------------------------------------------
                    for ( i = 0 ; i < oohike_time ; i++){
 
                        if(t[i].yakujou == 1){
                            yakujou +=1;
                            Lkk00=yakujou_ryou;
                            yakujou_ryou=Lkk00+t[i].xv;
                            if(t[i].es==16){
                                sellyakujou +=1;
                                Lkk01=sell_yakujou_ryou;
                                sell_yakujou_ryou=Lkk01+t[i].xv;
                            }
                            else if(t[i].es == 48){
                                buyyakujou +=1;
                                Lkk02=buy_yakujou_ryou;
                                buy_yakujou_ryou=Lkk02+t[i].xv;}
                            else if(t[i].es == 1){
                                itayose_yakujou_ryou += t[i].xv;}
                            Lkk00=Lkk01=Lkk02=0;
                        }
                    }
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する 終了
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する--------------------------------------------------------------------------------------
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
                    output = fopen(f_fullname_new,"a");
                    if (output == NULL)
                    {
                        printf ("Error opening file");
                        getchar();
                        exit (1);
                    }
                    else
                    {   fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
                            ,
                            f_name[mn],y, m/10, m%10, d/10, d%10,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
                        );
                    }
                    fclose (output);                    
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する 終了
                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 出力ファイルを複数作るには、プログラムの高速化

#8

投稿記事 by softya(ソフト屋) » 9年前

今のコードとは全く別の話ですが、将来的にどうしたいかも考えたほうが良いと思います。
データベースに蓄積して毎日データを加えるのは、その日のデータだけにすれば処理時間は短く出来そうです。
あとデータ出力も薬雲に出さないとか出し方を考慮すれば時間は節約できます。
ただ、今のものに比べると内容が高度になるのと、C言語で作るのは無駄な労力なのでC#など他の言語を選択する必要が出てきます。

【補足】
今のままでもマージ・アルゴリズムを使うとか高速化の方法はあると思いますが現代的ではありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#9

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:指摘されたdayの部分については、色々処理を追加していた名残で、消し忘れた部分で今回の処理では全く使っていない部分です。
(今回提示したコードは色々追加していた部分を省いて基本的な処理だけにしたものなので)
指摘したところがまずかったかな…
(3)の終了のあとの以下2行

コード:

                    fclose(fp);                                                                                                 
                    row = i;    /*i=CSV_MAX*/
も余計ですか?
(2)の後の話だけではなく他のもチェックしてくださいってことですよ。
(4)と(5)はちゃんと分けているのに惜しいなあ。(^^;
datte123 さんが書きました:(1)の関数化
入力:list.csv
出力:なし?
戻り値:f_name[](銘柄コードが入った配列)
このように考えて、単純に関数化?してみましたが、戻り値が配列なので、これって複数の戻り値ってことですよね?ということはこのままではダメなんですよね?

コード:

char meigara_list_read(char x){
	if((fp = fopen("x","r")) == NULL){
		printf("list file can't open!!\n");
		exit(EXIT_FAILURE);
	}
	while ((c = getc(fp)) != EOF) {
		if(c == '\n'){
			i=0;
			f_num++;
			continue;
		}
		f_name[f_num][i++] = c;
	}
	return f_name[]
}
(1)の関数化ですが、私ならこうします。
入力:const char *read_file_name // 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
出力:char f_name[MEIGARA_MAX][64] // 銘柄コードが入った配列(配列は出力の引数として渡せます)
戻り値:int // 0.成功、1.失敗

数学の関数f(x)の話であれば、確かに戻り値は計算の結果を返すものですが、
C言語の関数は考え方が違います。
関数は処理のかたまりなので、処理の結果を戻り値として返すのが普通です。
引数で入力用と出力用、あるいは入出力用の変数が定義できますからね。
銘柄コードが入った配列は出力の引数で定義しましょう。
また関数化する際、その中にexit関数は通常含めません。
なので以下のようなコードになります。

コード:

// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 銘柄コードが入った配列(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64])
{
	FILE *fp;
	int i = 0, c = 0, f_num = 0;

	if ((fp = fopen(read_file_name, "r")) == NULL) {
		printf("list file can't open!!\n");
		return 1; // 失敗。
	}
	while ((c = getc(fp)) != EOF) {
		if (c == '\n') {
			i=0;
			f_num++;
			continue;
		}
		f_name[f_num][i++] = c;
	}
	fclose(fp);
	return 0; // 成功
}
では、この関数をmain関数から呼び出すようにソースを修正してみてください。
それができたら今度は、(3)~(7)の関数化と行きましょう。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#10

投稿記事 by datte123 » 9年前

(1)の関数を呼び出す部分を加えたときに、f_numの最後の値も必要なことがわかり、(1)の関数に少し追加してみました。

(3)~(7)の関数化 (3)~(5)はデータの読み込み,(6),(7)は処理なので分けて考えたいです。(処理の部分は今後追加分析が必要になる可能性があるため)
(3)~(5)の関数
入力:fp //(2)で読み込んだ証券コードのフォルダ内にあるcsvファイル
出力:table t[] (その日のt構造体)
:basyo(t[0].excの値),
:t.amkt,t.bmkt,t.mkt_i //t[]から作る
:itayose_time,oohike_time(区切りの時間)
戻り値:?
(6),(7)の関数
入力:table t[]
出力:yakujou,sellyakujou,buyyakujou//それぞれの約定回数
:yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou//それぞれの約定量
戻り値:?

構造体での出力について、(6),(7)での出力に関する構造体をコードの初めで今までの構造体のように定義してやればいいのでしょうか?

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
    fclose(fp);
	*meigara_kazu = f_num;
    return 0; // 成功
}
//(1)終了
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
 
    output = fopen("result.csv", "w");
    fclose(output);
 
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
    char f_fullname_new[64]="new/";
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char temp[100];
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
	int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了

	//(1)を呼び出す
	meigara_list_read("list.csv",f_name,&meigara_kazu);
	//(1)終了
	//確認用
	printf("%s,%s\n",f_name[0],f_name[1]);
	//ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6503)が代入されていることが確認できた
	
	//(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	printf("%d\n",meigara_kazu);
	
	//(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {

        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く
                    sprintf(temp, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    printf("%s\n",temp);

                    if ( (fp = fopen(temp, "r")) == NULL )  {   
                        continue;
                    }
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを開く終了
                    //day = day+1;	

					//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
                    for (i = 0; i < CSV_MAX; i++) {
                        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
                        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
                        t[i].hh = 0;t[i].mm = 0;
                        t[i].b_movement = 0;t[i].a_movement = 0;
                        t[i].yakujou = 0;
                        t[i].mkt_m = 0; t[i].mkt_i = 0;
                        t[i].timesec = 0;
                        for (j = 0; j < 8; j++) {
                            t[i].gbp[j] = 0;t[i].gap[j] = 0;
                            t[i].bbook[j] = 0;t[i].abook[j] = 0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
                            for(k=0;k<100;k++){
                                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
                            }
                        }
                        //デプスはoverの分も表示されるようになったため
                        for(j =0; j < 9; j++){
                            t[i].gbv[j] =0; t[i].gav[j]=0;
                            t[i].blmt[j] =0; t[i].almt[j]=0;
                            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
                        }
 
                        t[i].es=0;
                        t[i].cpa=0;t[i].cpb=0;
                        t[i].esr=0;
                        t[i].allgbv=0; t[i].allgav=0;
                        t[i].allblmt=0; t[i].allalmt=0;
                        t[i].allbclmt=0; t[i].allaclmt=0;
                    }
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;

					
                    i = 0;
                    n = 0;
                    while ((c = getc(fp)) != EOF) {
                        
                        if (c == ',') {     /* Kugiri */
                            n=n+1;          //date の何列目かをカウントする変数
                            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                                t[i].time=t[i].time*100;
                                t[i].time=t[i].time+t[i].timesec;
                            }
                            if(n ==4 ){
                                if(t[i].exc==21){
                                    break;
                                }
                            }
                        }
                        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
                        else {
                            switch (n) {
                                case 7:
                                    t[i].time = t[i].time * 10 + (c - '0');     break;
                                case 9:
                                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                                case 0:
                                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                                case 11:
                                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                                case 12:
                                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                                case 13:    
                                    t[i].es = t[i].es * 10 + (c - '0');     break;
                                case 3:
                                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                                case 14:    
                                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                                default :
                                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                                    break;
                            }
                        }   
                    }
                    fclose(fp);                                                                                                 
                    row = i;    /*i=CSV_MAX*/
					//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
					//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
                    for(i = 0; i<1;i++){
                        basyo=t[i].exc;
                    }
					//(4)初めの行のt[i].excの値をbasyoに保存する 終了
                    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
                    for(i = 0; i< row; i++ ) {
						if(t[i].exc != basyo){	//場所が違ったらその日は終了
							break;
						}
                        if ( t[i].yakujou ==1){
                            if(t[i].es == 16){          
                                t[i].amkt = t[i].xv;
                            }else if(t[i].es == 48){    
                                t[i].bmkt = t[i].xv;
                            }else if(t[i].es == 1){     
                                t[i].mkt_i=t[i].xv;
                                if(t[i].time<=113000){  
                                    itayose_time=i;
                                }
                            }else{                      
                                t[i].mkt_m=t[i].xv;
                            }
                            if(t[i].esr >= 0){
                                if(t[i].time==150000){
                                    oohike_time=i+2;
                                }
                            }
                        }
                    }
                    //(5)終了
					
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する------------------------------------------------------------------------------
                    for ( i = 0 ; i < oohike_time ; i++){
 
                        if(t[i].yakujou == 1){
                            yakujou +=1;
                            Lkk00=yakujou_ryou;
                            yakujou_ryou=Lkk00+t[i].xv;
                            if(t[i].es==16){
                                sellyakujou +=1;
                                Lkk01=sell_yakujou_ryou;
                                sell_yakujou_ryou=Lkk01+t[i].xv;
                            }
                            else if(t[i].es == 48){
                                buyyakujou +=1;
                                Lkk02=buy_yakujou_ryou;
                                buy_yakujou_ryou=Lkk02+t[i].xv;}
                            else if(t[i].es == 1){
                                itayose_yakujou_ryou += t[i].xv;}
                            Lkk00=Lkk01=Lkk02=0;
                        }
                    }
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する 終了
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する--------------------------------------------------------------------------------------
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
                    output = fopen(f_fullname_new,"a");
                    if (output == NULL)
                    {
                        printf ("Error opening file");
                        getchar();
                        exit (1);
                    }
                    else
                    {   fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
                            ,
                            f_name[mn],y, m/10, m%10, d/10, d%10,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
                        );
                    }
                    fclose (output);                    
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する 終了
                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#11

投稿記事 by へにっくす » 9年前

すみません。またもコンパイルエラーです。

コード:

1>------ ビルド開始: プロジェクト: ***, 構成: Debug Win32 ------
1>  .cpp
1>.cpp(65): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(218) : 'fopen' の宣言を確認してください。
1>.cpp(89): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(218) : 'fopen' の宣言を確認してください。
1>.cpp(155): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\stdio.h(357) : 'sprintf' の宣言を確認してください。
1>.cpp(158): error C2146: 構文エラー : ';' が、識別子 ';' の前に必要です。
1>.cpp(158): error C2065: ';' : 定義されていない識別子です。
1>.cpp(158): error C2143: 構文エラー : ';' が 'if' の前にありません。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
No.10のコードの、156行目に全角の「;」があります。
半角の打ち間違えだと思いますが、何度も言うようにコンパイルできるか確認してから、掲示してください。

さて本題。
datte123 さんが書きました:(1)の関数を呼び出す部分を加えたときに、f_numの最後の値も必要なことがわかり、(1)の関数に少し追加してみました。
OKです。素晴らしい。だいぶやり方が分かってきたようですね。ちゃんと確認のコードも入れてるので検証方法も言うことはありません。
ただ、main関数からの呼び出しで、失敗した後exit関数を呼び出していないですね。
失敗した後はプログラムを終了したいわけでしょう?
以下のように書き換えてください。このようにして処理の結果を判定させないと、戻り値をintにした意味がありません。

コード:

    //(1)を呼び出す
    if (0 != meigara_list_read("list.csv",f_name,&meigara_kazu)) {
		// 0以外(=失敗)したら終了
		exit(EXIT_FAILURE);
	}
    //(1)終了
次の(3)~(7)ですが、
datte123 さんが書きました:(3)~(5)はデータの読み込み,(6),(7)は処理なので分けて考えたいです。(処理の部分は今後追加分析が必要になる可能性があるため)
ということなので、(3)~(5)と(6)(7)に分けましょう。
と行きたいところですが、ちょっと待ってください。

(3)は、ファイルから読み込んでtable t[]に突っ込んでいるのですよね。
で、そのファイルfpは(2)で開いてて(fopen)、(3)でそのfpを閉じている(fclose)。
普通、処理の1単位としてfopen/fcloseはセットでないといけません
(1)を関数化したときもそうなっているでしょう?
なので関数をまたがらせないために(2)側にあるfopenは(3)に移動しましょう。
オフトピック
(2)の内容も、
(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
という感じに書き換えてください。
なので(3)~(5)をあらためて考えると、fopenに指定するファイル名が必要だから、

入力:char *shoken_filename 証券コードのフォルダの中にあるcsvファイル名
出力:table t[CSV_MAX] csvファイルから格納する構造体
出力:int *basyo // t[0].excの値 出力なので*をつけてポインタにする必要がある
出力:t.amkt//t[]から作る
出力:t.bmkt//t[]から作る
出力:t.mkt_i//t[]から作る
出力:long int* itayose_time // 板寄せ時間 出力なので*をつけてポインタにする必要がある
出力:long int* oohike_time // 引け時間 出力なので*をつけてポインタにする必要がある
戻り値:int 0.成功 1.失敗(ファイルオープンに失敗した場合とか)

となります。でもあれ?amkt、bmkt、mkt_iは table t[]から作るし、しかもtableの項目ですよね。
だったらtable tの中に含まれているのでいりません。
また出力のbasyoは(4)(5)で、itayose_timeは(5)で代入だけで、(3)~(5)の範囲に収まります。
basyo、itayose_timeの初期化は(3)の初めに行うようにすればいいだけなのでいらないですね。
t[CSV_MAX]とoohike_timeは(6)で使用してるので、これだけはないといけないですね。

なので

入力:char *shoken_filename 証券コードのフォルダの中にあるcsvファイル名
出力:table t[CSV_MAX] csvファイルから格納する構造体
出力:long int* oohike_time // 引け時間 出力なので*をつけてポインタにする必要がある
戻り値:int 0.成功 1.失敗(ファイルオープンに失敗した場合とか)
となります。

(6)(7)はtable t[]、long int oohike_timeから単純に別の項目へセットしてファイルへ保存している。
これも失敗したら、exit関数を呼び出していますね。ならば(1)と同様、戻り値は成功、失敗を返してもらうようにintにします。
ファイル名は固定のようなので引数にはしないでおきます。
なので、
入力:table t[CSV_MAX] (3)~(5)の関数で得たtable
入力:long int oohike_time // 引け時間
出力:int *yakujou//約定回数 出力なので*をつけてポインタにする必要がある
出力:int *sellyakujou//約定回数 出力なので*をつけてポインタにする必要がある
出力:int *buyyakujou //約定回数 出力なので*をつけてポインタにする必要がある
出力:long int *yakujou_ryou //約定量 出力なので*をつけてポインタにする必要がある
出力:long int *sell_yakujou_ryou //約定量 出力なので*をつけてポインタにする必要がある
出力:long int *buy_yakujou_ryou //約定量 出力なので*をつけてポインタにする必要がある
戻り値:int 0.成功 1.失敗(ファイル出力に失敗した場合とか)
となりますね。しかし出力の引数がやたらとあるな~と思ったら。
(6)(7)以外に使用されないのでは?
(3)で初期化してるけど、それ以外に使用されていませんから。
だったら(6)の初めに初期化でも問題ないはずです。
なら出力いらないよね?

なので再考した結果、これだけになりますね。
入力:table t[CSV_MAX] (3)~(5)の関数で得たtable
入力:long int oohike_time // 引け時間
戻り値:int 0.成功 1.失敗(ファイル出力に失敗した場合とか)
だいぶスッキリしますね。
このように、変数の使用範囲というものも考慮して考えるのが関数化の作業です。

datte123 さんが書きました:構造体での出力について、(6),(7)での出力に関する構造体をコードの初めで今までの構造体のように定義してやればいいのでしょうか?

その通りです。まあ上記のように出力の引数は必要なくなったので、構造体にする必要もなくなったと思いますが。
複数の項目を入力/出力に指定する場合はよくそれ用の構造体を作成します。
struct 適当な名前 {
};
を宣言してやって、その構造体名を使えばよろしい。
たとえば
出力:int *basyo // t[0].excの値 出力なので*をつけてポインタにする必要がある
出力:long int* itayose_time // 板寄せ時間 出力なので*をつけてポインタにする必要がある
出力:long int* oohike_time // 引け時間 出力なので*をつけてポインタにする必要がある
を hogehoge(マジでこんな名前使わないでくださいね 笑) という構造体にするのであれば、

コード:

struct hogehoge {
    int basyo; // 場所
    long int itayose_time; // 板寄せ時間
    long int oohike_time; // 引け時間
};
という感じにして、
出力:struct hogehoge*
とすればいいです。

不明なことはありませんか?
なければ、
(1)のmain関数から呼び出した結果、exitさせる修正と、
(2)と(3)の区切りを変え、(3)~(5)、(6)(7)の関数化の修正をしてください。
もちろん、(3)~(5)と(6)(7)の関数名はそれの処理が分かるような名前にしてくださいね。
(コードを掲示してくださいね)

できたら今度は高速化の話に行きます。

【修正:8/17 10:35】(3)~(5)の出力の引数名を間違ってました。
【修正:8/17 22:34】(6)(7)の入力が一つ足りませんでしたので追加。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#12

投稿記事 by datte123 » 9年前

(3)~(5)の部分だけまずはj関数化してみたのですが、現状から言いますと、動きません。
(1)の関数の時に指摘されたエラーの時の

コード:

exit(EXIT_FAILURE);
を入れてみたら、次の日に進まなかったので以前のコード通りcontinueを使ってみました。

実行してみると「ハンドルされていない例外が発生しました」と出てしまいます。

コード:

#include "stdafx.h"

 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
    fclose(fp);
	*meigara_kazu = f_num;
    return 0; // 成功
}
//(1)終了

//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)	//今回はconstはいらないのか?
{
	FILE *fp;
	int i=0,j=0,k=0,c=0,n=0;
	int basyo =0;
	int row=0;
	int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
	if((fp = fopen(syouken_filename,"r")) == NULL ) {
		return 1;
	}
	//初期化
	for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	
    while ((c = getc(fp)) != EOF) {
                        
        if (c == ',') {     /* Kugiri */
            n=n+1;          //date の何列目かをカウントする変数
            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                t[i].time=t[i].time*100;
                t[i].time=t[i].time+t[i].timesec;
            }
            if(n ==4 ){
                if(t[i].exc==21){
                    break;
                }
            }
        }
        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
        else {
            switch (n) {
                case 7:
                    t[i].time = t[i].time * 10 + (c - '0');     break;
                case 9:
                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                case 0:
                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                case 11:
                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                case 12:
                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                case 13:    
                    t[i].es = t[i].es * 10 + (c - '0');     break;
                case 3:
                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                case 14:    
                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                default :
                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                    break;
            }
        }   
    }
    fclose(fp);                                                                                                 
    row = i;    /*i=CSV_MAX*/
	//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
	//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	//(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
		if(t[i].exc != basyo){	//場所が違ったらその日は終了
			break;
		}
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
 
    output = fopen("result.csv", "w");
    fclose(output);
 
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
    char f_fullname_new[64]="new/";
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
	int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了

	//(1)を呼び出す
	if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
		//0以外(失敗)したら終了
		exit(EXIT_FAILURE);
	}
	meigara_list_read("list.csv",f_name,&meigara_kazu);
	//(1)終了
	//確認用
	printf("%s,%s\n",f_name[0],f_name[1]);
	//ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6503)が代入されていることが確認できた
	
	//(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	printf("%d\n",meigara_kazu);
	
	//(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {

        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
					itayose_time=oohike_time=0;
					yakujou = buyyakujou = sellyakujou =0;
					yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
					Lkk00=Lkk01=Lkk02=0;

					//(3)~(5)関数呼び出し
					if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
						continue;
					}
					table_syutoku(syouken_filename,t,&oohike_time,&itayose_time);
					//(3)~(5)終了
					//確認用
					printf("%d,%Ld,%Ld\n",t[50].yakujou,oohike_time,itayose_time);
					
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する------------------------------------------------------------------------------
                    for ( i = itayose_time ; i < oohike_time ; i++){
 
                        if(t[i].yakujou == 1){
                            yakujou +=1;
                            Lkk00=yakujou_ryou;
                            yakujou_ryou=Lkk00+t[i].xv;
                            if(t[i].es==16){
                                sellyakujou +=1;
                                Lkk01=sell_yakujou_ryou;
                                sell_yakujou_ryou=Lkk01+t[i].xv;
                            }
                            else if(t[i].es == 48){
                                buyyakujou +=1;
                                Lkk02=buy_yakujou_ryou;
                                buy_yakujou_ryou=Lkk02+t[i].xv;}
                            else if(t[i].es == 1){
                                itayose_yakujou_ryou += t[i].xv;}
                            Lkk00=Lkk01=Lkk02=0;
                        }
                    }
					//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する 終了
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する--------------------------------------------------------------------------------------
					sprintf(f_fullname_new, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
                    output = fopen(f_fullname_new,"a");
                    if (output == NULL)
                    {
                        printf ("Error opening file");
                        getchar();
                        exit (1);
                    }
                    else
                    {   fprintf(output, "%s,%d%d%d%d%d,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
                            ,
                            f_name[mn],y, m/10, m%10, d/10, d%10,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
                        );
                    }
                    fclose (output);                    
					//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する 終了
                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#13

投稿記事 by へにっくす » 9年前

ざっと気になったところは、No.12のコードの、300行目と303行目で同じ関数を呼んでるのはなぜかってところですね・・・1回呼べばすみますよね?
また、92行目で、「今回はconstはいらないのか?」とコメントに記述していますが、もちろん入力で書き換えたらまずいものに対しては、constをつけるべきですよ。
一応関数化に関しては、言うところがもうないです。あとは1関数100行以内に収まるように、細分化するぐらいでしょうか。

ただ、例外で落ちているのはちょっとまずいですね。
どこで落ちているのか特定してみてください。

高速化はそのあとですね。
オフトピック
平日なので、朝と夜、ざっとしか見れないのでご了承願います。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#14

投稿記事 by datte123 » 9年前

例外で落ちているというのはどういう意味でしょうか?

(3)~(5)のところでエラーとなる所を言っているのでしたら、その場合というのは、開こうとしている日が取引日ではない場合です
このコードは2012年の1月1日から順にその名前のcsvを開くようにしていて、そのファイルが無かったら、次の日のものを開くようにしています。

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#15

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:例外で落ちているというのはどういう意味でしょうか?
以下のことを言ってます。
datte123 さんが書きました:(3)~(5)の部分だけまずはj関数化してみたのですが、現状から言いますと、動きません。
実行してみると「ハンドルされていない例外が発生しました」と出てしまいます。
例外で落ちてるんじゃないのですか?動きませんと書かれてますよね?
それを直したということなら私の勘違いです。すみません。


ではtable_syutokuを2回呼んでるのを直してから、
次は(6)(7)を関数化しましょう。
そのあとですね高速化は。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#16

投稿記事 by datte123 » 9年前

まだ直せていません。
エラーが出たときにvisual studioでデバックしてみたら、159行目に→が表示され止まりました。(下に載せた部分)

コード:

                   t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#17

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:まだ直せていません。
エラーが出たときにvisual studioでデバックしてみたら、159行目に→が表示され止まりました。(下に載せた部分)

コード:

                   t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
tのiはどんな値になってるか確認しましたか?
初期化した後、iをそのままにしてますよね?
Visual Studioを使用しているなら、変数ウィンドウを使って確認してみてください。
オフトピック
これぐらいは自力で直してほしいなあ (^^;
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#18

投稿記事 by datte123 » 9年前

(3)~(5)の関数の問題点は解決しました
(6)(7)を関数化してみたのですが、実行してみると(3)~(5)の時と同様に動かなくて、
今度は output.cという知らないcファイルが開き、

コード:

#else  /* _UNICODE */
                if (flags & (FL_LONG|FL_WIDECHAR)) {
                    if (text.wz == NULL) /* NULL passed, use special string */
                        text.wz = __wnullstring;
                    bufferiswide = 1;
                    pwch = text.wz;
                    while ( i-- && *pwch )
                        ++pwch;
                    textlen = (int)(pwch - text.wz);
                    /* textlen now contains length in wide chars */
                } else {
                    if (text.sz == NULL) /* NULL passed, use special string */
                        text.sz = __nullstring;
                    p = text.sz;
                    while (i-- && *p)
                        ++p;
                    textlen = (int)(p - text.sz);    /* length of the string */
                }
その中のこの部分の,下記のところに→が表示されます

コード:

while (i-- && *p)

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
    fclose(fp);
	*meigara_kazu = f_num;
    return 0; // 成功
}
//(1)終了

//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
	FILE *fp;
	int i=0,j=0,k=0,c=0,n=0;
	int basyo =0;
	int row=0;
	if((fp = fopen(syouken_filename,"r")) == NULL ) {
		return 1;
	}
	//printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
	//初期化
	for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	i = 0;
	n = 0;

    while ((c = getc(fp)) != EOF) {
                        
        if (c == ',') {     /* Kugiri */
            n=n+1;          //date の何列目かをカウントする変数
            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                t[i].time=t[i].time*100;
                t[i].time=t[i].time+t[i].timesec;
            }
            if(n ==4 ){
                if(t[i].exc==21){
                    break;
                }
            }
        }
        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
        else {
            switch (n) {
                case 7:
                    t[i].time = t[i].time * 10 + (c - '0');     break;
                case 9:
                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                case 0:
                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                case 11:
                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                case 12:
                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                case 13:    
                    t[i].es = t[i].es * 10 + (c - '0');     break;
                case 3:
                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                case 14:    
                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                default :
                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                    break;
            }
        }   
    }
    fclose(fp);                                                                                                 
    row = i;    /*i=CSV_MAX*/
	//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
	//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	//(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
		if(t[i].exc != basyo){	//場所が違ったらその日は終了
			break;
		}
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
	return 0;
}

//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
	int i;
	int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
	char syuturyoku_fullname[64]="new/";
	FILE *output;
	output = fopen("result.csv", "w");
    fclose(output);
	for ( i = *itayose_time ; i < *oohike_time ; i++){
 		if(t[i].yakujou == 1){
			yakujou +=1;
			Lkk00=yakujou_ryou;
			yakujou_ryou=Lkk00+t[i].xv;
			if(t[i].es==16){
				sellyakujou +=1;
				Lkk01=sell_yakujou_ryou;
				sell_yakujou_ryou=Lkk01+t[i].xv;
			}
			else if(t[i].es == 48){
				buyyakujou +=1;
				Lkk02=buy_yakujou_ryou;
				buy_yakujou_ryou=Lkk02+t[i].xv;}
			else if(t[i].es == 1){
				itayose_yakujou_ryou += t[i].xv;}
			Lkk00=Lkk01=Lkk02=0;
		}
	}

	sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            *syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
	fclose (output);

	return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;

 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
	char syoukencode[10];
	char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
	int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了

	//(1)を呼び出す
	if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
		//0以外(失敗)したら終了
		exit(EXIT_FAILURE);
	}
	//(1)終了
	//確認用
	printf("%s,%s\n",f_name[0],f_name[1]);
	//ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
	
	//(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	printf("%d\n",meigara_kazu);
	
	//(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {

        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
					sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
					sprintf(syoukencode,"%s", f_name[mn]);
					printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
					itayose_time=oohike_time=0;
					yakujou = buyyakujou = sellyakujou =0;
					yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
					Lkk00=Lkk01=Lkk02=0;

					//(3)~(5)関数呼び出し
					if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
						continue;
					}
					//(3)~(5)終了
					//確認用
					//printf("%d,%Ld,%Ld\n",t[50].yakujou,oohike_time,itayose_time);
					//(6),(7)関数呼び出し
					if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
						continue;
					}

                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#19

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:(3)~(5)の関数の問題点は解決しました
(6)(7)を関数化してみたのですが、実行してみると(3)~(5)の時と同様に動かなくて、
今度は output.cという知らないcファイルが開き
あーこれは、ライブラリの中で落ちた場合ですね。

こういうときは、呼び出し階層のウィンドウを表示してみてください。
ブレークした状態で、表示メニューの「呼び出し階層」を選択すると出てきます。
参考)呼び出し階層
最初にマスターしたいVisual Studioのデバッグ機能 - 応用編 2.呼び出し履歴ウィンドウ/ビジュアライザ

これで上から順に見ていき、自分のソースのどこで止まっているかを確認してみてください。
(6)(7)を関数化して出たんですから、yakujou_countのどこかで止まってるはずですよ。
(もちろん原因がわかったら直してください)
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#20

投稿記事 by datte123 » 9年前

直りました。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while ((c = getc(fp)) != EOF) {
        if (c == '\n') {
            i=0;
            f_num++;
            continue;
        }
        f_name[f_num][i++] = c;
    }
    fclose(fp);
	*meigara_kazu = f_num;
    return 0; // 成功
}
//(1)終了

//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
	FILE *fp;
	int i=0,j=0,k=0,c=0,n=0;
	int basyo =0;
	int row=0;
	if((fp = fopen(syouken_filename,"r")) == NULL ) {
		return 1;
	}
	//printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
	//初期化
	for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	i = 0;
	n = 0;

    while ((c = getc(fp)) != EOF) {
                        
        if (c == ',') {     /* Kugiri */
            n=n+1;          //date の何列目かをカウントする変数
            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                t[i].time=t[i].time*100;
                t[i].time=t[i].time+t[i].timesec;
            }
            if(n ==4 ){
                if(t[i].exc==21){
                    break;
                }
            }
        }
        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
        else {
            switch (n) {
                case 7:
                    t[i].time = t[i].time * 10 + (c - '0');     break;
                case 9:
                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                case 0:
                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                case 11:
                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                case 12:
                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                case 13:    
                    t[i].es = t[i].es * 10 + (c - '0');     break;
                case 3:
                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                case 14:    
                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                default :
                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                    break;
            }
        }   
    }
    fclose(fp);                                                                                                 
    row = i;    /*i=CSV_MAX*/
	//(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
	//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	//(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
		if(t[i].exc != basyo){	//場所が違ったらその日は終了
			break;
		}
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
	return 0;
}

//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
	int i;
	int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
	char syuturyoku_fullname[64]="new/";
	FILE *output;
	output = fopen("result.csv", "w");
    fclose(output);
	for ( i = *itayose_time ; i < *oohike_time ; i++){
 		if(t[i].yakujou == 1){
			yakujou +=1;
			Lkk00=yakujou_ryou;
			yakujou_ryou=Lkk00+t[i].xv;
			if(t[i].es==16){
				sellyakujou +=1;
				Lkk01=sell_yakujou_ryou;
				sell_yakujou_ryou=Lkk01+t[i].xv;
			}
			else if(t[i].es == 48){
				buyyakujou +=1;
				Lkk02=buy_yakujou_ryou;
				buy_yakujou_ryou=Lkk02+t[i].xv;}
			else if(t[i].es == 1){
				itayose_yakujou_ryou += t[i].xv;}
			Lkk00=Lkk01=Lkk02=0;
		}
	}

	sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
	fclose (output);

	return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;

 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
	char syoukencode[10];
	char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
	int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了

	//(1)を呼び出す
	if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
		//0以外(失敗)したら終了
		exit(EXIT_FAILURE);
	}
	//(1)終了
	//確認用
	printf("%s,%s\n",f_name[0],f_name[1]);
	//ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
	
	//(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	printf("%d\n",meigara_kazu);
	
	//(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {

        hiduke = 0;//ban = 0;
        day =0;
		//(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
 					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
					sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
					sprintf(syoukencode,"%s", f_name[mn]);
					printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
					//(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
					itayose_time=oohike_time=0;
					yakujou = buyyakujou = sellyakujou =0;
					yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
					Lkk00=Lkk01=Lkk02=0;

					//(3)~(5)関数呼び出し
					if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
						continue;
					}
					//(3)~(5)終了
					//確認用
					//printf("%d,%Ld,%Ld\n",t[50].yakujou,oohike_time,itayose_time);
					//(6),(7)関数呼び出し
					if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
						continue;
					}

                }//日ごと
            }//月ごと
        }//年ごと
		//(8) 1年間分繰り返す 終了
    }
	//(9) (1)~(8)を複数の会社に対して行う 終了

}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#21

投稿記事 by へにっくす » 9年前

OKです。どこで落ちてるか、分かったようですね。

では、高速化と行きましょう。
まずは、getcで一文字ずつ読んでいるのをどうにかしましょう。
ファイルアクセスするのはなるべく少なくするべきです。
一文字ずつ読むより、一行ずつ読むほうが早いです。
一行ずつ読むより、ファイルサイズ分一気に読んで、文字列を加工する方が早いです。

たとえば
関数meigara_list_readなんかは、一行ずつ読みこんでf_nameに格納してるんですよね。
この部分を、fscanfか、fgetsか、freadかどれでもいいので、getc以外の処理にしてみてください・・・
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#22

投稿記事 by datte123 » 9年前

まずはmeigara_list_readだけやってみました。

table_syutokuにも同じようにやろうと思ったのですが、必要な列のみそれぞれ別の変数に代入する方法がよくわからないのです。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
 
typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while ((c = fscanf(fp,"%s",f_name[f_num])) != EOF) {
		f_num++;
    }
    fclose(fp);
    *meigara_kazu = f_num;
    return 0; // 成功
}
//(1)終了
 
//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    int row=0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
    i = 0;
    n = 0;
 
    while ((c = getc(fp)) != EOF) {
                        
        if (c == ',') {     /* Kugiri */
            n=n+1;          //date の何列目かをカウントする変数
            if(n == 10){    //秒が読み終えたときに秒を時分に結合する
                t[i].time=t[i].time*100;
                t[i].time=t[i].time+t[i].timesec;
            }
            if(n ==4 ){
                if(t[i].exc==21){
                    break;
                }
            }
        }
        else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
        else {
            switch (n) {
                case 7:
                    t[i].time = t[i].time * 10 + (c - '0');     break;
                case 9:
                    t[i].timesec = t[i].timesec*10+(c-'0');     break;
                case 0:
                    t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
                case 11:
                    t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
                case 12:
                    t[i].xv = t[i].xv*10 + (c - '0');       break;
                case 13:    
                    t[i].es = t[i].es * 10 + (c - '0');     break;
                case 3:
                    t[i].exc = t[i].exc * 10 + (c - '0');   break;
                case 14:    
                    t[i].esr = t[i].esr * 10 + (c - '0');   break;
                default :
                    if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
                    else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
                    else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
                    else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
                    break;
            }
        }   
    }
    fclose(fp);                                                                                                 
    row = i;    /*i=CSV_MAX*/
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);
    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
 
    sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
 
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
    int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
    
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了
 
    //(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
    printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
                    printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
                        continue;
                    }
                    //(3)~(5)終了
                    //確認用
                    //printf("%d,%Ld,%Ld\n",t[50].yakujou,oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#23

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:まずはmeigara_list_readだけやってみました。
以下ですね。

コード:

    while ((c = fscanf(fp,"%s",f_name[f_num])) != EOF) {
        f_num++;
    }
動作上問題ないのでたぶんokですが、
cは代入だけで使ってませんね。
私なら、以下のように一行にします。

コード:

while (fscanf(fp,"%s",f_name[f_num++]) != EOF);
本当は上記ですと空行がまじった場合とかが不安ですが、それはないとみなしてよいのですよね・・・
datte123 さんが書きました:table_syutokuにも同じようにやろうと思ったのですが、必要な列のみそれぞれ別の変数に代入する方法がよくわからないのです。
さてあなたが懸念する必要な列のみそれぞれ別の変数に代入する方法ですが
まずはどんな書式になるのか示してください。
たとえば、こんな感じ?

コード:

列番(n)、格納する項目
0, t[i].yakujou
3, t[i].exc
16~23, t[i].gap[0]~t[i].gap[7]
無視する列番があるのかと、最大の列数を確認したいのです。
また、一行につき、t 一つぶんと見なしていいのですよね?
それが分かってから、どのような処理にできるかを示したいと思います。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#24

投稿記事 by datte123 » 9年前

csvファイルの列番号,格納する項目
1 t.yakujou
4 t.exc
9 t.esr
8 t.time
10 t.timesec
12 t.dpp
13 t.xv
14 t.es
17~24 t.gap[0]~t.gap[7]
28~35 t[i].gbp[0]~t[i].gbp[7]
39~47 t[i].gav[0]~t[i].gav[8]
50~58 t[i].gbv[0]~t[i].gbv[8]

最大104列です
行によっては最大までない行もあります
t[i].time+t[i].timesecを後で行います
(何時何分+何秒)

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#25

投稿記事 by へにっくす » 9年前

順番通りでないのでちと整理。

1 int t.yakujou
4 int t.exc
8 int t.time
9 int t.esr
10 int t.timesec
12 double t.dpp
13 long t.xv
14 int t.es
17~24 int t.gap[0]~t.gap[7]
28~35 int t[i].gbp[0]~t[i].gbp[7]
39~47 long int t[i].gav[0]~t[i].gav[8]
50~58 long int t[i].gbv[0]~t[i].gbv[8]

無視する列がありますね。
しかも列数が最大104列とな。
こりゃー、一行ずつ読みこんで、文字列を加工した方がいいね。

とゆーわけで、
カンマ区切りの文字列から文字列の配列にする処理を考えました。
参考にしたのはここですが、このソースで使用しているstrtokは「1,,3」となってるときに「1」「3」の2つとして認識するので、それでは駄目なのです。
なので、ちゃんと「1」「」「3」と認識するようにsplit関数を作ってみました。

コード:

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#define MAXITEM 20

// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
	char *tk, *next = NULL;
	int  cnt = 0;

	for(tk = str, cnt = 0; cnt < countmax;){
		next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
		outlist[cnt++] = tk;
		if ( NULL != next ) {
			*next = '\0';
			tk = next + 1;
		} else {
			break;
		}
	}
	return cnt;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char    memostr[1024] = "1,2,3,4,,6,7,8,9,,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,,104";
	char    *shoppinglst[MAXITEM] = {0};
	int     i, cnt;

	printf( "memostr = '%s'\n", memostr );
	cnt = split( memostr, "," , shoppinglst, MAXITEM );
	printf( "split実行後:memostr = '%s'\n", memostr );
	for( i = 0; i < cnt; i++ ) {
		printf( "%d:%s\n", i+1, shoppinglst[i] );
	}
	return 0;
}
上記の実行結果:

コード:

> sample.exe
memostr = '1,2,3,4,,6,7,8,9,,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,,104'
split実行後:memostr = '1'
1:1
2:2
3:3
4:4
5:
6:6
7:7
8:8
9:9
10:
11:11
12:12
13:13
14:14
15:15
16:16
17:17
18:18
19:19
20:20
>
fscanfで1行読んだら、
このsplit関数を使って、文字列の配列にしてもらいましょう。
あとは、文字列を数値に変換する関数(atoi、atof、strtol、strtodなど)を使って各項目に代入ですね。

さあ、split関数を使って修正してみてください。
【8/29 05:30編集】 split関数を修正。(strpbrk呼び出しの場所を変えました)
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#26

投稿記事 by datte123 » 9年前

参考に修正してみたんですが、これを実行してみると、Debug Assertion Fiaed!と表示されました。
File : f:\dd\vctools\ctr_bld\self_x86\crt\src\strtol.c
Line:94
Expresssion:nptr !=NULL

これを検索してみたら,strtol関数の使い方がいけないみたいなんですが、何がいけないかよくわかりません。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了
 
//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    int row=0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	basyo = 0;
    i = 0;
    n = 0;
	
	//高速化試行錯誤
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024] = {0};	//読み込んだcsvをカンマ区切りにする
	int cnt;
	int gyou = 0;
	//char* endptr;
	
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		for(i=0;i<cnt;i++){
			t[i].yakujou = atoi(hituyou_data_t[0]);
			t[i].exc	 = atoi(hituyou_data_t[3]);
			t[i].time	 = atoi(hituyou_data_t[7]);
			t[i].esr	 = atoi(hituyou_data_t[8]);
			t[i].timesec = atoi(hituyou_data_t[9]);
			t[i].dpp	 = atof(hituyou_data_t[11]);
			t[i].xv		 = strtol(hituyou_data_t[12],0,10);
			t[i].es		 = atoi(hituyou_data_t[13]);
			for(j=0;j<8;j++){
				t[i].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[i].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[i].gav[k]	 = strtol(hituyou_data_t[k+38],0,10);
				t[i].gbv[k]	 = strtol(hituyou_data_t[k+49],0,10);
			}
		}
		gyou++;
	}
	
	//確認用
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	//ここから下の部分を高速化する↑
    //while ((c = getc(fp)) != EOF) {
    //                    
    //    if (c == ',') {     /* Kugiri */
    //        n=n+1;          //date の何列目かをカウントする変数
    //        if(n == 10){    //秒が読み終えたときに秒を時分に結合する
    //            t[i].time=t[i].time*100;
    //            t[i].time=t[i].time+t[i].timesec;
    //        }
    //        if(n ==4 ){
    //            if(t[i].exc==21){
    //                break;
    //            }
    //        }
    //    }
    //    else if (c == '\n'){n = 0;i++;} //1行分読み込んだら初期化
    //    else {
    //        switch (n) {
    //            case 7:
    //                t[i].time = t[i].time * 10 + (c - '0');     break;
    //            case 9:
    //                t[i].timesec = t[i].timesec*10+(c-'0');     break;
    //            case 0:
    //                t[i].yakujou = t[i].yakujou * 10 +(c-'0');  break;
    //            case 11:
    //                t[i].dpp = t[i].dpp * 10 + (c - '0');   break;
    //            case 12:
    //                t[i].xv = t[i].xv*10 + (c - '0');       break;
    //            case 13:    
    //                t[i].es = t[i].es * 10 + (c - '0');     break;
    //            case 3:
    //                t[i].exc = t[i].exc * 10 + (c - '0');   break;
    //            case 8:    
    //                t[i].esr = t[i].esr * 10 + (c - '0');   break;
    //            default :
    //                if (n >= 16 && n <= 23) {t[i].gap[n%16] = t[i].gap[n%16]*10 + (c - '0');}
    //                else if (n >= 27 && n <= 34) {t[i].gbp[n%27] = t[i].gbp[n%27]*10 + (c - '0');}
    //                else if (n >= 38 && n <= 46) {t[i].gav[n%38] = t[i].gav[n%38]*10 + (c - '0');}
    //                else if (n >= 49 && n <= 57) {t[i].gbv[n%49] = t[i].gbv[n%49]*10 + (c - '0');}
    //                break;
    //        }
    //    }   
    //}
    fclose(fp);                                                                                                 
    row = gyou;    /*i=CSV_MAX*/
	printf("%d\n",row);
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);
    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
 
    sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
 
 
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
    
 // //(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力 ←この処理を関数化する
 //   if ((fp = fopen("list.csv", "r")) == NULL) {
 //       printf("list file can't open!!\n");
 //       exit(EXIT_FAILURE);
 //   }
 //   while ((c = getc(fp)) != EOF) {
 //       if (c == '\n') {
 //           i=0;
 //           f_num++;
 //           continue;
 //       }
 //       f_name[f_num][i++] = c;
 //   }
 //
 //   fclose(fp);
 // //(1)終了
 
    //(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
    printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=1; m++){
                 for (d=1; d<=4; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
                    printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
                        continue;
                    }
                    //(3)~(5)終了
                    //確認用
                    printf("%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap,oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#27

投稿記事 by へにっくす » 9年前

strtolの第一引数にNULLが入力されていますね。エラーはそのことを示しています。
この場合、どんな条件によってこの第一引数がNULLになっているのかを確認することですね。
落ちた時の変数の内容、その時の読み込んだ行などをブレークポイントなどで止めて確認してください。
オフトピック
落ちた原因とは違いますが、strtolの第二引数が0はおかしいです。NULLにしてください。
ヒント。
一行読んだらsplit関数に渡して文字列の配列にすると書きましたよね?
カンマで区切るんだから、戻り値は格納したの数ですよ。
そこから指定した列番で項目に代入するのだから、その列数(cnt)をforの条件で使うのは間違ってると分かるよね?
tの添え字はほんとにiでいいのですか?gyouじゃないの?また、
datte123 さんが書きました:行によっては最大までない行もあります
上記のように列数は固定じゃないと、自分で言ってますよね?
だから列数によっては、代入できない時もあるはずです。if判定が必要ですよ。

さあ直してみてください。
【編集 8/30 21:45】オフトピック追記
【編集 8/30 22:05】冒頭の指摘とヒントを少し修正。(ごめん。ちょくちょく変更して・・・^^;)
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#28

投稿記事 by datte123 » 9年前

直してみました。
先ほどの実行時のエラーは直りました。
その次に実際に必要なデータが入っているか確認してみたところ、t[].gap,t[]gbp,t[].gav,t[].gbvに想定した値が入っていないことが確認されました。
例えば410とt[1788].gap[0]には入っていてほしかったのですが、1843342という値が入っていました。
何が原因なのでしょうか?
atoi(hituyou_data_t[j+16]);のところに問題があるのではと思い、一時変数(h)を用意して、h=j+16として
atoi(hituyou_data_t[h]);とかやってみましたが直りませんでした。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
	int time_hms;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num-1;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了
 
//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    int row=0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
		t[i].time_hms =0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	basyo = 0;
    i = 0;
    n = 0;
	
	//高速化試行錯誤

	//その1	この
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024];
	for (i=0;i<1024;i++){
		hituyou_data_t[i] = "0";
	}
	int cnt;
	int gyou = 0;
	char *itiji;
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		t[gyou].yakujou = atoi(hituyou_data_t[0]);
		t[gyou].exc	 = atoi(hituyou_data_t[3]);
		t[gyou].time	 = atoi(hituyou_data_t[7]);
		t[gyou].esr	 = atoi(hituyou_data_t[8]);
		t[gyou].timesec = atoi(hituyou_data_t[9]);
		t[gyou].dpp	 = atof(hituyou_data_t[11]);
		t[gyou].xv		 = strtol(hituyou_data_t[12],NULL,10);
		t[gyou].es		 = atoi(hituyou_data_t[13]);
		if(t[gyou].yakujou == 2){
			for(j=0;j<8;j++){
				t[gyou].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[gyou].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[gyou].gav[k]	 = strtol(hituyou_data_t[k+38],NULL,10);
				t[gyou].gbv[k]	 = strtol(hituyou_data_t[k+49],NULL,10);
			}
		}
		t[gyou].time_hms=t[gyou].time*100+t[gyou].timesec;
		gyou++;
	}
	
	//必要データが入っているか確認
	printf("%d,%d,%f,%ld,\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1788].yakujou,  t[1788].gap,t[1788].gbp,t[1788].gav,t[1788].gbv);
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	
    fclose(fp);                                                                                                 
    row = gyou;    /*i=CSV_MAX*/
	printf("%d\n",row);
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);
    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
 
    sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
  
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;

	//(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
    printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=1; m++){
                 for (d=1; d<=4; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
                    printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
                        continue;
                    }
                    //(3)~(5)終了
                    //確認用
                    printf("%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap,oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#29

投稿記事 by へにっくす » 9年前

datte123 さんが書きました:直してみました。
先ほどの実行時のエラーは直りました。
やれば出来るじゃないですか。(^^
datte123 さんが書きました:その次に実際に必要なデータが入っているか確認してみたところ、t[].gap,t[]gbp,t[].gav,t[].gbvに想定した値が入っていないことが確認されました。
例えば410とt[1788].gap[0]には入っていてほしかったのですが、1843342という値が入っていました。
何が原因なのでしょうか?
atoi(hituyou_data_t[j+16]);のところに問題があるのではと思い、一時変数(h)を用意して、h=j+16として
atoi(hituyou_data_t[h]);とかやってみましたが直りませんでした。
【編集:8/31 07:40】原因判明のため書き直し。
確認用のprintfがおかしいですね。

コード:

    printf("%d,%d,%f,%ld,\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1788].yakujou,  t[1788].gap,t[1788].gbp,t[1788].gav,t[1788].gbv);
t[1788].gapは配列ですよね?
配列の内容を出力したいのならば、ちゃんと添え字を指定してください
t[1788].gap[0]と書くべきところを、t[1788].gapと書くと、
配列を格納する場所の値を表示します。その配列の内容を出力したりしません。
オフトピック
プログラムは思った通りには動かない。書いた通りに動くのです。
それを忘れないでください。
ではその確認用のprintfを直したら再度コードを掲示してください。
そしたら私の懸念する点を挙げて終わりです。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#30

投稿記事 by datte123 » 9年前

あ、初歩的なところでしたね。直しました。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
	int time_hms;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num-1;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了
 
//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    int row=0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    for (i = 0; i < CSV_MAX; i++) {
        t[i].time = 0; t[i].zss = 0; t[i].dpp = 0; t[i].xv = 0;
        t[i].bmkt = 0; t[i].amkt = 0;t[i].period = 0;
        t[i].hh = 0;t[i].mm = 0;
        t[i].b_movement = 0;t[i].a_movement = 0;
        t[i].yakujou = 0;
        t[i].mkt_m = 0; t[i].mkt_i = 0;
        t[i].timesec = 0;
		t[i].time_hms =0;
        for (j = 0; j < 8; j++) {
            t[i].gbp[j] = 0;t[i].gap[j] = 0;
            t[i].bbook[j] = 0;t[i].abook[j] = 0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
 
            for(k=0;k<100;k++){
                t[i].pxv[k][j]=0;   t[i].dpxv[k][j]=0;
            }
        }
        //デプスはoverの分も表示されるようになったため
        for(j =0; j < 9; j++){
            t[i].gbv[j] =0; t[i].gav[j]=0;
            t[i].blmt[j] =0; t[i].almt[j]=0;
            t[i].bclmt[j] = 0; t[i].aclmt[j] =0;
        }
 
        t[i].es=0;
        t[i].cpa=0;t[i].cpb=0;
        t[i].esr=0;
        t[i].allgbv=0; t[i].allgav=0;
        t[i].allblmt=0; t[i].allalmt=0;
        t[i].allbclmt=0; t[i].allaclmt=0;
    }
	basyo = 0;
    n = 0;
	
	//高速化試行錯誤

	//その1	この
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024];
	for (i=0;i<1024;i++){
		hituyou_data_t[i] = "0";
	}
	int cnt;
	int gyou = 0;
	char *itiji;
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		t[gyou].yakujou = atoi(hituyou_data_t[0]);
		t[gyou].exc	 = atoi(hituyou_data_t[3]);
		t[gyou].time	 = atoi(hituyou_data_t[7]);
		t[gyou].esr	 = atoi(hituyou_data_t[8]);
		t[gyou].timesec = atoi(hituyou_data_t[9]);
		t[gyou].dpp	 = atof(hituyou_data_t[11]);
		t[gyou].xv		 = strtol(hituyou_data_t[12],NULL,10);
		t[gyou].es		 = atoi(hituyou_data_t[13]);
		if(t[gyou].yakujou == 2){
			for(j=0;j<8;j++){
				t[gyou].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[gyou].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[gyou].gav[k]	 = strtol(hituyou_data_t[k+38],NULL,10);
				t[gyou].gbv[k]	 = strtol(hituyou_data_t[k+49],NULL,10);
			}
		}
		t[gyou].time_hms=t[gyou].time*100+t[gyou].timesec;
		gyou++;
	}
	
	//必要データが入っているか確認
	printf("%d,%d,%f,%ld,\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1788].yakujou,  t[1788].gap[0],t[1788].gbp[0],t[1788].gav[0],t[1788].gbv[0]);
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	
    fclose(fp);                                                                                                 
    row = gyou;    /*i=CSV_MAX*/
	printf("%d\n",row);
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){
            if(t[i].es == 16){          
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);
    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
 
    sprintf(syuturyoku_fullname, "%s%s", "new/", "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}
 
int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, flag, k, j, flag_gap, flag_gbp,hiduke,z,z2,y;
    int ban;
  
    //2013用
    int syou;
    int ctp;
    int ccc; 
    int h, jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari,counthh,countmm;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;

	//(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
    printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=1; m++){
                 for (d=1; d<=4; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
                    printf("%s\n",csv_day);
                    sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
                        continue;
                    }
                    //(3)~(5)終了
                    //確認用
                    printf("%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap,oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#31

投稿記事 by へにっくす » 9年前

OKです。
あとは特に直すべきところはないですね。ある程度の高速化もできているはずです。
最後に気になる点を挙げておきます。

・全体をざっと見る限り、変数名が分かりづらいです。
 table tの項目でgbvとかgavとかなんかの略号のような変数名にするのは、コメントは必須です。
 なぜならば時間が経った後、再度修正しようとなったとき、この変数ってなんだっけ?となる可能性が高いからです。
オフトピック
人は忘れる動物である。笑
・ところどころif(t.es==16)とかif判定している箇所もコメントは必須です。
 なぜならばその値がどういう意味を持っているか傍目には分からないからです。こういうのをマジックナンバーといいます。

・以下のsprintf

コード:

sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
これはこのように置き換えられます。
詳細は、「printf フォーマット指定子」で検索してみてください。

コード:

sprintf(syouken_filename, "%s%s%s%04d%02d%02d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m, d, ".csv");
・0で初期化してる部分ですが、いちいち面倒じゃありません?
私なら、以下の一行で問題がなければそのままにします。

コード:

memset(t, 0, sizeof(table) * CSV_MAX); // table t[CSV_MAX]を全部0で埋める
・一つの関数は100行以内におさまるのが理想です。
 関数化の話で言ったように、100行以上になるのは、どこかしら冗長の部分があるものです。
 その点を踏まえて、さらに細分化に挑戦してみてください。

・未使用の変数はなるべく削除してください。
 コンパイル時に警告が出るのはよくありません。通るからと無視せず、ちゃんと対処することをお勧めします。
 ちなみにNo.30の結果は以下の通り。

コード:

1>------ ビルド開始: プロジェクト: ***, 構成: Debug Win32 ------
1>  .cpp
1>~.cpp(166): warning C4101: 'itiji' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'h' : ローカル変数は 1 度も使われていません。
1>~.cpp(305): warning C4101: 'ban' : ローカル変数は 1 度も使われていません。
1>~.cpp(326): warning C4101: 'counthh' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'flag_gap' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'n' : ローカル変数は 1 度も使われていません。
1>~.cpp(326): warning C4101: 'countmm' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'qq' : ローカル変数は 1 度も使われていません。
1>~.cpp(300): warning C4101: 'fp' : ローカル変数は 1 度も使われていません。
1>~.cpp(308): warning C4101: 'syou' : ローカル変数は 1 度も使われていません。
1>~.cpp(301): warning C4101: 'output' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'flag_gbp' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'row' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'jjj' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'kk' : ローカル変数は 1 度も使われていません。
1>~.cpp(309): warning C4101: 'ctp' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'z2' : ローカル変数は 1 度も使われていません。
1>~.cpp(326): warning C4101: 'amari' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'kkk' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'z' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'k' : ローカル変数は 1 度も使われていません。
1>~.cpp(310): warning C4101: 'ccc' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'flag' : ローカル変数は 1 度も使われていません。
1>~.cpp(311): warning C4101: 'jj' : ローカル変数は 1 度も使われていません。
1>~.cpp(304): warning C4101: 'j' : ローカル変数は 1 度も使われていません。
1>  .vcxproj -> .exe
========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ==========
以上。
あなたの今後の楽しいプログラミングライフをお祈りします。笑
【追記:8/31 09:30】
すみません。もう一つありましたね。
datte123 さんが書きました:今困っているのは、現在のコードだと出力ファイルが1つになってしまうことです。
希望は銘柄コード+文字列.csv(例えば、銘柄コードが6501だとすると、6501_market.csv)のように出力ファイルを銘柄ごとに分けたいのです。
銘柄ごとに出力したいのでした。
でもここまできたら、直すところも分かってきたのではないのでしょうか?
できるところまでやってみてください。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#32

投稿記事 by datte123 » 9年前

この掲示板次のページが存在したのですね。
銘柄ごとの出力はできたのですが、出力されたファイルの内容が希望した内容になっていなくて、どこがいけないのか探している最中なのですが、どうやら、itayose_timeとoohike_timeが関数(6,7)に渡されていないので、処理が全くなされていないようです。
どこがいけないのでしょうか?

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
	int time_hms;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード
    int bclmt[9],aclmt[9];//キャンセル注文流入量
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];

// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num-1;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了
 
//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//戻り値:int 0.成功 1.失敗
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], long int* oohike_time,long int* itayose_time)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    int row=0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    memset(t,0,sizeof(table) * CSV_MAX);	//table t[]を全部0で埋める
	basyo = 0;
    n = 0;
	
	//高速化試行錯誤

	//その1
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024];
	for (i=0;i<1024;i++){
		hituyou_data_t[i] = "0";
	}
	int cnt;
	int gyou = 0;
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		t[gyou].yakujou = atoi(hituyou_data_t[0]);
		t[gyou].exc	 = atoi(hituyou_data_t[3]);
		t[gyou].time	 = atoi(hituyou_data_t[7]);
		t[gyou].esr	 = atoi(hituyou_data_t[8]);
		t[gyou].timesec = atoi(hituyou_data_t[9]);
		t[gyou].dpp	 = atof(hituyou_data_t[11]);
		t[gyou].xv		 = strtol(hituyou_data_t[12],NULL,10);
		t[gyou].es		 = atoi(hituyou_data_t[13]);
		if(t[gyou].yakujou == 2){
			for(j=0;j<8;j++){
				t[gyou].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[gyou].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[gyou].gav[k]	 = strtol(hituyou_data_t[k+38],NULL,10);
				t[gyou].gbv[k]	 = strtol(hituyou_data_t[k+49],NULL,10);
			}
		}
		t[gyou].time_hms=t[gyou].time*100+t[gyou].timesec;
		gyou++;
	}
	
	//必要データが入っているか確認
	printf("%d,%d,%f,%ld,\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1788].yakujou,  t[1788].gap[0],t[1788].gbp[0],t[1788].gav[0],t[1788].gbv[0]);
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	
    fclose(fp);                                                                                                 
    row = gyou;    /*i=CSV_MAX*/
	printf("%d\n",row);
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< row; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){	//約定1,気配2
            if(t[i].es == 16){	//売成行
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    //買成行
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     //寄付き
                t[i].mkt_i=t[i].xv;
                if(t[i].time<=113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;		//その他
            }
            if(t[i].esr >= 0){
                if(t[i].time==150000){
                    *oohike_time=i+2;
                }
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:f_name[mn]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],long int*oohike_time,long int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);

    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
			//確認用
			printf("約定=1");
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
    sprintf(syuturyoku_fullname, "%s%s%s", "new/",syoukencode, "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}


int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, row, k, j,hiduke,z,z2,y;
  
    //2013用
    int syou;
    int jj, kk,qq,jjj,kkk;   
 
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    long int itayose_time;  //板寄せ時間
    long int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;

	//(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
    printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
					printf("%s\n",csv_day);
					sprintf(syouken_filename, "%s%s%s%04d%02d%02d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m, d, ".csv");
					//sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time)){
                        continue;
                    }
                    //(3)~(5)終了
                    //確認用
                    //printf("%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap[0],oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#33

投稿記事 by へにっくす » 9年前

どこがいけないって、、、
代入する値が変なのでしょう?

気になるところと言えば、
table_syutoku関数で代入しているようですが、
代入する時の条件が
itayose_timeが113000以下で、
oohike_timeが150000のとき
になってるみたいだけど?
本当にoohike_timeが150000以下でなくていいのか?

あとはitayose_timeとoohike_timeがlong intなのに、forでまわす変数iがintなのは
どうなの?
また、itayose_timeとoohike_timeの大小関係は常に一定なの?

とかね。
調べる点はこんな感じかな。


デバッグすればすぐ気が付くレベルと思いますが、どうでしょう?
デバッガで確認してみてください。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#34

投稿記事 by datte123 » 9年前

デバックしてみても、デバックの出力には
'market_order.exe': 'D:\tick2012\2014\market_order\Debug\market_order.exe' を読み込みました。シンボルが読み込まれました。
'market_order.exe': 'C:\Windows\SysWOW64\ntdll.dll' を読み込みました。Cannot find or open the PDB file
'market_order.exe': 'C:\Windows\SysWOW64\kernel32.dll' を読み込みました。Cannot find or open the PDB file
'market_order.exe': 'C:\Windows\SysWOW64\KernelBase.dll' を読み込みました。Cannot find or open the PDB file
'market_order.exe': 'C:\Windows\SysWOW64\msvcr100d.dll' を読み込みました。シンボルが読み込まれました。
プログラム '[14252] market_order.exe: ネイティブ' はコード 1 (0x1) で終了しました。
としか表示されないんですが、どうしたらデバックで問題が見つけることができるのでしょうか?

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#35

投稿記事 by へにっくす » 9年前

デバッグすればと言ったのは、適当なところでブレークして、変数の内容をみるとか、呼び出し階層をみるとか、
どんな条件のときにその現象が起こるのかとか、今まで私が教えたことを言っています。
デバッグの出力のことなんて一言も言ってません。
それより、No.33に書いた、調べる点はどうなったのですか。答えてください。
それを報告しないで、別なことを報告しても進みませんよ。

No.33の再掲
へにっくす さんが書きました:代入する時の条件が
itayose_timeが113000以下で、
oohike_timeが150000のとき
になってるみたいだけど?
本当にoohike_timeが150000以下でなくていいのか?
あとはitayose_timeとoohike_timeがlong intなのに、forでまわす変数iがintなのは
どうなの?
また、itayose_timeとoohike_timeの大小関係は常に一定なの?
以下に訂正します。
t.es == 1でかつt.time <= 113000でitayose_timeに、
t.esr >= 0でかつt.time == 150000のときoohike_timeに代入してるみたいだけど?
もしかしてt.time <= 150000のときにoohike_timeに代入するんじゃないの?とか、
またそこ以外代入するところがないみたいだけど。代入されなきゃ、(2)で初期化している0のままなのは分かるよね?
代入する条件をもう一度洗ってください。
オフトピック
・itayose_timeとoohike_timeがlong intなのに、forでまわす変数 i がintなのは
変ですよ。同じ型にしてください。
・(6)(7)の関数のコメントと、引数の名前が合っていませんね。
 ちゃんと修正してください。
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#36

投稿記事 by datte123 » 9年前

oohike_time,itayose_timeの方をint型にしてiと揃えました。
大小関係は必ずitayose_time<oohike_timeです.
itayose_timeは存在しない場合がありますが、その時は0で問題ありません
oohike_timeは必ず存在します
代入する条件を見直したら、解決しました.

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45
#define KUGIRI_30M 10
#define KUGIRI_15M 20

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
	int time_hms;
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード 33 0
    int bclmt[9],aclmt[9];//キャンセル注文流入量
	int syuuryou;//終了レコード  0新規,4システム停止,8一時停止,12中断,16板寄せ,33不連続歩み,64停止解除,128終了(売買高有),160終了(売買高無)
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];



// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num-1;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了

//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//出力:int row//使用するcsvの最後の行
//戻り値:int 0.成功 1.失敗

//新規 table tの項目periodの値を決定
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], int* oohike_time,int* itayose_time,int* row)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    memset(t,0,sizeof(table) * CSV_MAX);	//table t[]を全部0で埋める
	basyo = 0;
    n = 0;
	//高速化試行錯誤

	//その1
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024];
	for (i=0;i<1024;i++){
		hituyou_data_t[i] = "0";
	}
	int cnt;
	int gyou = 0;
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		t[gyou].yakujou = atoi(hituyou_data_t[0]);
		t[gyou].exc	 = atoi(hituyou_data_t[3]);
		t[gyou].time	 = atoi(hituyou_data_t[7]);
		t[gyou].esr	 = atoi(hituyou_data_t[8]);
		t[gyou].timesec = atoi(hituyou_data_t[9]);
		t[gyou].dpp	 = atof(hituyou_data_t[11]);
		t[gyou].xv		 = strtol(hituyou_data_t[12],NULL,10);
		t[gyou].es		 = atoi(hituyou_data_t[13]);
		t[gyou].syuuryou = atoi(hituyou_data_t[14]);
		if(t[gyou].yakujou == 2){
			for(j=0;j<8;j++){
				t[gyou].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[gyou].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[gyou].gav[k]	 = strtol(hituyou_data_t[k+38],NULL,10);
				t[gyou].gbv[k]	 = strtol(hituyou_data_t[k+49],NULL,10);
			}
		}
		t[gyou].time_hms=t[gyou].time*100+t[gyou].timesec;
		gyou++;
	}
	for (i = 0; i < gyou ; i++ ) {
		t[i].hh = t[i].time_hms / 10000;
		t[i].mm = t[i].time_hms % 10000;

			if( t[i].hh == 8 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 21;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 21;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 22;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 22;}
			}
			else if( t[i].hh == 9 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 1;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 2;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 3;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 4;}
			} else if( t[i].hh == 10 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 5;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 6;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 7;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 8;}
			} else if( t[i].hh == 11 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 9;}
				else if ( t[i].mm >= 1500 && t[i].mm <= 3000 ) {t[i].period = 10;}
				else if ( t[i].mm > 3000 && t[i].mm < 4500 ) {t[i].period = 24;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 24;}
			} else if( t[i].hh == 12 ) {
				if( t[i].mm >= 0 && t[i].mm < 500 ) {t[i].period = 24;}
				else if ( t[i].mm >= 0500 && t[i].mm < 3000 ) {t[i].period = 23;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 11;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 12;}
			} else if( t[i].hh == 13 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 13;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 14;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 15;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 16;}
			} else if( t[i].hh == 14 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 17;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 18;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 19;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 20;}
			} else if( t[i].hh == 15){
				if( t[i].mm==0000){t[i].period = 20;}
			}
	}
	
	//必要データが入っているか確認
	printf("%d,%d,%f,%ld,\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1788].yakujou,  t[1788].gap[0],t[1788].gbp[0],t[1788].gav[0],t[1788].gbv[0]);
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	
    fclose(fp);                                                                                                 
    *row = gyou;    /*i=CSV_MAX*/
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< gyou; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){	//約定1,気配2
            if(t[i].es == 16){	//売成行
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    //買成行
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     //寄付き
                t[i].mkt_i=t[i].xv;
                if(t[i].time_hms<113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;		//その他
            }
			if(t[i].time_hms<=150000){
	            if(t[i].syuuryou > 127){
					*oohike_time=i+2;
				}
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:char csv_day;
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],int*oohike_time,int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);

    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
			//確認用
			//printf("約定=1");
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
	
    sprintf(syuturyoku_fullname, "%s%s%s", "new/",syoukencode, "market_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}

//指値注文流入量・回数を調べる
//入力:int oohike_time,itayose_time
//入力:table t[CSV_MAX]
//char syoukencode
//char csv_day
//入力:row	//最後の行
//出力:table tに追加
//戻り値:int 0.成功 1.失敗
int limit_count(table t[CSV_MAX],int*oohike_time,int* itayose_time,const char*syoukencode,const char* csv_day)
{

}



int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, k, j,hiduke,z,z2,y;
    //2013用
    int syou;
    int jj, kk,qq,jjj,kkk;   
	int row;
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    int itayose_time;  //板寄せ時間
    int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	//(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	//printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
					printf("%s\n",csv_day);
					sprintf(syouken_filename, "%s%s%s%04d%02d%02d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m, d, ".csv");
					//sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time,&row)){
                        continue;
                    }
					//確認用
					//printf("行,%d\n",row);
					//printf("大引け,板寄せ%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap[0],oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
 
                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main
最後に編集したユーザー datte123 on 2014年9月01日(月) 22:53 [ 編集 1 回目 ]

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#37

投稿記事 by へにっくす » 9年前

コンパイルエラーです。
何度も言ってるのになあ・・・
いきなりlimit_count関数を追加してますが、なんでreturnがないの。

コード:

1>------ ビルド開始: プロジェクト: ***, 構成: Debug Win32 ------
1>  .cpp
1>~.cpp(339): warning C4101: 'n' : ローカル変数は 1 度も使われていません。
1>~.cpp(342): warning C4101: 'qq' : ローカル変数は 1 度も使われていません。
1>~.cpp(335): warning C4101: 'fp' : ローカル変数は 1 度も使われていません。
1>~.cpp(341): warning C4101: 'syou' : ローカル変数は 1 度も使われていません。
1>~.cpp(336): warning C4101: 'output' : ローカル変数は 1 度も使われていません。
1>~.cpp(342): warning C4101: 'jjj' : ローカル変数は 1 度も使われていません。
1>~.cpp(342): warning C4101: 'kk' : ローカル変数は 1 度も使われていません。
1>~.cpp(339): warning C4101: 'z2' : ローカル変数は 1 度も使われていません。
1>~.cpp(357): warning C4101: 'amari' : ローカル変数は 1 度も使われていません。
1>~.cpp(342): warning C4101: 'kkk' : ローカル変数は 1 度も使われていません。
1>~.cpp(339): warning C4101: 'z' : ローカル変数は 1 度も使われていません。
1>~.cpp(339): warning C4101: 'k' : ローカル変数は 1 度も使われていません。
1>~.cpp(342): warning C4101: 'jj' : ローカル変数は 1 度も使われていません。
1>~.cpp(339): warning C4101: 'j' : ローカル変数は 1 度も使われていません。
1>~.cpp(328): error C4716: 'limit_count' : 値を返さなければいけません
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
datte123 さんが書きました:oohike_time,itayose_timeの方をint型にしてiと揃えました。
大小関係は必ずitayose_time<oohike_timeです.
itayose_timeは存在しない場合がありますが、その時は0で問題ありません
oohike_timeは必ず存在します
代入する条件を見直したら、解決しました.
まあ直ったんなら、このスレの目的は達成ですね。
(銘柄ごとの出力も出来てそうなので)
お疲れ様でした。
解決のチェックを押してくださいね。
さらに質問がある場合は、別トピックにした方がよいと思います。
オフトピック
0500とか0000とかありますが、
C言語では0x~だと16進数、0から始まり数字0~7ですと8進数になります。
なので「0500」は「5 * 8 * 8 + 0 * 8 + 0 = 320」になりますが想定した値ですか?
「0000」は「0」ですけど、C言語としては「0」と書いてほしいですね。
参考)C 言語での 16 進法と 8 進法
written by へにっくす

datte123
記事: 19
登録日時: 9年前

Re: 出力ファイルを複数作るには、プログラムの高速化

#38

投稿記事 by datte123 » 9年前

書きかけの部分を除いたものを乗せようとしたら、失敗してしまったようです。ごめんなさい。
最後に、table t[]の中の中身を使用しようと思って中身を確認していたら、t[].gbv[]の中身が入っていないようなのです。
具体的には(3)~(5)の中で

コード:

	printf("%d,%d,%f,%ld\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1791].yakujou,  t[1791].gap[0],t[1791].gbp[0],t[1791].gav[0],t[1791].gbv[0]);
としている部分で、t[1791].gav[0]までは元のcsvと照らし合わせて、ちゃんとした値が入っているのですが、t[1791].gbv[0]~[8]の値が代入されていません。
一時的に用意した配列hituyou_data_t[]の要素数が足りないのかと思い5000とかにしてみても解決しませんでした。何が原因なのでしょうか?
[tab=30]MAXITEMを増やしたら解決しました。

コード:

#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>     
#include <direct.h>
#include <string.h>
#include <math.h>
 
#define CSV_MAX 500000
#define MEIGARA_MAX 4000
#define START_YEAR 2012
#define STOP_YEAR 2012
#define MA_RANGE 10
#define SMOOTH 0.1
#define START 50
#define DD 300
#define MAXITEM 45
#define KUGIRI_30M 10
#define KUGIRI_15M 20

typedef struct{
    int time;int zss;double dpp;int gbp[8], gap[8];//dpp現値,xv約定高,gbp買気配値,gap売気配値,gbv,買気配量,blmt買指値注文
    long int gbv[9],gav[9],blmt[9],almt[9], xv;
	int time_hms;
	int time_count;	//同一時間内の連番
    double pmin_dpp;double pmax_dpp;double dpmin_dpp; double dpmax_dpp;long int pxv[100][2];long int dpxv[100][2];//pmin_dpp 期間最低約定値 dpmin_dpp 日中最低約定値
    long int bmkt; //買成行注文
    long int amkt; //売成行注文
    int b_movement; //買い気配値のTickの移動分
    int a_movement; //売り気配値のTickの移動分
    long int bbook[8]; //買板の合計(時点ごと)
    long int abook[8]; //売板の合計
    int period; /*時間区切り*/
    long double blmt_prob[8];   /*買い指値注文確率*/
    long double almt_prob[8];
    int hh;int mm;          /*hh=時間(例 09時,14時) mmは分*/
    int yakujou;            //その行が約定のデータor気配データなのかを判別するため 約定=1,気配=2
    int timesec;    //秒用
    int es; //約定種別
    int blmt_canc[9];int almt_canc[9]; //キャンセル
    int cpb;//買い最良気配値の変化用フラグ 1=上昇,2=下落,0=変化なし
    int cpa;//売り最良気配値の変化用フラグ
    int exc;//上場場所
    int esr;//約定レコード 33 0
    int bclmt[9],aclmt[9];//キャンセル注文流入量
	int syuuryou;//終了レコード  0新規,4システム停止,8一時停止,12中断,16板寄せ,33不連続歩み,64停止解除,128終了(売買高有),160終了(売買高無)
 
    long int mkt_i; //板寄せ時点での出来高
    long int mkt_m; //買い売りどちらの成行き注文か判断できないものを格納する
 
    long int allgbv, allgav;    //その時の全気配量(overを含む)
    long int allblmt, allalmt;  //その時の全指値注文量
    long int allbclmt, allaclmt;    //その時の全キャンセル量
 
 
}table;
 
table t[CSV_MAX];



// split関数
// [入出力] char *str 分割する対象の文字列(書き換えるので、constはつけない)
// [入力]   const char *delim 分割文字
// [出力]   char *outlist[] 配列出力用
// [入力]   int countmax    outlistの配列数 (1以上を指定する)
// [戻り値] int 格納した配列の数 (countmaxを超えることはない)
int split( char *str, const char *delim, char *outlist[], int countmax ) {
    char *tk, *next = NULL;
    int  cnt = 0;
 
    for(tk = str, cnt = 0; cnt < countmax;){
        next = strpbrk(tk, delim); // 分割文字検索。なかったらNULLを返す
        outlist[cnt++] = tk;
        if ( NULL != next ) {
            *next = '\0';
            tk = next + 1;
        } else {
            break;
        }
    }
    return cnt;
}
 
//(1)list.csvから処理したい証券コード全て読み込んでf_name[]に入力する関数
// 関数名:meigara_list_read
// 入力:const char *read_file_name 入力ファイル名(文字列を指定するなら、charでなくchar*です。入力専用なので書き換え不可を示すためにconstも付けます)
// 出力:char f_name[MEIGARA_MAX][64] 出力先リスト(配列は出力の引数として渡せます)
// 戻り値:int 0.成功。f_nameにリストが入っている、1.失敗
// f_numの最後の値 == list.csvの最後の行数も出力したいことが分かったため、int* meigara_kazuを追加してみた
int meigara_list_read(const char* read_file_name, char f_name[MEIGARA_MAX][64], int* meigara_kazu )
{
    FILE *fp;
    int i = 0, c = 0, f_num = 0;
 
    if ((fp = fopen(read_file_name, "r")) == NULL) {
        printf("list file can't open!!\n");
        return 1; // 失敗。
    }
    while (fscanf(fp,"%s",f_name[f_num++]) != EOF) {
    }
    fclose(fp);
    *meigara_kazu = f_num-1;	//銘柄数+1になっているようだ
    return 0; // 成功
}
//(1)終了

//(3)~(5)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する,その日のcsvの最後の行まで行ったらその行数をrowに保存する
//(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
//(5)成行注文の種類分け,区切りの時間を探す
//入力:char *syouken_filename 証券コードフォルダの中にあるcsvファイル名(例: 20120105.csv)
//出力:table t[CSV_MAX] csvファイルから格納する構造体
//出力:long int* oohike_time //出力のため*をつけてポインタとする必要がある
//出力:long int* itayose_time //処理によってはループをi=0からではなくittayose_timeからで十分な場合があるのでこの値も使えると思い追加
//出力:int row//使用するcsvの最後の行
//戻り値:int 0.成功 1.失敗

//新規 table tの項目periodの値を決定
int table_syutoku(const char *syouken_filename, table t[CSV_MAX], int* oohike_time,int* itayose_time,int* row)
{
    FILE *fp;
    int i=0,j=0,k=0,c=0,n=0;
    int basyo =0;
    if((fp = fopen(syouken_filename,"r")) == NULL ) {
        return 1;
    }
    //printf("%s,%d\n",syouken_filename,CSV_MAX);//確認用
    //初期化
    memset(t,0,sizeof(table) * CSV_MAX);	//table t[]を全部0で埋める
	basyo = 0;
    n = 0;
	//高速化試行錯誤

	//その1
	char csv_row[CSV_MAX];	//csvを一行ずつ読み込んで一時的に記憶しておくところ
	char *hituyou_data_t[1024];
	for (i=0;i<1024;i++){
		hituyou_data_t[i] = "0";
	}
	int cnt;
	int gyou = 0;
	while (fscanf(fp,"%s",csv_row) != EOF){
		//確認用 1行ずつよんでいる
		//printf("%s\n",csv_row);
		cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
		//printf("split実行後= '%s'\n",csv_row);
		t[gyou].yakujou = atoi(hituyou_data_t[0]);
		t[gyou].exc	 = atoi(hituyou_data_t[3]);
		t[gyou].time	 = atoi(hituyou_data_t[7]);
		t[gyou].esr	 = atoi(hituyou_data_t[8]);
		t[gyou].timesec = atoi(hituyou_data_t[9]);
		t[gyou].time_count = atoi(hituyou_data_t[10]);
		t[gyou].dpp	 = atof(hituyou_data_t[11]);
		t[gyou].xv		 = strtol(hituyou_data_t[12],NULL,10);
		t[gyou].es		 = atoi(hituyou_data_t[13]);
		t[gyou].syuuryou = atoi(hituyou_data_t[14]);
		if(t[gyou].yakujou == 2){
			for(j=0;j<8;j++){
				t[gyou].gap[j]	 = atoi(hituyou_data_t[j+16]);
				t[gyou].gbp[j]	 = atoi(hituyou_data_t[j+27]);
			}
			for(k=0;k<9;k++){
				t[gyou].gav[k]	 = strtol(hituyou_data_t[k+38],NULL,10);
				t[gyou].gbv[k]	 = strtol(hituyou_data_t[k+49],NULL,10);
			}
		}
		t[gyou].time_hms=t[gyou].time*100+t[gyou].timesec;
		gyou++;
	}
	for (i = 0; i < gyou ; i++ ) {
		t[i].hh = t[i].time_hms / 10000;
		t[i].mm = t[i].time_hms % 10000;

			if( t[i].hh == 8 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 21;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 21;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 22;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 22;}
			}
			else if( t[i].hh == 9 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 1;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 2;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 3;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 4;}
			} else if( t[i].hh == 10 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 5;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 6;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 7;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 8;}
			} else if( t[i].hh == 11 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 9;}
				else if ( t[i].mm >= 1500 && t[i].mm <= 3000 ) {t[i].period = 10;}
				else if ( t[i].mm > 3000 && t[i].mm < 4500 ) {t[i].period = 24;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 24;}
			} else if( t[i].hh == 12 ) {
				if( t[i].mm >= 0 && t[i].mm < 500 ) {t[i].period = 24;}
				else if ( t[i].mm >= 0500 && t[i].mm < 3000 ) {t[i].period = 23;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 11;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 12;}
			} else if( t[i].hh == 13 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 13;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 14;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 15;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 16;}
			} else if( t[i].hh == 14 ) {
				if( t[i].mm >= 0 && t[i].mm < 1500 ) {t[i].period = 17;}
				else if ( t[i].mm >= 1500 && t[i].mm < 3000 ) {t[i].period = 18;}
				else if ( t[i].mm >= 3000 && t[i].mm < 4500 ) {t[i].period = 19;}
				else if ( t[i].mm >= 4500 && t[i].mm <= 5900 ) {t[i].period = 20;}
			} else if( t[i].hh == 15){
				if( t[i].mm==0000){t[i].period = 20;}
			}
	}

	//必要データが入っているか確認
	printf("%d,%d,%f,%ld\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1791].yakujou,  t[1791].gap[0],t[1791].gbp[0],t[1791].gav[0],t[1791].gbv[0]);
//	printf("%s\n",csv_row);
//	printf("%s\n%s\n",csv_row[0],csv_row[1]);
	//cnt = split(csv_row,",",hituyou_data_t,MAXITEM);
	//printf("split実行後:csv_row= '%s'\n",csv_row);

	
    fclose(fp);                                                                                                 
    *row = gyou;    /*i=CSV_MAX*/
    //(3)1行目からその日のcsvの最後まで1列目の値をt[i].yakujouに4列目をt[i].excに…使用する列の値をそれぞれ別の変数に代入する ,その日のcsvの最後の行まで行ったらその行数をrowに保存する 終了
    //(4)初めの行のt[i].excの値をbasyoに保存する (1日の処理の終了条件に使用する)
    for(i = 0; i<1;i++){
        basyo=t[i].exc;
    }
	
    //(4)初めの行のt[i].excの値をbasyoに保存する 終了
    //(5)成行注文の種類分け,区切りの時間を探す------------------------------------------------------
    for(i = 0; i< gyou; i++ ) {
        if(t[i].exc != basyo){  //場所が違ったらその日は終了
            break;
        }
        if ( t[i].yakujou ==1){	//約定1,気配2
            if(t[i].es == 16){	//売成行
                t[i].amkt = t[i].xv;
            }else if(t[i].es == 48){    //買成行
                t[i].bmkt = t[i].xv;
            }else if(t[i].es == 1){     //寄付き
                t[i].mkt_i=t[i].xv;
                if(t[i].time_hms<113000){  
                    *itayose_time=i;
                }
            }else{                      
                t[i].mkt_m=t[i].xv;		//その他
            }
			if(t[i].time_hms<=150000){
	            if(t[i].syuuryou > 127){
					*oohike_time=i+2;
				}
            }
        }
    }
    return 0;
}
 
//(6)(7)関数
//(6)最後の行までt[i].yakujouが1の行の約定回数と数量をそれぞれの変数に加算する
//(7)そのファイル(1日分)の加算した合計をmarket_canc,csvに出力する
//入力:char syoukencode;
//入力:char csv_day
//入力:table t[CSV_MAX]
//入力:long int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
int yakujou_count(table t[CSV_MAX],int*oohike_time,int* itayose_time,const char*syoukencode,const char* csv_day)
{
    int i;
    int yakujou = 0, buyyakujou = 0 ,sellyakujou =0;
    long int yakujou_ryou = 0 ,buy_yakujou_ryou = 0 ,sell_yakujou_ryou = 0, itayose_yakujou_ryou =0;
    long int Lkk00 = 0,Lkk01=0,Lkk02=0;
    char syuturyoku_fullname[64]="new/";
    FILE *output;
    output = fopen("result.csv", "w");
    fclose(output);

    for ( i = *itayose_time ; i < *oohike_time ; i++){
        if(t[i].yakujou == 1){
            yakujou +=1;
            Lkk00=yakujou_ryou;
            yakujou_ryou=Lkk00+t[i].xv;
			//確認用
			//printf("約定=1");
            if(t[i].es==16){
                sellyakujou +=1;
                Lkk01=sell_yakujou_ryou;
                sell_yakujou_ryou=Lkk01+t[i].xv;
            }
            else if(t[i].es == 48){
                buyyakujou +=1;
                Lkk02=buy_yakujou_ryou;
                buy_yakujou_ryou=Lkk02+t[i].xv;}
            else if(t[i].es == 1){
                itayose_yakujou_ryou += t[i].xv;}
            Lkk00=Lkk01=Lkk02=0;
        }
    }
	
    sprintf(syuturyoku_fullname, "%s%s%s", "new/",syoukencode, "limit_canc.csv"); //ファイルへ出力 
    output = fopen(syuturyoku_fullname,"a");
    if (output == NULL)
    {
        printf ("Error opening file");
        //getchar();
        return 1;
    }
    else
    {   fprintf(output, "%s,%s,%d,%d,%d,%Ld,%Ld,%Ld,%Ld\n"
            ,
            syoukencode,csv_day,yakujou,sellyakujou,buyyakujou,yakujou_ryou,sell_yakujou_ryou,buy_yakujou_ryou,itayose_yakujou_ryou
        );
    }
    fclose (output);
 
    return 0;
}

//指値注文流入量・回数を調べる
//入力:int oohike_time,itayose_time
//入力:char syoukencode
//入力:char csv_day
//入力:table t[CSV_MAX]
//入力:row	//最後の行
//出力:table t[CSV_MAX]に追加
//戻り値:int 0.成功 1.失敗
int limit_count(table t[CSV_MAX],int*oohike_time,int* itayose_time,const char*syoukencode,const char* csv_day,int* row)
{

	return 0;
}

//成行注文後の指値注文流入量,価格変動を調べる
//入力:char syoukencode;
//入力:csv_day[50]
//入力:table t[CSV_MAX]
//入力:int oohike_time,itayose_time
//戻り値:int 0.成功 1.失敗
//int market_hendou()
//{
//
//}


int main() {
 
    //struct table t[CSV_MAX];
    FILE *fp;
    FILE *output;
  
    long int i;
    int c, n, f_num, m, d, mn, k, j,hiduke,z,z2,y;
    //2013用
    int syou;
    int jj, kk,qq,jjj,kkk;   
	int row;
    char syouken_filename[100];
    char syoukencode[10];
    char csv_day[50];//csvの名前
    int itayose_time;  //板寄せ時間
    int oohike_time;   //引け時間
   // int basyo;      //場所
    int day;//日
    int yakujou,buyyakujou,sellyakujou;//約定回数,買/売
    long int yakujou_ryou,buy_yakujou_ryou,sell_yakujou_ryou,itayose_yakujou_ryou;//約定量,買/売
    long int Lkk00,Lkk01,Lkk02; //一時変数
    int meigara_kazu;
 
    char f_name[MEIGARA_MAX][64] = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
    int amari;/*時刻読み込み用*/
    c = 0;  i = 0;
    f_num=0;
	//(1)を呼び出す
    if(0 != meigara_list_read("list.csv",f_name,&meigara_kazu)){
        //0以外(失敗)したら終了
        exit(EXIT_FAILURE);
    }
    //(1)終了
    //確認用
    printf("%s,%s\n",f_name[0],f_name[1]);
    //ちゃんとf_name[0]にlist.csvの1行1列の値(6501),f_name[1]にlist.csvの2行1列の値(6502)が代入されていることが確認できた
    
    //(1)の関数でf_numの最後の値をmeigara_kazuに代入するようにしたので、その確認用
	//printf("%d\n",meigara_kazu);
    
    //(9)複数の会社に対して(2)~(8)を行う
    for (mn=0; mn<meigara_kazu; mn++) {
 
        hiduke = 0;//ban = 0;
        day =0;
        //(8)1年間分繰り返す
        for (y=START_YEAR; y<=STOP_YEAR; y++){
            for (m=1; m<=12; m++){
                 for (d=1; d<=31; d++){
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する
                    sprintf(csv_day,"%d%d%d%d%d",y, m/10, m%10, d/10, d%10);
                    sprintf(syoukencode,"%s", f_name[mn]);
					printf("%s\n",csv_day);
					sprintf(syouken_filename, "%s%s%s%04d%02d%02d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m, d, ".csv");
					//sprintf(syouken_filename, "%s%s%s%d%d%d%d%d%s","D:\\tick2012\\data\\" , f_name[mn] ,"\\",y, m/10, m%10, d/10, d%10, ".csv");
                    //printf("%s\n",syouken_filename);
                    //(2)読み込んだ証券コードのフォルダの中にあるcsvファイルを読むためにファイル名を構築する 終了
                    //この部分の置き場に困ったが一応ここでいいのかな?関数の中に入れたらうまくいかなかった
                    itayose_time=oohike_time=0;
                    yakujou = buyyakujou = sellyakujou =0;
                    yakujou_ryou = buy_yakujou_ryou = sell_yakujou_ryou = itayose_yakujou_ryou =0;
                    Lkk00=Lkk01=Lkk02=0;
 
                    //(3)~(5)関数呼び出し
                    if(0 != table_syutoku(syouken_filename,t,&oohike_time,&itayose_time,&row)){
                        continue;
                    }
					//確認用
					//printf("行,%d\n",row);
					//printf("大引け,板寄せ%d,%d,%Ld,%Ld\n",t[50].yakujou,t[50].gap[0],oohike_time,itayose_time);
                    //(6),(7)関数呼び出し
                    if(0 != yakujou_count(t,&oohike_time,&itayose_time,syoukencode,csv_day)){
                        continue;
                    }
					//limit_count関数呼び出し
					/*if(0 != limit_count(t,&oohike_time,&itayose_time,syoukencode,csv_day,&row)){
						continue;
					}
					printf("limit流入,%d,%d,%d,%d,%d\n",t[1790].time_count,t[1790].gbp[0],t[1791].blmt[0],t[1791].gbp[0],t[1791].blmt[0]);*/

                }//日ごと
            }//月ごと
        }//年ごと
        //(8) 1年間分繰り返す 終了
    }
    //(9) (1)~(8)を複数の会社に対して行う 終了
 
}//main

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: 出力ファイルを複数作るには、プログラムの高速化

#39

投稿記事 by へにっくす » 9年前

コンパイルokです。やれやれ。
datte123 さんが書きました:書きかけの部分を除いたものを乗せようとしたら、失敗してしまったようです。ごめんなさい。
最後に、table t[]の中の中身を使用しようと思って中身を確認していたら、t[].gbv[]の中身が入っていないようなのです。
具体的には(3)~(5)の中で

コード:

	printf("%d,%d,%f,%ld\n,%d,%d,%d,%ld,%ld\n",t[1787].yakujou,t[1787].time_hms,t[1787].dpp,t[1787].xv,t[1791].yakujou,  t[1791].gap[0],t[1791].gbp[0],t[1791].gav[0],t[1791].gbv[0]);
としている部分で、t[1791].gav[0]までは元のcsvと照らし合わせて、ちゃんとした値が入っているのですが、t[1791].gbv[0]~[8]の値が代入されていません。
一時的に用意した配列hituyou_data_t[]の要素数が足りないのかと思い5000とかにしてみても解決しませんでした。何が原因なのでしょうか?
[tab=30]MAXITEMを増やしたら解決しました。
・・・最終的には問題ないのですよね? 笑
No.24であなたは、
datte123 さんが書きました:50~58 t.gbv[0]~t.gbv[8]

と書いてますよね。MAXITEMが45のままじゃん。
そこに気が付いたようで何より。
最大104列なんだから104でいいと思いますよ?
(splitに指定するcountmaxは最大値です)

あとは使ってない変数など、私の言ったことを念頭に置いて、見やすいコードにしてみてくださいね。
(解決チェックされたようですので、特に返事はいりません)
written by へにっくす

閉鎖

“C言語何でも質問掲示板” へ戻る