最近用一个月的时间开发了一个股票行情的软件,虽然我一直都没怎么研究过股票,但是在熟悉股票的同事帮助下还算顺利,文章结束后会放上Demo。
行情中大概有五个图需要绘制,分别是分时图、五日图、日K图、周K图、月K图。
其中分时图和五日图可以分为一类,日K、周K和月K也一类,那就是分两类图表绘制。
先按五日图作为例子举例:
首先需要一个数据模块KLineTimeModel,属性都加上了注释方便看。
@property (nonatomic,retain) NSString *transationPrice;// 个股中表示每分钟的最后及时成交价,大盘中表示每分钟的大盘指数
@property (nonatomic,retain) NSString *MAn;// 个股中表示该种股票即时成交的平均价格,即当天成交总金额除以成交总股数,大盘中表示大盘不含加权的大盘指数
@property (nonatomic,retain) NSString *changeValue;// 涨跌额
@property (nonatomic,retain) NSString *changeRate;// 涨跌幅
@property (nonatomic,retain) NSString *volume;// 成交量
@property (nonatomic,retain) NSString *volumePrice;// 成交额
@property (nonatomic,retain) NSString *heightPrice;// 及时成交价最高值(第一次返回昨天最高价)
@property (nonatomic,retain) NSString *closePrice;// 昨日收盘价
@property (nonatomic,retain) NSString *time;// 时间
@property (nonatomic,retain) NSString *turnoverRate;// 换手率
@property (nonatomic,retain) NSString *priceType;// 涨幅标识(与上一分钟的差决定)
@property (nonatomic,retain) NSString *timeFrame;// 时间段描述
@property (nonatomic,retain) NSString *betsType;// 盘口类型 0=买盘 1=卖盘
{"transationPrice":"34.8","MAn":"34.487034078685","changeValue":"0.11","changeRate":"0.32","volume":"26950","volumePrice":"1.651049513E7","time":"10:23","turnoverRate":"0.14","priceType":"1","betsType":"0"}
以上是根据接口返回的股票一个点的数据,咋一看未必就是能拿来画线的数据,还需要换算处理等,接下来说下需要进行换算的数据:
K线图中Y轴左面的是成交价,Y轴右面的数据是成交量,算出最大和最小成交价,然后通过最高值跟昨日收盘价的比例,算出Y轴每份的比例。
然后就是如何把成交价数据转换为实际坐标数组:
//把分时数据换算成实际的点坐标数组
-(NSArray*)changePointWithData:(NSArray*)data andType:(int)type{
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
CGFloat PointStartX = self.kLineWidth/2; // 起始点坐标
CGFloat padRealValue = (mainView.frame.size.height) / 6;
for (KLineTimeModel *item in data) {
CGFloat currentValue = [item.transationPrice floatValue];// 得到及时成交价
if (type==1) {//0=成交价 1=成交均价
currentValue = [item.MAn floatValue]; // 均值
}
// 如果最高价为0并且 最大成交量为0 则股票为停牌状态
if (volMaxValue==0) {
currentValue = self.closePrice;
}
// 换算成实际的坐标
CGFloat currentPointY = padRealValue*4 - ((currentValue - minValue) / (maxValue - minValue) * padRealValue*4)+0.5;
CGPoint currentPoint = CGPointMake(PointStartX, currentPointY); // 换算到当前的坐标值
[tempArray addObject:NSStringFromCGPoint(currentPoint)]; // 把坐标添加进新数组
PointStartX += self.kLineWidth+self.kLinePadding; // 生成下一个点的x轴
}
return tempArray;
}
时分图和五日图的区别在于,时分图按成交价画线后,要再画一条成交均价的线,画法也是一样的。
然后就是把成交量实际数据转换坐标数组:
//把股市数据换算成成交量的实际坐标数组
-(NSArray*)changeVolumePointWithData:(NSArray*)data{
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
CGFloat PointStartX = self.kLineWidth/2; // 起始点坐标
CGFloat padRealValue = (mainView.frame.size.height) / 6;
for (KLineTimeModel *item in data) {
CGFloat volumevalue = [item.volume floatValue];// 得到没份成交量
CGFloat yHeight = volMaxValue - volMinValue ; // y的价格高度
CGFloat yViewHeight = 2*padRealValue ;// y的实际像素高度
// 换算成实际的坐标
CGFloat volumePointY = yViewHeight * (1 - (volumevalue - volMinValue) / yHeight);
CGPoint volumePoint = CGPointMake(PointStartX, volumePointY); // 成交量换算为实际坐标值
CGPoint volumePointStart = CGPointMake(PointStartX, yViewHeight);
// 把开盘价收盘价放进去好计算实体的颜色
CGFloat openvalue = 1;// 得到开盘价
CGFloat closevalue = 2;// 得到收盘价
NSString *changeValue = item.priceType;
if ([changeValue intValue]==-1) {
closevalue = 0;
}
CGPoint openPoint = CGPointMake(PointStartX, closevalue); // 开盘价换算为实际坐标值
CGPoint closePoint = CGPointMake(PointStartX, openvalue); // 收盘价换算为实际坐标值
NSArray *currentArray = [[NSArray alloc] initWithObjects:
NSStringFromCGPoint(volumePointStart),
NSStringFromCGPoint(volumePoint),
NSStringFromCGPoint(openPoint),
NSStringFromCGPoint(closePoint),
nil];
[tempArray addObject:currentArray]; // 把坐标添加进新数组
currentArray = Nil;
PointStartX += self.kLineWidth+self.kLinePadding; // 生成下一个点的x轴
}
return tempArray;
}
好了,成交量和成交价的数组也得出来了,然后下一步就是把数组连线画上去了。下一节将会介绍通过UIView的-(void)drawRect:(CGRect)rect方法坐标点连线。