53歳限界プログラマの憂鬱

SU/CAR-ST-APplication-cellsから派生したプログラマのブログ

来訪ありがとうございます
シストレツールを自作してました
自分用の記事が多いのであまり役には立たないブログでした

f:id:sucar:20150414193802p:plain

自作システム詳細目次

10 通常パラメタのヘッダ #include "mt_prm.h" 生成部

追記2018/3/9) 標準フィルター設定を固定し/^X/を削除(別で書き換える方式)

追記2018/2/19) オペコード DEFにUNDEFオプション追加

追記2018/2/18) オペコード  _P_対応

ストラテジーを記述しているcsvファイルをC言語に取り込める形式に変換する部分にはawkを使っている

通常パラメタのヘッダ #include "mt_prm.h" 生成部は

awk/mt_h_2.awk ※suQ2/ではないので注意

    
#!/bin/awk
BEGIN { 
	FS=","
	printf("uint8_t* rule=\"%s\";\n",ARGV[1])
	#
	print "int Xp=50;"
	print "double Xper1=88.0;"
	print "double Xpf1=0.75;"
	print "double Xper2=87.0;"
	print "double Xpf2=1.5;"
	print "double Xper3=87.0;"
	print "double Xpf3=2.3;"
	print "double Xper4=80.0;"
	print "double Xpf4=2.8;"
	print "double Xper5=78.0;"
	print "double Xpf5=3.0;"
	#
	ex_cnt=0
 }
$1=="NK225" {
	print "#define SHIJOU \"./code/codeNK225.cfg\""
	}
$1=="INDEX0" {
	print "#define SHIJOU \"./code/INDEX0.txt\""
	}
$1=="INDEX1" {
	print "#define SHIJOU \"./code/INDEX1.txt\""
	}
$1=="T1" {
	print "#define SHIJOU \"./code/codeT1.cfg\""
	}
$1=="NotT1" {
	print "#define SHIJOU \"./code/codeNotT1.cfg\""
}
$1=="T1NotNK225" {
	print "#define SHIJOU \"./code/codeT1NotNK225.cfg\""
}


$1=="FILTER" {
	print "#define FILTER"
	}

$1=="DAYSON" {
	print "#define DAYSON"
	}
$1=="Yson" {
	print "#define _YSON_"
	}
$1=="Zday" {
	print "#define _ZDAY_"
	}
/^Y/ {
	printf("double %s=%f;\n",$1,$2)
	}
/^Z/ {
	printf("int %s=%d;\n",$1,$2)
	}

/^[abcdefghijkz]/{
		if ($2>$3) {
			printf("double P%s=%f,P%s%s=%f;\n",$1,$2,$1,$1,$3)
		}
		else {
			printf("double P%s=%f,P%s%s=%f;\n",$1,$3,$1,$1,$2)
		}
	}

	
#拡張パラメタ対応
#入れ替え 234->342
$1=="_P" {
		if (ex_cnt==0) printf("#define Ex_para\n")
		ex_cnt++
		if ($2>$3) {
			printf("double P%su=%f,P%sd=%f;\n",$4,$2,$4,$3)
		}
		else {
			printf("double P%su=%f,P%sd=%f;\n",$4,$3,$4,$2)
		}
	}	
#パラメタそのまま
$1=="P" {
		if ($2>$3) {
			printf("double P%su=%f,P%sd=%f;\n",$4,$2,$4,$3)
		}
		else {
			printf("double P%su=%f,P%sd=%f;\n",$4,$3,$4,$2)
		}
	}
#######add 2018/2/18
$1=="_P_" {
		if (ex_cnt==0) printf("#define Ex_para\n")
		ex_cnt++
	}
#########
	
$1=="MAX" {
	printf("#define MAX\n")
	}
$1=="MIM" {
	printf("#define MIN\n")
	}
$1=="BUG" {
	printf("#define BUG\n")
	}
	
$1=="DEF" {
	if ($4=="UNDEF") {printf("#undef %s\n",$2)}
	printf("#define %s %s\n",$2,$3)
}
END {}

 

 

9 パラメタ&ルール適用部分のC言語ソース

追記2018/3/9)mm_0,ml_0追加

追記2018/2/20)  check() calc() 以外の関数をfunction.hへ移動

追記2018/2/19)#define _HEI_P_ #define _HEI_M_ 追加

追記2018/2/18)Heihei25,75,125を先に計算する

最も重要なパラメタ&ルール適用部分のC言語ソース

suQ2/main/mt/mt_rule.c

    
///////////////////////////////////////////////////////////////////////////////
//function.h 共通化
//2015/10/11 パラメタ拡張対応(anaint06と同等)
//2017/2/5 #ifdef _CALC_125_ etc
//         _MAXn_ の定義
//2017/3/19 heikin75()だけ特別 平均を求める
//2018/2/18 ↑特別平均を事前に求める方式に変える
//2018/2/19 #define _HEI_P_ #define _HEI_M_
#define _HEI_P_ 100
#define _HEI_M_ -100
int rsk1[DATAMAX][DATEMAX]; int rsk2[DATAMAX][DATEMAX]; double rsk1d[DATAMAX][DATEMAX]; double rsk2d[DATAMAX][DATEMAX]; int Xso=90; //Max損切 int Xrk=100; //Max利確% //最適利確損切を算出する期間 //int Xdd=200; // int Xdd=100; // int Xd0=0; // //int Xd=35; //checkが遡るdetaの日数 毎回確認 25+10 int Xd=127; //checkが遡るdetaの日数 毎回確認 パラメタ拡張対応 //2017/3/19 double Heihei25[DATEMAX]; double Heihei75[DATEMAX]; double Heihei125[DATEMAX]; #include "mt_prm.h" #include "function.h" int calc(void) { int i,j; double rsk; int cnt25,cnt75,cnt125; double hei25s,hei75s,hei125s; heikin5(); fprintf(stderr,"+1"); dxheikin5(); fprintf(stderr,"+2"); dx2heikin5(); fprintf(stderr,"+3"); heikin25(); fprintf(stderr,"+4"); dxheikin25(); fprintf(stderr,"+5"); dxave3_25(); fprintf(stderr,"+6"); // dx2heikin25(); calhei5_25(); fprintf(stderr,"+7"); // calhei5_25_25(); // dxave2_5_25_25(); calm5(); fprintf(stderr,"+8"); calm25(); fprintf(stderr,"+9"); heikin75(); heikin125(); #ifdef _CALC_3_ heikin3(); dxheikin3(); calm3(); fprintf(stderr,"-3"); #endif #ifdef _CALC_15_ heikin15(); dxheikin15(); calm15(); fprintf(stderr,"-15"); #endif #ifdef _CALC_75_ dxheikin75(); calm75(); fprintf(stderr,"-75"); #endif #ifdef _CALC_125_ dxheikin125(); fprintf(stderr,"-125"); #endif #ifdef _CALC_DA_ da_heikin3(); da_heikin5(); fprintf(stderr,"da"); #endif //2018/2/18 i j 入れ替え Heihei 1回のみ初期化 for (j=0;j<DtMax-Xd;j++) { //2018/2/18 Heihei25[j]=0.0; Heihei75[j]=0.0; Heihei125[j]=0.0; //2018/2/18 cnt25=0; cnt75=0; cnt125=0; for (i=0;i<CodeMax;i++) { //ここのrskは整数 1 0 -1 Rと同じにするには支障あり? rsk=owa[i][j+1]-hjm[i][j+1]; rsk1d[i][j]=rsk; if (rsk<0.0) rsk1[i][j]=-1; else if (rsk==0.0) rsk1[i][j]=0; else rsk1[i][j]=1; rsk=owa[i][j+2]-hjm[i][j+2]; rsk2d[i][j]=rsk; if (rsk<0.0) rsk2[i][j]=-1; else if (rsk==0.0) rsk2[i][j]=0; else rsk2[i][j]=1; //2018/2/18 hei25s=-(hei25[i][j]-owa[i][j])/owa[i][j]*100; //a if ((_HEI_P_ >hei25s) && (hei25s> _HEI_M_)) { Heihei25[j]+=hei25s; cnt25++; } hei75s=-(hei75[i][j]-owa[i][j])/owa[i][j]*100; if ((_HEI_P_ >hei75s) && (hei75s > _HEI_M_)) { Heihei75[j]+=hei75s; cnt75++; } hei125s=-(hei125[i][j]-owa[i][j])/owa[i][j]*100; if ((_HEI_P_ >hei125s) && (hei125s > _HEI_M_)) { Heihei125[j]+=hei125s; cnt125++; } } //2018/2/18 Heihei25[j]/=(double)cnt25; Heihei75[j]/=(double)cnt75; Heihei125[j]/=(double)cnt125; fprintf(stderr,"%d:%8.2lf:%8.2lf:%8.2lf\n",j,Heihei25[j],Heihei75[j],Heihei125[j]); } } //代金maxだけが2 int check(void){ #ifndef _MAXn_ #define _MAXn_ 5 #endif int i,ii,ii1,ii2,ii3,ii4,j,k,l; //test int iin[_MAXn_]; // // int hit,sc; int hit,sc1,sc2,sc3,sc4,sc5; int m; int mm_0,mm_1,mm_2,mm_3,mm_4,mm_5,mm_6,mm_7,mm_8,mm_9,mm_10; int rsks1,rsks2; double rsks1d,rsks2d; double sp1,sp2,sp3,sp4,sp5; double pf1,pf2,pf3,pf4,pf5; double per1,per2,per3,per4,per5; double phit; double maxdai,maxdai1,maxdai2,maxdai3,maxdai4; //test double maxdain[_MAXn_]; // double hei5s,hei25s,hei5_25s,dxhei5s,dxave3hei25s,zrk; double dai; double data; double hei5s1; double hei25s1; double dxhei5s1; double dxhei25s1; double hei5_25s1; double dxave3hei25s1; //add 2015/09/23 double hei75s; double hei3s; double hei15s; double hei125s; //add 2015/09/27 double dxhei75s; double dxhei3s; double dxhei15s; double dxhei125s; //add 2015/12/06 double hei3_15s; //add 2016/07/10 double hei5s2; double hei25s2; double hei5_25s2; //add 2016/7/16 double dxhei5s2; double dxhei25s2; double zrk1; double zrk2; int ml; int ml_0,ml_1,ml_2,ml_3,ml_4,ml_5,ml_6,ml_7,ml_8,ml_9,ml_10; //2017/3/19 int cnt25,cnt75,cnt125; int FLT; #ifdef _CALC_DA_ double da_hei3s; double da_hei5s; #endif #ifdef Ex_para #include "ex_para.h" #endif for (j=0;j<DtMax-Xd;j++) { if (j%50==0) fputs(".",stderr); //2017/3/19 cnt25=0; cnt75=0; cnt125=0; for (i=0;i<CodeMax;i++) { hei5s=-(hei5[i][j]-owa[i][j])/owa[i][j]*100; //b hei25s=-(hei25[i][j]-owa[i][j])/owa[i][j]*100; //a hei5_25s=hei5_25[i][j]/owa[i][j]*100; //配列なくても計算できる //f dxhei5s=dxhei5[i][j]/owa[i][j]*100; dxave3hei25s=dxave3hei25[i][j]/owa[i][j]*100; zrk=(owa[i][j]-hjm[i][j+1])/hjm[i][j+1]*100;//多分間違いだがそのままにしとく //z hei5s1=-(hei5[i][j+1]-owa[i][j+1])/owa[i][j+1]*100; hei25s1=-(hei25[i][j+1]-owa[i][j+1])/owa[i][j+1]*100; dxhei5s1=dxhei5[i][j+1]/owa[i][j+1]*100; dxhei25s1=dxhei25[i][j+1]/owa[i][j+1]*100; hei5_25s1=hei5_25[i][j+1]/owa[i][j+1]*100; //配列なくても計算できる dxave3hei25s1=dxave3hei25[i][j+1]/owa[i][j+1]*100; hei75s=-(hei75[i][j]-owa[i][j])/owa[i][j]*100; hei125s=-(hei125[i][j]-owa[i][j])/owa[i][j]*100; #ifdef _CALC_3_ hei3s=-(hei3[i][j]-owa[i][j])/owa[i][j]*100; dxhei3s=dxhei3[i][j]/owa[i][j]*100; //g #ifdef _CALC_15_ hei3_15s=(hei3[i][j]-hei15[i][j])/owa[i][j]*100;//配列なくても計算できた ml=m3[i][j]+m15[i][j]*5; ml_0=m3[i][j]+m15[i][j]*5; ml_1=m3[i][j+1]+m15[i][j+1]*5; ml_2=m3[i][j+2]+m15[i][j+2]*5; ml_3=m3[i][j+3]+m15[i][j+3]*5; ml_4=m3[i][j+4]+m15[i][j+4]*5; ml_5=m3[i][j+5]+m15[i][j+5]*5; ml_6=m3[i][j+6]+m15[i][j+6]*5; ml_7=m3[i][j+7]+m15[i][j+7]*5; ml_8=m3[i][j+8]+m15[i][j+8]*5; ml_9=m3[i][j+9]+m15[i][j+9]*5; ml_10=m3[i][j+10]+m15[i][j+10]*5; #endif #endif #ifdef _CALC_15_ hei15s=-(hei15[i][j]-owa[i][j])/owa[i][j]*100; dxhei15s=dxhei15[i][j]/owa[i][j]*100; #endif #ifdef _CALC_75_ dxhei75s=dxhei75[i][j]/owa[i][j]*100; #endif #ifdef _CALC_125_ dxhei125s=dxhei125[i][j]/owa[i][j]*100; #endif #ifdef _CALC_DA_ da_hei3s=-(da_hei3[i][j]-dispda[i][j])/dispda[i][j]*100; da_hei5s=-(da_hei5[i][j]-dispda[i][j])/dispda[i][j]*100; #endif //add 2016/07/10 hei5s2=-(hei5[i][j+2]-owa[i][j+2])/owa[i][j+2]*100; //i hei25s2=-(hei25[i][j+2]-owa[i][j+2])/owa[i][j+2]*100; //j hei5_25s2=hei5_25[i][j+2]/owa[i][j+2]*100; //配列なくても計算できる //k //add 2016/07/16 dxhei5s2=dxhei5[i][j+2]/owa[i][j+2]*100; dxhei25s2=dxhei25[i][j+2]/owa[i][j+2]*100; zrk1=(owa[i][j+1]-hjm[i][j+2])/hjm[i][j+2]*100;//多分間違いだがそのままにしとく //z zrk2=(owa[i][j+2]-hjm[i][j+3])/hjm[i][j+3]*100;//多分間違いだがそのままにしとく //z //冗長だがRと同じ表記で条件が書けるように m=m5[i][j]+m25[i][j]*5; mm_0=m5[i][j]+m25[i][j]*5; mm_1=m5[i][j+1]+m25[i][j+1]*5; mm_2=m5[i][j+2]+m25[i][j+2]*5; mm_3=m5[i][j+3]+m25[i][j+3]*5; mm_4=m5[i][j+4]+m25[i][j+4]*5; mm_5=m5[i][j+5]+m25[i][j+5]*5; mm_6=m5[i][j+6]+m25[i][j+6]*5; mm_7=m5[i][j+7]+m25[i][j+7]*5; mm_8=m5[i][j+8]+m25[i][j+8]*5; mm_9=m5[i][j+9]+m25[i][j+9]*5; mm_10=m5[i][j+10]+m25[i][j+10]*5; //簡易資金考慮用(かつてのbugの再現も可能) dai=da[i][j]; rsks1=rsk1[i][j]; rsks2=rsk2[i][j]; rsks1d=rsk1d[i][j]; rsks2d=rsk2d[i][j]; //p1 <- subset(s , daikin1>dai & dai>daikin & a>hei25s & hei25s>aa) //p <- subset(p1 , m==(-24) & m5m(mm_5)<0 & zrkhei5s & hei5s>bb & c>dxave3hei25s & dxave3hei25s>cc & e>dxhei5s & dxhei5s>ee) #ifdef Ex_para #include "ex_para.mt" #endif if ( #include "rule.mt" 1 ) ck[i][j]=1; } } for (j=0;j<DtMax-Xd;j++) { maxdai=0.0; maxdai1=0.0; maxdai2=0.0; maxdai3=0.0; maxdai4=0.0; ii=-1; ii1=-1; ii2=-1; ii3=-1; ii4=-1; //test for (k=0;k<_MAXn_;k++) { maxdain[k]=0.0; iin[k]=-1; } // //2017/3/19 #ifndef _HH25_L #define _HH25_L -100 #endif #ifndef _HH75_L #define _HH75_L -100 #endif #ifndef _HH125_L #define _HH125_L -100 #endif #ifndef _HH25_H #define _HH25_H 100 #endif #ifndef _HH75_H #define _HH75_H 100 #endif #ifndef _HH125_H #define _HH125_H 100 #endif if ((_HH25_H >Heihei25[j]) && (Heihei25[j]>_HH25_L) && (_HH75_H >Heihei75[j]) && (Heihei75[j]>_HH75_L) && (_HH125_H >Heihei125[j]) &&(Heihei125[j]>_HH125_L)) FLT=1; else FLT=0; for (i=0;i<CodeMax;i++) { if(ck[i][j]==1) { perform(i,j,Xp,&hit,&sc1,&pf1,&sc2,&pf2,&sc3,&pf3,&sc4,&pf4,&sc5,&pf5); per1=(((double)sc1+0.62*2.0)/((double)hit+2.0))*100; per2=(((double)sc2+0.62*2.0)/((double)hit+2.0))*100; per3=(((double)sc3+0.62*2.0)/((double)hit+2.0))*100; per4=(((double)sc4+0.62*2.0)/((double)hit+2.0))*100; per5=(((double)sc5+0.62*2.0)/((double)hit+2.0))*100; sp1=((double)sc1/(double)hit)*100; sp2=((double)sc2/(double)hit)*100; sp3=((double)sc3/(double)hit)*100; sp4=((double)sc4/(double)hit)*100; sp5=((double)sc5/(double)hit)*100; phit=hit/(double)DtMax; pf1/=(double)hit; pf2/=(double)hit; pf3/=(double)hit; pf4/=(double)hit; pf5/=(double)hit; #ifdef FILTER if (((per1>Xper1 && pf1>Xpf1) ||(per2>Xper2 && pf2>Xpf2) || (per3>Xper3 && pf3>Xpf3) || (per4>Xper4 && pf4>Xpf4) || (per5>Xper5 && pf5>Xpf5)) && FLT) { #endif //printf("%s\t%d\t%5.2lf\t%5.2lf\t%5.2lf\t%5.2lf\n",code[i],j,per2,pf2,per3,pf3); //何もなければdaiで簡易資金考慮 data=dai; #ifdef MAX #include "max.mt" //max.mtでdataを差し替える #endif //test for (k=0;k<_MAXn_;k++) { if(data>maxdain[k]) { for(l=_MAXn_-1;l>k;l--) { maxdain[l]=maxdain[l-1]; iin[l]=iin[l-1]; } maxdain[l]=dai; iin[l]=i; break; } } // #ifdef FILTER } #endif } } for (k=0;k<_MAXn_;k++) { if (iin[k]!=-1) ck[iin[k]][j]=2; } //test //if (ii!=iin[0] || ii1!=iin[1] || maxdai!=maxdain[0] || maxdai1!=maxdain[1] ) fprintf(stderr,"error\n"); // } fputs("\n",stderr); } //////////////////////////////////////////////////////////////

 結構ごちゃごちゃしてて整理したいけど下手に弄って、現在の運用をおかしくしたくはない

それに、もっと機能を拡張したいけどさてどうするか?

とりあえず最新ソースとして記事にしといて、弄ったら更新していく

現在ストラテジーは外部に記述されていてインクルードされている

抜き出すと

 

通常パラメタのヘッダ
#include "mt_prm.h"

拡張パラメタのヘッダ
#ifdef Ex_para
#include "ex_para.h"
#endif

拡張パラメタの記述
#ifdef Ex_para
#include "ex_para.mt"
#endif

ここまででパラメタは準備できたので

ルールの記述
#include "rule.mt"

1

 ※最後の1は必要

このままで行くか、C言語の外で拡張するかまだ未定

追記)C言語ソース拡張は最小限にして、外部でm4を駆使して拡張することにしました

ちなみにストラテジーはcsvになってて

f:id:sucar:20180204095029p:plain

mt_mp20_0_1T1test

こんな感じに記述できる

 

8 データファイルの場所を指定

最近、データファイルの場所を変更したので、弄るファイルを書いておく

まず、C言語ソース

suQ2/main/sub/env.h

    
#ifndef _ENV_H_
#define _ENV_H_

#define DATAMAX 4000
#define DATEMAX 1200
#define XDAYMAX2 100
#define  PM 5000
#define _YN_ "\r\n"
#define STOCKSNEW2OLDDIR "../stocksnew2old"
//stocksdata/new2old"
#define STOCKSTRDIR "../stockstr"
//stocksdata/stockstr"
#define BNKTMAX 2000
#endif //_ENV_H_

 あと

.bash_profile 末尾に

    
export STOCKSNEWDIR=../stocksnew
export STOCKSNEW2OLDDIR=../stocksnew2old
export STOCKSTRDIR=../stockstr

を指定しておく

7 プログラムメイン部分現状

11ヶ月ぶりに記事書いてますw

ほぼ自分用の記事

現在の自作シストレC言語ソースのメイン部分

suQ2/main/simxp8trsu_nobug2.c

    
/*
 * 業種別を取り込む準備⇒廃止
 * 分割処理 1/500まで拡張
 * 分割時の代金バグを修正
 * mt_rule対応
 * 表示用dispda[][]
 * 2016/6/25 出力をdispda[][]⇒owa[][]
 * simxp7->8
 * 出力を根本的に変える(一つずれる)
 *
 * 2016/8/11 
 *	char* c_cfg=".\\code\\code.cfg"; を
 *  SHIJOUが定義されていたら変更する
 *
 * 2016/09/10
 * Zday=\t%d\t Yson=\t%5.2f
 *
 * 2016/11/05
 * msys2 移行
 * UTF-8 LF
 
 * 2017/1/17
 * daiの出力+-
 *
 * 2017/1/22 BUG定義時の修正
 * 2017/2/5 DAYSON 定義の廃止
 * 2017/2/11 分割の正規対応try開始
 * 2017/3/19 平均乖離率の平均を計算 hei75
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>


#include "sub/env.h"
#include "sub/check0.h"
#include "sub/read_kd2.h"
#include "sub/matome.h"
#include "sub/sngrx.h"
#include "sub/common_y.h"
#include "sub/output.h"
#include "sub/bnkt.h"

uint8_t dt[DATEMAX][11]; //use output
uint8_t code[DATAMAX][8]; //use output main
int gys[DATAMAX]; //read_kd2
double hjm[DATAMAX][DATEMAX]; //use output
double tak[DATAMAX][DATEMAX]; //use output
double yas[DATAMAX][DATEMAX]; //use output
double owa[DATAMAX][DATEMAX]; //use output
double da[DATAMAX][DATEMAX];//daiから変更
int bnk[DATAMAX]; //株式分割
double dispda[DATAMAX][DATEMAX];//表示用のdaikin(分割バグ無関係)// output //で使用

double suii[DATEMAX][XDAYMAX2]; //購入後の損益推移(安値→高値) // use output
double pfm[100];
double pfmmax;
double pfmson;
double pfmm[50];
double pfmall[100][100];
double dispda[DATAMAX][DATEMAX];//表示用のdaikin(分割バグ無関係)

int ck[DATAMAX][DATEMAX];        //フラグ 1
int CodeMax;
int DtMax;

int Jkc=0;

double Pmax[PM];
int Lr[PM];
int Ms[PM];

int fm=0; //output format 0 or 1

//int bncode[BNKTMAX]; //分割データcode
//int bnj[BNKTMAX]; //分割データj
//double bnkt[BNKTMAX]; //分割データ分割比率

//////
#include "mt/mt_rule.c"
//////

#ifndef _YSON_
double Yson=-70.0; //損切% 必要に応じて変える
#endif
#ifndef _ZDAY_
int Zday=5; //損切ライン 必要に応じて変える
#endif

int main (void) {
	//2016/8/11 市場切り替え対応
#ifdef SHIJOU
	uint8_t* c_cfg=SHIJOU;
#else
	uint8_t* c_cfg="./code/code.cfg"; 
#endif
	//
	uint8_t* d_cfg="data.cfg";
	uint8_t* rksg="./output/rksg.txt"; //利確損切を別ファイルに
	uint8_t  filename[40];
	uint8_t buf[40];
	double brk;
	double pmax;
	int i,k,n;
	//2017/1/22 add
	int bug=0;
	//int lr,ms;

	//2017/2/11 add
	int bncnt; //読み込んだ分割データの総数
	int bnflg=0;//0なら今までの分割チェックをしない

	FILE *fp;
	//code fileの読み込み
	fp = fopen(c_cfg, "rt");
	if ( fp ){
		i=0;
		while ( fgets(buf,40,fp)!=NULL) { 
			n=check0(buf);
			if (n!=0) {
				strcpy(code[i],buf);
				//printf("%d %s \n",i,code[i]);
				i++;
			}
		}
		CodeMax=i;
	
	}
	fclose(fp);
	fprintf(stderr,"read code file\n");
	
#ifdef BUG
				bug=1;
#endif

	//data file の読み込み
	fp = fopen(d_cfg, "rt");
	if ( fp ){
	//  d_cfg   data読込作業
		i=0;
		while ( fgets(filename,40,fp)!=NULL) { 
			n=check0(filename);
			if (n!=0) {             //#コメント以外 @は除外
			//2017/1/22

				read_kd2(filename,i,bug,bnflg);
				//
				i++;
			}
		}
		DtMax=i;
		fclose(fp);
	}
#ifdef _DEBUG_
	for (k=0;k<CodeMax;k++) {if(strncmp(code[k],"9830",5)==0)break;} //j=29
	fprintf(stderr,"test %s %d %f %f\n",code[k],k,hjm[k][29],hjm[k][30]);
#endif
	fprintf(stderr,"\nread data file\n");
	//分割データ読み込み
	if (bnflg==0){
		bncnt=bnkt_read(bug);
		fprintf(stderr,"read bnkt.dat %d\n",bncnt);
	}
#ifdef _DEBUG_
	fprintf(stderr,"test %s %d %f %f\n",code[k],k,hjm[k][29],hjm[k][30]);
#endif
	maxxday();
	minxday();
	
	//calc25();
	calc();
	check();
#ifdef _OUTPUT_FMT_
	fm=_OUTPUT_FMT_;
#endif
	output(fm);
	
	fp=fopen(rksg,"w");
	fprintf(fp,"----\tXd0\t%d\t----\tXdd\t%d\t-----\t%d\t---------------------------\n",Xd0,Xdd,DtMax);
	fprintf(fp,"利確\t損切\n");
	matome();
	pmax=-100.0;
	for (k=0;k<PM;k++) {
		if (Pmax[k]!=pmax && Lr[k]!=0){
			fprintf(fp,"%d\t%d\t%6.3lf\t%8.2lf\n",Lr[k]+1,-Ms[k]-1,Pmax[k],Pmax[k]*Jkc);
			pmax=Pmax[k];
		}
	}
	fclose(fp);

}

 

現在はこんな感じ

ビルド前に定義する部分だけ抜き出すと

#ifndef _YSON_
double Yson=-30.0; //損切% 必要に応じて変える
#endif
簡易損切:_YSON_ を明示的に定義しなかった場合のデフォルト設定が-30%


#ifndef _ZDAY_
int Zday=5; //損切ライン 必要に応じて変える
#endif
時間切れ損切:_ZDAY_を明示的に定義しなかった場合のデフォルト設定が5日


#ifdef SHIJOU
uint8_t* c_cfg=SHIJOU;
#else
uint8_t* c_cfg="./code/code.cfg";
#endif
市場ファイル:銘柄コード群が記載されたファイルを指定

 

#ifdef BUG
bug=1;
#endif
read_kd2(filename,i,bug,bnflg);
かつてデータ読み込みにbugがあったのだが、その方が成績良かったのでそのbugを残す際に定義

 

#ifdef _DEBUG_
デバッグ用にデータをプリント

 

#ifdef _OUTPUT_FMT_
fm=_OUTPUT_FMT_;
#endif
output(fm);
出力フォーマットを指定

 

あと気づいたけど

int bnflg=0;//0なら今までの分割チェックをしない

で固定になってる

もしProtraが使えなくなって元の簡易分割推定処理に戻すならここを弄ること

 

 

gawkとigawk (@include)

awkで@include文を活用する記事を書いた

abenomix.hatenablog.com

ただ、gawk 4.0 以降だと@include文が使える

といことはそれ以前のバージョンだと@include文は使えない

mingw+msysのシステムだとgawk3.1.7なので、@includeは使えなかった

まあ、どこかから4以上のバージョンのものをとってきて置き換えればよさそうだが

いろいろググってみるとigawkというシェルスクリプトがあり、これをgawkの代わりにつかうと@include文が使えるらしい

ということで試してみたらエラーが出る

どうもバージョン4以降のgawkとigawkでは少し違いがあるようだ

調べたところ

バージョン4以降のgawk

@include "インクルードするファイル"

と""が必要

igawk

@include インクルードするファイル

と""は不要

ということらしい

なぜ統一しなかったのだろう? まあいいけど

 

awkの引数で-vオプションのありなし

自作のawkスクリプトコマンドラインから、引数を渡そうと思い、ググったところ

qiita.com

で詳しく説明されていた

詳細はリンク先を見てもらえばわかるので改めて説明はしませんが簡単に書くと

  • awkで引数を渡す場合2つ方法がある
  • 1つは-vオプションを使う方法
  • もう一つは-vオプションを使わない方法
  • -vオプションを使うとちゃんとBEGINブロック内でも代入した値を参照することができる
  • -vオプションを使わないとBEGINブロック内で代入した値を参照することができない

ということで、最後に

-vオプションを使わない方法は、どのような場面で活用するんだろう... 思いつかない

で終わっている 当然

「なるほど、まあ普通-vオプション必要だよな」と思ったのだが・・・

自作awkスクリプトに引数を渡すshellスクリプトを作成したのだが、何と逆に-vオプションをつけるとうまくいかないことが発覚!

つまり、自分の設計は、あまり他人が思いつかない

-vオプションを使わない方法が活躍する場面

を無意識に想定していたのでした(やはり私は天邪鬼?)

いや、むしろ-vオプション付けない方が楽なんだけど・・・

以下、説明を試みる

-vオプションを付けると順番は以下のようになる

  1. コマンドラインでの変数への代入
  2. BEGIN{}の実行
  3. 本体の実行
  4. END{}の実行

これが、-vオプションを付けないとこうなる

  1. BEGIN{}の実行
  2. コマンドラインでの変数への代入
  3. 本体の実行
  4. END{}の実行

確かに-vオプションを付けない場合の処理の順番は変な感じである

大体、BEGIN{}の前に変数に代入されなければ、チェックすらできないではないか

うっかり代入しなかったらNULLになって・・・・

で、ここではたと気付くのである

代入しなかったらデフォルトの値を使ってくれた方がいい場合もある

BEGIN{}の中で変数にデフォルト値を入れておき、使う時にコマンドラインで変数を書き換えてやる、ってのが、-vオプションを使わない方法だとすんなりできるのだ

これが、-vオプションを使って引数を渡すと、BEGIN{}の中で変数にデフォルト値が上書き代入されてしまうので、渡しても意味がなくなる

-vオプションで渡す場合、BEGIN{}の中で変数のNULLチェックをして、NULLなら、デフォルト値を代入ってやらなければならない面倒な部分が-vオプションを使わない方法なら、BEGIN{}の中でのチェックは不要になる

awkはいろいろ奥深いですw

 

awkで$数字でなく$列名で計算(@includeの活用)

awkは便利です

なので、なるべくエクセルじゃなくawkを活用しようと考えている今日この頃・・・

今、システムの大規模改良を目論んでいて、C言語ソースから大幅に手を入れようと思っているのだけど、なかなかC言語でのシステムの出力データのフォーマットが決まらない・・・

これが決まってないと、その出力を入力とするツールがどうにもならないのです

awkにせよ、エクセルにせよ、列がずれると使い物にならない(方法はあるのかもしれないけどよくわからない)

R言語ならデータフレームに取り込んで、データフレーム$列名でアクセスできる

だけど・・・

エクセルはともかくawkでは何とかしたい

ということで、どんくさいけどこんな方法を考えてみた(たぶんもっとエレガントな方法があるんじゃないかと思うのだけど・・・)

まず、列名付きのcsvデータを準備

扱えるフォーマットは2種類

f:id:sucar:20170205102509p:plain

↑1行目はコメント行:約束として最初のセルに #1 と書くことにする

2行目に列名indexが記述される

f:id:sucar:20170205102752p:plain

↑コメント行なし 1行目に列名indexが記述される

で、awkで、例えば、hjm1を抜き出したかったら

print $2

とか書くのだけど これを

print $hjm1

と書けるようにしたいという話

いろいろ方法を考えて、連想配列使えばできそうなんだけとそれだと

print $ar["hjm1"]

とかなりそうで、記述が美しくない

で、gawk 4.0 以降だと@include文が使えるらしいのでこれを活用してみるテストを実施

以下test1.awk

#使い捨て関数をインクルード
@include "indexfunc.awk"

BEGIN{
	FS = ","
	#使用する変数に大きなマイナス数を入れておく
	owa1=hjm1=-10000
	#使い捨て関数実行
	indexfunc()
	#使用する変数の和がマイナスならエラー
	if (owa1+hjm1<0) {
		print "error\n"
		exit
	}
}
NR==1{
	if ($1!="#1") {
		hd=1
	}
	else {
		hd=2
	}

}
#本体
NR>hd{
	printf("%s=%8.2f : %s=%8.2f\n","hjm1",$hjm1,"owa1",$owa1)
}

こんな感じで、要はhjm1=2 owa1=5を代入してくれる関数を別途作ってincludeしてあげればよい

で、indexfunc.awkawkを使って

以下test.awk

BEGIN{
	FS = ","
	print "function indexfunc() {\n"
	}
NR==1{
	if ($1!="#1") {
		for(i=1;i<=NF;i++) printf("%s=%2d\n",$(i),i)
		print "}\n"
		exit
	}
	else {
		hd=2
	}
}
NR==hd{
	for(i=1;i<=NF;i++) printf("%s=%2d\n",$(i),i)
	print "}\n"
	exit
}

ってやって作成する

これらを纏めるシェルスクリプトを作成

以下awktest

#!/bin/bash
awk -f test.awk $1 > indexfunc.awk
awk -f test1.awk $1 
rm indexfunc.awk

こんな感じで

f:id:sucar:20170205104717p:plain

一応うまくいった感じ

これで、データのフォーマットがどんなに変更されても列名さえ変化なければawkスクリプトは変更する必要はない

ただ、気になる点として・・・・

変数名を間違ってもエラーにならず、0が入るだけで$0が参照され、そのまま処理が進んじゃうとこが、ちょっと・・・

まあ気を付けるしかないか