Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bluefrankey
hqchart
提交
0d7824ba
hqchart
项目概览
bluefrankey
/
hqchart
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
hqchart
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0d7824ba
编写于
7月 01, 2019
作者:
J
jones
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ver 6133
上级
97e10564
变更
18
展开全部
隐藏空白更改
内联
并排
Showing
18 changed file
with
3833 addition
and
10 deletion
+3833
-10
umychart_python/.vscode/launch.json
umychart_python/.vscode/launch.json
+15
-0
umychart_python/__init__.py
umychart_python/__init__.py
+4
-0
umychart_python/umychart_complier_data.py
umychart_python/umychart_complier_data.py
+379
-0
umychart_python/umychart_complier_job.py
umychart_python/umychart_complier_job.py
+145
-0
umychart_python/umychart_complier_jsalgorithm.py
umychart_python/umychart_complier_jsalgorithm.py
+1078
-0
umychart_python/umychart_complier_jscomplier.py
umychart_python/umychart_complier_jscomplier.py
+61
-0
umychart_python/umychart_complier_jsexecute.py
umychart_python/umychart_complier_jsexecute.py
+349
-0
umychart_python/umychart_complier_jsparser.py
umychart_python/umychart_complier_jsparser.py
+850
-0
umychart_python/umychart_complier_jssymboldata.py
umychart_python/umychart_complier_jssymboldata.py
+260
-0
umychart_python/umychart_complier_scanner.py
umychart_python/umychart_complier_scanner.py
+546
-0
umychart_python/umychart_complier_testcase.py
umychart_python/umychart_complier_testcase.py
+103
-0
umychart_python/umychart_complier_util.py
umychart_python/umychart_complier_util.py
+21
-0
vuehqchart/src/jscommon/umychart.complier.js
vuehqchart/src/jscommon/umychart.complier.js
+3
-2
vuehqchart/src/jscommon/umychart.stock.js
vuehqchart/src/jscommon/umychart.stock.js
+2
-2
vuehqchart/src/jscommon/umychart.vue/stockstringformat.js
vuehqchart/src/jscommon/umychart.vue/stockstringformat.js
+9
-0
vuehqchart/src/jscommon/umychart.vue/umychart.stock.vue.js
vuehqchart/src/jscommon/umychart.vue/umychart.stock.vue.js
+2
-2
webhqchart.demo/jscommon/umychart.complier.js
webhqchart.demo/jscommon/umychart.complier.js
+3
-2
webhqchart/umychart.complier.js
webhqchart/umychart.complier.js
+3
-2
未找到文件。
umychart_python/.vscode/launch.json
0 → 100644
浏览文件 @
0d7824ba
{
//
Use
IntelliSense
to
learn
about
possible
attributes.
//
Hover
to
view
descriptions
of
existing
attributes.
//
For
more
information
,
visit:
https://go.microsoft.com/fwlink/?linkid=
830387
"version"
:
"0.2.0"
,
"configurations"
:
[
{
"name"
:
"Python: Test Case"
,
"type"
:
"python"
,
"request"
:
"launch"
,
"program"
:
"${workspaceRoot}/umychart_complier_testcase.py"
,
"console"
:
"integratedTerminal"
}
]
}
\ No newline at end of file
umychart_python/__init__.py
0 → 100644
浏览文件 @
0d7824ba
version
=
'1.0.1'
__version__
=
(
1
,
0
,
1
)
from
umychart.python
import
*
\ No newline at end of file
umychart_python/umychart_complier_data.py
0 → 100644
浏览文件 @
0d7824ba
###########################################################################
#
# 数据结构类
#
############################################################################
import
sys
import
time
import
datetime
# 历史K线数据
class
HistoryData
()
:
def
__init__
(
self
)
:
self
.
Date
=
None
self
.
YClose
=
None
self
.
Open
=
None
self
.
Close
=
None
self
.
High
=
None
self
.
Low
=
None
self
.
Vol
=
None
self
.
Amount
=
None
self
.
Time
=
None
self
.
FlowCapital
=
0
# 流通股本
# 指数才有的数据
self
.
Stop
=
None
# 停牌家数
self
.
Up
=
None
# 上涨
self
.
Down
=
None
# 下跌
self
.
Unchanged
=
None
# 平盘
def
IsVaild
(
self
,
type
=
5
)
:
# 开高低收昨收数据时候有效
if
type
==
5
:
return
self
.
Open
>
0
and
self
.
High
>
0
and
self
.
Low
>
0
and
self
.
Close
>
0
and
self
.
YClose
>
0
elif
type
==
4
:
return
self
.
Open
>
0
and
self
.
High
>
0
and
self
.
Low
>
0
and
self
.
Close
>
0
@
staticmethod
def
Copy
(
data
)
:
newData
=
HistoryData
()
newData
.
Date
=
data
.
Date
newData
.
YClose
=
data
.
YClose
newData
.
Open
=
data
.
Open
newData
.
Close
=
data
.
Close
newData
.
High
=
data
.
High
newData
.
Low
=
data
.
Low
newData
.
Vol
=
data
.
Vol
newData
.
Amount
=
data
.
Amount
newData
.
Time
=
data
.
Time
newData
.
FlowCapital
=
data
.
FlowCapital
newData
.
Stop
=
data
.
Stop
newData
.
Up
=
data
.
Up
newData
.
Down
=
data
.
Down
newData
.
Unchanged
=
data
.
Unchanged
return
newData
@
staticmethod
# 数据复权拷贝
def
CopyRight
(
data
,
seed
=
1
)
:
newData
=
HistoryData
()
newData
.
Date
=
data
.
Date
newData
.
YClose
=
data
.
YClose
*
seed
newData
.
Open
=
data
.
Open
*
seed
newData
.
Close
=
data
.
Close
*
seed
newData
.
High
=
data
.
High
*
seed
newData
.
Low
=
data
.
Low
*
seed
newData
.
Vol
=
data
.
Vol
newData
.
Amount
=
data
.
Amount
newData
.
FlowCapital
=
data
.
FlowCapital
return
newData
class
ChartData
:
def
__init__
(
self
,
data
,
dataType
)
:
self
.
Data
=
data
self
.
Period
=
0
# 周期 0=日线 1=周线 2=月线 3=年线
self
.
Right
=
0
# 复权 0=不复权 1=前复权 2=后复权
self
.
DataType
=
dataType
# 获取收盘价
def
GetClose
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Close
return
result
def
GetYClose
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
YClose
return
result
def
GetHigh
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
High
return
result
def
GetLow
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Low
return
result
def
GetOpen
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Open
return
result
def
GetVol
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Vol
return
result
def
GetAmount
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Amount
return
result
def
GetUp
(
self
)
:
# 上涨家数
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Up
return
result
def
GetDown
(
self
)
:
# 下跌家数
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Down
return
result
def
GetYear
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
int
(
self
.
Data
[
i
].
Date
/
10000
)
return
result
def
GetMonth
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
int
(
self
.
Data
[
i
].
Date
%
10000
/
100
)
return
result
def
GetDate
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
result
[
i
]
=
self
.
Data
[
i
].
Date
return
result
def
GetWeek
(
self
)
:
result
=
[
None
]
*
len
(
self
.
Data
)
for
i
in
range
(
len
(
self
.
Data
))
:
value
=
self
.
Data
[
i
].
Date
if
value
==
None
:
result
[
i
]
=
None
continue
date
=
datetime
.
datetime
.
strptime
(
str
(
value
),
'%Y%m%d'
)
day
=
date
.
weekday
()
result
[
i
]
=
day
+
1
return
result
# 复权 0 不复权 1 前复权 2 后复权
def
GetRightDate
(
self
,
right
)
:
result
=
[]
if
len
(
self
.
Data
)
<=
0
:
return
result
result
=
[
None
]
*
len
(
self
.
Data
)
if
right
==
1
:
count
=
len
(
self
.
Data
)
index
=
count
-
1
seed
=
1
#复权系数
yClose
=
self
.
Data
[
index
].
YClose
result
[
index
]
=
HistoryData
.
Copy
(
self
.
Data
[
index
])
for
i
in
range
(
index
-
1
,
-
1
,
-
1
):
index
=
i
if
yClose
!=
self
.
Data
[
index
].
Close
:
break
result
[
index
]
=
HistoryData
.
Copy
(
self
.
Data
[
index
])
yClose
=
self
.
Data
[
index
].
YClose
for
i
in
range
(
index
,
-
1
,
-
1
)
:
index
=
i
if
yClose
!=
self
.
Data
[
index
].
Close
:
seed
*=
yClose
/
self
.
Data
[
index
].
Close
result
[
index
]
=
HistoryData
.
CopyRight
(
self
.
Data
[
index
],
seed
)
yClose
=
self
.
Data
[
index
].
YClose
elif
right
==
2
:
index
=
0
seed
=
1
close
=
self
.
Data
[
index
].
Close
result
[
index
]
=
HistoryData
.
Copy
(
self
.
Data
[
index
])
for
i
in
range
(
len
(
self
.
Data
))
:
index
=
i
if
close
!=
self
.
Data
[
index
].
YClose
:
break
result
[
index
]
=
HistoryData
.
Copy
(
self
.
Data
[
index
])
close
=
self
.
Data
[
index
].
Close
for
i
in
range
(
index
,
len
(
self
.
Data
))
:
index
=
i
if
close
!=
self
.
Data
[
index
].
YClose
:
seed
*=
close
/
self
.
Data
[
index
].
YClose
result
[
index
]
=
HistoryData
.
CopyRight
(
self
.
Data
[
index
],
seed
)
close
=
self
.
Data
[
index
].
Close
return
result
# 周期数据 1=周 2=月 3=年
def
GetPeriodData
(
self
,
period
)
:
if
period
in
(
1
,
2
,
3
)
:
return
self
.
GetDayPeriodData
(
period
)
if
period
in
(
5
,
6
,
7
,
8
)
:
return
self
.
GetMinutePeriodData
(
period
)
# 计算周,月,年
def
GetDayPeriodData
(
self
,
period
)
:
result
=
[]
startDate
=
0
newData
=
None
for
dayData
in
self
.
Data
:
isNewData
=
False
if
period
==
1
:
# 周线
fridayDate
=
ChartData
.
GetFirday
(
dayData
.
Date
)
if
fridayDate
!=
startDate
:
isNewData
=
True
startDate
=
fridayDate
elif
period
==
2
:
# 月线
if
int
(
dayData
.
Date
/
100
)
!=
int
(
startDate
/
100
)
:
isNewData
=
True
startDate
=
dayData
.
Date
elif
period
==
3
:
# 年线
if
int
(
dayData
.
Date
/
10000
)
!=
int
(
startDate
/
10000
)
:
isNewData
=
True
startDate
=
dayData
.
Date
if
isNewData
:
newData
=
HistoryData
()
newData
.
Date
=
dayData
.
Date
result
.
append
(
newData
)
if
dayData
.
Open
==
None
or
dayData
.
Close
==
None
:
continue
newData
.
Open
=
dayData
.
Open
newData
.
High
=
dayData
.
High
newData
.
Low
=
dayData
.
Low
newData
.
YClose
=
dayData
.
YClose
newData
.
Close
=
dayData
.
Close
newData
.
Vol
=
dayData
.
Vol
newData
.
Amount
=
dayData
.
Amount
newData
.
FlowCapital
=
dayData
.
FlowCapital
else
:
if
newData
==
None
:
continue
if
dayData
.
Open
==
None
or
dayData
.
Close
==
None
:
continue
if
newData
.
Open
==
None
or
newData
.
Close
==
None
:
newData
.
Open
=
dayData
.
Open
newData
.
High
=
dayData
.
High
newData
.
Low
=
dayData
.
Low
newData
.
YClose
=
dayData
.
YClose
newData
.
Close
=
dayData
.
Close
newData
.
Vol
=
dayData
.
Vol
newData
.
Amount
=
dayData
.
Amount
newData
.
FlowCapital
=
dayData
.
FlowCapital
else
:
if
newData
.
High
<
dayData
.
High
:
newData
.
High
=
dayData
.
High
if
newData
.
Low
>
dayData
.
Low
:
newData
.
Low
=
dayData
.
Low
newData
.
Close
=
dayData
.
Close
newData
.
Vol
+=
dayData
.
Vol
newData
.
Amount
+=
dayData
.
Amount
newData
.
FlowCapital
+=
dayData
.
FlowCapital
newData
.
Date
=
dayData
.
Date
return
result
@
staticmethod
def
GetFirday
(
value
)
:
date
=
datetime
.
datetime
.
strptime
(
str
(
value
),
'%Y%m%d'
)
day
=
date
.
weekday
()
if
day
==
4
:
return
value
date
+=
datetime
.
timedelta
(
days
=
4
-
day
)
fridayDate
=
date
.
year
*
10000
+
date
.
month
*
100
+
date
.
day
return
fridayDate
# 计算分钟
def
GetMinutePeriodData
(
self
,
period
)
:
result
=
[]
periodDataCount
=
5
if
period
==
5
:
periodDataCount
=
5
elif
period
==
6
:
periodDataCount
=
15
elif
period
==
7
:
periodDataCount
=
30
elif
period
==
8
:
periodDataCount
=
60
else
:
return
self
.
Data
bFirstPeriodData
=
False
newData
=
None
dataCount
=
len
(
self
.
Data
)
i
=-
1
while
i
<
dataCount
:
# for (var i = 0; i < this.Data.length; )
bFirstPeriodData
=
True
# for (var j = 0; j < periodDataCount && i < this.Data.length; ++i)
j
=
0
while
j
<
periodDataCount
and
i
<
dataCount
:
i
+=
1
if
i
>=
dataCount
:
break
if
bFirstPeriodData
:
newData
=
HistoryData
()
result
.
append
(
newData
)
bFirstPeriodData
=
False
minData
=
self
.
Data
[
i
]
if
minData
==
None
:
j
+=
1
continue
if
minData
.
Time
in
(
925
,
930
,
1300
)
:
pass
else
:
j
+=
1
newData
.
Date
=
minData
.
Date
newData
.
Time
=
minData
.
Time
if
minData
.
Open
==
None
or
minData
.
Close
==
None
:
continue
if
newData
.
Open
==
None
or
newData
.
Close
==
None
:
newData
.
Open
=
minData
.
Open
newData
.
High
=
minData
.
High
newData
.
Low
=
minData
.
Low
newData
.
YClose
=
minData
.
YClose
newData
.
Close
=
minData
.
Close
newData
.
Vol
=
minData
.
Vol
newData
.
Amount
=
minData
.
Amount
newData
.
FlowCapital
=
minData
.
FlowCapital
else
:
if
newData
.
High
<
minData
.
High
:
newData
.
High
=
minData
.
High
if
newData
.
Low
>
minData
.
Low
:
newData
.
Low
=
minData
.
Low
newData
.
Close
=
minData
.
Close
newData
.
Vol
+=
minData
.
Vol
newData
.
Amount
+=
minData
.
Amount
newData
.
FlowCapital
+=
minData
.
FlowCapital
return
result
umychart_python/umychart_complier_job.py
0 → 100644
浏览文件 @
0d7824ba
###############################################################################################
#
# 基础|财务|日线 等数据
#
#################################################################################################
import
sys
class
JS_EXECUTE_JOB_ID
:
JOB_DOWNLOAD_SYMBOL_DATA
=
1
# 下载股票的K线数据
JOB_DOWNLOAD_INDEX_DATA
=
2
# 下载大盘的K线数据
JOB_DOWNLOAD_SYMBOL_LATEST_DATA
=
3
# 最新的股票行情数据
JOB_DOWNLOAD_INDEX_INCREASE_DATA
=
4
# 涨跌股票个数统计数据
JOB_DOWNLOAD_VOLR_DATA
=
5
# 5日量比均量下载量比数据
# 财务函数
JOB_DOWNLOAD_TOTAL_EQUITY_DATA
=
100
# 总股本(万股)
JOB_DOWNLOAD_FLOW_EQUITY_DATA
=
101
# 流通股本(万股)
JOB_DOWNLOAD_PER_U_PROFIT_DATA
=
102
# 每股未分配利润
JOB_DOWNLOAD_PER_NETASSET_DATA
=
103
# 每股净资产
JOB_DOWNLOAD_PER_C_RESERVE_DATA
=
104
# 每股资本公积金
JOB_DOWNLOAD_PER_S_EARNING_DATA
=
105
# 每股收益
JOB_DOWNLOAD_PER_S_EARNING2_DATA
=
106
# 每股收益(折算为全年收益),对于沪深品种有效
JOB_DOWNLOAD_RELEASE_DATE_DATA
=
107
# 上市的天数
JOB_DOWNLOAD_N_PROFIT_DATA
=
108
# 净利润
JOB_DOWNLOAD_FLOW_MARKETVALUE_DATA
=
109
# 流通市值
JOB_DOWNLOAD_MARKETVALUE_DATA
=
110
# 总市值
JOB_DOWNLOAD_PROFIT_YOY_DATA
=
111
# 利润同比 (Profit year on year)
JOB_DOWNLOAD_AL_RATIO_DATA
=
112
# 资产负债率 (asset-liability ratio)
JOB_DOWNLOAD_DIVIDEND_YIELD_DATA
=
113
# 股息率
JOB_DOWNLOAD_CAPITAL_DATA
=
200
# 流通股本(手)
JOB_DOWNLOAD_EXCHANGE_DATA
=
201
# 换手率 成交量/流通股本*100
JOB_DOWNLOAD_MARGIN_BALANCE
=
1000
# 融资融券余额
JOB_DOWNLOAD_MARGIN_RATE
=
1001
# 融资占比
JOB_DOWNLOAD_MARGIN_BUY_BALANCE
=
1010
# 买入信息-融资余额
JOB_DOWNLOAD_MARGIN_BUY_AMOUNT
=
1011
# 买入信息-买入额
JOB_DOWNLOAD_MARGIN_BUY_REPAY
=
1012
# 买入信息-偿还额
JOB_DOWNLOAD_MARGIN_BUY_NET
=
1013
# 买入信息-融资净买入
JOB_DOWNLOAD_MARGIN_SELL_BALANCE
=
1020
# 卖出信息-融券余量
JOB_DOWNLOAD_MARGIN_SELL_VOLUME
=
1021
# 卖出信息-卖出量
JOB_DOWNLOAD_MARGIN_SELL_REPAY
=
1022
# 卖出信息-偿还量
JOB_DOWNLOAD_MARGIN_SELL_NET
=
1023
# 卖出信息-融券净卖出
JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE
=
2000
# 负面新闻统计
JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH
=
2001
# 机构调研
JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT
=
2002
# 互动易
JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE
=
2003
# 股东增持
JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2
=
2004
# 股东减持
JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER
=
2005
# 信托持股
JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING
=
2006
# 大宗交易
JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS
=
2007
# 官网新闻
JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS
=
2008
# 高管要闻
JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE
=
2009
# 股权质押
JOB_DOWNLOAD_HK_TO_SH
=
2050
,
# 北上流入上证
JOB_DOWNLOAD_HK_TO_SZ
=
2051
,
# 北上流入深证
JOB_DOWNLOAD_HK_TO_SH_SZ
=
2052
,
# /北上流总的
JOB_RUN_SCRIPT
=
10000
,
# 执行脚本
@
staticmethod
def
GetFinnanceJobID
(
value
):
dataMap
=
{
1
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_TOTAL_EQUITY_DATA
,
# FINANCE(1) 总股本(万股)
7
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_FLOW_EQUITY_DATA
,
# FINANCE(7) 流通股本(万股)
9
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_AL_RATIO_DATA
,
# FINANCE(9) 资产负债率 (asset-liability ratio)
18
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PER_C_RESERVE_DATA
,
# FINANCE(18) 每股公积金
30
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_N_PROFIT_DATA
,
# FINANCE(30) 净利润
32
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PER_U_PROFIT_DATA
,
# FINANCE(32) 每股未分配利润
33
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PER_S_EARNING2_DATA
,
# FINANCE(33) 每股收益(折算为全年收益),对于沪深品种有效
34
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PER_NETASSET_DATA
,
# FINANCE(34) 每股净资产
38
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PER_S_EARNING_DATA
,
# FINANCE(38) 每股收益(最近一期季报)
40
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_FLOW_MARKETVALUE_DATA
,
# FINANCE(40) 流通市值
41
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARKETVALUE_DATA
,
# FINANCE(41) 总市值
42
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_RELEASE_DATE_DATA
,
# FINANCE(42) 上市的天数
43
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_PROFIT_YOY_DATA
,
# FINANCE(43) 利润同比 (Profit year on year)
45
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_DIVIDEND_YIELD_DATA
,
# FINANCE(45) 股息率
200
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_CAPITAL_DATA
,
# 流通股本(手)
201
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_EXCHANGE_DATA
# 换手率 成交量/流通股本
}
return
dataMap
.
get
(
value
)
@
staticmethod
# 融资融券
def
GetMarginJobID
(
value
)
:
dataMap
=
{
1
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_BALANCE
,
# 换MARGIN(1) 融资融券余额
2
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_RATE
,
# 换MARGIN(2) 融资占比
3
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_BUY_BALANCE
,
# 换MARGIN(3) 买入信息-融资余额
4
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_BUY_AMOUNT
,
# 换MARGIN(4) 买入信息-买入额
5
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_BUY_REPAY
,
# 换MARGIN(5) 买入信息-偿还额
6
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_BUY_NET
,
# 换MARGIN(6) 买入信息-融资净买入
7
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_SELL_BALANCE
,
# 换MARGIN(7) 卖出信息-融券余量
8
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_SELL_VOLUME
,
# 换MARGIN(8) 卖出信息-卖出量
9
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_SELL_REPAY
,
# 换MARGIN(9) 卖出信息-偿还量
10
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_MARGIN_SELL_NET
,
# 换MARGIN(10) 卖出信息-融券净卖出
}
return
dataMap
.
get
(
value
)
@
staticmethod
# 北上资金
def
GetHK2SHSZJobID
(
value
)
:
dataMap
=
{
1
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_HK_TO_SH_SZ
,
# HK2SHSZ(1) 北上流总的
2
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_HK_TO_SH
,
# HK2SHSZ(2) 北上流入上证
3
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_HK_TO_SZ
,
# HK2SHSZ(3) 北上流入深证
}
return
dataMap
.
get
(
value
)
@
staticmethod
# 资讯类
def
GetNewsAnalysisID
(
value
):
dataMap
=
{
1
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE
,
# NEWS(1) 负面新闻统计
2
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH
,
# NEWS(2) 机构调研统计
3
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT
,
# NEWS(3) 互动易
4
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE
,
# NEWS(4) 股东增持
5
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2
,
# NEWS(5) 股东减持
6
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER
,
# NEWS(6) 信托持股
7
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING
,
# NEWS(7) 大宗交易
8
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS
,
# NEWS(8) 官网新闻
9
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS
,
# NEWS(9) 高管要闻
10
:
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE
,
# NEWS(10) 股权质押
}
return
dataMap
.
get
(
value
)
class
JobItem
:
def
__init__
(
self
,
id
,
symbol
=
None
)
:
self
.
ID
=
id
# 任务ID
self
.
Symbol
=
symbol
# 任务的代码 可以为空
\ No newline at end of file
umychart_python/umychart_complier_jsalgorithm.py
0 → 100644
浏览文件 @
0d7824ba
此差异已折叠。
点击以展开。
umychart_python/umychart_complier_jscomplier.py
0 → 100644
浏览文件 @
0d7824ba
import
sys
from
umychart_complier_scanner
import
Error
from
umychart_complier_jsparser
import
JSParser
,
Tokenizer
from
umychart_complier_jssymboldata
import
g_JSComplierResource
from
umychart_complier_jsexecute
import
JSExecute
#################################################################################################
#
#
#
##################################################################################################
class
JSComplier
:
@
staticmethod
# 词法分析
def
Tokenize
(
code
):
print
(
'[JSComplier::Tokenize] '
,
code
)
tokenizer
=
Tokenizer
(
code
)
tokens
=
[]
try
:
while
True
:
token
=
tokenizer
.
GetNextToken
()
if
not
token
:
break
tokens
.
append
(
token
)
except
Error
as
e
:
print
(
'[JSComplier::Tokenize] Error'
,
e
)
return
tokens
@
staticmethod
#语法解析 生成抽象语法树(Abstract Syntax Tree)
def
Parse
(
code
):
print
(
'[JSComplier::Parse]'
,
code
)
parser
=
JSParser
(
code
)
parser
.
Initialize
()
program
=
parser
.
ParseScript
()
ast
=
program
return
ast
@
staticmethod
#执行器
def
Execute
(
code
,
option
=
None
)
:
print
(
'[JSComplier::Execute] '
,
code
)
parser
=
JSParser
(
code
)
parser
.
Initialize
()
program
=
parser
.
ParseScript
()
ast
=
program
print
(
'[JSComplier.Execute] parser finish.'
)
execute
=
JSExecute
(
ast
,
option
)
execute
.
JobList
=
parser
.
Node
.
GetDataJobList
()
result
=
execute
.
Execute
()
return
result
@
staticmethod
# 修改API地址
def
SetDomain
(
domain
=
None
,
cacheDomain
=
None
)
:
if
domain
:
g_JSComplierResource
.
Domain
=
domain
if
cacheDomain
:
g_JSComplierResource
.
CacheDomain
=
cacheDomain
umychart_python/umychart_complier_jsexecute.py
0 → 100644
浏览文件 @
0d7824ba
######################################################################################
#
#
#
#####################################################################################
import
sys
from
umychart_complier_scanner
import
ErrorHandler
from
umychart_complier_job
import
JS_EXECUTE_JOB_ID
,
JobItem
from
umychart_complier_jsparser
import
Syntax
,
BinaryExpression
,
AssignmentExpression
from
umychart_complier_jssymboldata
import
JSSymbolData
,
g_JSComplierResource
from
umychart_complier_jsalgorithm
import
JSAlgorithm
,
JSDraw
#################################################################################################
#
# AST执行器
#
#################################################################################################
# 参数结构体
class
ArgumentItem
:
def
__init__
(
self
,
name
,
value
)
:
self
.
Name
=
name
self
.
Value
=
value
class
VariableItem
:
def
__init__
(
self
,
name
,
data
,
type
)
:
self
.
Name
=
name
self
.
Data
=
data
self
.
Type
=
type
class
JSExecute
:
def
__init__
(
self
,
ast
,
option
=
None
)
:
self
.
AST
=
ast
# 语法树
self
.
ErrorHandler
=
ErrorHandler
()
self
.
VarTable
=
{}
# 变量表
self
.
OutVarTable
=
[]
# 输出变量
self
.
Arguments
=
[]
# 脚本自动变量表, 只读
self
.
ConstVarTable
=
{
# 个股数据
'CLOSE'
:
None
,
'VOL'
:
None
,
'OPEN'
:
None
,
'HIGH'
:
None
,
'LOW'
:
None
,
'AMOUNT'
:
None
,
'C'
:
None
,
'V'
:
None
,
'O'
:
None
,
'H'
:
None
,
'L'
:
None
,
'VOLR'
:
None
,
# 日期类
'DATE'
:
None
,
'YEAR'
:
None
,
'MONTH'
:
None
,
'PERIOD'
:
None
,
'WEEK'
:
None
,
# 大盘数据
'INDEXA'
:
None
,
'INDEXC'
:
None
,
'INDEXH'
:
None
,
'INDEXL'
:
None
,
'INDEXO'
:
None
,
'INDEXV'
:
None
,
'INDEXADV'
:
None
,
'INDEXDEC'
:
None
,
# 到最后交易日的周期数
'CURRBARSCOUNT'
:
None
,
# 流通股本(手)
'CAPITAL'
:
None
,
# 换手率
'EXCHANGE'
:
None
,
'SETCODE'
:
None
}
self
.
SymbolData
=
JSSymbolData
(
ast
=
ast
,
option
=
option
)
self
.
Algorithm
=
JSAlgorithm
(
errorHandler
=
self
.
ErrorHandler
,
symbolData
=
self
.
SymbolData
)
self
.
Draw
=
JSDraw
(
errorHandler
=
self
.
ErrorHandler
,
symbolData
=
self
.
SymbolData
)
self
.
JobList
=
[]
# 执行的任务队列
def
Execute
(
self
)
:
self
.
SymbolData
.
RunDownloadJob
(
self
.
JobList
)
# 准备数据
outVar
=
self
.
RunAST
()
return
outVar
def
ReadSymbolData
(
self
,
name
,
node
)
:
if
name
in
(
'CLOSE'
,
'C'
,
'VOL'
,
'V'
,
'OPEN'
,
'O'
,
'HIGH'
,
'H'
,
'LOW'
,
'L'
,
'AMOUNT'
)
:
return
self
.
SymbolData
.
GetSymbolCacheData
(
name
)
elif
name
==
'VOLR'
:
# 量比
pass
# return self.SymbolData.GetVolRateCacheData(node)
elif
name
in
(
'INDEXA'
,
'INDEXC'
,
'INDEXH'
,
'INDEXH'
,
'INDEXO'
,
'INDEXV'
,
'INDEXL'
,
'INDEXADV'
,
'INDEXDEC'
)
:
# 大盘数据
pass
# return self.SymbolData.GetIndexCacheData(name)
elif
name
==
'CURRBARSCOUNT'
:
pass
# return self.SymbolData.GetCurrBarsCount()
elif
name
==
'CAPITAL'
:
pass
# return self.SymbolData.GetFinanceCacheData(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_CAPITAL_DATA)
elif
name
==
'EXCHANGE'
:
pass
# return self.SymbolData.GetFinanceCacheData(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_EXCHANGE_DATA)
elif
name
==
'SETCODE'
:
return
self
.
SymbolData
.
SETCODE
()
elif
name
==
'DATE'
:
return
self
.
SymbolData
.
DATE
()
elif
name
==
'YEAR'
:
return
self
.
SymbolData
.
YEAR
()
elif
name
==
'MONTH'
:
return
self
.
SymbolData
.
MONTH
()
elif
name
==
'WEEK'
:
return
self
.
SymbolData
.
WEEK
()
elif
name
==
'PERIOD'
:
return
self
.
SymbolData
.
PERIOD
()
# 读取变量
def
ReadVariable
(
self
,
name
,
node
)
:
if
name
in
self
.
ConstVarTable
:
data
=
self
.
ConstVarTable
[
name
]
if
not
data
:
# 动态加载,用到再加载
data
=
self
.
ReadSymbolData
(
name
,
node
)
self
.
ConstVarTable
[
name
]
=
data
return
data
if
name
in
self
.
VarTable
:
return
self
.
VarTable
[
name
]
self
.
ThrowUnexpectedNode
(
node
,
'变量'
+
name
+
'不存在'
)
return
None
# 单数据转成数组 个数和历史数据一致
def
SingleDataToArrayData
(
self
,
value
)
:
count
=
len
(
self
.
SymbolData
.
Data
.
Data
)
result
=
[
value
]
*
count
return
result
def
RunAST
(
self
)
:
# 预定义的变量
for
item
in
self
.
Arguments
:
self
.
VarTable
[
item
.
Name
]
=
item
.
Value
if
not
self
.
AST
or
not
self
.
AST
.
Body
:
self
.
ThrowError
()
for
item
in
self
.
AST
.
Body
:
self
.
VisitNode
(
item
)
if
item
.
Type
==
Syntax
.
ExpressionStatement
and
item
.
Expression
:
if
item
.
Expression
.
Type
==
Syntax
.
AssignmentExpression
and
item
.
Expression
.
Operator
==
':'
and
item
.
Expression
.
Left
:
assignmentItem
=
item
.
Expression
varName
=
assignmentItem
.
Left
.
Name
outVar
=
self
.
VarTable
[
varName
]
if
not
isinstance
(
outVar
,
list
)
:
outVar
=
self
.
SingleDataToArrayData
(
outVar
)
self
.
OutVarTable
.
append
(
VariableItem
(
name
=
varName
,
data
=
outVar
,
type
=
0
))
return
self
.
OutVarTable
def
VisitNode
(
self
,
node
)
:
if
node
.
Type
==
Syntax
.
SequenceExpression
:
self
.
VisitSequenceExpression
(
node
)
elif
node
.
Type
==
Syntax
.
ExpressionStatement
:
self
.
VisitNode
(
node
.
Expression
)
elif
node
.
Type
==
Syntax
.
AssignmentExpression
:
self
.
VisitAssignmentExpression
(
node
)
elif
node
.
Type
in
(
Syntax
.
BinaryExpression
,
Syntax
.
LogicalExpression
)
:
self
.
VisitBinaryExpression
(
node
)
elif
node
.
Type
==
Syntax
.
CallExpression
:
self
.
VisitCallExpression
(
node
)
def
VisitSequenceExpression
(
self
,
node
)
:
for
item
in
node
.
Expression
:
self
.
VisitNode
(
item
)
# 函数调用
def
VisitCallExpression
(
self
,
node
)
:
funcName
=
node
.
Callee
.
Name
args
=
[]
for
item
in
node
.
Arguments
:
if
item
.
Type
==
Syntax
.
BinaryExpression
or
item
.
Type
==
Syntax
.
LogicalExpression
:
value
=
self
.
VisitBinaryExpression
(
item
)
elif
item
.
Type
==
Syntax
.
CallExpression
:
value
=
self
.
VisitCallExpression
(
item
)
else
:
value
=
self
.
GetNodeValue
(
item
)
args
.
append
(
value
)
# console.log('[JSExecute::VisitCallExpression]' , funcName, '(', args.toString() ,')');
if
funcName
==
'DYNAINFO'
:
# 行情最新数据
node
.
Out
=
self
.
SymbolData
.
GetLatestCacheData
(
args
[
0
])
elif
funcName
==
'STICKLINE'
:
node
.
Draw
=
self
.
Draw
.
STICKLINE
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
])
node
.
Out
=
[]
elif
funcName
==
'DRAWTEXT'
:
node
.
Draw
=
self
.
Draw
.
DRAWTEXT
(
args
[
0
],
args
[
1
],
args
[
2
])
node
.
Out
=
[]
elif
funcName
==
'SUPERDRAWTEXT'
:
node
.
Draw
=
self
.
Draw
.
SUPERDRAWTEXT
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
])
node
.
Out
=
[]
elif
funcName
==
'DRAWICON'
:
node
.
Draw
=
self
.
Draw
.
DRAWICON
(
args
[
0
],
args
[
1
],
args
[
2
])
node
.
Out
=
[]
elif
funcName
==
'DRAWLINE'
:
node
.
Draw
=
self
.
Draw
.
DRAWLINE
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
])
node
.
Out
=
node
.
Draw
.
DrawData
elif
funcName
==
'DRAWBAND'
:
node
.
Draw
=
self
.
Draw
.
DRAWBAND
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
])
node
.
Out
=
[]
elif
funcName
==
'DRAWKLINE'
:
node
.
Draw
=
self
.
Draw
.
DRAWKLINE
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
])
node
.
Out
=
[]
elif
funcName
==
'DRAWKLINE_IF'
:
node
.
Draw
=
self
.
Draw
.
DRAWKLINE_IF
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
])
node
.
Out
=
[]
elif
funcName
in
(
'PLOYLINE'
,
'POLYLINE'
)
:
node
.
Draw
=
self
.
Draw
.
POLYLINE
(
args
[
0
],
args
[
1
])
node
.
Out
=
node
.
Draw
.
DrawData
elif
funcName
==
'DRAWNUMBER'
:
node
.
Draw
=
self
.
Draw
.
DRAWNUMBER
(
args
[
0
],
args
[
1
],
args
[
2
])
node
.
Out
=
node
.
Draw
.
DrawData
.
Value
elif
funcName
==
"DRAWCHANNEL"
:
node
.
Draw
=
self
.
Draw
.
DRAWCHANNEL
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
])
node
.
Out
=
[]
elif
funcName
==
'CODELIKE'
:
node
.
Out
=
self
.
SymbolData
.
CODELIKE
(
args
[
0
])
elif
funcName
==
'NAMELIKE'
:
node
.
Out
=
self
.
SymbolData
.
NAMELIKE
(
args
[
0
])
elif
funcName
==
'REFDATE'
:
node
.
Out
=
self
.
SymbolData
.
REFDATE
(
args
[
0
],
args
[
1
])
elif
funcName
==
'FINANCE'
:
node
.
Out
=
self
.
SymbolData
.
GetFinanceCacheData
(
args
[
0
],
node
)
elif
funcName
==
"MARGIN"
:
node
.
Out
=
self
.
SymbolData
.
GetMarginCacheData
(
args
[
0
],
node
)
elif
funcName
==
"HK2SHSZ"
:
node
.
Out
=
self
.
SymbolData
.
GetHKToSHSZCacheData
(
args
[
0
],
node
)
elif
funcName
==
"NEWS"
:
node
.
Out
=
self
.
SymbolData
.
GetNewsAnalysisCacheData
(
args
[
0
],
node
)
elif
funcName
in
(
'UPCOUNT'
,
'DOWNCOUNT'
)
:
node
.
Out
=
self
.
SymbolData
.
GetIndexIncreaseCacheData
(
funcName
,
args
[
0
],
node
)
else
:
node
.
Out
=
self
.
Algorithm
.
CallFunction
(
funcName
,
args
,
node
)
return
node
.
Out
# 赋值
def
VisitAssignmentExpression
(
self
,
node
)
:
left
=
node
.
Left
if
left
.
Type
!=
Syntax
.
Identifier
:
self
.
ThrowUnexpectedNode
(
node
)
varName
=
left
.
Name
right
=
node
.
Right
value
=
None
if
right
.
Type
==
Syntax
.
BinaryExpression
or
right
.
Type
==
Syntax
.
LogicalExpression
:
value
=
self
.
VisitBinaryExpression
(
right
)
elif
right
.
Type
==
Syntax
.
CallExpression
:
value
=
self
.
VisitCallExpression
(
right
)
elif
right
.
Type
==
Syntax
.
Literal
:
value
=
right
.
Value
elif
right
.
Type
==
Syntax
.
Identifier
:
# 右值是变量
value
=
self
.
ReadVariable
(
right
.
Name
,
right
)
# console.log('[JSExecute::VisitAssignmentExpression]' , varName, ' = ',value);
self
.
VarTable
[
varName
]
=
value
# 逻辑运算
def
VisitBinaryExpression
(
self
,
node
)
:
stack
=
[]
stack
.
append
(
node
)
temp
=
None
while
len
(
stack
)
!=
0
:
temp
=
stack
[
-
1
]
if
isinstance
(
temp
,(
BinaryExpression
,
AssignmentExpression
))
and
temp
.
Left
and
node
!=
temp
.
Left
and
node
!=
temp
.
Right
:
stack
.
append
(
temp
.
Left
)
elif
isinstance
(
temp
,(
BinaryExpression
,
AssignmentExpression
))
and
temp
.
Right
and
node
!=
temp
.
Right
:
stack
.
append
(
temp
.
Right
)
else
:
value
=
stack
.
pop
()
if
value
.
Type
==
Syntax
.
BinaryExpression
:
# 只遍历操作符就可以
leftValue
=
self
.
GetNodeValue
(
value
.
Left
)
rightValue
=
self
.
GetNodeValue
(
value
.
Right
)
# console.log('[JSExecute::VisitBinaryExpression] BinaryExpression',value , leftValue, rightValue);
value
.
Out
=
None
# 保存中间值
if
value
.
Operator
==
'-'
:
value
.
Out
=
self
.
Algorithm
.
Subtract
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'*'
:
value
.
Out
=
self
.
Algorithm
.
Multiply
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'/'
:
value
.
Out
=
self
.
Algorithm
.
Divide
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'+'
:
value
.
Out
=
self
.
Algorithm
.
Add
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'>'
:
value
.
Out
=
self
.
Algorithm
.
GT
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'>='
:
value
.
Out
=
self
.
Algorithm
.
GTE
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'<'
:
value
.
Out
=
self
.
Algorithm
.
LT
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'<='
:
value
.
Out
=
self
.
Algorithm
.
LTE
(
leftValue
,
rightValue
)
elif
value
.
Operator
==
'=='
:
value
.
Out
=
self
.
Algorithm
.
EQ
(
leftValue
,
rightValue
)
elif
value
.
Operator
in
(
'!='
,
'<>'
)
:
value
.
Out
=
self
.
Algorithm
.
NEQ
(
leftValue
,
rightValue
)
# console.log('[JSExecute::VisitBinaryExpression] BinaryExpression',value);
elif
value
.
Type
==
Syntax
.
LogicalExpression
:
leftValue
=
self
.
GetNodeValue
(
value
.
Left
)
rightValue
=
self
.
GetNodeValue
(
value
.
Right
)
# console.log('[JSExecute::VisitBinaryExpression] LogicalExpression',value , leftValue, rightValue);
value
.
Out
=
None
# 保存中间值
if
value
.
Operator
in
(
'&&'
,
'AND'
)
:
value
.
Out
=
self
.
Algorithm
.
And
(
leftValue
,
rightValue
)
elif
value
.
Operator
in
(
'||'
,
'OR'
)
:
value
.
Out
=
self
.
Algorithm
.
Or
(
leftValue
,
rightValue
)
# console.log('[JSExecute::VisitBinaryExpression] LogicalExpression',value);
node
=
temp
return
node
.
Out
def
GetNodeValue
(
self
,
node
)
:
if
node
.
Type
==
Syntax
.
Literal
:
#数字
return
node
.
Value
elif
node
.
Type
==
Syntax
.
UnaryExpression
:
if
node
.
Operator
==
'-'
:
value
=
self
.
GetNodeValue
(
node
.
Argument
)
return
self
.
Algorithm
.
Subtract
(
0
,
value
)
return
node
.
Argument
.
Value
elif
node
.
Type
==
Syntax
.
Identifier
:
value
=
self
.
ReadVariable
(
node
.
Name
,
node
)
return
value
elif
node
.
Type
in
(
Syntax
.
BinaryExpression
,
Syntax
.
LogicalExpression
)
:
return
node
.
Out
elif
node
.
Type
==
Syntax
.
CallExpression
:
return
self
.
VisitCallExpression
(
node
)
else
:
self
.
ThrowUnexpectedNode
(
node
)
def
ThrowUnexpectedNode
(
self
,
node
,
message
=
"执行异常"
)
:
marker
=
node
.
Marker
msg
=
message
return
self
.
ErrorHandler
.
ThrowError
(
marker
.
Index
,
marker
.
Line
,
marker
.
Column
,
msg
)
def
ThrowError
(
self
)
:
pass
umychart_python/umychart_complier_jsparser.py
0 → 100644
浏览文件 @
0d7824ba
此差异已折叠。
点击以展开。
umychart_python/umychart_complier_jssymboldata.py
0 → 100644
浏览文件 @
0d7824ba
#####################################################################
#
# 股票数据类
#
#####################################################################
import
sys
import
requests
# 网络数据下载
from
umychart_complier_job
import
JS_EXECUTE_JOB_ID
,
JobItem
from
umychart_complier_data
import
ChartData
,
HistoryData
# 全局api域名变量
class
JSComplierResource
:
def
__init__
(
self
)
:
self
.
Domain
=
"https://opensource.zealink.com"
# API域名
self
.
CacheDomain
=
"https://opensourcecache.zealink.com"
# 缓存域名
g_JSComplierResource
=
JSComplierResource
()
class
JSSymbolData
()
:
def
__init__
(
self
,
ast
,
option
=
None
)
:
self
.
AST
=
ast
# 语法树
self
.
Symbol
=
'600000.sh'
self
.
Name
=
None
self
.
Data
=
None
# 个股数据 (ChartData)
self
.
SourceData
=
None
# 不复权的个股数据 (ChartData)
self
.
MarketValue
=
None
# 总市值
self
.
Period
=
5
# 周期
self
.
Right
=
2
# 复权
self
.
DataType
=
0
# 默认K线数据 2=分钟走势图数据 3=多日分钟走势图
self
.
MaxRequestDataCount
=
1000
# 读取日线数据天数
self
.
MaxRequestMinuteDayCount
=
5
# 读取分钟数据天数
self
.
KLineApiUrl
=
g_JSComplierResource
.
Domain
+
"/API/KLine2"
# 日线
self
.
MinuteKLineApiUrl
=
g_JSComplierResource
.
Domain
+
'/API/KLine3'
# 分钟K线
self
.
RealtimeApiUrl
=
g_JSComplierResource
.
Domain
+
'/API/stock'
# 实时行情
# 准备数据
def
RunDownloadJob
(
self
,
jobList
)
:
for
job
in
jobList
:
if
job
.
ID
==
JS_EXECUTE_JOB_ID
.
JOB_DOWNLOAD_SYMBOL_DATA
:
self
.
GetSymbolData
()
# 下载股票数据
def
GetSymbolData
(
self
)
:
if
self
.
Data
:
return
if
self
.
Period
<=
3
:
# 请求日线数据
url
=
self
.
KLineApiUrl
postData
=
{
"field"
:
[
"name"
,
"symbol"
,
"yclose"
,
"open"
,
"price"
,
"high"
,
"low"
,
"vol"
,
'up'
,
'down'
,
'stop'
,
'unchanged'
],
"symbol"
:
[
self
.
Symbol
],
"start"
:
-
1
,
"count"
:
self
.
MaxRequestDataCount
}
print
(
'[JSSymbolData::GetSymbolData] '
,
self
.
Period
,
url
,
postData
)
response
=
requests
.
post
(
url
,
postData
)
jsonData
=
response
.
json
()
data
=
JSSymbolData
.
JsonDataToHistoryData
(
jsonData
)
self
.
SourceData
=
ChartData
(
data
=
data
,
dataType
=
self
.
DataType
)
self
.
Data
=
ChartData
(
data
=
data
,
dataType
=
self
.
DataType
)
if
self
.
Right
>
0
:
# 复权
rightData
=
self
.
Data
.
GetRightDate
(
self
.
Right
)
self
.
Data
.
Data
=
rightData
if
self
.
Period
>
0
and
self
.
Period
<=
3
:
# 周期数据
periodData
=
self
.
Data
.
GetPeriodData
(
self
.
Period
)
self
.
Data
.
Data
=
periodData
self
.
Data
.
Right
=
self
.
Right
self
.
Data
.
Period
=
self
.
Period
self
.
Name
=
jsonData
[
'name'
]
else
:
url
=
self
.
MinuteKLineApiUrl
postData
=
{
"field"
:
[
"name"
,
"symbol"
,
"yclose"
,
"open"
,
"price"
,
"high"
,
"low"
,
"vol"
],
"symbol"
:
self
.
Symbol
,
"start"
:
-
1
,
"count"
:
self
.
MaxRequestMinuteDayCount
}
print
(
'[JSSymbolData::GetSymbolData] '
,
self
.
Period
,
url
,
postData
)
response
=
requests
.
post
(
url
,
postData
)
jsonData
=
response
.
json
()
data
=
JSSymbolData
.
JsonDataToMinuteHistoryData
(
jsonData
)
self
.
SourceData
=
ChartData
(
data
=
data
,
dataType
=
self
.
DataType
)
self
.
Data
=
ChartData
(
data
=
data
,
dataType
=
self
.
DataType
)
if
self
.
Period
>=
5
:
# 周期数据
periodData
=
self
.
Data
.
GetPeriodData
(
self
.
Period
)
self
.
Data
.
Data
=
periodData
self
.
Data
.
Period
=
self
.
Period
self
.
Name
=
jsonData
[
'name'
]
@
staticmethod
# 日线数据转类
def
JsonDataToHistoryData
(
data
)
:
list
=
data
[
'data'
]
aryDayData
=
[]
date
=
0
yclose
=
1
open
=
2
high
=
3
low
=
4
close
=
5
vol
=
6
amount
=
7
up
=
8
down
=
9
stop
=
10
unchanged
=
11
for
item
in
list
:
if
item
[
open
]
<=
0
:
#停牌的数据剔除
continue
kData
=
HistoryData
()
kData
.
Date
=
item
[
date
]
kData
.
Open
=
item
[
open
]
kData
.
YClose
=
item
[
yclose
]
kData
.
Close
=
item
[
close
]
kData
.
High
=
item
[
high
]
kData
.
Low
=
item
[
low
]
kData
.
Vol
=
item
[
vol
]
# 原始单位股
kData
.
Amount
=
item
[
amount
]
# 上涨 下跌家数
fieldCount
=
len
(
item
)
if
fieldCount
>
up
:
kData
.
Up
=
item
[
up
]
if
fieldCount
>
down
:
kData
.
Down
=
item
[
down
]
if
fieldCount
>
stop
:
kData
.
Stop
=
item
[
stop
]
if
fieldCount
>
unchanged
:
kData
.
Unchanged
=
item
[
unchanged
]
aryDayData
.
append
(
kData
)
return
aryDayData
@
staticmethod
# 1分钟K线数据转类
def
JsonDataToMinuteHistoryData
(
data
):
list
=
data
[
'data'
]
aryDayData
=
[]
date
=
0
yclose
=
1
open
=
2
high
=
3
low
=
4
close
=
5
vol
=
6
amount
=
7
time
=
8
for
item
in
list
:
kData
=
HistoryData
()
kData
.
Date
=
item
[
date
]
kData
.
Time
=
item
[
time
]
kData
.
Open
=
item
[
open
]
kData
.
YClose
=
item
[
yclose
]
kData
.
Close
=
item
[
close
]
kData
.
High
=
item
[
high
]
kData
.
Low
=
item
[
low
]
kData
.
Vol
=
item
[
vol
]
# 原始单位股
kData
.
Amount
=
item
[
amount
]
aryDayData
.
append
(
kData
)
# 无效数据处理
for
i
,
minData
in
enumerate
(
aryDayData
)
:
if
not
minData
.
IsVaild
(
5
):
if
i
==
0
:
if
minData
.
YClose
>
0
:
minData
.
Open
=
minData
.
YClose
minData
.
High
=
minData
.
YClose
minData
.
Low
=
minData
.
YClose
minData
.
Close
=
minData
.
YClose
else
:
# 用前一个有效数据填充
for
j
in
range
(
i
-
1
,
-
1
,
-
1
)
:
minData2
=
aryDayData
[
j
]
if
minData2
.
IsVaild
(
4
)
:
if
minData
.
YClose
<=
0
or
minData
.
YClose
==
None
:
minData
.
YClose
=
minData2
.
Close
minData
.
Open
=
minData2
.
Open
minData
.
High
=
minData2
.
High
minData
.
Low
=
minData2
.
Low
minData
.
Close
=
minData2
.
Close
break
return
aryDayData
def
GetSymbolCacheData
(
self
,
dataName
)
:
if
not
self
.
Data
:
return
[]
if
dataName
in
(
'CLOSE'
,
'C'
)
:
return
self
.
Data
.
GetClose
()
elif
dataName
in
(
'VOL'
,
'V'
)
:
return
self
.
Data
.
GetVol
()
elif
dataName
in
(
'OPEN'
,
'O'
)
:
return
self
.
Data
.
GetOpen
()
elif
dataName
in
(
'HIGH'
,
'H'
)
:
return
self
.
Data
.
GetHigh
()
elif
dataName
in
(
'LOW'
,
'AMOUNT'
)
:
return
self
.
Data
.
GetLow
()
elif
dataName
in
(
'AMOUNT'
)
:
return
self
.
Data
.
GetAmount
()
# CODELIKE 模糊股票代码
def
CODELIKE
(
self
,
value
)
:
if
self
.
Symbol
and
self
.
Symbol
.
find
(
value
)
==
0
:
return
1
return
0
def
NAMELIKE
(
self
,
value
)
:
if
self
.
Name
and
self
.
Name
.
find
(
value
)
==
0
:
return
1
return
0
# SETCODE 市场类型
# 0:深圳 1:上海,47:中金所期货 28:郑州商品 29:大连商品 30:上海商品,27:香港指数 31:香港主板,48:香港创业板...
def
SETCODE
(
self
)
:
if
'.sh'
in
self
.
Symbol
:
return
1
if
'.sz'
in
self
.
Symbol
:
return
0
return
0
def
DATE
(
self
)
:
result
=
[]
if
not
self
.
Data
:
return
result
return
self
.
Data
.
GetDate
()
def
YEAR
(
self
)
:
result
=
[]
if
not
self
.
Data
:
return
result
return
self
.
Data
.
GetYear
()
def
MONTH
(
self
)
:
result
=
[]
if
not
self
.
Data
:
return
result
return
self
.
Data
.
GetMonth
()
def
WEEK
(
self
)
:
result
=
[]
if
not
self
.
Data
:
return
result
return
self
.
Data
.
GetWeek
()
# 用法:结果从0到11,依次分别是1/5/15/30/60分钟,日/周/月,多分钟,多日,季,年
def
PERIOD
(
self
)
:
# Period周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟
PERIOD_MAP
=
[
5
,
6
,
7
,
11
,
0
,
1
,
2
,
3
,
4
,
5
]
return
PERIOD_MAP
[
self
.
Period
]
umychart_python/umychart_complier_scanner.py
0 → 100644
浏览文件 @
0d7824ba
此差异已折叠。
点击以展开。
umychart_python/umychart_complier_testcase.py
0 → 100644
浏览文件 @
0d7824ba
import
sys
from
umychart_complier_jscomplier
import
JSComplier
def
Test_Tokenize
():
code1
=
'VARHIGH:=IF(VAR1<=REF(HH,-1),REF(H,BARSLAST(VAR1>=REF(HH,1))),DRAWNULL),COLORYELLOW;'
code2
=
'VAR1=((SMA(MAX((CLOSE - LC),0),3,1) / SMA(ABS((CLOSE - LC)),3,1)) * 100);'
tokens
=
JSComplier
.
Tokenize
(
code1
+
code2
)
return
True
if
tokens
else
False
def
Test_Parse
():
code1
=
'VARHIGH:=IF(VAR1<=REF(HH,-1),REF(H,BARSLAST(VAR1>=REF(HH,1))),DRAWNULL),COLORYELLOW;'
code2
=
'VAR1=((SMA(MAX((CLOSE - LC),0),3,1) / SMA(ABS((CLOSE - LC)),3,1)) * 100);'
ast
=
JSComplier
.
Parse
(
code1
+
code2
)
return
True
if
ast
else
False
def
Test_REF
():
result
=
JSComplier
.
Execute
(
'VAR2:C-REF(O,1)'
)
return
True
if
result
else
False
def
Test_Add
()
:
result
=
JSComplier
.
Execute
(
'VAR2:C+100'
)
return
True
if
result
else
False
def
Test_Multiply
():
code
=
[
'VAR2:C*O;'
,
"VAR3:100*100;"
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
])
return
True
if
result
else
False
def
Test_MAX_MIN
():
code
=
[
'VAR2:MAX(C,O);'
,
"VAR3:MAX(C,100);"
,
"VAR4:MAX(100,C);"
,
'VAR5:MIN(C,O);'
,
'VAR5:MIN(C,4);'
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
]
+
code
[
2
]
+
code
[
4
]
+
code
[
3
])
return
True
if
result
else
False
def
Test_MA
()
:
code
=
[
'VAR2:MA(C,5);'
,
'VAR3:MA(C,10);'
,
'VAR4:MA(C,15);'
,
'VAR4:MA(C,30);'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
]
+
code
[
2
]
+
code
[
3
])
return
True
if
result
else
False
def
Test_EMA
():
code
=
[
'VAR2:EMA(C,5);'
,
'VAR3:EMA(C,10);'
,
'VAR4:EMA(C,15);'
,
'VAR4:EMA(C,30);'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
]
+
code
[
2
]
+
code
[
3
])
return
True
if
result
else
False
def
Test_SMA
():
code
=
[
'VAR2:SMA(C,5,10);'
,
'VAR3:SMA(C,10,10);'
,
'VAR4:SMA(C,15,10);'
,
'VAR4:SMA(C,30,10);'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
]
+
code
[
2
]
+
code
[
3
])
return
True
if
result
else
False
def
Test_DMA
():
code
=
[
'VAR3:C;'
,
'VAR2:DMA(C,O/C);'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
])
return
True
if
result
else
False
def
Test_WMA
()
:
code
=
[
'VAR3:C;'
,
'VAR2:WMA(C,20);'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
])
return
True
if
result
else
False
def
Test_SUMBARS
()
:
code
=
[
'VAR3:SUMBARS(C,O)'
,
'VAR2:C;'
,
]
result
=
JSComplier
.
Execute
(
code
[
0
]
+
code
[
1
])
return
True
if
result
else
False
Test_Add
()
Test_Multiply
()
Test_MAX_MIN
()
Test_SUMBARS
()
\ No newline at end of file
umychart_python/umychart_complier_util.py
0 → 100644
浏览文件 @
0d7824ba
###########################################################################
#
#
#
##########################################################################
import
sys
#不同版本字符串操作函数
PY3
=
sys
.
version_info
>=
(
3
,
0
)
print
(
'[UMyChart.Complier] only support pythone 3. current version is '
,
sys
.
version_info
)
if
PY3
:
# Python 3:
basestring
=
str
long
=
int
xrange
=
range
unicode
=
str
uchr
=
chr
def
uord
(
ch
):
return
ord
(
ch
[
0
])
\ No newline at end of file
vuehqchart/src/jscommon/umychart.complier.js
浏览文件 @
0d7824ba
...
...
@@ -2478,7 +2478,7 @@ function JSAlgorithm(errorHandler,symbolData)
result
[
index
]
=
null
;
else
{
if
(
data
[
index
]
<
1
)
if
(
data
2
[
index
]
<
1
)
result
[
index
]
=
(
data2
[
index
]
*
data
[
index
])
+
(
1
-
data2
[
index
])
*
result
[
index
-
1
];
else
result
[
index
]
=
data
[
index
];
...
...
@@ -2646,9 +2646,10 @@ function JSAlgorithm(errorHandler,symbolData)
{
result
[
start
]
=
null
;
}
var
total
=
0
;
for
(
i
=
data
.
length
-
1
;
i
>=
start
;
--
i
)
{
var
total
=
0
;
for
(
j
=
i
,
total
=
0
;
j
>=
start
&&
total
<
data2
[
i
];
--
j
)
total
+=
data
[
j
];
if
(
j
<
start
)
result
[
i
]
=
null
;
...
...
vuehqchart/src/jscommon/umychart.stock.js
浏览文件 @
0d7824ba
...
...
@@ -609,12 +609,12 @@ function StockData(symbol)
if
(
this
.
Name
.
indexOf
(
'
ST
'
)
>=
0
)
{
this
.
MaxPrice
=
(
1
+
0.05
)
*
this
.
Open
;
this
.
MinPrice
=
(
1
-
0.05
)
*
this
.
O
P
en
;
this
.
MinPrice
=
(
1
-
0.05
)
*
this
.
O
p
en
;
}
else
{
this
.
MaxPrice
=
(
1
+
0.1
)
*
this
.
Open
;
this
.
MinPrice
=
(
1
-
0.1
)
*
this
.
O
P
en
;
this
.
MinPrice
=
(
1
-
0.1
)
*
this
.
O
p
en
;
}
if
(
this
.
Price
&&
this
.
YClose
)
...
...
vuehqchart/src/jscommon/umychart.vue/stockstringformat.js
浏览文件 @
0d7824ba
...
...
@@ -207,6 +207,15 @@ StockStringFormat.IsObjectExist=function(obj)
return
true
;
}
StockStringFormat
.
Guid
=
function
()
{
function
S4
()
{
return
(((
1
+
Math
.
random
())
*
0x10000
)
|
0
).
toString
(
16
).
substring
(
1
);
}
return
(
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
());
}
export
default
{
StockStringFormat
:
StockStringFormat
...
...
vuehqchart/src/jscommon/umychart.vue/umychart.stock.vue.js
浏览文件 @
0d7824ba
...
...
@@ -609,12 +609,12 @@ function StockData(symbol)
if
(
this
.
Name
.
indexOf
(
'
ST
'
)
>=
0
)
{
this
.
MaxPrice
=
(
1
+
0.05
)
*
this
.
Open
;
this
.
MinPrice
=
(
1
-
0.05
)
*
this
.
O
P
en
;
this
.
MinPrice
=
(
1
-
0.05
)
*
this
.
O
p
en
;
}
else
{
this
.
MaxPrice
=
(
1
+
0.1
)
*
this
.
Open
;
this
.
MinPrice
=
(
1
-
0.1
)
*
this
.
O
P
en
;
this
.
MinPrice
=
(
1
-
0.1
)
*
this
.
O
p
en
;
}
if
(
this
.
Price
&&
this
.
YClose
)
...
...
webhqchart.demo/jscommon/umychart.complier.js
浏览文件 @
0d7824ba
...
...
@@ -2478,7 +2478,7 @@ function JSAlgorithm(errorHandler,symbolData)
result
[
index
]
=
null
;
else
{
if
(
data
[
index
]
<
1
)
if
(
data
2
[
index
]
<
1
)
result
[
index
]
=
(
data2
[
index
]
*
data
[
index
])
+
(
1
-
data2
[
index
])
*
result
[
index
-
1
];
else
result
[
index
]
=
data
[
index
];
...
...
@@ -2646,9 +2646,10 @@ function JSAlgorithm(errorHandler,symbolData)
{
result
[
start
]
=
null
;
}
var
total
=
0
;
for
(
i
=
data
.
length
-
1
;
i
>=
start
;
--
i
)
{
var
total
=
0
;
for
(
j
=
i
,
total
=
0
;
j
>=
start
&&
total
<
data2
[
i
];
--
j
)
total
+=
data
[
j
];
if
(
j
<
start
)
result
[
i
]
=
null
;
...
...
webhqchart/umychart.complier.js
浏览文件 @
0d7824ba
...
...
@@ -2478,7 +2478,7 @@ function JSAlgorithm(errorHandler,symbolData)
result
[
index
]
=
null
;
else
{
if
(
data
[
index
]
<
1
)
if
(
data
2
[
index
]
<
1
)
result
[
index
]
=
(
data2
[
index
]
*
data
[
index
])
+
(
1
-
data2
[
index
])
*
result
[
index
-
1
];
else
result
[
index
]
=
data
[
index
];
...
...
@@ -2646,9 +2646,10 @@ function JSAlgorithm(errorHandler,symbolData)
{
result
[
start
]
=
null
;
}
var
total
=
0
;
for
(
i
=
data
.
length
-
1
;
i
>=
start
;
--
i
)
{
var
total
=
0
;
for
(
j
=
i
,
total
=
0
;
j
>=
start
&&
total
<
data2
[
i
];
--
j
)
total
+=
data
[
j
];
if
(
j
<
start
)
result
[
i
]
=
null
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录