BCB里画股票技术图线,K线等

FigoZhu 2008-09-19 11:09:41
BCB里画股票技术图线,K线等
效果要类似大智慧的,K线,以及其他的技术曲线。能缩放的。
用TeeChart?还是直接API画?
...全文
838 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
aihuaren 2010-08-05
  • 打赏
  • 举报
回复
最好给一个完整的代码啊
echun369 2008-10-06
  • 打赏
  • 举报
回复
学习
jaffy 2008-09-22
  • 打赏
  • 举报
回复
是的,最好封装在一个类中,方便其他人调用,复用性啊复用性
wg961423 2008-09-22
  • 打赏
  • 举报
回复
学习中。
laowang2 2008-09-21
  • 打赏
  • 举报
回复
upup
Greg_han 2008-09-21
  • 打赏
  • 举报
回复
经典的好问题,我在做类似的软件!!!
FigoZhu 2008-09-20
  • 打赏
  • 举报
回复
谢谢楼上的兄弟啊。
回头我试试
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
当时水平有限没有用C++类来构建整个系统是个遗憾,
愿重新搞的时候,建议你用C++类来构建,这样更高效,灵活........
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
//----------------------------------------------------------------------
x=da+dasize-1;
if(pk==0) //画平均线
{
if((dasize>t1-1)&((kscmax-kscmin)*(p_p(x,t1)-kscmin)!=0))
{
t=(dasize-1)*ksc+5; /* 从最后日K线导推画均线 */
Image1->Canvas->MoveTo(t+ksc/2,260-225/(kscmax-kscmin)*(p_p(x,t1)-kscmin)); /* 五日均线第一点*/
Image1->Canvas->Pen->Color=clYellow;
for(q=x;q>=da;q--)
{
if(q==0) break;
if(q>t1-2) Drawp(t,ksc,kscmax,kscmin,p_p(q,t1)); /* 作五日均线 */
t-=ksc;
}
}
if((sc2>t2-1)&((kscmax-kscmin)*(p_p(x,t2)-kscmin)!=0))
{
t=(dasize-1)*ksc+5; /* 从最后日K线导推画均线 */
Image1->Canvas->MoveTo(t+ksc/2,260-225/(kscmax-kscmin)*(p_p(x,t2)-kscmin)); /* 十日均线第一点*/
Image1->Canvas->Pen->Color=clFuchsia;
for(q=x;q>=da;q--)
{
if(q==0) break;
if(q>t2-2) Drawp(t,ksc,kscmax,kscmin,p_p(q,t2)); /* 作十日均线 */
t-=ksc;
}
}
Image1->Canvas->Pen->Color=clLime;
if((sc2>t3-1)&((kscmax-kscmin)*(p_p(x,t3)-kscmin)!=0))
{
t=(dasize-1)*ksc+5; /* 从最后日K线导推画均线 */
Image1->Canvas->MoveTo(t+ksc/2,260-225/(kscmax-kscmin)*(p_p(x,t3)-kscmin)); /* 三十日均线第一点*/
for(q=x;q>=da;q--)
{
if(q==0) break;
if(q>t3-2) Drawp(t,ksc,kscmax,kscmin,p_p(q,t3)); /* 作三十日均线 */
t-=ksc;
}
}
//-------------------------------------------------------------------
if(volmax!=0) /*画均量线先条件*/
{
if(dasize>v1-1)
{
t=(dasize-1)*ksc+5; /* 从最后日K线导推画5日均量线 */
Image1->Canvas->MoveTo(t+ksc/2, 335-vol_(x,v1)*60/volmax);
Image1->Canvas->Pen->Color=clYellow;
for(q=x;q>=da;q--)
{
if(q==0) break;
if(q>v1-2) draw_p_vol(t,ksc,vol_(q,v1),volmax);
t-=ksc;
}
}
if(dasize>v2-1)
{
t=(dasize-1)*ksc+5; /* 从最后日K线导推画10日均量线 */
Image1->Canvas->MoveTo(t+ksc/2, 335-vol_(x,v2)*60/volmax);
Image1->Canvas->Pen->Color=clFuchsia;
for(q=x;q>=da;q--)
{
if(q==0) break;
if(q>v2-2) draw_p_vol(t,ksc,vol_(q,v2),volmax);
t-=ksc;
}
}
}
} //是否画平均线结束
//------------------------------------------------------------
qq=da+dasize-1;
tt=(dasize-1)*ksc+5; //左右移动记数
show(qq); //显示最后的价目,指标
switch(zb)
{
case 0: drawkd();
break; //kd指数
case 1: drawbias();
break;
case 2: drawpsy(); //画psy线
break;
case 3: drawwr(); // 画W%R线
break;
case 4: drawexpma();
break;
/* ----------------------------------------- */
case 21: drawmtm(); //画MoM
break;
case 22: drawrsi(); //画rsi线
break;
case 23: drawroc(); //画ROC
break;
case 24: drawasi();
break; //asi振动升降
}
if(ts==1) showts(); /*显示提示信号*/
}

太多累了。。。。。
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
/*****************************************************************************
* 画日K线,成交量,均线
* da,dasize
* da :当前屏幕起始数据 (da-1)
* dasize : 当前屏幕显示个数
* ksc : 显示比例
* kscmax: K 线最高价
* kscmin: K 线最低价
* kvol: 成交量最大
*****************************************************************************/
void TForm1::readk(void)
{
float kscmax,kscmin,kmax,kmin; /*kmax,kmin 画面K线最大小*/
int x,q,t=5;
float p5;

StatusBar1->Panels->Items[2]->Text=AnsiString(Str)+String(" ")+AnsiString(dm);
if(fq==0)
StatusBar1->Panels->Items[1]->Text="不复权";
else
StatusBar1->Panels->Items[1]->Text="复权";
//--------------------------------
Image1->Canvas->Pen->Mode=pmCopy;
Screenshow(); //显示屏幕
//设置显示参数
Image1->Canvas->Brush->Style=bsSolid;
Image1->Canvas->Brush->Color=screencolor;
Image1->Canvas->FillRect(Rect(600,0,770,19)); //画图区377
Image1->Canvas->Font->Color=clYellow;
Image1->Canvas->TextOut(621,2,AnsiString(Str)+String(" ")+ AnsiString(dm));
Image1->Canvas->Pen->Style=psSolid; //画实线
Image1->Canvas->Font->Color=clWhite;
if(sys_.sys1==0)
ShowMessage("系统没有找到符合的数据,是否亲自查找...");
if((ksc==10)&(sc2-da>=68))
dasize=68; /* 比例为10时从数组中取第N个画K线*/
if((ksc==10)&(sc2-da<68))
dasize=sc2-da; /*比例为10=69时*/
if((ksc==8)&(sc2-da>=85))
dasize=85; /* 比例为8时从数组中取第N个画K线*/
if((ksc==8)&(sc2-da<85))
dasize=sc2-da; /*比例为8=85时*/
if((ksc==6)&(sc2-da>=114))
dasize=114; /* 比例为6时从数组中取第N个画K线*/
if((ksc==6)&(sc2-da<114))
dasize=sc2-da; /*比例为6=82时*/
if((ksc==4)&(sc2-da>=172))
dasize=172; /*比例为4=123时*/
if((ksc==4)&(sc2-da<172))
dasize=sc2-da;
if((ksc==2)&(sc2-da>=340))
dasize=340; /*比例为2=240时 */
if((ksc==2)&(sc2-da<340))
dasize=sc2-da;
//---------------------------------------------------------
kscmax=0;
volmax=0;
kscmin=k_min(da);
for(q=da;q<da+dasize;q+= 1) /*求屏幕最大值*/
{
if(k_max(q)>kscmax)
kscmax=k_max(q);
if(k_min(q)!=0)
if(k_min(q)<kscmin)
kscmin=k_min(q);
if(k_vol(q)>volmax)
volmax=k_vol(q);
}
kmax=kscmax;
kmin=kscmin;
p5=0;
if(da>t3) /* 如果三十日线最低取三十日线最低*/
p5=p_p(da,t3);
if((kscmin>p5)&(p5>0))
kscmin = p5; /*如果30日均线小于 */
if(kscmax<p5)
kscmax = p5;
p5=0;
if(da>t2) /* 如果十日线最高取十日线最高 */
p5=p_p(da,t2);
if(kscmax<p5)
kscmax=p5;
if((kscmin>p5)&(p5>0))
kscmin=p5; /*如果10日均线小于 */
p5=0;
if(da>t1) /* 如果五日线最高取五日线最高*/
p5=p_p(da,t1);
if((kscmin>p5)&(p5>0))
kscmin=p5; /*如果5日均线小于 */
if(kscmax<p5)kscmax=p5;
kkmax=kscmax; //比例最大,小写入公共变量
kkmin=kscmin;
kxmax=kmax; //k线最大,小写入公共变量
kxmin=kmin;
//----------------------------------------
if(pk!=0) //画江恩重新定高
{
kscmax=kxmax; //k线最大,小写入公共变量
kscmin=kxmin;
}
/*------------成交量坐标----------------*/
Image1->Canvas->Font->Color=clAqua;
Image1->Canvas->TextOut(703,268,floattotxt(volmax,6,6,0));
Image1->Canvas->TextOut(703,288,floattotxt(volmax*2/3,6,6,0));
Image1->Canvas->TextOut(703,306,floattotxt(volmax*1/3,6,6,0));
/*-----------K线坐标------------------ */
Image1->Canvas->Font->Color=zbcolor;
Image1->Canvas->TextOut(703,30 ,floattotxt(kscmax,6,5,2));
Image1->Canvas->TextOut(703,64,floattotxt(kscmin+(kscmax-kscmin)*5/6,6,5,2));
Image1->Canvas->TextOut(703,99,floattotxt(kscmin+(kscmax-kscmin)*4/6,6,5,2));
Image1->Canvas->TextOut(703,140,floattotxt(kscmin+(kscmax-kscmin)*3/6,6,5,2));
Image1->Canvas->TextOut(703,177,floattotxt(kscmin+(kscmax-kscmin)*2/6,6,5,2));
Image1->Canvas->TextOut(703,214,floattotxt(kscmin+(kscmax-kscmin)*1/6,6,5,2));
ScrollBar1->Max=sc2-1; //滚动条长度
ScrollBar1->Position=da; //滚动条滑块位置
if(yali==1) base(kscmax,kscmin); /*画压力支撑带*/
for(q=da;q<da+dasize;q+= 1) /*画日K线 */
{
if((k_min(q)!=0)|(k_end(q)!=0)|(k_sat(q)!=0)|(k_max(q)!=0))
Drawk(t,ksc,kscmax,kscmin,k_sat(q),k_end(q),k_max(q),k_min(q));
if(volmax!=0)
Drawvol(t,ksc,volmax,k_sat(q),k_end(q),k_vol(q));
t+=ksc;
}
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
//--------------------------------------------------------
voldata=0; //读流通量
if(lttab==1)
for(x=0;x<string_lt->Count-1;x++)
{
int pos1=string_lt->Strings[x].Pos(" ");
if(string_lt->Strings[x].SubString(0,pos1-1)==AnsiString(Str))
{voldata=string_lt->Strings[x].SubString(pos1+1,string_lt->Strings[x].Length()-pos1).ToInt();
break; }

}
//------------------------复权处理模块--------------------
if(fq==1) //上复权
{ for(x=0;x<sc2;x++)
{ if(k_end(x)>0)
if((k_sat(x+1)-k_end(x))/k_end(x)*100<-10)
{ p5=k_end(x)-k_sat(x+1);
for(q=x+1;q<sc2;q++)
{
u_k_sat(q,k_sat(q)+p5);
u_k_min(q,k_min(q)+p5);
u_k_max(q,k_max(q)+p5);
u_k_end(q,k_end(q)+p5);
} } }
}
//--------------------------------------------------
if(sc2>0) {draw=1; y=1; } else {draw=0; y=0; };
}
return y;
}



void TForm1::Screenshow() //画屏幕坐标
{
int i,b,j;

Image1->Canvas->Font->Name="System";
Image1->Canvas->Font->Size=12;
Image1->Canvas->Pen->Style=psSolid; //画实线
Image1->Canvas->Brush->Style=bsSolid;
Image1->Canvas->Brush->Color=screencolor;
Image1->Canvas->FillRect(Rect(0,0,770,470)); //画图区377
for(i=0;i<350;i++)
{
Image1->Canvas->Pixels[i*2][20]= brodcolor; //画最上横线
Image1->Canvas->Pixels[i*2][260]=brodcolor; //画k横线
Image1->Canvas->Pixels[i*2][335]=brodcolor; //画成交量横线
Image1->Canvas->Pixels[i*2][410]=brodcolor; //画底横线宽
}
for(i=0;i<230;i++)
Image1->Canvas->Pixels[700][i*2+20]=brodcolor; //画竖线宽350
for(i=0;i<6;i++) //坐标
for(b=0;b<175;b++)
Image1->Canvas->Pixels[b*4][i*37.5+35]=zbcolor;
for(i=0;i<3;i++) //坐标
for(b=0;b<175;b++)
Image1->Canvas->Pixels[b*4][i*20+275]=zbcolor;
for(i=0;i<175;i++) //提示线3
Image1->Canvas->Pixels[i*4][350]=clRed;
//---------------纵坐标-------------------------------------
if(pk!=0)
{
switch(ksc)
{
case 10: j=9; break;
case 8: j=11; break;
case 6: j=15; break;
case 4: j=22; break;
case 2: j=43; break;
}
for(b=0;b<j;b++)
for(i=0;i<60;i++)
Image1->Canvas->Pixels[5+ksc/2+ksc*b*8][35+i*4]=zbcolor; //画竖线宽350
}
}

////////////////////////////////////////////////////////////////////////////////
// 画日K线图
//x:位置 ksc:比例 smax:比例最大 smin:比例最小 ksat:开盘 kend:收盘
//max:最高 min:最低
////////////////////////////////////////////////////////////////////////////////
void TForm1::Drawk(int x,int ksc,float smax,float smin,float sat,float end,float max,float min)
{
float s;
s = 225 /(smax-smin);
Image1->Canvas->Pen->Style=psSolid; //画实线
if(end>=sat)
{
Image1->Canvas->Pen->Color=k1color;
Image1->Canvas->MoveTo(x+ksc/2,260-s*(max-smin));
Image1->Canvas->LineTo(x+ksc/2,260-s*(min-smin));
if(end>sat) //阳线
{
Image1->Canvas->Brush->Color=screencolor;
Image1->Canvas->Rectangle(x+2,260-s*(sat-smin),x+ksc-1,260-s*(end-smin));
Image1->Canvas->Pen->Color=k1color;
Image1->Canvas->Rectangle(x+2,260-s*(sat-smin),x+ksc-1,260-s*(end-smin));
}
if((end==sat)|((end-sat)<0.03)) //十字星
{
Image1->Canvas->Pen->Color=k1color;
Image1->Canvas->MoveTo(x+2,260-s*(sat-smin));
Image1->Canvas->LineTo(x+ksc-1,260-s*(sat-smin));
}
}
else //阴线
{
Image1->Canvas->Pen->Color=k2color;
Image1->Canvas->MoveTo(x+ksc/2,260-s*(max-smin));
Image1->Canvas->LineTo(x+ksc/2,260-s*(min-smin));
Image1->Canvas->Brush->Color=k2color;
Image1->Canvas->Rectangle(x+2,260-s*(sat-smin),x+ksc-1,260-s*(end-smin));
}
}
/////////////////////////////////////////////////////////////////////////////////////
// 画成交量
//x:位置 ksc:比例因子 volmax:屏幕最大成交量 ksat:开盘 kend:收盘 kvol:成交量
/////////////////////////////////////////////////////////////////////////////////////
void TForm1::Drawvol(int x,int ksc,float volmax,float ksat,float kend,float kvol)
{
float s;
s=volmax/60;
Image1->Canvas->Pen->Style=psSolid; //画实线
if(kend>=ksat) //阳线成交量
{
Image1->Canvas->Brush->Color=k1color;
Image1->Canvas->Brush->Style=bsClear;
Image1->Canvas->Rectangle(x+1,335-kvol/s,x+ksc-1,335);
if(ksc==2)
{
Image1->Canvas->Pen->Color=k1color;
Image1->Canvas->MoveTo(x+1,335-kvol/s);
Image1->Canvas->LineTo(x+1,335);
}
}
else //阴线成交量
{
Image1->Canvas->Pen->Color=k2color;
Image1->Canvas->Brush->Color=k2color;
Image1->Canvas->Rectangle(x+1,335-kvol/s,x+ksc-1,335);
if(ksc==2)
{
Image1->Canvas->Pen->Color=k2color;
Image1->Canvas->MoveTo(x+1,335-kvol/s);
Image1->Canvas->LineTo(x+1,335);
}
}
}
代码可能比较乱,自己慢慢看了....
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
/************************************************************************
初始化
先查询代码库,如果有则打开
按Str输入代码打开文件 分配内存 sc2:调入K线长度 个数
备份nafile jk=0显示提示
**************************************************************************/
int init(int jk)
{
FILE *hzkfile;
long int sc3,fsize;
char s[MAXPATH],addx[8];
int x,q,i,y=0;
float p5;

if(strlen(Str)==6) /*上海代码 */
{
for(i=0;i<len_sha;i++)
{
shtab(i);
if(strcmp(znum,Str)==0)
{
strncpy(dm,zname,8); //读取名称
dm[8]='\0';
break;
}
}
switch(test) /*设置路径*/
{
case 1:
chdir("\\slon\\data\\sh\\day");
break;
case 2:
chdir("\\eye\\stkdt"); strcpy(addx,"ha");
strcat(addx,Str);
break;
case 3:
chdir("\\ml30\\data\\shase\\day");
break;
case 4:
chdir("\\hjin\\exe\\lineday\\sh");
strcpy(addx,"sh");
strcat(addx,Str);
break;
}
}
if(strlen(Str)==4) /*深圳代码 */
{
for(i=0;i<len_sza;i++)
{
sztab(i);
if(strcmp(znum,Str)==0)
{
strncpy(dm,zname,8);
dm[8]='\0';
break;
}
}
switch(test) /*设置路径*/
{
case 1:
chdir("\\slon\\data\\sz\\day");
break;
case 2:
chdir("\\eye\\stkdt"); strcpy(addx,"za");
strcat(addx,Str);
break;
case 3:
chdir("\\ml30\\data\\sznse\\day");
break;
case 4:
chdir("\\hjin\\exe\\lineday\\sz");
strcpy(addx,"sz"); strcat(addx,Str);
break;
}
}
switch(test) /*文件名拼接*/
{
case 1:
fnmerge(s,"","",Str,".day");
break;
case 2:
fnmerge(s,"","",addx,".dat");
break;
case 3:
fnmerge(s,"","",Str,".day");
break;
case 4:
fnmerge(s,"","",addx,".psd");
break;
}
if((hzkfile=fopen(s,"rb"))==NULL)
{
fclose(hzkfile); /*如果文件不存在显示提示*/
if(jk==1)
ShowMessage("读入数据错误...");
}
else
{
fseek(hzkfile,0L,SEEK_END);
fsize=ftell(hzkfile);
rewind(hzkfile);
switch(test) /*数出读取数量 */
{
case 1: if(fsize>=360*40) /*胜龙系统*/
{
sc2=360*40;
sc3=fsize-360*40;
}
else
{
sc2=fsize;
sc3=0;
}
sc2=sc2/40;
break;
case 2: if(fsize>=360*28) /*慧眼系统*/
{
sc2=360*28;
sc3=fsize-360*28;
}
else
{
sc2=fsize;
sc3=0;
}
sc2=sc2/28;
break;
case 3: if(fsize>=360*40) /*钱龙系统*/
{
sc2=360*40;
sc3=fsize-360*40;
}
else
{
sc2=fsize;
sc3=0;
}
sc2=sc2/40;
break;
case 4: if(fsize>=360*29) /*汇金系统*/
{
sc2=360*29;
sc3=fsize-360*29;
}
else
{
sc2=fsize;
sc3=0;
}
sc2=sc2/29;
break;
}
fseek(hzkfile,sc3,SEEK_SET); /*读取位置*/
switch(test) /* 读sc2个K线*/
{
case 1: for(i=0;i<sc2;i++) /*胜龙*/
fread(&day[i],sizeof(struct data),1,hzkfile);
break;
case 2: for(i=0;i<sc2;i++) /*慧眼*/
fread(&hy_[i],sizeof(struct hy),1,hzkfile);
break;
case 3: for(i=0;i<sc2;i++) /*钱龙*/
fread(&ql_[i],sizeof(struct ql),1,hzkfile);
break;
case 4: for(i=0;i<sc2;i++) /*汇金*/
fread(&hj_[i],sizeof(struct hj),1,hzkfile);
break;
}
fclose(hzkfile);
if((ksc==10)&(sc2>=68)) da=sc2-68;
if((ksc==10)&(sc2<68)) da=0;
if((ksc==8)&(sc2>=85)) da=sc2-85;
if((ksc==8)&(sc2<85)) da=0;
if((ksc==6)&(sc2>=114)) da=sc2-114;
if((ksc==6)&(sc2<114)) da=0;
if((ksc==4)&(sc2>=172)) da=sc2-172;
if((ksc==4)&(sc2<172)) da=0;
if((ksc==2)&(sc2>=340)) da=sc2-340;
if((ksc==2)&(sc2<340)) da=0;
strcpy(name,Str);
vc8fans 2008-09-20
  • 打赏
  • 举报
回复
用画布很好控制,在2000年时候作用BCB3 搞了一套,自己专用的分析K线分析系统

1.Canvas可按窗口大小变化,重新绘制K线比例。
2.你要有胜龙,大智慧的K线文件结构资料,保存在....\sz\*.dat ...\sh\*.dat
给个结构给你参考,
struct data{ /*胜龙日K线数据结构*/
unsigned long far kkdate; //日期
unsigned long far kksat; //开盘价
unsigned long far kkend; //收盘价
unsigned long far kkmax; //最高价
unsigned long far kkmin; //最低价
unsigned long far kkeol; //成交量
unsigned long far kkvol;
unsigned long far kkcq;
unsigned long far bk1;
unsigned long far bk2;
} *day;
struct ql{ /*乾龙日K线数据结构*/
unsigned long far kkdate;
unsigned long far kksat;
unsigned long far kkmax;
unsigned long far kkmin;
unsigned long far kkend;
unsigned long far kkeol;
unsigned long far kkvol;
unsigned long far kkcq;
unsigned long far bk1;
unsigned long far bk2;
} *ql_;

算了贴段2000年时写的段代码,看你能用得上就好了,
1。初始化,开段内存空间,把日线数据加载
2。画背景,画K线及成交量线,其他画MACD,KDJ,.....自己画了,很容易实现了................................
yumikoo 2008-09-19
  • 打赏
  • 举报
回复
可以用API画
也可以用Tchart画。
用控件的话方便快捷点,封装好的很多功能会使得开发起来比较顺手顺心。
但是如果对API掌握熟练,用API画的话,更加贴近需求,功能上也有独到的一面。
FigoZhu 2008-09-19
  • 打赏
  • 举报
回复
各位推荐Canvas的,能不能给点范例代码?
jacknes009 2008-09-19
  • 打赏
  • 举报
回复
在Canvas上直接画线好
vbcrack 2008-09-19
  • 打赏
  • 举报
回复
建议用canvas比较好控制,效率也高
jaffy 2008-09-19
  • 打赏
  • 举报
回复
我也很想知道,没有这方面的开发经验,我看过大智慧的软件,功能还是很丰富的
jxw1987628 2008-09-19
  • 打赏
  • 举报
回复
用Teechart吧 ,毕竟可以省下一些代码
柯本 2008-09-19
  • 打赏
  • 举报
回复
自动生成,可用Tchart
不过,像股票技术图这样多种线条合一,且公式较多的,还是用在Canvas上直接画线好
加载更多回复(1)

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧