Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
zengbin93
czsc
提交
c9377147
C
czsc
项目概览
zengbin93
/
czsc
通知
23
Star
2
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
czsc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c9377147
编写于
8月 08, 2019
作者:
Z
zengbin93
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add kline_viewer
上级
0978e173
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
257 addition
and
12 deletion
+257
-12
chan/__init__.py
chan/__init__.py
+8
-1
chan/utils.py
chan/utils.py
+20
-11
chan/web/vis_kline.py
chan/web/vis_kline.py
+228
-0
requirements.txt
requirements.txt
+1
-0
未找到文件。
chan/__init__.py
浏览文件 @
c9377147
# coding: utf-8
import
os
import
shutil
from
.
import
a
author
=
"zengbin93"
version
=
"0.0.
1
"
version
=
"0.0.
2
"
email
=
"zeng_bin8888@163.com"
...
...
@@ -12,3 +13,9 @@ cache_path = os.path.join(os.path.expanduser('~'), ".chan")
if
not
os
.
path
.
exists
(
cache_path
):
os
.
mkdir
(
cache_path
)
def
clean_cache
():
shutil
.
rmtree
(
cache_path
)
os
.
mkdir
(
cache_path
)
chan/utils.py
浏览文件 @
c9377147
...
...
@@ -84,16 +84,17 @@ def find_bi(kline):
columns = ["symbol", "dt", "open", "close", "high", "low", "vol"]
:return: kline: pd.DataFrame
"""
kline
[
'bi_fx'
]
=
None
kline
[
'fx'
]
=
None
kline
[
'bi'
]
=
None
for
i
in
range
(
1
,
len
(
kline
)
-
1
):
data
=
kline
.
iloc
[
i
-
1
:
i
+
2
]
row
=
kline
.
iloc
[
i
]
if
max
(
data
[
'high'
])
==
row
[
'high'
]:
kline
.
loc
[
row
.
name
,
'
bi_
fx'
]
=
0
kline
.
loc
[
row
.
name
,
'fx'
]
=
0
elif
min
(
data
[
'low'
])
==
row
[
'low'
]:
kline
.
loc
[
row
.
name
,
'
bi_
fx'
]
=
1
kline
.
loc
[
row
.
name
,
'fx'
]
=
1
else
:
continue
...
...
@@ -101,17 +102,17 @@ def find_bi(kline):
last_index
=
None
for
i
in
kline
.
index
[::
-
1
]:
if
kline
.
loc
[
i
,
'
bi_
fx'
]
not
in
[
0
,
1
]:
if
kline
.
loc
[
i
,
'fx'
]
not
in
[
0
,
1
]:
continue
if
kline
.
loc
[
i
,
'
bi_
fx'
]
in
[
0
,
1
]:
if
kline
.
loc
[
i
,
'fx'
]
in
[
0
,
1
]:
if
last_index
is
None
:
last_index
=
i
else
:
curr_index
=
i
if
last_index
-
curr_index
<
3
:
kline
.
loc
[
last_index
,
'
bi_
fx'
]
=
2
kline
.
loc
[
curr_index
,
'
bi_
fx'
]
=
2
kline
.
loc
[
last_index
,
'fx'
]
=
2
kline
.
loc
[
curr_index
,
'fx'
]
=
2
last_index
=
None
else
:
last_index
=
curr_index
...
...
@@ -120,14 +121,22 @@ def find_bi(kline):
kline
[
'bi_mark'
]
=
None
mark
=
0
for
i
,
row
in
kline
.
iterrows
():
if
mark
==
0
and
row
[
'
bi_
fx'
]
==
0
:
if
mark
==
0
and
row
[
'fx'
]
==
0
:
kline
.
loc
[
i
,
'bi_mark'
]
=
mark
kline
.
loc
[
i
,
'bi'
]
=
kline
.
loc
[
i
,
'high'
]
mark
+=
1
continue
if
mark
>
0
and
row
[
'
bi_
fx'
]
in
[
0
,
1
]:
if
mark
>
0
and
row
[
'fx'
]
in
[
0
,
1
]:
kline
.
loc
[
i
,
'bi_mark'
]
=
mark
mark
+=
1
if
row
[
'fx'
]
==
0
:
kline
.
loc
[
i
,
'bi'
]
=
kline
.
loc
[
i
,
'high'
]
elif
row
[
'fx'
]
==
1
:
kline
.
loc
[
i
,
'bi'
]
=
kline
.
loc
[
i
,
'low'
]
else
:
raise
ValueError
(
"fx value error, valid is 0 or 1,"
" current is %i"
%
row
[
'fx'
])
return
kline
...
...
@@ -160,13 +169,13 @@ def find_xd(kline):
# 第二个顶分型的最高价小于或等于第一个顶分型的最高价,向上过程有可能结束
if
direction
==
"向上"
and
gd2
[
'high'
]
<=
gd1
[
'high'
]:
kline
.
loc
[
gd1
.
name
,
'xd_mark'
]
=
0
kline
.
loc
[
gd1
.
name
,
'xd_mark'
]
=
mark
mark
+=
1
direction
=
"向下"
# 第二个底分型的最低价大于或等于第一个底分型的最低价,向下过程有可能结束
elif
direction
==
"向下"
and
dd2
[
'low'
]
>=
dd1
[
'low'
]:
kline
.
loc
[
dd1
.
name
,
'xd_mark'
]
=
1
kline
.
loc
[
dd1
.
name
,
'xd_mark'
]
=
mark
mark
+=
1
direction
=
"向上"
...
...
chan/web/vis_kline.py
0 → 100644
浏览文件 @
c9377147
# coding: utf-8
"""
https://pyecharts.org/#/zh-cn/rectangular_charts?id=klinecandlestick%ef%bc%9ak%e7%ba%bf%e5%9b%be
"""
import
os
import
webbrowser
from
pyecharts
import
options
as
opts
from
pyecharts.charts
import
Kline
,
Grid
,
Line
,
Bar
,
Scatter
from
pyecharts.globals
import
ThemeType
,
CurrentConfig
from
chan.a
import
get_kline
from
chan.utils
import
preprocess
,
find_bi
,
find_xd
from
chan
import
cache_path
CurrentConfig
.
PAGE_TITLE
=
"chan - 缠论分析"
def
kline_viewer
(
ts_code
,
freq
,
end_date
,
asset
=
'E'
):
"""
:param ts_code:
:param freq:
:param end_date:
:param asset:
:return:
example:
>>> from chan.web.vis_kline import kline_viewer
>>> kline_viewer(ts_code='002739.SZ', freq='1min', end_date="20190809", asset='E')
"""
kline_raw
=
get_kline
(
ts_code
,
freq
=
freq
,
end_date
=
end_date
,
asset
=
asset
,
indicators
=
(
'ma'
,
'macd'
))
kline_chan
=
find_xd
(
find_bi
(
preprocess
(
kline_raw
)))
kline_chan
=
kline_chan
[[
'dt'
,
'fx'
,
'bi_mark'
,
'bi'
,
'xd_mark'
]]
kline_raw
=
kline_raw
.
merge
(
kline_chan
,
how
=
'left'
,
on
=
'dt'
)
start_dt
=
kline_raw
.
iloc
[
0
][
"dt"
]
end_dt
=
kline_raw
.
iloc
[
-
1
][
"dt"
]
x_data
=
kline_raw
.
dt
.
values
.
tolist
()
oclh
=
kline_raw
[[
'open'
,
'close'
,
'low'
,
'high'
]].
values
.
tolist
()
symbol
=
kline_raw
.
iloc
[
0
][
'symbol'
]
kline
=
(
Kline
(
init_opts
=
opts
.
InitOpts
(
theme
=
ThemeType
.
WHITE
))
.
add_xaxis
(
xaxis_data
=
x_data
)
.
add_yaxis
(
series_name
=
symbol
,
y_axis
=
oclh
,
itemstyle_opts
=
opts
.
ItemStyleOpts
(
color
=
"#ec0000"
,
color0
=
"#00da3c"
),
)
.
set_global_opts
(
title_opts
=
opts
.
TitleOpts
(
title
=
"缠论分析结果:%s-%s"
%
(
symbol
,
freq
),
subtitle
=
"时间区间:%s 至 %s"
%
(
start_dt
,
end_dt
)
),
xaxis_opts
=
opts
.
AxisOpts
(
type_
=
"category"
),
yaxis_opts
=
opts
.
AxisOpts
(
is_scale
=
True
,
splitarea_opts
=
opts
.
SplitAreaOpts
(
is_show
=
True
,
areastyle_opts
=
opts
.
AreaStyleOpts
(
opacity
=
1
)
),
),
legend_opts
=
opts
.
LegendOpts
(
is_show
=
True
,
pos_top
=
10
,
pos_left
=
"center"
),
datazoom_opts
=
[
opts
.
DataZoomOpts
(
is_show
=
False
,
type_
=
"inside"
,
xaxis_index
=
[
0
,
1
],
range_start
=
0
,
range_end
=
100
,
),
opts
.
DataZoomOpts
(
is_show
=
True
,
xaxis_index
=
[
0
,
1
],
type_
=
"slider"
,
pos_top
=
"90%"
,
range_start
=
0
,
range_end
=
100
,
),
],
tooltip_opts
=
opts
.
TooltipOpts
(
trigger
=
"axis"
,
axis_pointer_type
=
"cross"
,
background_color
=
"rgba(245, 245, 245, 0.8)"
,
border_width
=
1
,
border_color
=
"#ccc"
,
textstyle_opts
=
opts
.
TextStyleOpts
(
color
=
"#000"
),
),
visualmap_opts
=
opts
.
VisualMapOpts
(
is_show
=
False
,
dimension
=
2
,
series_index
=
5
,
is_piecewise
=
True
,
pieces
=
[
{
"value"
:
1
,
"color"
:
"#ec0000"
},
{
"value"
:
-
1
,
"color"
:
"#00da3c"
},
],
),
axispointer_opts
=
opts
.
AxisPointerOpts
(
is_show
=
True
,
link
=
[{
"xAxisIndex"
:
"all"
}],
label
=
opts
.
LabelOpts
(
background_color
=
"#777"
),
),
brush_opts
=
opts
.
BrushOpts
(
x_axis_index
=
"all"
,
brush_link
=
"all"
,
out_of_brush
=
{
"colorAlpha"
:
0.1
},
brush_type
=
"lineX"
,
),
)
)
line
=
(
Line
(
init_opts
=
opts
.
InitOpts
(
theme
=
ThemeType
.
WHITE
))
.
add_xaxis
(
xaxis_data
=
x_data
)
.
add_yaxis
(
series_name
=
"MA5"
,
y_axis
=
kline_raw
.
ma5
.
values
.
tolist
(),
is_smooth
=
True
,
is_symbol_show
=
False
,
is_hover_animation
=
False
,
linestyle_opts
=
opts
.
LineStyleOpts
(
width
=
2
,
opacity
=
0.5
),
label_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
)
.
add_yaxis
(
series_name
=
"MA10"
,
y_axis
=
kline_raw
.
ma10
.
values
.
tolist
(),
is_smooth
=
True
,
is_symbol_show
=
False
,
is_hover_animation
=
False
,
linestyle_opts
=
opts
.
LineStyleOpts
(
width
=
2
,
opacity
=
0.5
),
label_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
)
.
add_yaxis
(
series_name
=
"MA20"
,
y_axis
=
kline_raw
.
ma20
.
values
.
tolist
(),
is_smooth
=
True
,
is_symbol_show
=
False
,
is_hover_animation
=
False
,
linestyle_opts
=
opts
.
LineStyleOpts
(
width
=
2
,
opacity
=
0.5
),
label_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
)
.
add_yaxis
(
series_name
=
"MA60"
,
y_axis
=
kline_raw
.
ma60
.
values
.
tolist
(),
is_smooth
=
True
,
is_symbol_show
=
False
,
is_hover_animation
=
False
,
linestyle_opts
=
opts
.
LineStyleOpts
(
width
=
2
,
opacity
=
0.5
),
label_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
)
.
set_global_opts
(
xaxis_opts
=
opts
.
AxisOpts
(
type_
=
"category"
))
)
chan
=
(
Scatter
(
init_opts
=
opts
.
InitOpts
(
theme
=
ThemeType
.
WHITE
))
.
add_xaxis
(
xaxis_data
=
x_data
)
.
add_yaxis
(
"笔标记"
,
kline_raw
.
bi
.
values
.
tolist
())
.
set_global_opts
(
visualmap_opts
=
opts
.
VisualMapOpts
(
type_
=
"size"
,
max_
=
150
,
min_
=
20
),
)
)
bar
=
(
Bar
(
init_opts
=
opts
.
InitOpts
(
theme
=
ThemeType
.
LIGHT
))
.
add_xaxis
(
xaxis_data
=
x_data
)
.
add_yaxis
(
series_name
=
"Volume"
,
yaxis_data
=
kline_raw
.
vol
.
values
.
tolist
(),
xaxis_index
=
1
,
yaxis_index
=
1
,
label_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
)
.
set_global_opts
(
xaxis_opts
=
opts
.
AxisOpts
(
type_
=
"category"
,
is_scale
=
True
,
grid_index
=
1
,
boundary_gap
=
False
,
axisline_opts
=
opts
.
AxisLineOpts
(
is_on_zero
=
False
),
axistick_opts
=
opts
.
AxisTickOpts
(
is_show
=
False
),
splitline_opts
=
opts
.
SplitLineOpts
(
is_show
=
False
),
axislabel_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
split_number
=
20
,
min_
=
"dataMin"
,
max_
=
"dataMax"
,
),
yaxis_opts
=
opts
.
AxisOpts
(
grid_index
=
1
,
is_scale
=
True
,
split_number
=
2
,
axislabel_opts
=
opts
.
LabelOpts
(
is_show
=
False
),
axisline_opts
=
opts
.
AxisLineOpts
(
is_show
=
False
),
axistick_opts
=
opts
.
AxisTickOpts
(
is_show
=
False
),
splitline_opts
=
opts
.
SplitLineOpts
(
is_show
=
False
),
),
legend_opts
=
opts
.
LegendOpts
(
is_show
=
False
),
)
)
# Kline And Line
kline
=
kline
.
overlap
(
line
)
kline
=
kline
.
overlap
(
chan
)
# Grid Overlap + Bar
grid_chart
=
Grid
(
opts
.
InitOpts
(
width
=
"1400px"
,
height
=
"800px"
,
theme
=
ThemeType
.
WHITE
))
grid_chart
.
add
(
kline
,
grid_opts
=
opts
.
GridOpts
(
pos_left
=
"8%"
,
pos_right
=
"8%"
,
height
=
"60%"
),
)
grid_chart
.
add
(
bar
,
grid_opts
=
opts
.
GridOpts
(
pos_left
=
"8%"
,
pos_right
=
"8%"
,
pos_top
=
"70%"
,
height
=
"16%"
),
)
# 调用浏览器打开可视化结果
graph_path
=
os
.
path
.
join
(
cache_path
,
"%s_kline_%s.html"
%
(
symbol
,
freq
))
grid_chart
.
render
(
path
=
graph_path
)
webbrowser
.
open
(
graph_path
)
requirements.txt
浏览文件 @
c9377147
pyecharts
tqdm
pandas
tushare
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录