股票分时图绘制
- 名词解释
- 分时图:
分时图是指大盘和个股的动态实时(即时)分时走势图,其在实战研判中的地位极其重要,是即时把握多空力量转化即市场变化直接的根本所在。时间范围为9:30~11:30,13:00~15:00。
蓝色曲线:表示该种股票即时实时成交的价格;
黄色曲线:表示该种股票即时成交的平均价格,即当天成交总金额除以成交总股数;
柱线:用来表示每一分钟的成交量;
数字标注:中间数字表示昨收,右上表示今日最高,右下表示今日最低。
2.分时图画法:
1)计算宽高:
1 -(void)generateHeightAndWidth{ 2 // 默认最大值和最小值为昨收 3 _maxY = self.lastCloseValue.doubleValue; 4 _minY = self.lastCloseValue.doubleValue; 5 double last = self.lastCloseValue.doubleValue; 6 if (self.dataArray.count > 0) { 7 //有分时数据 8 for (int i = 0 ; i<_dataArray.count; i++) { 9 TimeLinePointModel *model = [_dataArray objectAtIndex:i]; 10 double d = model.p_stock_price.doubleValue; 11 12 if (d >= last ) { 13 model.isRaise = YES; 14 } 15 last = model.p_stock_price.doubleValue; 16 17 //判断最大最小值 18 if (d > _maxY) { 19 _maxY = d; 20 }else if(d < _minY){ 21 _minY = d; 22 } 23 if(model.p_average_price.doubleValue > _maxY){ 24 _maxY = model.p_average_price.doubleValue; 25 }else if(model.p_average_price.doubleValue < _minY){ 26 _minY = model.p_average_price.doubleValue; 27 } 28 29 30 //成交量 31 if (model.p_trading_volume.intValue > _maxSaleY) { 32 _maxSaleY = model.p_trading_volume.intValue ; 33 } 34 35 36 } 37 //按昨收对称 38 if ((_maxY - self.lastCloseValue.doubleValue) > (self.lastCloseValue.doubleValue - _minY)) { 39 _minY = self.lastCloseValue.doubleValue - (_maxY - self.lastCloseValue.doubleValue); 40 }else if((_maxY - self.lastCloseValue.doubleValue) < (self.lastCloseValue.doubleValue - _minY)){ 41 _maxY = self.lastCloseValue.doubleValue + (self.lastCloseValue.doubleValue - _minY); 42 } 43 44 }else{ 45 //无分时数据 lastCloseValue 自带% 如 0.53 即 0.53% 46 if(self.lastFloatRate.doubleValue >=0){ 47 _maxY = [NSString stringWithFormat:@"%@",[NumberFormatter noThousandBitStyleWithNSNumberValue:[NSNumber numberWithDouble:self.lastCloseValue.doubleValue * (1 + self.lastFloatRate.doubleValue/100.0)] maximumFractionDigits:2 minimumFractionDigits:2 roundingMode:NSNumberFormatterRoundHalfUp]].doubleValue; 48 _minY = [NSString stringWithFormat:@"%@",[NumberFormatter noThousandBitStyleWithNSNumberValue:[NSNumber numberWithDouble:self.lastCloseValue.doubleValue * (1 - self.lastFloatRate.doubleValue/100.0)] maximumFractionDigits:2 minimumFractionDigits:2 roundingMode:NSNumberFormatterRoundHalfUp]].doubleValue; 49 }else { 50 _maxY = [NSString stringWithFormat:@"%@",[NumberFormatter noThousandBitStyleWithNSNumberValue:[NSNumber numberWithDouble:self.lastCloseValue.doubleValue * (1 - self.lastFloatRate.doubleValue/100.0)] maximumFractionDigits:2 minimumFractionDigits:2 roundingMode:NSNumberFormatterRoundHalfUp]].doubleValue; 51 _minY = [NSString stringWithFormat:@"%@",[NumberFormatter noThousandBitStyleWithNSNumberValue:[NSNumber numberWithDouble:self.lastCloseValue.doubleValue * (1 + self.lastFloatRate.doubleValue/100.0)] maximumFractionDigits:2 minimumFractionDigits:2 roundingMode:NSNumberFormatterRoundHalfUp]].doubleValue; 52 } 53 } 54 55 //横线间距离 56 _distanceY = (_maxY - _minY) / (YCOUNT-1) ; 57 58 //X轴 列间距 59 self.xPerStepWidth = (self.width-2*MARGIN_LEFT_AND_RIGHT) / (XCOUNT-1); 60 //Y轴 行间距 61 self.yPerStepHeight = (self.height- BOTTOM_VIEW_HEIGHT - TWO_CHART_INTERVAL - BOTTOM_CHART_HEIGHT - MARGIN_LEFT_AND_RIGHT) / (YCOUNT - 1); 62 if (_portraitLine.hidden) { 63 self.volumeLabel.text = [NSString stringWithFormat:@"成交量:%@",[KLineUtil transformVolume:_maxSaleY]]; 64 } 65 }
2)画分时坐标系
1 //画分时图坐标系 2 -(void)drawTimeCoordinateSystem:(CGContextRef)ctx{ 3 4 //efefef 5 CGContextSetRGBStrokeColor(ctx, 239.0/255.0, 239.0/255.0, 239.0/255.0, 1); 6 CGContextSetLineWidth(ctx, 1); 7 //画纵坐标系 8 9 for (int i = 0 ; i<5; i++) { 10 CGContextMoveToPoint(ctx, MARGIN_LEFT_AND_RIGHT + (self.width - MARGIN_LEFT_AND_RIGHT*2)/4*i, MARGIN_LEFT_AND_RIGHT); 11 CGContextAddLineToPoint(ctx,MARGIN_LEFT_AND_RIGHT + (self.width - MARGIN_LEFT_AND_RIGHT*2)/4*i, self.height - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL- BOTTOM_VIEW_HEIGHT); 12 CGContextStrokePath(ctx); 13 } 14 15 16 for(int i = 0 ; i < YCOUNT ; i++){ 17 18 if(i == YCOUNT/2){ 19 //中间线为虚线 20 CGFloat lengths[] = {3, 3}; 21 CGContextSetLineDash(ctx, 0, lengths, 2); 22 }else{ 23 CGContextSetLineDash(ctx, 0, 0, 0); 24 } 25 26 CGContextMoveToPoint(ctx, MARGIN_LEFT_AND_RIGHT, MARGIN_LEFT_AND_RIGHT+i*_yPerStepHeight); 27 CGContextAddLineToPoint(ctx, self.width - MARGIN_LEFT_AND_RIGHT, MARGIN_LEFT_AND_RIGHT+i*_yPerStepHeight); 28 CGContextStrokePath(ctx); 29 30 } 31 32 33 }
3)画数字标注
1 /** 2 * 画分时图标签 3 * 4 * @param ctx <#ctx description#> 5 */ 6 -(void)drawTimeLabel:(CGContextRef)ctx{ 7 NSMutableDictionary *attribute = [NSMutableDictionary new]; 8 NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 9 paragraphStyle.alignment = NSTextAlignmentCenter; 10 attribute[NSForegroundColorAttributeName] = [@"777777" hexColor]; 11 attribute[NSFontAttributeName] = [UIFont HeitiSCWithFontSize:11]; 12 attribute[NSParagraphStyleAttributeName] = paragraphStyle; 13 14 //最大值 15 CGRect maxYRect =CGRectMake( self.width - MARGIN_LEFT_AND_RIGHT - 70*ScreenWidthRate , 3*ScreenHeightRate+MARGIN_LEFT_AND_RIGHT, 65*ScreenWidthRate , 15*ScreenHeightRate); 16 paragraphStyle.alignment = NSTextAlignmentRight; 17 18 [[NSString stringWithFormat:@"%.2f",_maxY] drawInRect:maxYRect withAttributes:attribute]; 19 CGRect maxPercentRect =CGRectMake( MARGIN_LEFT_AND_RIGHT+3*ScreenWidthRate , maxYRect.origin.y, maxYRect.size.width , maxYRect.size.height); 20 paragraphStyle.alignment = NSTextAlignmentLeft; 21 22 [[NSString stringWithFormat:@"%.2f%%",((_maxY-self.lastCloseValue.doubleValue)/self.lastCloseValue.doubleValue)*100] drawInRect:maxPercentRect withAttributes:attribute]; 23 24 //0 25 CGRect zeroRect =CGRectMake( maxYRect.origin.x , (self.height - BOTTOM_VIEW_HEIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL - MARGIN_LEFT_AND_RIGHT)/2+MARGIN_LEFT_AND_RIGHT - 7.5*ScreenHeightRate, maxYRect.size.width , maxYRect.size.height); 26 paragraphStyle.alignment = NSTextAlignmentRight; 27 28 [[NSString stringWithFormat:@"%.2f",(_maxY-_minY)/2+_minY] drawInRect:zeroRect withAttributes:attribute]; 29 paragraphStyle.alignment = NSTextAlignmentLeft; 30 31 CGRect zeroPercentRect =CGRectMake( maxPercentRect.origin.x , zeroRect.origin.y, maxYRect.size.width , maxYRect.size.height); 32 [@"0.00%" drawInRect:zeroPercentRect withAttributes:attribute]; 33 34 //最小值 35 CGRect minYRect =CGRectMake( maxYRect.origin.x , self.height- BOTTOM_VIEW_HEIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL-17*ScreenHeightRate, maxYRect.size.width , maxYRect.size.height); 36 paragraphStyle.alignment = NSTextAlignmentRight; 37 38 [[NSString stringWithFormat:@"%.2f",_minY] drawInRect:minYRect withAttributes:attribute]; 39 40 CGRect minPercentRect =CGRectMake( maxPercentRect.origin.x , minYRect.origin.y , maxYRect.size.width , maxYRect.size.height); 41 paragraphStyle.alignment = NSTextAlignmentLeft; 42 43 [[NSString stringWithFormat:@"%.2f%%",((_minY-self.lastCloseValue.doubleValue)/self.lastCloseValue.doubleValue)*100] drawInRect:minPercentRect withAttributes:attribute]; 44 45 46 //9:30 47 attribute[NSForegroundColorAttributeName] = [@"333333" hexColor]; 48 CGRect openRect = CGRectMake( MARGIN_LEFT_AND_RIGHT , self.height- BOTTOM_VIEW_HEIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL+2*ScreenHeightRate, 35*ScreenWidthRate , 15*ScreenHeightRate); 49 [@"9:30" drawInRect:openRect withAttributes:attribute]; 50 51 //11:30 52 paragraphStyle.alignment = NSTextAlignmentCenter; 53 CGRect middleRect = CGRectMake( (self.width - 2*MARGIN_LEFT_AND_RIGHT)/2-35*ScreenWidthRate/5 , self.height - BOTTOM_CHART_HEIGHT - BOTTOM_VIEW_HEIGHT- TWO_CHART_INTERVAL+2*ScreenHeightRate, 35*ScreenWidthRate , 15*ScreenHeightRate); 54 [@"11:30" drawInRect:middleRect withAttributes:attribute]; 55 56 //15:00 57 paragraphStyle.alignment = NSTextAlignmentRight; 58 attribute[NSParagraphStyleAttributeName] = paragraphStyle; 59 CGRect closeRect = CGRectMake( self.width - MARGIN_LEFT_AND_RIGHT - 35*ScreenWidthRate , self.height - BOTTOM_CHART_HEIGHT- BOTTOM_VIEW_HEIGHT - TWO_CHART_INTERVAL+2*ScreenHeightRate, 35*ScreenWidthRate , 15*ScreenHeightRate); 60 [@"15:00" drawInRect:closeRect withAttributes:attribute]; 61 //画矩形 62 CGContextSetRGBFillColor(ctx, 244/255.0, 244/255.0, 244/255.0, 1.0); 63 //填充矩形 64 CGContextFillRect(ctx, CGRectMake(0, closeRect.origin.y+closeRect.size.height +5*ScreenHeightRate, Width, 5*ScreenHeightRate)); 65 //执行绘画 66 CGContextStrokePath(ctx); 67 68 69 //画矩形 70 CGContextSetRGBFillColor(ctx, 244/255.0, 244/255.0, 244/255.0, 1.0); 71 //填充矩形 72 CGContextFillRect(ctx, CGRectMake(0, self.height-BOTTOM_VIEW_HEIGHT,Width,5*ScreenHeightRate)); 73 //执行绘画 74 CGContextStrokePath(ctx); 75 }
4) 绘制分时图
1 /** 2 * 画分时图线 3 * 4 * @param ctx <#ctx description#> 5 */ 6 -(void)drawTimeLine:(CGContextRef)ctx{ 7 NSMutableArray *pointArray = [[NSMutableArray alloc] initWithCapacity:1]; 8 NSMutableArray *averagePointArray = [[NSMutableArray alloc] initWithCapacity:1]; 9 10 self.pathPointArray = [[NSMutableArray alloc] initWithCapacity:1]; 11 //画点 12 if (self.distanceY <= 0) { 13 return ; 14 } 15 for ( int i = 0; i<[self.dataArray count]; i++) { 16 //取出model 17 TimeLinePointModel *model = [self.dataArray objectAtIndex:i]; 18 19 20 21 //依次取出model中第i个值 22 double d = model.p_stock_price.doubleValue; 23 //计算当前值得x坐标 24 double x = MARGIN_LEFT_AND_RIGHT + i * self.xPerStepWidth; 25 26 //计算y坐标 27 CGFloat y = self.height - MARGIN_LEFT_AND_RIGHT- BOTTOM_VIEW_HEIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL - (d-_minY) / (self.distanceY) * self.yPerStepHeight + MARGIN_LEFT_AND_RIGHT; 28 CGFloat averY = self.height - MARGIN_LEFT_AND_RIGHT- BOTTOM_VIEW_HEIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL - (model.p_average_price.doubleValue - _minY)/ (self.distanceY) * self.yPerStepHeight + MARGIN_LEFT_AND_RIGHT; 29 30 NSValue *value = [NSValue valueWithCGPoint:CGPointMake(x, averY)]; 31 [averagePointArray addObject:value]; 32 if ( i == 0) { 33 //绘制第一个点前 先将画笔移动到原点到第一个点直线 与 Y轴的交点 则记录临时点 即 i --> 索引 d-->数值 并循环下一次 34 NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:1]; 35 [dic setObject:[NSNumber numberWithInt:i] forKey:@"i"]; 36 [dic setObject:[NSNumber numberWithDouble:d] forKey:@"d"]; 37 [pointArray addObject:dic]; 38 39 RCPoint *p = [[RCPoint alloc] initWithX:x y:y index:i]; 40 41 [self.pathPointArray addObject:p]; 42 43 44 continue; 45 46 }else{ 47 //如果不是第一个 则取出上一个临时点 48 NSMutableDictionary *kdic =[pointArray objectAtIndex:(i-1)]; 49 NSInteger ki = [[kdic objectForKey:@"i"] integerValue]; 50 double kd = [[kdic objectForKey:@"d"] doubleValue]; 51 52 //计算上一个临时点的x坐标及y坐标 53 double lastY =self.height- BOTTOM_VIEW_HEIGHT - MARGIN_LEFT_AND_RIGHT - BOTTOM_CHART_HEIGHT - TWO_CHART_INTERVAL - (kd-_minY) / (self.distanceY) * self.yPerStepHeight + MARGIN_LEFT_AND_RIGHT; 54 ; 55 double lastX =MARGIN_LEFT_AND_RIGHT + ki * self.xPerStepWidth; 56 57 58 //连接上一点和当前点 59 CGPoint startPoint = CGPointMake(lastX,lastY); 60 CGPoint endPoint = CGPointMake(x, y); 61 [RCLineChartCommon drawLine:ctx startPoint: startPoint endPoint: endPoint lineColor:time_line_color lineWidth:.5]; 62 63 64 RCPoint *p = [[RCPoint alloc] initWithX:endPoint.x y:endPoint.y index:i]; 65 [self.pathPointArray addObject:p]; 66 67 //记录临时点 68 NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithCapacity:1]; 69 [dic setObject:[NSNumber numberWithInt:i] forKey:@"i"]; 70 [dic setObject:[NSNumber numberWithDouble:d] forKey:@"d"]; 71 [pointArray addObject:dic]; 72 } 73 } 74 75 76 [self drawAverageLine:averagePointArray context:ctx]; 77 } 78 /** 79 * 画均线图 80 * 81 * @param averageArray 均线数组 82 * @param ctx <#ctx description#> 83 */ 84 -(void)drawAverageLine:(NSArray*)averageArray context:(CGContextRef)ctx{ 85 86 for (int i = 0; i < averageArray.count ; i++) { 87 if (i == averageArray.count - 1 || averageArray.count <= 1 ) { 88 break; 89 } 90 CGPoint start = ((NSValue*)[averageArray objectAtIndex:i]).CGPointValue; 91 CGPoint end = ((NSValue*)[averageArray objectAtIndex:i+1]).CGPointValue; 92 93 [RCLineChartCommon drawLine:ctx startPoint: start endPoint: end lineColor:average_line_color lineWidth:.5]; 94 } 95 }
5)绘制成交量
/** * 画成交量 * * @param ctx <#ctx description#> */ -(void)drawSalesLine:(CGContextRef)ctx{ //画点 for ( int i = 0; i<[self.dataArray count]; i++) { //取出model TimeLinePointModel *model = [self.dataArray objectAtIndex:i]; //依次取出model中第j个值 double d = model.p_trading_volume.doubleValue; //计算当前值得x坐标 float x = MARGIN_LEFT_AND_RIGHT + i * self.xPerStepWidth; //计算y坐标 CGFloat y = (self.height- BOTTOM_VIEW_HEIGHT-5*ScreenHeightRate) - (d) / _maxSaleY * (BOTTOM_CHART_HEIGHT-20*ScreenHeightRate); CGPoint startPoint = CGPointMake(x,self.height- BOTTOM_VIEW_HEIGHT-5*ScreenHeightRate); CGPoint endPoint = CGPointMake(x, y); if (model.isRaise) { [RCLineChartCommon drawLine:ctx startPoint: startPoint endPoint: endPoint lineColor:[UIColor colorWithRed:234/255.0f green:51/255.0f blue:40/255.0f alpha:1] lineWidth:self.xPerStepWidth-.5]; }else{ [RCLineChartCommon drawLine:ctx startPoint: startPoint endPoint: endPoint lineColor:[UIColor colorWithRed:63/255.0f green:140/255.0f blue:67/255.0f alpha:1] lineWidth:self.xPerStepWidth-.5]; } } }