seolpyo-mplchart 1.4.0.2__tar.gz → 1.4.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of seolpyo-mplchart might be problematic. Click here for more details.
- {seolpyo_mplchart-1.4.0.2/seolpyo_mplchart.egg-info → seolpyo_mplchart-1.4.0.4}/PKG-INFO +6 -4
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/README.md +4 -2
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/pyproject.toml +1 -1
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/_cursor.py +29 -7
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/_draw.py +124 -54
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/_slider.py +1 -1
- seolpyo_mplchart-1.4.0.4/seolpyo_mplchart/test.py +71 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4/seolpyo_mplchart.egg-info}/PKG-INFO +6 -4
- seolpyo_mplchart-1.4.0.2/seolpyo_mplchart/test.py +0 -11
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/MANIFEST.in +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/__init__.py +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/_base.py +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart/utils.py +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/SOURCES.txt +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/dependency_links.txt +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/requires.txt +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/top_level.txt +0 -0
- {seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: seolpyo-mplchart
|
|
3
|
-
Version: 1.4.0.
|
|
3
|
+
Version: 1.4.0.4
|
|
4
4
|
Summary: Fast candlestick chart using Python. Includes navigator, slider, navigation, and text information display functions
|
|
5
5
|
Author-email: white-seolpyo <white-seolpyo@naver.com>
|
|
6
6
|
License: MIT License
|
|
@@ -32,9 +32,9 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
# Document
|
|
35
|
-
[English Document](https://white.seolpyo.com/entry/148
|
|
35
|
+
[English Document](https://white.seolpyo.com/entry/148/?from=pypi)
|
|
36
36
|
|
|
37
|
-
[한글 설명서](https://white.seolpyo.com/entry/147
|
|
37
|
+
[한글 설명서](https://white.seolpyo.com/entry/147/?from=pypi)
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
# Sample Image
|
|
@@ -50,6 +50,8 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
50
50
|
## Korean format sample
|
|
51
51
|

|
|
52
52
|
|
|
53
|
+
## change Candle shape sample
|
|
54
|
+

|
|
53
55
|
|
|
54
56
|
# 40,000 data sample
|
|
55
57
|

|
|
@@ -5,9 +5,9 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
# Document
|
|
8
|
-
[English Document](https://white.seolpyo.com/entry/148
|
|
8
|
+
[English Document](https://white.seolpyo.com/entry/148/?from=pypi)
|
|
9
9
|
|
|
10
|
-
[한글 설명서](https://white.seolpyo.com/entry/147
|
|
10
|
+
[한글 설명서](https://white.seolpyo.com/entry/147/?from=pypi)
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
# Sample Image
|
|
@@ -23,6 +23,8 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
23
23
|
## Korean format sample
|
|
24
24
|

|
|
25
25
|
|
|
26
|
+
## change Candle shape sample
|
|
27
|
+

|
|
26
28
|
|
|
27
29
|
# 40,000 data sample
|
|
28
30
|

|
|
@@ -321,10 +321,10 @@ class BoxMixin(CrossLineMixin):
|
|
|
321
321
|
else:
|
|
322
322
|
# 캔들 강조
|
|
323
323
|
self.in_candle = True
|
|
324
|
-
x1, x2 = (self.intx-0.3, self.intx+1.
|
|
324
|
+
x1, x2 = (self.intx-0.3, self.intx+1.3)
|
|
325
325
|
self.collection_price_box.set_segments([((x1, high), (x2, high), (x2, low), (x1, low), (x1, high))])
|
|
326
326
|
self.collection_price_box.draw(renderer)
|
|
327
|
-
|
|
327
|
+
elif self.volume:
|
|
328
328
|
# 거래량 강조
|
|
329
329
|
high = self.df['max_box_volume'][self.intx]
|
|
330
330
|
low = 0
|
|
@@ -333,7 +333,7 @@ class BoxMixin(CrossLineMixin):
|
|
|
333
333
|
if high < y or y < low: self.in_volumebar = False
|
|
334
334
|
else:
|
|
335
335
|
self.in_volumebar = True
|
|
336
|
-
x1, x2 = (self.intx-0.3, self.intx+1.
|
|
336
|
+
x1, x2 = (self.intx-0.3, self.intx+1.3)
|
|
337
337
|
self.collection_volume_box.set_segments([((x1, high), (x2, high), (x2, low), (x1, low), (x1, high))])
|
|
338
338
|
self.collection_volume_box.draw(renderer)
|
|
339
339
|
return
|
|
@@ -384,6 +384,10 @@ class InfoMixin(BoxMixin):
|
|
|
384
384
|
def set_data(self, df, sort_df=True, calc_ma=True, set_candlecolor=True, set_volumecolor=True, calc_info=True, *args, **kwargs):
|
|
385
385
|
super().set_data(df, sort_df, calc_ma, set_candlecolor, set_volumecolor, calc_info, *args, **kwargs)
|
|
386
386
|
|
|
387
|
+
self._set_length_text()
|
|
388
|
+
return
|
|
389
|
+
|
|
390
|
+
def _set_length_text(self):
|
|
387
391
|
self._length_text = self.df[(self.volume if self.volume else self.high)].apply(lambda x: len(f'{x:,}')).max()
|
|
388
392
|
lenth_high = self.df[self.high].apply(lambda x: len(f'{x:,}')).max()
|
|
389
393
|
lenth_volume = 0 if not self.volume else self.df[self.volume].apply(lambda x: len(f'{x:,}')).max()
|
|
@@ -395,7 +399,7 @@ class InfoMixin(BoxMixin):
|
|
|
395
399
|
|
|
396
400
|
if self.intx is not None:
|
|
397
401
|
if self.in_candle: self._draw_candle_info_artist(e)
|
|
398
|
-
elif self.in_volumebar: self._draw_volume_info_artist(e)
|
|
402
|
+
elif self.volume and self.in_volumebar: self._draw_volume_info_artist(e)
|
|
399
403
|
return
|
|
400
404
|
|
|
401
405
|
def _draw_candle_info_artist(self, e: MouseEvent):
|
|
@@ -433,6 +437,18 @@ class InfoMixin(BoxMixin):
|
|
|
433
437
|
self.artist_text_volume_info.draw(self.figure.canvas.renderer)
|
|
434
438
|
return
|
|
435
439
|
|
|
440
|
+
def get_info_kwargs(self, is_price: bool, **kwargs)-> dict:
|
|
441
|
+
"""
|
|
442
|
+
get text info kwargs
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
is_price (bool): is price chart info or not
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
dict[str, any]: text info kwargs
|
|
449
|
+
"""
|
|
450
|
+
return kwargs
|
|
451
|
+
|
|
436
452
|
def _get_info(self, index, is_price=True):
|
|
437
453
|
dt = self.df[self.date][index]
|
|
438
454
|
if not self.volume: v, vr = ('-', '-')
|
|
@@ -470,7 +486,8 @@ class InfoMixin(BoxMixin):
|
|
|
470
486
|
if ld[1]: l = f'{float_to_str(ld[0])} {Fraction(ld[1])}'
|
|
471
487
|
else: l = float_to_str(ld[0])
|
|
472
488
|
|
|
473
|
-
|
|
489
|
+
kwargs = self.get_info_kwargs(
|
|
490
|
+
is_price=is_price,
|
|
474
491
|
dt=dt,
|
|
475
492
|
close=f'{c:>{self._length_text}}{self.unit_price}',
|
|
476
493
|
rate=f'{r:>{self._length_text}}%',
|
|
@@ -480,11 +497,13 @@ class InfoMixin(BoxMixin):
|
|
|
480
497
|
low=f'{l:>{self._length_text}}{self.unit_price}', rate_low=f'{lr:+06,.2f}%',
|
|
481
498
|
volume=f'{v:>{self._length_text}}{self.unit_volume}', rate_volume=f'{vr}%',
|
|
482
499
|
)
|
|
500
|
+
text = self.format_candleinfo.format(**kwargs)
|
|
483
501
|
else:
|
|
484
502
|
o, h, l, c = (float_to_str(o, self.digit_price), float_to_str(h, self.digit_price), float_to_str(l, self.digit_price), float_to_str(c, self.digit_price))
|
|
485
503
|
com = float_to_str(compare, self.digit_price, plus=True)
|
|
486
504
|
|
|
487
|
-
|
|
505
|
+
kwargs = self.get_info_kwargs(
|
|
506
|
+
is_price=is_price,
|
|
488
507
|
dt=dt,
|
|
489
508
|
close=f'{c:>{self._length_text}}{self.unit_price}',
|
|
490
509
|
rate=f'{r:>{self._length_text}}%',
|
|
@@ -494,15 +513,18 @@ class InfoMixin(BoxMixin):
|
|
|
494
513
|
low=f'{l:>{self._length_text}}{self.unit_price}', rate_low=f'{lr:+06,.2f}%',
|
|
495
514
|
volume=f'{v:>{self._length_text}}{self.unit_volume}', rate_volume=f'{vr}%',
|
|
496
515
|
)
|
|
516
|
+
text = self.format_candleinfo.format(**kwargs)
|
|
497
517
|
elif self.volume:
|
|
498
518
|
compare = self.df['compare_volume'][index]
|
|
499
519
|
com = float_to_str(compare, self.digit_volume, plus=True)
|
|
500
|
-
|
|
520
|
+
kwargs = self.get_info_kwargs(
|
|
521
|
+
is_price=is_price,
|
|
501
522
|
dt=dt,
|
|
502
523
|
volume=f'{v:>{self._length_text}}{self.unit_volume}',
|
|
503
524
|
rate_volume=f'{vr:>{self._length_text}}%',
|
|
504
525
|
compare=f'{com:>{self._length_text}}{self.unit_volume}',
|
|
505
526
|
)
|
|
527
|
+
text = self.format_volumeinfo.format(**kwargs)
|
|
506
528
|
else: text = ''
|
|
507
529
|
|
|
508
530
|
return text
|
|
@@ -140,7 +140,9 @@ class DrawMixin(CollectionMixin):
|
|
|
140
140
|
|
|
141
141
|
_set_key = {
|
|
142
142
|
'x', 'zero', 'close_pre', 'ymax_volume',
|
|
143
|
-
'
|
|
143
|
+
'is_up',
|
|
144
|
+
'top_candle', 'bottom_candle',
|
|
145
|
+
'left_candle', 'right_candle',
|
|
144
146
|
'left_volume', 'right_volume',
|
|
145
147
|
}
|
|
146
148
|
|
|
@@ -166,6 +168,9 @@ class DataMixin(DrawMixin):
|
|
|
166
168
|
self.set_candlecolor = set_candlecolor
|
|
167
169
|
self.set_volumecolor = set_volumecolor
|
|
168
170
|
|
|
171
|
+
self.chart_price_ymax = df[self.high].max() * 1.3
|
|
172
|
+
self.chart_volume_ymax = df[self.volume].max() * 1.3
|
|
173
|
+
|
|
169
174
|
self._validate_column_key(df)
|
|
170
175
|
|
|
171
176
|
# 오름차순 정렬
|
|
@@ -195,10 +200,9 @@ class DataMixin(DrawMixin):
|
|
|
195
200
|
df['right_volume'] = df['x'] + self.volume_width_half
|
|
196
201
|
df.loc[:, 'zero'] = 0
|
|
197
202
|
|
|
198
|
-
df['
|
|
199
|
-
df['top_candle'] = np.where(df[
|
|
200
|
-
df['bottom_candle'] = np.where(df[
|
|
201
|
-
df['bottom_candle'] = np.where(df[self.close] < df[self.Open], df[self.close], df[self.Open])
|
|
203
|
+
df['is_up'] = np.where(df[self.Open] < df[self.close], True, False)
|
|
204
|
+
df['top_candle'] = np.where(df['is_up'], df[self.close], df[self.Open])
|
|
205
|
+
df['bottom_candle'] = np.where(df['is_up'], df[self.Open], df[self.close])
|
|
202
206
|
|
|
203
207
|
df['close_pre'] = df[self.close].shift(1)
|
|
204
208
|
if self.volume: df['ymax_volume'] = df[self.volume] * 1.2
|
|
@@ -229,23 +233,58 @@ class CandleSegmentMixin(DataMixin):
|
|
|
229
233
|
color_priceline = 'k'
|
|
230
234
|
limit_candle = 800
|
|
231
235
|
|
|
236
|
+
def get_candle_segment(self, *, is_up, x, left, right, top, bottom, high, low):
|
|
237
|
+
"""
|
|
238
|
+
get candle segment
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
is_up (bool): (True if open < close else False)
|
|
242
|
+
x (float): center of candle
|
|
243
|
+
left (float): left of candle
|
|
244
|
+
right (float): right of candle
|
|
245
|
+
top (float): top of candle(close if open < close else open)
|
|
246
|
+
bottom (float): bottom of candle(open if open < close else close)
|
|
247
|
+
high (float): top of candle wick
|
|
248
|
+
low (float): bottom of candle wick
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
tuple[tuple[float, float]]: candle segment
|
|
252
|
+
"""
|
|
253
|
+
return (
|
|
254
|
+
(x, high),
|
|
255
|
+
(x, top),
|
|
256
|
+
(left, top),
|
|
257
|
+
(left, bottom),
|
|
258
|
+
(x, bottom),
|
|
259
|
+
(x, low),
|
|
260
|
+
(x, bottom),
|
|
261
|
+
(right, bottom),
|
|
262
|
+
(right, top),
|
|
263
|
+
(x, top),
|
|
264
|
+
(x, high),
|
|
265
|
+
(x, top),
|
|
266
|
+
)
|
|
267
|
+
|
|
232
268
|
def _create_candle_segments(self):
|
|
233
269
|
# 캔들 세그먼트
|
|
234
|
-
segment_candle =
|
|
235
|
-
|
|
236
|
-
'x',
|
|
237
|
-
'left_candle', '
|
|
238
|
-
'
|
|
239
|
-
'
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
270
|
+
segment_candle = []
|
|
271
|
+
for x, left, right, top, bottom, is_up, high, low in zip(
|
|
272
|
+
self.df['x'].to_numpy().tolist(),
|
|
273
|
+
self.df['left_candle'].to_numpy().tolist(), self.df['right_candle'].to_numpy().tolist(),
|
|
274
|
+
self.df['top_candle'].to_numpy().tolist(), self.df['bottom_candle'].to_numpy().tolist(),
|
|
275
|
+
self.df['is_up'].to_numpy().tolist(),
|
|
276
|
+
self.df[self.high].to_numpy().tolist(), self.df[self.low].to_numpy().tolist(),
|
|
277
|
+
):
|
|
278
|
+
segment_candle.append(
|
|
279
|
+
self.get_candle_segment(
|
|
280
|
+
is_up=is_up,
|
|
281
|
+
x=x,
|
|
282
|
+
left=left, right=right,
|
|
283
|
+
top=top, bottom=bottom,
|
|
284
|
+
high=high, low=low,
|
|
285
|
+
)
|
|
286
|
+
)
|
|
287
|
+
self.segment_candle = np.array(segment_candle)
|
|
249
288
|
|
|
250
289
|
# 심지 세그먼트
|
|
251
290
|
segment_wick = self.df[[
|
|
@@ -261,22 +300,26 @@ class CandleSegmentMixin(DataMixin):
|
|
|
261
300
|
self._create_candle_color_segments()
|
|
262
301
|
return
|
|
263
302
|
|
|
303
|
+
def add_candle_color_column(self):
|
|
304
|
+
columns = ['facecolor', 'edgecolor']
|
|
305
|
+
# 양봉
|
|
306
|
+
self.df.loc[:, columns] = (self.color_up, self.color_up)
|
|
307
|
+
if self.color_up != self.color_down:
|
|
308
|
+
# 음봉
|
|
309
|
+
self.df.loc[self.df[self.close] < self.df[self.Open], columns] = (self.color_down, self.color_down)
|
|
310
|
+
if self.color_up != self.color_flat and self.color_down != self.color_flat:
|
|
311
|
+
# 보합
|
|
312
|
+
self.df.loc[self.df[self.close] == self.df[self.Open], columns] = (self.color_flat, self.color_flat)
|
|
313
|
+
if self.color_up != self.color_up_down:
|
|
314
|
+
# 양봉(비우기)
|
|
315
|
+
self.df.loc[(self.df['facecolor'] == self.color_up) & (self.df[self.close] <= self.df['close_pre']), 'facecolor'] = self.color_up_down
|
|
316
|
+
if self.color_down != self.color_down_up:
|
|
317
|
+
# 음봉(비우기)
|
|
318
|
+
self.df.loc[(self.df['facecolor'] == self.color_down) & (self.df['close_pre'] <= self.df[self.close]), ['facecolor']] = self.color_down_up
|
|
319
|
+
return
|
|
320
|
+
|
|
264
321
|
def _create_candle_color_segments(self):
|
|
265
|
-
if self.set_candlecolor:
|
|
266
|
-
# 양봉
|
|
267
|
-
self.df.loc[:, ['facecolor', 'edgecolor']] = (self.color_up, self.color_up)
|
|
268
|
-
if self.color_up != self.color_down:
|
|
269
|
-
# 음봉
|
|
270
|
-
self.df.loc[self.df[self.close] < self.df[self.Open], ['facecolor', 'edgecolor']] = (self.color_down, self.color_down)
|
|
271
|
-
if self.color_up != self.color_flat and self.color_down != self.color_flat:
|
|
272
|
-
# 보합
|
|
273
|
-
self.df.loc[self.df[self.close] == self.df[self.Open], ['facecolor', 'edgecolor']] = (self.color_flat, self.color_flat)
|
|
274
|
-
if self.color_up != self.color_up_down:
|
|
275
|
-
# 양봉(비우기)
|
|
276
|
-
self.df.loc[(self.df['facecolor'] == self.color_up) & (self.df[self.close] <= self.df['close_pre']), 'facecolor'] = self.color_up_down
|
|
277
|
-
if self.color_down != self.color_down_up:
|
|
278
|
-
# 음봉(비우기)
|
|
279
|
-
self.df.loc[(self.df['facecolor'] == self.color_down) & (self.df['close_pre'] <= self.df[self.close]), ['facecolor']] = self.color_down_up
|
|
322
|
+
if self.set_candlecolor: self.add_candle_color_column()
|
|
280
323
|
|
|
281
324
|
self.facecolor_candle = self.df['facecolor'].values
|
|
282
325
|
self.edgecolor_candle = self.df['edgecolor'].values
|
|
@@ -362,15 +405,39 @@ class MaSegmentMixin(CandleSegmentMixin):
|
|
|
362
405
|
class VolumeSegmentMixin(MaSegmentMixin):
|
|
363
406
|
limit_volume = 200
|
|
364
407
|
|
|
408
|
+
def get_volume_segment(self, *, x, left, right, top):
|
|
409
|
+
"""
|
|
410
|
+
get volume bar segment
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
x (float): center of volume bar
|
|
414
|
+
left (float): left of volume bar
|
|
415
|
+
right (float): right of volume bar
|
|
416
|
+
top (float): top of volume bar
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
tuple[tuple[float, float]]: volume bar segment
|
|
420
|
+
"""
|
|
421
|
+
return (
|
|
422
|
+
(left, top),
|
|
423
|
+
(left, 0),
|
|
424
|
+
(right, 0),
|
|
425
|
+
(right, top),
|
|
426
|
+
(left, top),
|
|
427
|
+
)
|
|
428
|
+
|
|
365
429
|
def _create_volume_segments(self):
|
|
366
430
|
# 거래량 바 세그먼트
|
|
367
|
-
segment_volume =
|
|
368
|
-
|
|
369
|
-
'
|
|
370
|
-
'
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
431
|
+
segment_volume = []
|
|
432
|
+
for x, left, right, top in zip(
|
|
433
|
+
self.df['x'].to_numpy().tolist(),
|
|
434
|
+
self.df['left_volume'].to_numpy().tolist(), self.df['right_volume'].to_numpy().tolist(),
|
|
435
|
+
self.df[self.volume].to_numpy().tolist(),
|
|
436
|
+
):
|
|
437
|
+
segment_volume.append(
|
|
438
|
+
self.get_volume_segment(x=x, left=left, right=right, top=top)
|
|
439
|
+
)
|
|
440
|
+
self.segment_volume = np.array(segment_volume)
|
|
374
441
|
|
|
375
442
|
# 거래량 심지 세그먼트
|
|
376
443
|
segment_volume_wick = self.df[[
|
|
@@ -382,19 +449,22 @@ class VolumeSegmentMixin(MaSegmentMixin):
|
|
|
382
449
|
self._create_volume_color_segments()
|
|
383
450
|
return
|
|
384
451
|
|
|
452
|
+
def add_volume_color_column(self):
|
|
453
|
+
columns = ['facecolor_volume', 'edgecolor_volume']
|
|
454
|
+
# 거래량
|
|
455
|
+
self.df.loc[:, columns] = (self.color_volume_up, self.color_volume_up)
|
|
456
|
+
if self.color_up != self.color_down:
|
|
457
|
+
# 전일대비 하락
|
|
458
|
+
condition = self.df[self.close] < self.df['close_pre']
|
|
459
|
+
self.df.loc[condition, columns] = (self.color_volume_down, self.color_volume_down)
|
|
460
|
+
if self.color_up != self.color_flat:
|
|
461
|
+
# 전일과 동일
|
|
462
|
+
condition = self.df[self.close] == self.df['close_pre']
|
|
463
|
+
self.df.loc[condition, columns] = (self.color_volume_flat, self.color_volume_flat)
|
|
464
|
+
return
|
|
465
|
+
|
|
385
466
|
def _create_volume_color_segments(self):
|
|
386
|
-
if self.set_volumecolor:
|
|
387
|
-
columns = ['facecolor_volume', 'edgecolor_volume']
|
|
388
|
-
# 거래량
|
|
389
|
-
self.df.loc[:, columns] = (self.color_volume_up, self.color_volume_up)
|
|
390
|
-
if self.color_up != self.color_down:
|
|
391
|
-
# 전일대비 하락
|
|
392
|
-
condition = self.df[self.close] < self.df['close_pre']
|
|
393
|
-
self.df.loc[condition, columns] = (self.color_volume_down, self.color_volume_down)
|
|
394
|
-
if self.color_up != self.color_flat:
|
|
395
|
-
# 전일과 동일
|
|
396
|
-
condition = self.df[self.close] == self.df['close_pre']
|
|
397
|
-
self.df.loc[condition, columns] = (self.color_volume_flat, self.color_volume_flat)
|
|
467
|
+
if self.set_volumecolor: self.add_volume_color_column()
|
|
398
468
|
|
|
399
469
|
self.facecolor_volume = self.df['facecolor_volume'].values
|
|
400
470
|
self.edgecolor_volume = self.df['edgecolor_volume'].values
|
|
@@ -241,7 +241,7 @@ class DataMixin(NavigatorMixin):
|
|
|
241
241
|
self._set_slider_lim()
|
|
242
242
|
self._set_navigator(*self.navcoordinate)
|
|
243
243
|
|
|
244
|
-
self.
|
|
244
|
+
self._set_length_text()
|
|
245
245
|
return
|
|
246
246
|
|
|
247
247
|
def get_default_lim(self):
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
sys.path.insert(0, Path(__file__).parent.parent.__str__())
|
|
8
|
+
# print(f'{sys.path=}')
|
|
9
|
+
|
|
10
|
+
import seolpyo_mplchart as mc
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Chart(mc.SliderChart):
|
|
14
|
+
format_candleinfo = mc.format_candleinfo_ko + '\nCustom info: {ci}'
|
|
15
|
+
format_volumeinfo = mc.format_volumeinfo_ko
|
|
16
|
+
min_distance = 5
|
|
17
|
+
|
|
18
|
+
def __init__(self, *args, **kwargs):
|
|
19
|
+
super().__init__(*args, **kwargs)
|
|
20
|
+
self.collection_candle.set_linewidth(1.5)
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
def get_info_kwargs(self, is_price, **kwargs):
|
|
24
|
+
if is_price:
|
|
25
|
+
kwargs['ci'] = 'You can add Custom text Info or Change text info.'
|
|
26
|
+
kwargs['close'] = 'You can Change close price info.'
|
|
27
|
+
return kwargs
|
|
28
|
+
|
|
29
|
+
def get_candle_segment(self, *, x, left, right, top, bottom, is_up, high, low):
|
|
30
|
+
if is_up:
|
|
31
|
+
return (
|
|
32
|
+
(x, high),
|
|
33
|
+
(x, top),
|
|
34
|
+
(right, top),
|
|
35
|
+
(x, top),
|
|
36
|
+
(x, bottom),
|
|
37
|
+
(left, bottom),
|
|
38
|
+
(x, bottom),
|
|
39
|
+
(x, low),
|
|
40
|
+
(x, high)
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
return (
|
|
44
|
+
(x, high),
|
|
45
|
+
(x, bottom),
|
|
46
|
+
(right, bottom),
|
|
47
|
+
(x, bottom),
|
|
48
|
+
(x, top),
|
|
49
|
+
(left, top),
|
|
50
|
+
(x, top),
|
|
51
|
+
(x, low),
|
|
52
|
+
(x, high)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
C = Chart()
|
|
58
|
+
path_file = Path(__file__).parent / 'sample/samsung.txt'
|
|
59
|
+
# C.format_candleinfo = mc.format_candleinfo_ko
|
|
60
|
+
# C.format_volumeinfo = mc.format_volumeinfo_ko
|
|
61
|
+
# C.volume = None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
with open(path_file, 'r', encoding='utf-8') as txt:
|
|
65
|
+
data = json.load(txt)
|
|
66
|
+
df = pd.DataFrame(data)
|
|
67
|
+
|
|
68
|
+
C.set_data(df)
|
|
69
|
+
|
|
70
|
+
mc.show()
|
|
71
|
+
mc.close()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: seolpyo-mplchart
|
|
3
|
-
Version: 1.4.0.
|
|
3
|
+
Version: 1.4.0.4
|
|
4
4
|
Summary: Fast candlestick chart using Python. Includes navigator, slider, navigation, and text information display functions
|
|
5
5
|
Author-email: white-seolpyo <white-seolpyo@naver.com>
|
|
6
6
|
License: MIT License
|
|
@@ -32,9 +32,9 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
# Document
|
|
35
|
-
[English Document](https://white.seolpyo.com/entry/148
|
|
35
|
+
[English Document](https://white.seolpyo.com/entry/148/?from=pypi)
|
|
36
36
|
|
|
37
|
-
[한글 설명서](https://white.seolpyo.com/entry/147
|
|
37
|
+
[한글 설명서](https://white.seolpyo.com/entry/147/?from=pypi)
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
# Sample Image
|
|
@@ -50,6 +50,8 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
50
50
|
## Korean format sample
|
|
51
51
|

|
|
52
52
|
|
|
53
|
+
## change Candle shape sample
|
|
54
|
+

|
|
53
55
|
|
|
54
56
|
# 40,000 data sample
|
|
55
57
|

|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/requires.txt
RENAMED
|
File without changes
|
{seolpyo_mplchart-1.4.0.2 → seolpyo_mplchart-1.4.0.4}/seolpyo_mplchart.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|