形式系统

计算机专业教学
posts - 48, comments - 150, trackbacks - 0, articles - 10
  教师博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

07课程设计(题4)

Posted on 2008-06-23 00:01 形式系统 阅读(281) 评论(2)  编辑 收藏 引用 网摘 所属分类: 编程开发

课题4:基于证券行情的KDJ指标求解

 

Step1:在数组中KDJ值求解

要求:

1、  采用数组作为存放数字序列,数字用float型。

2、  定义连续若干天的最大值,最小值求解。

3、  5日周期为例,计算RSV值。

4、  通过编写主程序将所求得的数打印出来。

 

以下为参考实现的框架。

#include <stdio.h>

 

float de[]={12.3 , 12.6, 12.5,… } /* 随机地设置一实数序列,作为每天收盘价 */

float dh[]={12.5 , 12.7, 12.9,… } /* 随机地设置一实数序列,作为每天的最高价 */

float dl[]={12.2 , 12.4, 12.4,… } /* 随机地设置一实数序列,作为每天的最低价 */

 

float K[MAX];           /* 当日K值,计算得出    */

float D[MAX];           /* 当日D值,计算得出    */

float J[MAX];           /* 当日J值,计算得出    */

 

/*  求以时间点t为基准,回溯r天的最低价(即dl数组中的相应区域元素的最小值) */

float high(int  t , int r){

  

}

 

/*  求以时间点t为基准,回溯r天的最高价(即dh数组中的相应区域元素的最大值) */

float low(int t , int r) {

 

}

 

/* 求出时间点tRSV值,并返回 */

float RSV(int t) {

 

}

 

/* 注:不足9日的KD值以50 */

/* K值,在9日周期的     */

float K(int t){ }

 

/* D值,在9日周期的 */

float D(int t){ }

 

/* J值,在9日周期的 */

float J(int t){ }

 

 

/* 调用上述函数,以二维列表的形式输出结果 */

void main(){

 

}

Feedback

# re: 07课程设计(题4)  回复  更多评论   

2008-07-01 01:43 by 形式系统
/*
Step 2 在Step1的基础上,重点实现从文件读和向文件写。
(此即昨天已检验过的代码)
*/

#include <stdio.h>
#define MAX 200

char str[20];
double d1,dh[MAX],dl[MAX],de[MAX],d2,d3; /*定义一系列数组*/

double K[MAX]; /* 当日K值,计算得出 */
double D[MAX]; /* 当日D值,计算得出 */
double J[MAX]; /* 当日J值,计算得出 */

double high(int t,int r) /*定义函数求数组dl最大值*/
{
int i;
double max=dh[t];
for(i=1;i<=r;i++)
if(max<dh[t-i])
max=dh[t-i]; return(max);
}

double low(int t,int r) /*定义函数求数组dl最小值*/
{
int i;
double min=dl[t];
for(i=1;i<=r;i++)
if(min>dl[t-i])
min=dl[t-i]; return(min);
}

double RSV(int t) /*定义函数求rsv值 int r ?????????????????? */
{
double l9,h9;
l9=low(t,9);
h9=high(t,9);
return((de[t]-l9)/(h9-l9)*100);
}

double fK(int t) /*定义函数求k*/
{
if (t<8) return(50);
else return(RSV(t)/3+2*fK(t-1)/3);
}

double fD(int t) /*定义函数求d*/
{
if(t<8)
return(50);
else
return(fK(t)/3+2*fD(t-1)/3);
}

double fJ(int t) /*定义函数求j*/
{
return(3*fD(t)-2*fK(t));
}

void read() /* 从文件中读数 */
{
FILE *f;
double str,d1,dh[MAX],dl[MAX],de[MAX],d2,d3;
int i;

if((f=fopen("D:\\x.TXT","r"))==NULL)
{ printf("Can't open the file.");
exit(1);
}

/* 先假定文件足够长,以数组的长度作为循环次数 */
for(i=0;i<MAX;i++)
{fscanf(f,"%s%lf%lf%lf%lf%lf%lf",str,&d1,&dh[i],&dl[i],&de[i],&d2,&d3);
printf("%s %10.3lf %10.3lf %10.3lf %10.3lf %10.3lf %10.3lf\n",str,d1,dh[i],dl[i],de[i],d2,d3);
}
fclose(f);
}

/* 写到文件中 */
void write()
{
FILE *f1;
char str[20];

int i;
if((f1=fopen("D:\\b.txt","w"))==NULL)
{
printf("Can't open the file.");
exit(1);
}

for(i=0;i<MAX;i++) /* 写入日期,K值,D值,J值。*/
{
fprintf(f1,"%s %f %f %f\n",str,&K[i],&D[i],&J[i]);
printf("%s %f %f %f\n",str,K[i],D[i],J[i]);
}
fclose(f1);
}

void compute() /* 计算每天的KDJ值 并分别储存在K[MAX],D[MAX],J[MAX] 分号? */
{ int t;
int h9,l9;
for(t=0;t<MAX;t++) {
RSV(t);
K[t]=fK(t);
D[t]=fD(t);
J[t]=fJ(t);
}
}

void main() {
read(); /* 读入数据 */
compute(); /* 计算 */
write(); /* 写入文件 */
}

# re: 07课程设计(题4)  回复  更多评论   

2008-07-01 09:42 by 形式系统
/*
题四:KDJ指标求解 Step 4.采用双缓冲实现长文件处理。
本题内容较多,由于两名同学完成。
1. 一人以文件读写及缓冲区管理为主。具体工作报括:
(1)readBlock,hasNext,moveNext,gePrePos,主程序的流程图。
(2)用论述或示意图的方式说明缓冲区的工作原理,说清楚Position结构体的功能,说清楚current,prePos,endOfFile的含义。
(3)进行测试,分别打开代码中的测试语句(共有两处),运行程序,获取输出数据(该数据全组可共享)。
2. 一人以算法重构为主。要求说明数据结构的主要变化.
(1)完成 high,low,RSV,fK,fD,fJ的流程图。
(2)说明dh,dl,de,K,D,J数组表什么,为什么只用长度为2的数组。
(3)画出模块调用图。

*/

#include <stdio.h>
#include <stdlib.h>

#define MAX 100 /* 缓冲区容量 */

typedef struct Position { /* 确定双缓冲中的元素位置 */
int b; /* 缓冲区编号 */
int p; /* 元素的位置 */
}Position;

char dates[2][MAX][10]; /* 考虑到双缓冲的因素,日期数组升级为3维字符数组 */
char datestr[15];

double de[2][MAX]; /* 升级为二维数组 */
double dh[2][MAX]; /* 升级为二维数组 */
double dl[2][MAX]; /* 升级为二维数组 */

/* 由于K,D均只依赖于前一步的K,D。同时考虑到每计算一个K,D,J就写入文件,故结果不用双缓冲而只保持两个变量 */
double K[2]; /* 当日K值,由于K,D均只依赖于前一个K,D */
double D[2]; /* 当日D值,计算得出 */
double J[2]; /* 当日J值,计算得出 */

Position current; /* 当前物理位置 */
Position prePos; /* 用户指示回溯位置 */
Position endOfFile; /* 文件结束点对应于缓冲区的位置 */

FILE *fr,*fw; /* 文件读写指针 */

/* 输出当前缓冲区的K线数据,测试用 */
void outputData(int i) {
printf("InputData:%s %10.3lf %10.3lf %10.3lf\n",
datestr,dh[current.b][i],dl[current.b][i],de[current.b][i]);
}

/* 输出当前记录的KDJ数据,测试用 */
void outputKDJ() {
printf("%10.3lf\t%10.3lf\t%10.3lf\n",K[1],D[1],J[1]);
}

/* 打开输入文件 */
void openFile() {
if((fr=fopen("D:\\f.txt","r"))==NULL) {
printf("Can't open the file");
exit(1);
}
}

/* 打开输出文件 */
void openFile1() {
if((fw=fopen("D:\\w.txt","w"))==NULL) {
printf("Can't open the file");
exit(1);
}
}

/* 从文件中读取一块数据到当前数组中,当前数组根据bufIndex指示 */
void readBlock() {
double v1,v2,v3;
int i=0;

if(fr==NULL) { printf("The file pointer is null.");exit(1); }

while(i<MAX && !feof(fr)) {
fscanf(fr,"%s%lf%lf%lf%lf%lf%lf",
datestr,&v1,&dh[current.b][i],&dl[current.b][i],&de[current.b][i],&v2,&v3);

/* outputData(i); 是否读入数据,可开启本测试函数 */

i++;
}

if(feof(fr)) { /* 到达文件末尾,在缓冲区中对应位置标记 */
endOfFile.b=current.b; /* current记录当前读写位置 */
endOfFile.p=current.p; /* 当前位置即为文件结束位置*/
}
}

/* 初始化 */
void init() {
current.b=0;
current.p=0;
readBlock(); /* 载入第一个缓冲区 */
endOfFile.b=-1;
endOfFile.p=-1;
}

/* 将当前已计算出来的一笔记录写入另一文件 */
void writeResult( ) {

fprintf(fw,"%s%10.3lf%10.3lf%10.3lf\n",datestr,K[1],D[1],J[1]);

K[0]=K[1]; D[0]=D[1];J[0]=J[1]; /* 原来的t变成下一步的t-1 */
}

/* 判断是否还有下一条记录 */
int hasNext() {
if(endOfFile.p==-1 && endOfFile.b==-1)
return 1;
else if(current.p!=endOfFile.p || current.p!=endOfFile.p)
return 1;
else
return 0;
}

/* 将当前记录索引指针移动到下一条记录 */
void moveNext() {
current.p++;
if(current.p >=MAX) {
current.b=(current.b+1)%2; /* 修改当前缓冲区得指示,即可换用缓冲区 */
current.p=0; /* 新的缓冲区,读写位置重新从0开始 */
readBlock(); /* 载入新的数据至缓冲区,readBlock自动识别要覆盖的缓冲区 */
}
}

/* 以当前位置为基准,获取回溯backStep步的绝对位置(即在数组中的位置。) */
Position getPrePos(Position cur,int backStep) {
Position prePos;

prePos.p=cur.p -backStep;
if( prePos.p<0) {
prePos.p=MAX+prePos.p;
prePos.b=(prePos.b+1)%2;
}
else
prePos.b=cur.b;
return prePos;
}


double getDe(Position pos){
return de[pos.b][pos.p]; /* 获取记录位置为pos的收盘价数据项 */
}
double getDh(Position pos){
return dh[pos.b][pos.p]; /* 获取记录位置为pos的最高价数据项 */
}
double getDl(Position pos){
return dl[pos.b][pos.p]; /* 获取记录位置为pos的最低价数据项 */
}

/****************************
以下为实现KDJ计算的代码
*****************************/
double high(Position cur,int r) /*定义函数求数组dh最大值*/
{
int i;
double max=dh[cur.b][cur.p];
double val;
Position prePos;

for(i=1;i<r;i++) {
prePos=getPrePos(cur,i);
val=getDh(prePos);

if(max<val) max=val;
}
return(max);
}

double low(Position cur,int r) /*定义函数求数组dl最小值*/
{
int i;
double val;
Position prePos;
double min;

min=dl[cur.b][cur.p];

for(i=1;i<r;i++) {
prePos=getPrePos(cur,i);
val=getDl(prePos);
if(min>val) min=val;
}
return(min);
}

double RSV(Position cur) /*定义函数求rsv值 int r ?????????????????? */
{
double l9,h9,ct;
l9=low(cur,9); /* 以当前位置为基准,求回溯9天的最低值。 */
h9=high(cur,9);
ct=getDe(cur); /* 求当天的收盘价 */
return((ct-l9)/(h9-l9)*100);
}

double fK(Position cur) /*定义函数求k*/
{
if (K[0]==-1) K[1]=50;
K[1]=RSV(cur)/3 + 2*K[0]/3;
return K[1]; /* 要确保此前K[t-1]已计算出 */
}

double fD(Position cur) /*定义函数求d*/
{
if(D[0]==-1)
D[1]=50;
else
D[1]=K[1]/3+2*D[0]/3; /* 确保此前 K[1]已经被计算出,即必须先调用 fK(cur) */
return D[1];
}

double fJ(Position cur) /*定义函数求j*/
{
J[1]=3*D[1]-2*K[1];
return J[1]; /* 确保此前先调用fK(cur),fD(cur);*/
}

/* 计算当前记录的K,D,J值 */
void compute() {
/*printf("%10.3lf %10.3lf %10.3l\n",
dh[current.b][current.p],dl[current.b][current.p],de[current.b][current.p]);
*/
fK(current);
fD(current);
fJ(current);

}

/* 重构原来的函数,包括high,low等。写也采用双缓冲方式。以前面已经实现的算法为基础,完成主程序*/
void main() {
openFile();
openFile1();
init();

/* printf("K\t\t\D\t\tJ\t\t\n"); /* 测试KDJ数据是否算出,和下面的语句配合。*/

fprintf(fw,"Date\tK\tD\tJ\t\n"); /* 在文件中输出头部 */
while(hasNext()) {
moveNext();
compute();

/* outputKDJ(); /* 测试KDJ数据是否算出,和上面的语句配合。*/

writeResult();
}

fprintf("已经写入到文件,请到相应目录下查看。\n");
fclose(fr);
fclose(fw);
}

只有注册用户登录后才能发表评论。