@@ -67,6 +67,11 @@ def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volume
67
67
if ptype == 'candle' or ptype == 'candlestick' :
68
68
collections = _construct_candlestick_collections (xdates , opens , highs , lows , closes ,
69
69
marketcolors = style ['marketcolors' ],config = config )
70
+
71
+ elif ptype == 'hollow_candle' :
72
+ collections = _construct_hollow_candlestick_collections (xdates , opens , highs , lows , closes ,
73
+ marketcolors = style ['marketcolors' ],config = config )
74
+
70
75
elif ptype == 'ohlc' or ptype == 'bars' or ptype == 'ohlc_bars' :
71
76
collections = _construct_ohlc_collections (xdates , opens , highs , lows , closes ,
72
77
marketcolors = style ['marketcolors' ],config = config )
@@ -159,6 +164,18 @@ def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False):
159
164
_list = [ cmap [pre < cls ] for cls ,pre in zip (closes [1 :], closes ) ]
160
165
return [first ] + _list
161
166
167
+
168
+ def _updownhollow_colors (upcolor ,downcolor ,uphollow ,downhollow ,opens ,closes ):
169
+ if upcolor == downcolor == downhollow == uphollow :
170
+ return upcolor
171
+ cmap = {True : upcolor , False : downcolor }
172
+ first = cmap [opens [0 ] < closes [0 ]]
173
+ umap = {True : upcolor , False : uphollow }
174
+ dmap = {True : downcolor , False : downhollow }
175
+ _list = [ umap [cls > opn ] if cls > cls0 else dmap [cls < opn ] for opn0 ,cls0 ,opn ,cls in zip (opens [0 :- 1 ],closes [0 :- 1 ],opens [1 :],closes [1 :]) ]
176
+ return [first ] + _list
177
+
178
+
162
179
def _date_to_iloc (dtseries ,date ):
163
180
d1s = dtseries .loc [date :]
164
181
if len (d1s ) < 1 :
@@ -471,6 +488,93 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market
471
488
472
489
return [rangeCollection , barCollection ]
473
490
491
+
492
+ def _construct_hollow_candlestick_collections (dates , opens , highs , lows , closes , marketcolors = None , config = None ):
493
+ """Represent the open, close as a bar line and high low range as a
494
+ vertical line. Same as basic candlestick, but utilizes solid and hollow candlesticks
495
+
496
+ NOTE: this code assumes if any value open, low, high, close is
497
+ missing they all are missing
498
+
499
+
500
+ Parameters
501
+ ----------
502
+ opens : sequence
503
+ sequence of opening values
504
+ highs : sequence
505
+ sequence of high values
506
+ lows : sequence
507
+ sequence of low values
508
+ closes : sequence
509
+ sequence of closing values
510
+ marketcolors : dict of colors: up, down, edge, wick, alpha
511
+ alpha : float
512
+ bar transparency
513
+
514
+ Returns
515
+ -------
516
+ ret : list
517
+ (lineCollection, barCollection)
518
+ """
519
+
520
+ _check_input (opens , highs , lows , closes )
521
+
522
+ if marketcolors is None :
523
+ marketcolors = _get_mpfstyle ('classic' )['marketcolors' ]
524
+ #print('default market colors:',marketcolors)
525
+
526
+ datalen = len (dates )
527
+
528
+ avg_dist_between_points = (dates [- 1 ] - dates [0 ]) / float (datalen )
529
+
530
+ delta = config ['_width_config' ]['candle_width' ] / 2.0
531
+
532
+ barVerts = [((date - delta , open ),
533
+ (date - delta , close ),
534
+ (date + delta , close ),
535
+ (date + delta , open ))
536
+ for date , open , close in zip (dates , opens , closes )]
537
+
538
+ rangeSegLow = [((date , low ), (date , min (open ,close )))
539
+ for date , low , open , close in zip (dates , lows , opens , closes )]
540
+
541
+ rangeSegHigh = [((date , high ), (date , max (open ,close )))
542
+ for date , high , open , close in zip (dates , highs , opens , closes )]
543
+
544
+ rangeSegments = rangeSegLow + rangeSegHigh
545
+
546
+ alpha = marketcolors ['alpha' ]
547
+
548
+ uc = mcolors .to_rgba (marketcolors ['candle' ][ 'up' ], alpha )
549
+ dc = mcolors .to_rgba (marketcolors ['candle' ]['down' ], alpha )
550
+ uh = mcolors .to_rgba (marketcolors ['candle' ]['up_hollow' ], alpha )
551
+ dh = mcolors .to_rgba (marketcolors ['candle' ]['down_hollow' ], alpha )
552
+ colors = _updownhollow_colors (uc , dc , uh , dh , opens , closes )
553
+
554
+ uc = mcolors .to_rgba (marketcolors ['edge' ][ 'up' ], 1.0 )
555
+ dc = mcolors .to_rgba (marketcolors ['edge' ]['down' ], 1.0 )
556
+ edgecolor = _updownhollow_colors (uc , dc , uc , dc , opens , closes )
557
+
558
+ uc = mcolors .to_rgba (marketcolors ['wick' ][ 'up' ], 1.0 )
559
+ dc = mcolors .to_rgba (marketcolors ['wick' ]['down' ], 1.0 )
560
+ wickcolor = _updownhollow_colors (uc , dc , uc , dc , opens , closes )
561
+
562
+ lw = config ['_width_config' ]['candle_linewidth' ]
563
+
564
+ rangeCollection = LineCollection (rangeSegments ,
565
+ colors = wickcolor ,
566
+ linewidths = lw ,
567
+ )
568
+
569
+ barCollection = PolyCollection (barVerts ,
570
+ facecolors = colors ,
571
+ edgecolors = edgecolor ,
572
+ linewidths = lw
573
+ )
574
+
575
+ return [rangeCollection , barCollection ]
576
+
577
+
474
578
def _construct_renko_collections (dates , highs , lows , volumes , config_renko_params , closes , marketcolors = None ):
475
579
"""Represent the price change with bricks
476
580
0 commit comments