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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

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

#31

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

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
登録日時: 11年前

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

#32

投稿記事 by datte123 » 11年前

この掲示板次のページが存在したのですね。
銘柄ごとの出力はできたのですが、出力されたファイルの内容が希望した内容になっていなくて、どこがいけないのか探している最中なのですが、どうやら、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
登録日時: 13年前
住所: 東京都

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

#33

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

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

気になるところと言えば、
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
登録日時: 11年前

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

#34

投稿記事 by datte123 » 11年前

デバックしてみても、デバックの出力には
'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
登録日時: 13年前
住所: 東京都

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

#35

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

デバッグすればと言ったのは、適当なところでブレークして、変数の内容をみるとか、呼び出し階層をみるとか、
どんな条件のときにその現象が起こるのかとか、今まで私が教えたことを言っています。
デバッグの出力のことなんて一言も言ってません。
それより、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
登録日時: 11年前

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

#36

投稿記事 by datte123 » 11年前

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
登録日時: 13年前
住所: 東京都

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

#37

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

コンパイルエラーです。
何度も言ってるのになあ・・・
いきなり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
登録日時: 11年前

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

#38

投稿記事 by datte123 » 11年前

書きかけの部分を除いたものを乗せようとしたら、失敗してしまったようです。ごめんなさい。
最後に、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
登録日時: 13年前
住所: 東京都

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

#39

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

コンパイル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言語何でも質問掲示板” へ戻る