hqchart 1.1.12687 → 1.1.12706

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.
Files changed (228) hide show
  1. package/lib/umychart.vue.js +94 -50
  2. package/package.json +15 -47
  3. package/src/jscommon/umychart.resource/js/codemirror/javascript.js +1 -1
  4. package/src/jscommon/umychart.uniapp.h5/umychart.uniapp.h5.js +409 -115
  5. package/src/jscommon/umychart.vue/umychart.vue.js +409 -115
  6. package/.babelrc +0 -6
  7. package/.vscode/settings.json +0 -4
  8. package/Makefile +0 -9
  9. package/README.md +0 -452
  10. package/index.js +0 -17
  11. package/postcss.config.js +0 -5
  12. package/src/index.html +0 -18
  13. package/src/jscommon/backup/announcement.png +0 -0
  14. package/src/jscommon/backup/announcement2.png +0 -0
  15. package/src/jscommon/backup/blocktrading.png +0 -0
  16. package/src/jscommon/backup/investor.png +0 -0
  17. package/src/jscommon/backup/pforecast.png +0 -0
  18. package/src/jscommon/backup/research.png +0 -0
  19. package/src/jscommon/backup/tradedetail.png +0 -0
  20. package/src/jscommon/backup/umychart - backup.js +0 -17631
  21. package/src/jscommon/backup/umychart.macro.js +0 -4
  22. package/src/jscommon/backup/umychart.macro.vue.js +0 -3
  23. package/src/jscommon/commonindextree.json +0 -92
  24. package/src/jscommon/index.html +0 -13
  25. package/src/jscommon/jschinamapdata.js +0 -3
  26. package/src/jscommon/umychart.NetworkFilterTest.js +0 -48803
  27. package/src/jscommon/umychart.aliYunnetwork.js +0 -47
  28. package/src/jscommon/umychart.cninfo.components/readme.txt +0 -1
  29. package/src/jscommon/umychart.complier.js +0 -25291
  30. package/src/jscommon/umychart.complier.node/umychart.complier.controller.js +0 -559
  31. package/src/jscommon/umychart.complier.node/umychart.complier.node.js +0 -7043
  32. package/src/jscommon/umychart.complier.node/umychart.data.node.js +0 -816
  33. package/src/jscommon/umychart.console.js +0 -12
  34. package/src/jscommon/umychart.deal.js +0 -1452
  35. package/src/jscommon/umychart.dragdiv.js +0 -48
  36. package/src/jscommon/umychart.index.data.js +0 -4132
  37. package/src/jscommon/umychart.js +0 -90257
  38. package/src/jscommon/umychart.keyboard.js +0 -1659
  39. package/src/jscommon/umychart.listctrl.js +0 -690
  40. package/src/jscommon/umychart.mind.js +0 -2203
  41. package/src/jscommon/umychart.network.js +0 -44
  42. package/src/jscommon/umychart.news.js +0 -823
  43. package/src/jscommon/umychart.node.build/buildall.bat +0 -1
  44. package/src/jscommon/umychart.node.build/umychart.node.bat +0 -1
  45. package/src/jscommon/umychart.node.build/umychart.node.export.js +0 -40
  46. package/src/jscommon/umychart.regressiontest.js +0 -400
  47. package/src/jscommon/umychart.report.js +0 -5803
  48. package/src/jscommon/umychart.scrollbar.js +0 -1345
  49. package/src/jscommon/umychart.stock.js +0 -4218
  50. package/src/jscommon/umychart.style.js +0 -618
  51. package/src/jscommon/umychart.testdata.js +0 -150
  52. package/src/jscommon/umychart.uniapp.build/buildall.bat +0 -1
  53. package/src/jscommon/umychart.uniapp.build/umychart.bat +0 -1
  54. package/src/jscommon/umychart.uniapp.build/umychart.export.js +0 -70
  55. package/src/jscommon/umychart.user.js +0 -137
  56. package/src/jscommon/umychart.version.js +0 -30
  57. package/src/jscommon/umychart.vue/umychart.aliYunnetwork.vue.js +0 -56
  58. package/src/jscommon/umychart.vue.build/buildall.bat +0 -4
  59. package/src/jscommon/umychart.vue.build/copy_codemirror.bat +0 -2
  60. package/src/jscommon/umychart.vue.build/umychart.aliYunnetwork.vue.export.js +0 -9
  61. package/src/jscommon/umychart.vue.build/umychart.dragdiv.bat +0 -1
  62. package/src/jscommon/umychart.vue.build/umychart.dragdiv.export.js +0 -6
  63. package/src/jscommon/umychart.vue.build/umychart.index.data.bat +0 -1
  64. package/src/jscommon/umychart.vue.build/umychart.index.data.export.js +0 -4
  65. package/src/jscommon/umychart.vue.build/umychart.listctrl.vue.export.js +0 -15
  66. package/src/jscommon/umychart.vue.build/umychart.regressiontest.vue.export.js +0 -7
  67. package/src/jscommon/umychart.vue.build/umychart.regressiontest.wechat.export.js +0 -12
  68. package/src/jscommon/umychart.vue.build/umychart.stock.bat +0 -1
  69. package/src/jscommon/umychart.vue.build/umychart.stock.vue.export.js +0 -16
  70. package/src/jscommon/umychart.vue.build/umychart.testdata.bat +0 -3
  71. package/src/jscommon/umychart.vue.build/umychart.testdata.vue.export.js +0 -7
  72. package/src/jscommon/umychart.vue.build/umychart.vue.bat +0 -8
  73. package/src/jscommon/umychart.vue.build/umychart.vue.export.js +0 -112
  74. package/src/jscommon/umychart.vue.components/empyt.vue +0 -51
  75. package/src/jscommon/umychart.vue.components/historydayline.vue +0 -240
  76. package/src/jscommon/umychart.vue.components/jsloader.adddialog.vue +0 -315
  77. package/src/jscommon/umychart.vue.components/jsloader.vue +0 -93
  78. package/src/jscommon/umychart.vue.components/jsvuecontainer.vue +0 -160
  79. package/src/jscommon/umychart.vue.components/jsvuecontainer2.0.vue +0 -391
  80. package/src/jscommon/umychart.vue.components/login.vue +0 -178
  81. package/src/jscommon/umychart.vue.components/queryContent.vue +0 -750
  82. package/src/jscommon/umychart.vue.components/readme.txt +0 -8
  83. package/src/jscommon/umychart.vue.components/searchsymbol.vue +0 -299
  84. package/src/jscommon/umychart.vue.components/simulatetrade.vue +0 -1471
  85. package/src/jscommon/umychart.vue.components/stockchart.vue +0 -343
  86. package/src/jscommon/umychart.vue.components/stockchartV2.vue +0 -195
  87. package/src/jscommon/umychart.vue.components/stockdeal.vue +0 -358
  88. package/src/jscommon/umychart.vue.components/stockdealcount.vue +0 -262
  89. package/src/jscommon/umychart.vue.components/stockdeallastest.vue +0 -316
  90. package/src/jscommon/umychart.vue.components/stockdrawtool.vue +0 -343
  91. package/src/jscommon/umychart.vue.components/stockfull.vue +0 -355
  92. package/src/jscommon/umychart.vue.components/stockinfo.demo.vue +0 -153
  93. package/src/jscommon/umychart.vue.components/stockinfo.vue +0 -685
  94. package/src/jscommon/umychart.vue.components/stockkline.demo.vue +0 -1904
  95. package/src/jscommon/umychart.vue.components/stockmultiorder.vue +0 -174
  96. package/src/jscommon/umychart.vue.components/stockmultiperiod.vue +0 -222
  97. package/src/jscommon/umychart.vue.components/stockorder.vue +0 -320
  98. package/src/jscommon/umychart.vue.components/stocktradeinfo.demo.vue +0 -250
  99. package/src/jscommon/umychart.vue.components/stocktradeinfo.vue +0 -1907
  100. package/src/jscommon/umychart.vue.components/test.vue +0 -0
  101. package/src/jscommon/umychart.wechat/getDate.wechat.js +0 -91
  102. package/src/jscommon/umychart.wechat/lighter.news.wechat.js +0 -262
  103. package/src/jscommon/umychart.wechat/readme.txt +0 -3
  104. package/src/jscommon/umychart.wechat/umychart.analyze.wechat.js +0 -551
  105. package/src/jscommon/umychart.wechat/umychart.apidraw.wechat.js +0 -126
  106. package/src/jscommon/umychart.wechat/umychart.bigV.wechat.js +0 -2510
  107. package/src/jscommon/umychart.wechat/umychart.chartframe.wechat.js +0 -2931
  108. package/src/jscommon/umychart.wechat/umychart.chartpaint.wechat.js +0 -9752
  109. package/src/jscommon/umychart.wechat/umychart.charttitle.wechat.js +0 -2023
  110. package/src/jscommon/umychart.wechat/umychart.complier.wechat.js +0 -14726
  111. package/src/jscommon/umychart.wechat/umychart.console.wechat.js +0 -8
  112. package/src/jscommon/umychart.wechat/umychart.coordinatedata.wechat.js +0 -3654
  113. package/src/jscommon/umychart.wechat/umychart.data.wechat.js +0 -2243
  114. package/src/jscommon/umychart.wechat/umychart.element.wechart.js +0 -132
  115. package/src/jscommon/umychart.wechat/umychart.explainer.wechat.js +0 -1077
  116. package/src/jscommon/umychart.wechat/umychart.extendchart.wechat.js +0 -1140
  117. package/src/jscommon/umychart.wechat/umychart.framesplit.wechat.js +0 -2247
  118. package/src/jscommon/umychart.wechat/umychart.hqIndexformula.wechat.js +0 -941
  119. package/src/jscommon/umychart.wechat/umychart.index.data.wechat.js +0 -3628
  120. package/src/jscommon/umychart.wechat/umychart.index.wechat.js +0 -4074
  121. package/src/jscommon/umychart.wechat/umychart.klineinfo.wechat.js +0 -836
  122. package/src/jscommon/umychart.wechat/umychart.markethot.js +0 -50
  123. package/src/jscommon/umychart.wechat/umychart.network.wechart.js +0 -62
  124. package/src/jscommon/umychart.wechat/umychart.news.wechat.js +0 -3568
  125. package/src/jscommon/umychart.wechat/umychart.regressiontest.wechat.js +0 -412
  126. package/src/jscommon/umychart.wechat/umychart.report.wechat.js +0 -3983
  127. package/src/jscommon/umychart.wechat/umychart.resource.wechat.js +0 -919
  128. package/src/jscommon/umychart.wechat/umychart.shareimage.wechat.js +0 -681
  129. package/src/jscommon/umychart.wechat/umychart.simulatetrade.wechat.js +0 -238
  130. package/src/jscommon/umychart.wechat/umychart.stock.wechat.js +0 -4035
  131. package/src/jscommon/umychart.wechat/umychart.style.wechat.js +0 -419
  132. package/src/jscommon/umychart.wechat/umychart.uniapp.canvas.helper.js +0 -99
  133. package/src/jscommon/umychart.wechat/umychart.user.wechat.js +0 -588
  134. package/src/jscommon/umychart.wechat/umychart.userlog.wechat.js +0 -240
  135. package/src/jscommon/umychart.wechat/umychart.vedio.wechat.js +0 -112
  136. package/src/jscommon/umychart.wechat/umychart.version.wechat.js +0 -36
  137. package/src/jscommon/umychart.wechat/umychart.wechat.3.0.js +0 -12051
  138. package/src/jscommon/umychart.wechat/umychart.wechat.js +0 -15460
  139. package/src/jscommon/umychart.worker.js +0 -114
  140. package/src/jscommon/umychart.ws.stock.js +0 -110
  141. package/src/jscommon/umychart_python/.vscode/launch.json +0 -15
  142. package/src/jscommon/umychart_python/__init__.py +0 -4
  143. package/src/jscommon/umychart_python/build.cmd +0 -2
  144. package/src/jscommon/umychart_python/setup.py +0 -25
  145. package/src/jscommon/umychart_python/umychart_cache_testcase.py +0 -165
  146. package/src/jscommon/umychart_python/umychart_complier_data.py +0 -781
  147. package/src/jscommon/umychart_python/umychart_complier_help.py +0 -175
  148. package/src/jscommon/umychart_python/umychart_complier_job.py +0 -193
  149. package/src/jscommon/umychart_python/umychart_complier_jsalgorithm.py +0 -4144
  150. package/src/jscommon/umychart_python/umychart_complier_jscomplier.py +0 -177
  151. package/src/jscommon/umychart_python/umychart_complier_jsexecute.py +0 -517
  152. package/src/jscommon/umychart_python/umychart_complier_jsparser.py +0 -864
  153. package/src/jscommon/umychart_python/umychart_complier_jssymboldata.py +0 -1238
  154. package/src/jscommon/umychart_python/umychart_complier_jssymboldata_cache.py +0 -146
  155. package/src/jscommon/umychart_python/umychart_complier_jssymboldata_json.py +0 -106
  156. package/src/jscommon/umychart_python/umychart_complier_pandas_help.py +0 -80
  157. package/src/jscommon/umychart_python/umychart_complier_scanner.py +0 -554
  158. package/src/jscommon/umychart_python/umychart_complier_testcase.py +0 -362
  159. package/src/jscommon/umychart_python/umychart_complier_util.py +0 -30
  160. package/src/jscommon/umychart_python/umychart_webtemplate.py +0 -131
  161. package/src/jscommon/umychart_python/updatehqchartweb.bat +0 -5
  162. package/src/jscommon/vendor.js +0 -2
  163. package/src/pages/block.list.demo.page/App.vue +0 -117
  164. package/src/pages/block.list.demo.page/index.js +0 -12
  165. package/src/pages/brushTool.demo.page/App.vue +0 -19
  166. package/src/pages/brushTool.demo.page/index.js +0 -12
  167. package/src/pages/container.demo.page/App.vue +0 -118
  168. package/src/pages/container.demo.page/index.js +0 -18
  169. package/src/pages/dataZoom.demo.page/App.vue +0 -265
  170. package/src/pages/dataZoom.demo.page/components/dataZoom.vue +0 -303
  171. package/src/pages/dataZoom.demo.page/index.js +0 -12
  172. package/src/pages/historydayline.demo.page/App.vue +0 -57
  173. package/src/pages/historydayline.demo.page/index.js +0 -12
  174. package/src/pages/hq.demo.page/App.vue +0 -163
  175. package/src/pages/hq.demo.page/index.js +0 -12
  176. package/src/pages/hqchart.black/App.vue +0 -90
  177. package/src/pages/hqchart.black/components/searchsymbol.vue +0 -299
  178. package/src/pages/hqchart.black/components/stockdrawtool.vue +0 -300
  179. package/src/pages/hqchart.black/components/stockfull.vue +0 -313
  180. package/src/pages/hqchart.black/components/stockinfo.vue +0 -428
  181. package/src/pages/hqchart.black/components/stockkline.demo.vue +0 -1652
  182. package/src/pages/hqchart.black/components/stocktradeinfo.vue +0 -1337
  183. package/src/pages/hqchart.black/index.js +0 -30
  184. package/src/pages/hqchart.black/router/candlestickChart.vue +0 -108
  185. package/src/pages/hqchart.black/router/pricePointsTable.vue +0 -294
  186. package/src/pages/hqchart.black/router/stockDeallas.vue +0 -417
  187. package/src/pages/hqchart.black/router/timeShareChart.vue +0 -108
  188. package/src/pages/hqchart.page/App.vue +0 -101
  189. package/src/pages/hqchart.page/index.js +0 -18
  190. package/src/pages/index/App.vue +0 -1408
  191. package/src/pages/index/index.js +0 -7
  192. package/src/pages/indexHq/App.vue +0 -110
  193. package/src/pages/indexHq/index.js +0 -18
  194. package/src/pages/login.demo.page/App.vue +0 -22
  195. package/src/pages/login.demo.page/index.js +0 -12
  196. package/src/pages/queryContent.demo.page/App.vue +0 -29
  197. package/src/pages/queryContent.demo.page/index.js +0 -18
  198. package/src/pages/ranking.black/App.vue +0 -199
  199. package/src/pages/ranking.black/index.js +0 -18
  200. package/src/pages/search.demo.page/App.vue +0 -28
  201. package/src/pages/search.demo.page/index.js +0 -12
  202. package/src/pages/simulatetrade.demo.page/app.vue +0 -121
  203. package/src/pages/simulatetrade.demo.page/index.js +0 -17
  204. package/src/pages/stockdeal.demo.page/App.vue +0 -63
  205. package/src/pages/stockdeal.demo.page/index.js +0 -19
  206. package/src/pages/stockdealcount.demo.page/App.vue +0 -37
  207. package/src/pages/stockdealcount.demo.page/index.js +0 -12
  208. package/src/pages/stockdeallastest.demo.page/App.vue +0 -74
  209. package/src/pages/stockdeallastest.demo.page/index.js +0 -18
  210. package/src/pages/stockinfo.demo.page/App.vue +0 -92
  211. package/src/pages/stockinfo.demo.page/index.html +0 -13
  212. package/src/pages/stockinfo.demo.page/index.js +0 -19
  213. package/src/pages/stockkline.demo.page/App.vue +0 -55
  214. package/src/pages/stockkline.demo.page/index.js +0 -18
  215. package/src/pages/stockmultiorder.demo.page/App.vue +0 -149
  216. package/src/pages/stockmultiorder.demo.page/index.js +0 -18
  217. package/src/pages/stockmultiperiod.demo.page/App.vue +0 -87
  218. package/src/pages/stockmultiperiod.demo.page/index.js +0 -18
  219. package/src/pages/stockorder.demo.page/App.vue +0 -69
  220. package/src/pages/stockorder.demo.page/index.js +0 -18
  221. package/src/pages/test/App.vue +0 -22
  222. package/src/pages/test/index.js +0 -7
  223. package/src/pages/tradeinfopage/app.vue +0 -40
  224. package/src/pages/tradeinfopage/index.js +0 -7
  225. package/src/pages/tradeinfopage/tradeinfo.html +0 -12
  226. package/src/utils/urlObj.js +0 -81
  227. package/src/vendor.js +0 -2
  228. package/webpack.config.js +0 -104
@@ -1,4144 +0,0 @@
1
- # Copyright (c) 2018 jones
2
- #
3
- # http://www.apache.org/licenses/LICENSE-2.0
4
- #
5
- # 开源项目 https://github.com/jones2000/HQChart
6
- #
7
- # jones_2000@163.com
8
-
9
-
10
- import sys
11
- import math
12
- import copy
13
- from umychart_complier_jssymboldata import JSSymbolData, g_JSComplierResource
14
- from umychart_complier_help import JSComplierHelper ,Variant
15
-
16
-
17
- #######################################################################################################
18
- #
19
- # 算法类
20
- #
21
- #######################################################################################################
22
- class JSAlgorithm() :
23
- def __init__(self, errorHandler, symbolData) :
24
- self.ErrorHandler=errorHandler
25
- self.SymbolData=symbolData # 股票数据
26
-
27
- @staticmethod
28
- def IsNumber(value):
29
- return JSComplierHelper.IsNumber(value)
30
-
31
- @staticmethod
32
- def IsDivideNumber(value):
33
- return JSComplierHelper.IsDivideNumber(value)
34
-
35
- @staticmethod
36
- def IsArray(value) :
37
- return isinstance(value,list)
38
-
39
- @staticmethod # value 和 value2 是否都是数值型
40
- def Is2Number(value,value2) :
41
- return JSComplierHelper.IsNumber(value) and JSComplierHelper.IsNumber(value2)
42
-
43
- @staticmethod # value 和 value2 是否有1个是非数值行
44
- def Is2NaN(value, value2) :
45
- bValue=JSComplierHelper.IsNaN(value)
46
- bValue2=JSComplierHelper.IsNaN(value2)
47
- return bValue or bValue2
48
- #return JSComplierHelper.IsNaN(value) or JSComplierHelper.IsNaN(value2)
49
-
50
- @staticmethod
51
- def IsNaN(value) :
52
- return JSComplierHelper.IsNaN(value)
53
-
54
- @staticmethod
55
- def CreateArray(count, value=JSComplierHelper.NoneNumber) :
56
- return JSComplierHelper.CreateArray(count,value)
57
-
58
- @staticmethod # 是否是一个有效素组 data!=null and data.length>0
59
- def IsVaildArray(data) :
60
- if not data :
61
- return False
62
- if not isinstance(data,list):
63
- return False
64
- if len(data)<=0 :
65
- return False
66
- return True
67
-
68
- @staticmethod # 计算数组均值
69
- def ArrayAverage(data,n) :
70
- dataLen=len(data)
71
- averageData=JSAlgorithm.CreateArray(dataLen) # 平均值
72
- for i in range(n-1, dataLen) :
73
- total=0
74
- for j in range(n) :
75
- if JSAlgorithm.IsNumber(data[i-j]) :
76
- total+=data[i-j]
77
- averageData[i]=total/n
78
- return averageData
79
-
80
-
81
- ######################################################################################
82
- #
83
- # 四则运算 + - * /
84
- #
85
- ########################################################################################
86
-
87
- # 相加
88
- def Add(self, data, data2) :
89
- isNumber=JSAlgorithm.IsNumber(data)
90
- isNumber2=JSAlgorithm.IsNumber(data2)
91
-
92
- if isNumber and isNumber2 : # 单数值相加
93
- return data+data2
94
-
95
- # 都是数组相加
96
- if not isNumber and not isNumber2 :
97
- len1=len(data)
98
- len2=len(data2)
99
- count=max(len1, len2)
100
- result=JSAlgorithm.CreateArray(count) # 初始化
101
- for i in range(count) :
102
- if i<len1 and i<len2 and JSAlgorithm.Is2Number(data[i],data2[i]) :
103
- result[i]=data[i]+data2[i]
104
-
105
- return result
106
-
107
- # 单数据和数组相加
108
- if isNumber :
109
- value=data
110
- aryData=data2
111
- else :
112
- value=data2
113
- aryData=data
114
-
115
- count=len(aryData)
116
- result=JSAlgorithm.CreateArray(count)
117
- for i in range(count) :
118
- if JSAlgorithm.Is2Number(aryData[i],value) :
119
- result[i]=value+aryData[i]
120
-
121
- return result
122
-
123
- # 相减
124
- def Subtract(self, data,data2) :
125
- isNumber=JSAlgorithm.IsNumber(data)
126
- isNumber2=JSAlgorithm.IsNumber(data2)
127
-
128
- # 单数值相减
129
- if isNumber and isNumber2 :
130
- return data-data2
131
-
132
- # 都是数组相减
133
-
134
- if not isNumber and not isNumber2 :
135
- len1=len(data)
136
- len2=len(data2)
137
- count=max(len1, len2)
138
- result=JSAlgorithm.CreateArray(count)
139
- for i in range(count) :
140
- if i<len1 and i<len2 and JSAlgorithm.Is2Number(data[i],data2[i]) :
141
- result[i]=data[i]-data2[i]
142
-
143
- return result
144
-
145
- if isNumber : # 单数据-数组
146
- count=len(data2)
147
- result=JSAlgorithm.CreateArray(count)
148
- for i in range(count) :
149
- if JSAlgorithm.Is2Number(data,data2[i]) :
150
- result[i]=data-data2[i]
151
- else : # 数组-单数据
152
- count=len(data)
153
- result=JSAlgorithm.CreateArray(count)
154
- for i in range(count) :
155
- if JSAlgorithm.Is2Number(data[i],data2) :
156
- result[i]=data[i]-data2
157
-
158
- return result
159
-
160
- # 相乘
161
- def Multiply(self,data,data2) :
162
- isNumber=JSAlgorithm.IsNumber(data)
163
- isNumber2=JSAlgorithm.IsNumber(data2)
164
-
165
- # 单数值相乘
166
- if isNumber and isNumber2 :
167
- return data*data2
168
-
169
- # 都是数组相乘
170
- if not isNumber and not isNumber2 :
171
- len1, len2 = len(data), len(data2)
172
- count=max(len1, len2)
173
- result=JSAlgorithm.CreateArray(count) # 初始化
174
- for i in range(count) :
175
- if i<len1 and i<len2 and JSAlgorithm.Is2Number(data[i],data2[i]) :
176
- result[i]=data[i]*data2[i]
177
-
178
- return result
179
-
180
- # 单数据和数组相乘
181
- if isNumber :
182
- value=data
183
- aryData=data2
184
- else :
185
- value=data2
186
- aryData=data
187
-
188
- count=len(aryData)
189
- result=JSAlgorithm.CreateArray(count) # 初始化
190
- for i in range(count) :
191
- if JSAlgorithm.Is2Number(aryData[i],value) :
192
- result[i]=value*aryData[i]
193
-
194
- return result
195
-
196
- # 相除
197
- def Divide(self, data,data2) :
198
- isNumber=JSAlgorithm.IsNumber(data)
199
- isNumber2=JSAlgorithm.IsNumber(data2)
200
-
201
- # 单数值相除
202
- if isNumber and isNumber2 :
203
- if data2==0 : # 除0判断
204
- return None
205
- return data/data2
206
-
207
- # 都是数组相除
208
- if not isNumber and not isNumber2 :
209
- len1, len2 = len(data), len(data2)
210
- count=max(len1, len2)
211
- result=JSAlgorithm.CreateArray(count) # 初始化
212
- for i in range(count) :
213
- if i<len1 and i<len2 and JSAlgorithm.IsNumber(data[i]) and JSAlgorithm.IsDivideNumber(data2[i]) :
214
- result[i]=data[i]/data2[i]
215
-
216
- return result
217
-
218
- if isNumber : # 单数据-数组
219
- count=len(data2)
220
- result=JSAlgorithm.CreateArray(count) # 初始化
221
- for i in range(count) :
222
- if JSAlgorithm.IsNumber(data) and JSAlgorithm.IsDivideNumber(data2[i]) :
223
- result[i]=data/data2[i]
224
- else : # 数组-单数据
225
- count=len(data)
226
- result=JSAlgorithm.CreateArray(count) # 初始化
227
- for i in range(count) :
228
- if JSAlgorithm.IsNumber(data[i]) and JSAlgorithm.IsDivideNumber(data2) :
229
- result[i]=data[i]/data2
230
-
231
- return result
232
-
233
- ############################################################################################
234
- #
235
- # 逻辑运算 > >= < <= = !=
236
- #
237
- #############################################################################################
238
-
239
- # 大于 >
240
- def GT(self, data,data2) :
241
- isNumber=JSAlgorithm.IsNumber(data)
242
- isNumber2=JSAlgorithm.IsNumber(data2)
243
-
244
- # 单数值比较
245
- if isNumber and isNumber2 :
246
- return 1 if data>data2 else 0
247
-
248
- # 都是数组比较
249
- if not isNumber and not isNumber2 :
250
- len1, len2 = len(data), len(data2)
251
- count=max(len1, len2)
252
- result=JSComplierHelper.CreateArray(count) # 初始化
253
- for i in range(count) :
254
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
255
- result[i]= 1 if data[i]>data2[i] else 0
256
-
257
- return result
258
-
259
-
260
- if isNumber : # 单数据-数组
261
- count=len(data2)
262
- result=JSComplierHelper.CreateArray(count) # 初始化
263
- for i in range(count) :
264
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
265
- result[i]=1 if data>data2[i] else 0
266
-
267
- else : # 数组-单数据
268
- count=len(data)
269
- result=JSComplierHelper.CreateArray(count) # 初始化
270
- for i in range(count) :
271
- if not JSAlgorithm.Is2NaN(data[i],data2) :
272
- result[i]=1 if data[i]>data2 else 0
273
-
274
- return result
275
-
276
- # 大于等于 >=
277
- def GTE(self, data,data2) :
278
- isNumber=JSAlgorithm.IsNumber(data)
279
- isNumber2=JSAlgorithm.IsNumber(data2)
280
-
281
- # 单数值比较
282
- if isNumber and isNumber2 :
283
- return 1 if data>=data2 else 0
284
-
285
- # 都是数组比较
286
- if not isNumber and not isNumber2 :
287
- len1, len2 = len(data), len(data2)
288
- count=max(len1, len2)
289
- result=JSComplierHelper.CreateArray(count) # 初始化
290
- for i in range(count) :
291
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
292
- result[i]= 1 if data[i]>=data2[i] else 0
293
-
294
- return result
295
-
296
-
297
- if isNumber : # 单数据-数组
298
- count=len(data2)
299
- result=JSComplierHelper.CreateArray(count) # 初始化
300
- for i in range(count) :
301
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
302
- result[i]=1 if data>=data2[i] else 0
303
-
304
- else : # 数组-单数据
305
- count=len(data)
306
- result=JSComplierHelper.CreateArray(count) # 初始化
307
- for i in range(count) :
308
- if not JSAlgorithm.Is2NaN(data[i],data2) :
309
- result[i]=1 if data[i]>=data2 else 0
310
-
311
- return result
312
-
313
- # 小于 <
314
- def LT(self,data,data2) :
315
- isNumber=JSAlgorithm.IsNumber(data)
316
- isNumber2=JSAlgorithm.IsNumber(data2)
317
-
318
- # 单数值比较
319
- if isNumber and isNumber2 :
320
- return 1 if data<data2 else 0
321
-
322
- # 都是数组比较
323
- if not isNumber and not isNumber2 :
324
- len1, len2 = len(data), len(data2)
325
- count=max(len1, len2)
326
- result=JSComplierHelper.CreateArray(count) # 初始化
327
- for i in range(count) :
328
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
329
- result[i]= 1 if data[i]<data2[i] else 0
330
-
331
- return result
332
-
333
-
334
- if isNumber : # 单数据-数组
335
- count=len(data2)
336
- result=JSComplierHelper.CreateArray(count) # 初始化
337
- for i in range(count) :
338
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
339
- result[i]=1 if data<data2[i] else 0
340
-
341
- else : # 数组-单数据
342
- count=len(data)
343
- result=JSComplierHelper.CreateArray(count) # 初始化
344
- for i in range(count) :
345
- if not JSAlgorithm.Is2NaN(data[i],data2) :
346
- result[i]=1 if data[i]<data2 else 0
347
-
348
- return result
349
-
350
- # 小于等于
351
- def LTE(self,data,data2) :
352
- isNumber=JSAlgorithm.IsNumber(data)
353
- isNumber2=JSAlgorithm.IsNumber(data2)
354
-
355
- # 单数值比较
356
- if isNumber and isNumber2 :
357
- return 1 if data<=data2 else 0
358
-
359
- # 都是数组比较
360
- if not isNumber and not isNumber2 :
361
- len1, len2 = len(data), len(data2)
362
- count=max(len1, len2)
363
- result=JSComplierHelper.CreateArray(count) # 初始化
364
- for i in range(count) :
365
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
366
- result[i]= 1 if data[i]<=data2[i] else 0
367
-
368
- return result
369
-
370
-
371
- if isNumber : # 单数据-数组
372
- count=len(data2)
373
- result=JSComplierHelper.CreateArray(count) # 初始化
374
- for i in range(count) :
375
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
376
- result[i]=1 if data<=data2[i] else 0
377
-
378
- else : # 数组-单数据
379
- count=len(data)
380
- result=JSComplierHelper.CreateArray(count) # 初始化
381
- for i in range(count) :
382
- if not JSAlgorithm.Is2NaN(data[i],data2) :
383
- result[i]=1 if data[i]<=data2 else 0
384
-
385
- return result
386
-
387
- # 等于
388
- def EQ(self, data,data2) :
389
- isNumber=JSAlgorithm.IsNumber(data)
390
- isNumber2=JSAlgorithm.IsNumber(data2)
391
-
392
- # 单数值比较
393
- if isNumber and isNumber2 :
394
- return 1 if data==data2 else 0
395
-
396
- # 都是数组比较
397
- if not isNumber and not isNumber2 :
398
- len1, len2 = len(data), len(data2)
399
- count=max(len1, len2)
400
- result=JSComplierHelper.CreateArray(count) # 初始化
401
- for i in range(count) :
402
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
403
- result[i]= 1 if data[i]==data2[i] else 0
404
-
405
- return result
406
-
407
-
408
- if isNumber : # 单数据-数组
409
- count=len(data2)
410
- result=JSComplierHelper.CreateArray(count) # 初始化
411
- for i in range(count) :
412
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
413
- result[i]=1 if data==data2[i] else 0
414
-
415
- else : # 数组-单数据
416
- count=len(data)
417
- result=JSComplierHelper.CreateArray(count) # 初始化
418
- for i in range(count) :
419
- if not JSAlgorithm.Is2NaN(data[i],data2) :
420
- result[i]=1 if data[i]==data2 else 0
421
-
422
- return result
423
-
424
- # 不等于
425
- def NEQ(self, data,data2) :
426
- isNumber=JSAlgorithm.IsNumber(data)
427
- isNumber2=JSAlgorithm.IsNumber(data2)
428
-
429
- # 单数值比较
430
- if isNumber and isNumber2 :
431
- return 1 if data!=data2 else 0
432
-
433
- # 都是数组比较
434
- if not isNumber and not isNumber2 :
435
- len1, len2 = len(data), len(data2)
436
- count=max(len1, len2)
437
- result=JSComplierHelper.CreateArray(count) # 初始化
438
- for i in range(count) :
439
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
440
- result[i]= 1 if data[i]!=data2[i] else 0
441
-
442
- return result
443
-
444
-
445
- if isNumber : # 单数据-数组
446
- count=len(data2)
447
- result=JSComplierHelper.CreateArray(count) # 初始化
448
- for i in range(count) :
449
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
450
- result[i]=1 if data!=data2[i] else 0
451
-
452
- else : # 数组-单数据
453
- count=len(data)
454
- result=JSComplierHelper.CreateArray(count) # 初始化
455
- for i in range(count) :
456
- if not JSAlgorithm.Is2NaN(data[i],data2) :
457
- result[i]=1 if data[i]!=data2 else 0
458
-
459
- return result
460
-
461
- ############################################################################################
462
- #
463
- # 逻辑运算 and, or
464
- #
465
- #############################################################################################
466
-
467
- # AND &&
468
- def And(self, data,data2):
469
- isNumber=JSAlgorithm.IsNumber(data)
470
- isNumber2=JSAlgorithm.IsNumber(data2)
471
-
472
- # 单数值比较
473
- if isNumber and isNumber2 :
474
- return 1 if data and data2 else 0
475
-
476
- # 都是数组比较
477
- result=[]
478
- if not isNumber and not isNumber2 :
479
- len1, len2 = len(data), len(data2)
480
- count=max(len1, len2)
481
- result=JSComplierHelper.CreateArray(count) # 初始化
482
- for i in range(count) :
483
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
484
- result[i]= 1 if data[i] and data2[i] else 0
485
-
486
- return result
487
-
488
-
489
- if isNumber : # 单数据-数组
490
- count=len(data2)
491
- result=JSComplierHelper.CreateArray(count) # 初始化
492
- for i in range(count) :
493
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
494
- result[i]=1 if data and data2[i] else 0
495
-
496
- else : # 数组-单数据
497
- count=len(data)
498
- result=JSComplierHelper.CreateArray(count) # 初始化
499
- for i in range(count) :
500
- if not JSAlgorithm.Is2NaN(data[i],data2) :
501
- result[i]=1 if data[i] and data2 else 0
502
-
503
- return result
504
-
505
- # OR ||
506
- def Or(self, data,data2) :
507
- isNumber=JSAlgorithm.IsNumber(data)
508
- isNumber2=JSAlgorithm.IsNumber(data2)
509
-
510
- # 单数值比较
511
- if isNumber and isNumber2 :
512
- return 1 if data or data2 else 0
513
-
514
- # 都是数组比较
515
- result=[]
516
- if not isNumber and not isNumber2 :
517
- len1, len2 = len(data), len(data2)
518
- count=max(len1, len2)
519
- result=JSComplierHelper.CreateArray(count) # 初始化
520
- for i in range(count) :
521
- if i<len1 and i<len2 and not JSAlgorithm.Is2NaN(data[i],data2[i]) :
522
- result[i]= 1 if data[i] or data2[i] else 0
523
-
524
- return result
525
-
526
-
527
- if isNumber : # 单数据-数组
528
- count=len(data2)
529
- result=JSComplierHelper.CreateArray(count) # 初始化
530
- for i in range(count) :
531
- if not JSAlgorithm.Is2NaN(data,data2[i]) :
532
- result[i]=1 if data or data2[i] else 0
533
-
534
- else : # 数组-单数据
535
- count=len(data)
536
- result=JSComplierHelper.CreateArray(count) # 初始化
537
- for i in range(count) :
538
- if not JSAlgorithm.Is2NaN(data[i],data2) :
539
- result[i]=1 if data[i] or data2 else 0
540
-
541
- return result
542
-
543
- ##########################################################################
544
- #
545
- # 条件语句 if , ifn
546
- #
547
- #########################################################################
548
-
549
- def IF(self,data,trueData,falseData) :
550
- isNumber=JSAlgorithm.IsNumber(data)
551
- isNumber2=JSAlgorithm.IsNumber(trueData)
552
- isNumber3=JSAlgorithm.IsNumber(falseData)
553
-
554
- # 单数值
555
- if isNumber :
556
- if isNumber2 and isNumber3 :
557
- return trueData if data else falseData
558
- return trueData if data else falseData
559
-
560
- # 都是数组
561
- count=len(data)
562
- result=JSComplierHelper.CreateArray(count)
563
- for i in range(count) :
564
- if data[i] :
565
- if isNumber2 :
566
- result[i]=trueData
567
- else :
568
- result[i]=trueData[i]
569
- else :
570
- if isNumber3 :
571
- result[i]=falseData
572
- else :
573
- result[i]=falseData[i]
574
-
575
- return result
576
-
577
-
578
- # 根据条件求不同的值,同IF判断相反.
579
- # 用法: IFN(X,A,B)若X不为0则返回B,否则返回A
580
- # 例如: IFN(CLOSE>OPEN,HIGH,LOW)表示该周期收阴则返回最高值,否则返回最低值
581
- def IFN(self, data,trueData,falseData) :
582
- return self.IF(data,falseData,trueData)
583
-
584
- ########################################################################
585
- #
586
- # 指标函数 函数名全部大写
587
- #
588
- #########################################################################
589
-
590
-
591
- # 引用若干周期前的数据(平滑处理).
592
- # 用法:REF(X,A),引用A周期前的X值.A可以是变量.
593
- # 平滑处理:当引用不到数据时进行的操作.此函数中,平滑时使用上一个周期的引用值.
594
- # 例如:REF(CLOSE,BARSCOUNT(C)-1)表示第二根K线的收盘价.
595
- def REF(self,data,n) :
596
- result=[]
597
- if JSAlgorithm.IsNumber(n) :
598
- count=len(data)
599
- n=int(n)
600
- if count<=0 :
601
- return result
602
- if n>=count :
603
- return result
604
-
605
- result=data[0:count-n]
606
-
607
- fristData=data[0] # 平滑使用第1个数据
608
- for i in range(n) :
609
- result.insert(0,fristData)
610
-
611
- else : # n 为数组的情况
612
- nCount=len(n)
613
- count=len(data)
614
- result=JSComplierHelper.CreateArray(count)
615
- for i in range(len(data)) :
616
- if i>=nCount :
617
- continue
618
-
619
- value=n[i]
620
- if (JSAlgorithm.IsNumber(value)) :
621
- value=int(value)
622
- if value>=0 and value<=i :
623
- result[i]=data[i-value]
624
- elif i :
625
- result[i]=result[i-1]
626
- else :
627
- result[i]=data[i]
628
-
629
- return result
630
-
631
- # 引用若干周期前的数据(未作平滑处理).
632
- # 用法: REFV(X,A),引用A周期前的X值.A可以是变量.
633
- # 平滑处理:当引用不到数据时进行的操作.
634
- # 例如: REFV(CLOSE,BARSCOUNT(C)-1)表示第二根K线的收盘价.
635
- def REFV(self,data,n) :
636
- result=[]
637
- if JSAlgorithm.IsNumber(n) :
638
- count=len(data)
639
- n=int(n)
640
- if count<=0 :
641
- return result
642
- if n>=count :
643
- return result
644
-
645
- result=data[0:count-n]
646
-
647
- for i in range(n) :
648
- result.insert(0,JSComplierHelper.NoneNumber)
649
-
650
- else : # n 为数组的情况
651
- nCount=len(n)
652
- count=len(data)
653
- result=JSComplierHelper.CreateArray(count)
654
- for i in range(len(data)) :
655
- result[i]=JSComplierHelper.NoneNumber
656
- if i>=nCount :
657
- continue
658
-
659
- value=n[i]
660
- if (JSAlgorithm.IsNumber(value)) :
661
- value=int(value)
662
- if value>=0 and value<=i :
663
- result[i]=data[i-value]
664
-
665
- return result
666
-
667
- # 属于未来函数,引用若干周期后的数据(平滑处理).
668
- # 用法:REFX(X,A),引用A周期后的X值.A可以是变量.
669
- # 平滑处理:当引用不到数据时进行的操作.此函数中,平滑时使用上一个周期的引用值.
670
- # 例如: TT:=IF(C>O,1,2);
671
- # REFX(CLOSE,TT);表示阳线引用下一周期的收盘价,阴线引用日后第二周期的收盘价.
672
- def REFX(self,data,n) :
673
- result=[]
674
- if JSAlgorithm.IsNumber(n) :
675
- count=len(data)
676
- n=int(n)
677
- if count<=0 :
678
- return result
679
- if n>=count :
680
- return result
681
-
682
- result=data[n:count]
683
- lastData=data[count-1]
684
-
685
- for i in range(n) :
686
- result.append(lastData) # 使用最后一个数据平滑
687
-
688
- else : # n 为数组的情况
689
- nCount=len(n)
690
- count=len(data)
691
- result=JSComplierHelper.CreateArray(count)
692
- for i in range(len(data)) :
693
- if i>=nCount :
694
- continue
695
-
696
- value=n[i]
697
- if (JSAlgorithm.IsNumber(value)) :
698
- value=int(value)
699
- if value>0 and value+i<count :
700
- result[i]=data[i+value]
701
- elif i :
702
- result[i]=result[i-1]
703
- else :
704
- result[i]=data[i]
705
-
706
- return result
707
-
708
- # 属于未来函数,引用若干周期后的数据(未作平滑处理).
709
- # 用法: REFXV(X,A),引用A周期后的X值.A可以是变量.
710
- # 平滑处理:当引用不到数据时进行的操作.
711
- # 例如: REFXV(CLOSE,1)表示下一周期的收盘价,在日线上就是明天收盘价
712
- def REFXV(self,data,n) :
713
- result=[]
714
- if JSAlgorithm.IsNumber(n) :
715
- count=len(data)
716
- n=int(n)
717
- if count<=0 :
718
- return result
719
- if n>=count :
720
- return result
721
-
722
- result=data[0:count-n]
723
-
724
- for i in range(n) :
725
- result.append(JSComplierHelper.NoneNumber)
726
-
727
- else : # n 为数组的情况
728
- nCount=len(n)
729
- count=len(data)
730
- result=JSComplierHelper.CreateArray(count)
731
- for i in range(len(data)) :
732
- if i>=nCount :
733
- continue
734
-
735
- value=n[i]
736
- if (JSAlgorithm.IsNumber(value)) :
737
- value=int(value)
738
- if value>=0 and value+i< count:
739
- result[i]=data[i-value]
740
-
741
- return result
742
-
743
- def MAX(self,data,data2) :
744
- isNumber=JSAlgorithm.IsNumber(data)
745
- isNumber2=JSAlgorithm.IsNumber(data2)
746
-
747
- # 单数值比较
748
- if isNumber and isNumber2 :
749
- return max(data,data2)
750
-
751
- # 都是数组比较
752
-
753
- if not isNumber and not isNumber2 :
754
- len1, len2 = len(data), len(data2)
755
- count=max(len1, len2)
756
- result=JSComplierHelper.CreateArray(count)
757
- for i in range(count) :
758
- if i<len1 and i<len2 and JSAlgorithm.Is2Number(data[i],data2[i]) :
759
- result[i]= max(data[i],data2[i])
760
-
761
- return result
762
-
763
-
764
- if isNumber : # 单数据-数组
765
- count=len(data2)
766
- result=JSComplierHelper.CreateArray(count)
767
- for i in range(count) :
768
- if JSAlgorithm.Is2Number(data,data2[i]) :
769
- result[i]=max(data,data2[i])
770
-
771
- else : # 数组-单数据
772
- count=len(data)
773
- result=JSComplierHelper.CreateArray(count)
774
- for i in range(count) :
775
- if JSAlgorithm.Is2Number(data[i],data2) :
776
- result[i]=max(data[i],data2)
777
-
778
- return result
779
-
780
-
781
- def MIN(self,data,data2) :
782
- isNumber=JSAlgorithm.IsNumber(data)
783
- isNumber2=JSAlgorithm.IsNumber(data2)
784
-
785
- # 单数值比较
786
- if isNumber and isNumber2 :
787
- return min(data,data2)
788
-
789
- # 都是数组比较
790
- result=[]
791
- if not isNumber and not isNumber2 :
792
- len1, len2 = len(data), len(data2)
793
- count=max(len1, len2)
794
- result=JSComplierHelper.CreateArray(count)
795
- for i in range(count) :
796
- if i<len1 and i<len2 and JSAlgorithm.Is2Number(data[i],data2[i]) :
797
- result[i]= min(data[i],data2[i])
798
-
799
- return result
800
-
801
-
802
- if isNumber : # 单数据-数组
803
- count=len(data2)
804
- result=JSComplierHelper.CreateArray(count)
805
- for i in range(count) :
806
- if JSAlgorithm.Is2Number(data,data2[i]) :
807
- result[i]=min(data,data2[i])
808
-
809
- else : # 数组-单数据
810
- count=len(data)
811
- result=JSComplierHelper.CreateArray(count)
812
- for i in range(count) :
813
- if JSAlgorithm.Is2Number(data[i],data2) :
814
- result[i]=min(data[i],data2)
815
-
816
- return result
817
-
818
- # 取正数
819
- def ABS(self, data) :
820
- isNumber=JSAlgorithm.IsNumber(data)
821
- if isNumber :
822
- return abs(data)
823
-
824
- count=len(data)
825
- result=JSComplierHelper.CreateArray(count)
826
- for i in range(count) :
827
- if not JSAlgorithm.IsNaN(data[i]) :
828
- result[i]=abs(data[i])
829
-
830
- return result
831
-
832
- # 返回简单移动平均
833
- # 用法:
834
- # MA(X,N):X的N日简单移动平均,算法(X1+X2+X3+...+Xn)/N,N支持变量
835
- # N 支持数组
836
- def MA(self, data,n) :
837
- if (JSAlgorithm.IsArray(n)):
838
- return self.MA_ARRAY(data,n)
839
-
840
- dayCount=int(n)
841
- if dayCount<=0:
842
- dayCount=1
843
-
844
- result=[]
845
- if not data or len(data)<=0:
846
- return result
847
-
848
- result=JSComplierHelper.CreateArray(len(data)) # 初始化数据
849
- for i in range(len(data)) :
850
- if JSAlgorithm.IsNumber(data[i]):
851
- break
852
-
853
- data2=data[0:] # 复制一份数据出来
854
- days=-1
855
- for i in range(i,len(data2)) :
856
- days+=1
857
-
858
- if days<dayCount-1 :
859
- continue
860
-
861
- preValue=data[i-(dayCount-1)]
862
- sum=0
863
-
864
- for j in range(dayCount-1,-1,-1) :
865
- value=data[i-j]
866
- if not JSAlgorithm.IsNumber(value) :
867
- value=preValue # 空数据就取上一个数据
868
- data[i-j]=value
869
- else :
870
- preValue=value
871
- sum+=value
872
-
873
- result[i]=sum/dayCount
874
-
875
- return result
876
-
877
- # MA N=数组
878
- def MA_ARRAY(self,data,n):
879
- if not data or len(data)<=0:
880
- return []
881
-
882
- dataCount=len(data)
883
- result=JSAlgorithm.CreateArray(dataCount)
884
- for i in range(len(n)) :
885
- period=n[i]
886
- if (not JSAlgorithm.IsNumber(period)) :
887
- continue
888
- period=int(period)
889
- if (period<=0):
890
- continue
891
- sum=0
892
- value=0
893
- sumCount=0
894
- for j in range(period):
895
- index=i-j
896
- if (index<0):
897
- break
898
- value=data[index]
899
- if JSAlgorithm.IsNumber(value):
900
- sum+=value
901
- sumCount+=1
902
- if (sumCount>0):
903
- value=sum/sumCount
904
- result[i]=value
905
-
906
- return result
907
-
908
-
909
- # 指数平均数指标 EMA(close,10)
910
- def EMA(self,data,n) :
911
- if (JSAlgorithm.IsArray(n)):
912
- return self.EMA_ARRAY(data,n)
913
-
914
- dayCount=int(n)
915
- result = []
916
- offset=0
917
- if offset>=len(data) :
918
- return result
919
-
920
- result=JSComplierHelper.CreateArray(len(data)) # 初始化数据
921
-
922
- # 取首个有效数据
923
- for i in range(len(data)) :
924
- if JSAlgorithm.IsNumber(data[i]) :
925
- break
926
-
927
- offset=i
928
- p1Index=offset
929
- p2Index=offset+1
930
- result[p1Index]=data[p1Index]
931
- for i in range(offset+1,len(data)) :
932
- result[p2Index]=((2*data[p2Index]+(dayCount-1)*result[p1Index]))/(dayCount+1)
933
- p1Index+=1
934
- p2Index+=1
935
-
936
- return result
937
-
938
- # EMA(N) = 2/(N+1)*C + (N-1)/(N+1)*EMA', EMA'为前一天的ema
939
- def EMA_ARRAY(self,data,n):
940
- dataCount=len(data)
941
- if (dataCount<=0):
942
- return []
943
-
944
- result=JSAlgorithm.CreateArray(dataCount)
945
- for i in range(len(n)) :
946
- period=n[i]
947
- if (not JSAlgorithm.IsNumber(period)) :
948
- continue
949
- period=int(period)
950
- if (period<=0) :
951
- continue
952
- if (period>i+1) :
953
- period=i+1
954
- ema=None
955
- lastEMA=None
956
- EMAFactor=[ 2.0/ (period + 1), (period - 1.0) / (period + 1.0)]
957
- for j in range(period) :
958
- index=i-(period-j-1)
959
- value=data[index]
960
- if (not JSAlgorithm.IsNumber(value)):
961
- continue
962
- if (lastEMA==None):
963
- ema=value
964
- lastEMA=ema
965
- else :
966
- ema = EMAFactor[0] * value + EMAFactor[1] * lastEMA
967
- lastEMA=ema
968
- if (ema!=None) :
969
- result[i]=ema
970
-
971
- return result
972
-
973
- # SMA 移动平均
974
- # 返回移动平均。
975
- # 用法: SMA(X,N,M) X的N日移动平均,M为权重,如Y=(X*M+Y'*(N-M))/N
976
- def SMA(self,data,n,m) :
977
- if (JSAlgorithm.IsArray(n)) :
978
- return self.SMA_ARRAY(data,n,m)
979
-
980
- period=int(n)
981
- if (period<=0) :
982
- return []
983
-
984
- result = JSComplierHelper.CreateArray(len(data))
985
- lastData=None
986
- for i in range(len(data)) :
987
- if JSAlgorithm.IsNumber(data[i]) :
988
- lastData=data[i]
989
- result[i]=lastData # 第一天的数据
990
- break
991
-
992
- for i in range(i+1,len(data)) :
993
- result[i]=(m*data[i]+(period-m)*lastData)/period
994
- lastData=result[i]
995
-
996
- return result
997
-
998
- def SMA_ARRAY(self,data,n,m) :
999
- dataCount=len(data)
1000
- if (dataCount<=0):
1001
- return []
1002
-
1003
- result=JSAlgorithm.CreateArray(dataCount)
1004
- for i in range(len(n)):
1005
- period=n[i]
1006
- if (not JSAlgorithm.IsNumber(period)) :
1007
- continue
1008
- period=int(period)
1009
- if (period<=0):
1010
- continue
1011
- if (period<i+1):
1012
- period=i+1
1013
-
1014
- sma=None
1015
- lastSMA=None
1016
- for j in range(period) :
1017
- index=i-(period-j-1)
1018
- value=data[index]
1019
- if (not JSAlgorithm.IsNumber(value)):
1020
- continue
1021
- if (lastSMA==None):
1022
- sma=value
1023
- lastSMA=sma
1024
- else :
1025
- sma=(m*data[i]+(period-m)*lastSMA)/period
1026
- lastSMA=sma
1027
- if (sma!=None):
1028
- result[i]=sma
1029
-
1030
- return result
1031
-
1032
-
1033
- # 求动态移动平均.
1034
- # 用法: DMA(X,A),求X的动态移动平均.
1035
- # 算法: 若Y=DMA(X,A)则 Y=A*X+(1-A)*Y',其中Y'表示上一周期Y值,A必须小于1.
1036
- # 例如:DMA(CLOSE,VOL/CAPITAL)表示求以换手率作平滑因子的平均价
1037
- def DMA(self,data,data2) :
1038
- result = []
1039
- len1, len2 = len(data), len(data2)
1040
- if len1<0 or len2!=len2 :
1041
- return result
1042
-
1043
- result = JSAlgorithm.CreateArray(len(data))
1044
- for index in range(len1) :
1045
- if JSAlgorithm.Is2Number(data[index],data2[index]) :
1046
- result[index]=data[index]
1047
- break
1048
-
1049
- for index in range(index+1,len1) :
1050
- if JSAlgorithm.Is2Number(data[index],data2[index]) :
1051
- if data2[index]<1 :
1052
- result[index]=(data2[index]*data[index])+(1-data2[index])*result[index-1]
1053
- else :
1054
- result[index]= data[index]
1055
- return result
1056
-
1057
-
1058
- # 返回加权移动平均
1059
- # 用法:WMA(X,N):X的N日加权移动平均.
1060
- # 算法:Yn=(1*X1+2*X2+...+n*Xn)/(1+2+...+n)
1061
- def WMA(self,data, n) :
1062
- result=[]
1063
- len1=len(data)
1064
- if not data or len1<=0 :
1065
- return result
1066
-
1067
- result=JSAlgorithm.CreateArray(len1) # 初始化
1068
-
1069
- if (JSAlgorithm.IsArray(n)) :
1070
- for i in range(len(n)):
1071
- period=n[i]
1072
- if (not JSAlgorithm.IsNumber(period)) :
1073
- continue
1074
- period=int(period)
1075
- if (period<=0):
1076
- continue
1077
- if (period>i+1) :
1078
- period=i+1
1079
-
1080
- start=0
1081
- preValue=0
1082
- for j in range(period) :
1083
- index=i-(period-j-1)
1084
- value=data[index]
1085
- start=j
1086
- if (JSAlgorithm.IsNumber(value)) :
1087
- preValue=value
1088
- break
1089
-
1090
- if (start>=period) :
1091
- continue
1092
-
1093
- sum, count , k =0, 0, 1
1094
- for j in range(start, period) :
1095
- index=i-(period-j-1)
1096
- value=data[index]
1097
- if (JSAlgorithm.IsNumber(value)) :
1098
- preValue = value
1099
- else :
1100
- value=preValue
1101
-
1102
- count+= k
1103
- sum += value * k
1104
- k+=1
1105
-
1106
- result[i] = sum / count
1107
-
1108
- else :
1109
- dayCount=int(n)
1110
- if dayCount<=0 :
1111
- return result
1112
-
1113
- start=0
1114
- for i in range(len1) :
1115
- start=i
1116
- if JSAlgorithm.IsNumber(data[i]) :
1117
- break
1118
-
1119
- data2 = data[0:]
1120
- days =int(-1)
1121
- for i in range(start,len1) :
1122
- days+=1
1123
- if days < dayCount-1 :
1124
- continue
1125
-
1126
- preValue = data2[i - (dayCount-1)]
1127
- sum = 0
1128
- count = 0
1129
- for j in range(dayCount-1,-1,-1) :
1130
- value = data2[i-j]
1131
- if not JSAlgorithm.IsNumber(value) :
1132
- value = preValue
1133
- data2[i-j] = value
1134
- else :
1135
- preValue = value
1136
-
1137
- count += dayCount - j
1138
- sum += value * (dayCount - j)
1139
-
1140
- result[i] = sum / count
1141
-
1142
- return result
1143
-
1144
-
1145
- # 返回平滑移动平均
1146
- # 用法:MEMA(X,N):X的N日平滑移动平均,如Y=(X+Y'*(N-1))/N
1147
- # MEMA(X,N)相当于SMA(X,N,1)
1148
- def MEMA(self, data, dayCount):
1149
- result=[]
1150
- dataLen=len(data)
1151
- if not data or dataLen<=0 :
1152
- return result
1153
-
1154
- result=JSAlgorithm.CreateArray(dataLen)
1155
- for i in range(dataLen) :
1156
- if JSAlgorithm.IsNumber(data[i]) :
1157
- break
1158
-
1159
- if dayCount<1 or i+dayCount>=dataLen :
1160
- return result
1161
-
1162
- sum = 0
1163
- data2 = data[0:]
1164
- for i in range(i,i+dayCount) :
1165
- if not JSAlgorithm.IsNumber(data2[i]) and i-1 >= 0 :
1166
- data2[i] = data2[i-1]
1167
- sum += data2[i]
1168
-
1169
- result[i-1] = sum / dayCount
1170
- for i in range(i,dataLen) :
1171
- if self.IsNumber(result[i-1]) and self.IsNumber(data[i]) :
1172
- result[i] = (data[i]+result[i-1]*(dayCount-1)) / dayCount
1173
- elif i-1 > -1 and self.IsNumber(result[i-1]) :
1174
- result[i] = result[i-1]
1175
-
1176
- return result
1177
-
1178
-
1179
- # 加权移动平均
1180
- # 返回加权移动平均
1181
- # 用法:EXPMA(X,M):X的M日加权移动平均
1182
- # EXPMA[i]=buffer[i]*para+(1-para)*EXPMA[i-1] para=2/(1+__para)
1183
- def EXPMA(self,data,dayCount) :
1184
- result=[]
1185
- dataLen=len(data)
1186
- if dayCount>=dataLen :
1187
- return result
1188
-
1189
- result=JSAlgorithm.CreateArray(dataLen) # 初始化
1190
- for i in range(dayCount,dataLen) : # 获取第1个有效数据
1191
- if JSAlgorithm.IsNumber(data[i]) :
1192
- result[i]=data[i]
1193
- break
1194
-
1195
- for i in range(i+1,dataLen) :
1196
- if JSAlgorithm.Is2Number(result[i-1], data[i]) :
1197
- result[i]=(2*data[i]+(dayCount-1)*result[i-1])/(dayCount+1)
1198
- elif JSAlgorithm.IsNumber(result[i-1]) :
1199
- result[i]=result[i-1]
1200
-
1201
- return result
1202
-
1203
- # 加权平滑平均,MEMA[i]=SMA[i]*para+(1-para)*SMA[i-1] para=2/(1+__para)
1204
- def EXPMEMA(self,data,dayCount) :
1205
- result=[]
1206
- dataLen=len(data)
1207
- if dayCount>=dataLen :
1208
- return result
1209
-
1210
- result=JSAlgorithm.CreateArray(dataLen) # 初始化
1211
- for i in range(dataLen) :
1212
- if JSAlgorithm.IsNumber(data[i]) :
1213
- break
1214
-
1215
- index=i
1216
- sum=0
1217
- for i in range(dayCount) :
1218
- if index>=dataLen :
1219
- break
1220
-
1221
- if JSAlgorithm.IsNumber(data[index]) :
1222
- sum+=data[index]
1223
- else :
1224
- sum+=data[index-1]
1225
-
1226
- index+=1
1227
-
1228
- result[index-1]=sum/dayCount
1229
- for index in range(index,dataLen) :
1230
- if JSAlgorithm.Is2Number(result[index-1], data[index]) :
1231
- result[index]=(2*data[index]+(dayCount-1)*result[index-1])/(dayCount+1)
1232
- elif JSAlgorithm.IsNumber(result[index-1]) :
1233
- result[index] = result[index-1]
1234
-
1235
- return result
1236
-
1237
- # 向前累加到指定值到现在的周期数.
1238
- # 用法:SUMBARS(X,A):将X向前累加直到大于等于A,返回这个区间的周期数
1239
- # 例如:SUMBARS(VOL,CAPITAL)求完全换手到现在的周期数
1240
- def SUMBARS(self, data, data2) :
1241
- result = []
1242
- if not data or not data2:
1243
- return result
1244
- len1, len2 = len(data), len(data2)
1245
- if len1<=0 or len2<=0:
1246
- return result
1247
-
1248
- result=JSAlgorithm.CreateArray(len1)
1249
- for start in range(len1) :
1250
- if JSAlgorithm.IsNumber(data[start]) :
1251
- break
1252
-
1253
- for i in range(len1-1,start-1,-1) :
1254
- total = 0
1255
- for j in range(i,start-1,-1) :
1256
- if total>=data2[i]:
1257
- break
1258
- total += data[j]
1259
-
1260
- if j < start:
1261
- pass
1262
- else :
1263
- result[i] = i - j
1264
-
1265
- for i in range(start+1,len1) :
1266
- if result[i]==JSComplierHelper.NoneNumber :
1267
- result[i] = result[i-1]
1268
-
1269
- return result
1270
-
1271
-
1272
- # 求相反数.
1273
- # 用法:REVERSE(X)返回-X.
1274
- # 例如:REVERSE(CLOSE)返回-CLOSE
1275
- def REVERSE(self,data) :
1276
- isNumber=JSAlgorithm.IsNumber(data)
1277
- if isNumber :
1278
- return 0-data
1279
-
1280
- count=len(data)
1281
- result = JSAlgorithm.CreateArray(count)
1282
- for i in range(count) :
1283
- if JSAlgorithm.IsNumber(data[i]) :
1284
- result[i]=0-data[i]
1285
-
1286
- return result
1287
-
1288
- def COUNT(self, data,n):
1289
- dataLen=len(data)
1290
- result=[0]*dataLen # 初始全部是0
1291
-
1292
- if (JSAlgorithm.IsArray(n)):
1293
- for i in range(len(n)) :
1294
- period=n[i]
1295
- if (not JSAlgorithm.IsNumber(period)):
1296
- continue
1297
- period=int(period)
1298
- if (period<1) :
1299
- period=i+1
1300
- count=0
1301
- for j in range(period) :
1302
- index=i-j
1303
- if (index<0):
1304
- break
1305
- if data[index] :
1306
- count+=1
1307
- result[i]=count
1308
- else :
1309
- n=int(n)
1310
- for i in range(dataLen) :
1311
- count=0
1312
- for j in range(n) :
1313
- if i-j<0 :
1314
- break
1315
- if data[i-j] :
1316
- count+=1
1317
- result[i]=count
1318
-
1319
- return result
1320
-
1321
- # HHV 最高值
1322
- # 求最高值。
1323
- # 用法: HHV(X,N) 求N周期内X最高值,N=0则从第一个有效值开始。
1324
- # 例如: HHV(HIGH,30) 表示求30日最高价。
1325
- def HHV(self,data,n):
1326
- dataLen=len(data)
1327
- result = JSAlgorithm.CreateArray(dataLen)
1328
- isNumber=JSAlgorithm.IsNumber(n)
1329
- if not isNumber : # n是一个数组 周期变动
1330
- max=None
1331
- nLen=len(n)
1332
- for i in range(dataLen) :
1333
- if i>nLen :
1334
- continue
1335
- max=None
1336
- count=int(n[i])
1337
- if count>0 and count<=i :
1338
- for j in range(i-count,i+1) :
1339
- if max==None or max<data[j] :
1340
- max=data[j]
1341
- else :
1342
- count=i
1343
- for j in range(i+1) :
1344
- if max==None or max<data[j] :
1345
- max=data[j]
1346
- result[i]=max
1347
-
1348
- else :
1349
- n=int(n)
1350
- if n>dataLen :
1351
- return result
1352
-
1353
- if n<=0:
1354
- n=dataLen-1
1355
-
1356
- for nMax in range(dataLen) :
1357
- if JSAlgorithm.IsNumber(data[nMax]) :
1358
- break
1359
-
1360
- if nMax<dataLen :
1361
- result[nMax]=data[nMax]
1362
-
1363
- j=2
1364
- for i in range(nMax+1,dataLen):
1365
- if j>=n :
1366
- break
1367
- if data[i]>=data[nMax] :
1368
- nMax=i
1369
- result[i]=data[nMax]
1370
- j+=1
1371
-
1372
- for i in range(i,dataLen) :
1373
- if i-nMax<n :
1374
- nMax=nMax if data[i]<data[nMax] else i
1375
- else :
1376
- nMax=(i-n+2)
1377
- for j in range(nMax,i+1) :
1378
- nMax=nMax if data[j]<data[nMax] else j
1379
- result[i]=data[nMax]
1380
-
1381
- return result
1382
-
1383
- # LLV 最低值
1384
- # 求最低值。
1385
- # 用法: LLV(X,N) 求N周期内X最低值,N=0则从第一个有效值开始。
1386
- # 例如: LLV(LOW,0) 表示求历史最低价。
1387
- def LLV(self,data,n) :
1388
- dataLen=len(data)
1389
- result = JSAlgorithm.CreateArray(dataLen)
1390
- isNumber=JSAlgorithm.IsNumber(n)
1391
- if not isNumber : # n是数组
1392
- for i in range(dataLen) :
1393
- if i>=dataLen :
1394
- continue
1395
- min=None
1396
- count=int(n[i])
1397
- if count>0 and count<=i :
1398
- for j in range(i-count,i+1):
1399
- if min==None or min>data[j] :
1400
- min=data[j]
1401
- else :
1402
- count=i
1403
- for j in range(i+1) :
1404
- if min==None or min>data[j] :
1405
- min=data[j]
1406
- result[i]=min
1407
- else :
1408
- n=int(n)
1409
- if n>dataLen :
1410
- return result
1411
- if n<=0 :
1412
- n=dataLen-1
1413
-
1414
- min=n
1415
- for i in range(n,dataLen):
1416
- if i<n+min :
1417
- min=min if data[i]>data[min] else i
1418
- else :
1419
- min=i-n+1
1420
- for j in range(min+1,i+1) :
1421
- if data[j]<data[min] :
1422
- min=j
1423
- result[i] = data[min]
1424
-
1425
- return result
1426
-
1427
- # STD(X,N) 返回估算标准差
1428
- def STD(self,data,n) :
1429
- if not data or len(data)<=0 :
1430
- return []
1431
-
1432
- dataLen=len(data)
1433
- result=JSAlgorithm.CreateArray(dataLen)
1434
- if n<=0:
1435
- n=dataLen-1
1436
-
1437
- averageData=JSAlgorithm.ArrayAverage(data,n) # 平均值
1438
- for i in range(dataLen) :
1439
- total=0
1440
- for j in range(n) :
1441
- if JSAlgorithm.Is2Number(data[i-j],averageData[i]) :
1442
- total+=(data[i-j]-averageData[i])*(data[i-j]-averageData[i])
1443
- result[i]=math.sqrt(total/n)
1444
-
1445
- return result
1446
-
1447
- # 平均绝对方差
1448
- def AVEDEV(self,data,n) :
1449
- if not JSAlgorithm.IsVaildArray(data) :
1450
- return []
1451
-
1452
- dataLen=len(data)
1453
- result=JSAlgorithm.CreateArray(dataLen)
1454
- if n<=0:
1455
- n=dataLen-1
1456
-
1457
- averageData=JSAlgorithm.ArrayAverage(data,n) # 平均值
1458
- for i in range(n-1,dataLen) :
1459
- total=0
1460
- for j in range(n) :
1461
- if JSAlgorithm.Is2Number(data[i-j],averageData[i]) :
1462
- total+=abs(data[i-j]-averageData[i])
1463
- result[i]=total/n
1464
-
1465
- return result
1466
-
1467
- # 上穿
1468
- def CROSS(self, data,data2) :
1469
- if JSAlgorithm.IsArray(data) and JSAlgorithm.IsArray(data2) :
1470
- len1, len2 = len(data), len(data2)
1471
- if len1!=len2 :
1472
- return []
1473
-
1474
- result=JSAlgorithm.CreateArray(len1,0)
1475
- for index in range(len1) :
1476
- if JSAlgorithm.Is2Number(data[index],data2[index]) :
1477
- break
1478
-
1479
- for index in range(index+1, len1) :
1480
- result[index]= 1 if data[index]>data2[index] and data[index-1]<data2[index-1] else 0
1481
-
1482
- elif JSAlgorithm.IsArray(data) and JSAlgorithm.IsNumber(data2):
1483
- # data2=float(data2)
1484
- len1=len(data)
1485
- result=JSAlgorithm.CreateArray(len1,0)
1486
- for index in range(len1) :
1487
- if JSAlgorithm.IsNumber(data[index]) :
1488
- break
1489
-
1490
- for index in range(index+1, len1) :
1491
- result[index]= 1 if data[index]>data2 and data[index-1]<data2 else 0
1492
-
1493
- elif JSAlgorithm.IsNumber(data) and JSAlgorithm.IsArray(data2) :
1494
- # data=float(data)
1495
- len2=len(data2)
1496
- result=JSAlgorithm.CreateArray(len2,0)
1497
- for index in range(len2) :
1498
- if JSAlgorithm.IsNumber(data2[index]) :
1499
- break
1500
-
1501
- for index in range(index+1, len2) :
1502
- result[index]= 1 if data2[index]<data and data2[index-1]>data else 0
1503
-
1504
- else :
1505
- return []
1506
-
1507
- return result
1508
-
1509
- # 累乘
1510
- def MULAR(self,data,n) :
1511
- if not JSAlgorithm.IsVaildArray(data) :
1512
- return []
1513
-
1514
- dataLen=len(data)
1515
- if dataLen<n:
1516
- return []
1517
-
1518
- result=JSAlgorithm.CreateArray(dataLen)
1519
-
1520
- for index in range(dataLen) :
1521
- if JSAlgorithm.IsNumber(data[index]):
1522
- result[index]=data[index]
1523
- break
1524
-
1525
- for index in range(index+1, dataLen):
1526
- if JSAlgorithm.IsNumber(data[index]):
1527
- result[index]=result[index-1]*data[index]
1528
- else :
1529
- result[index]=result[index-1]
1530
-
1531
- return result
1532
-
1533
- # 求总和.
1534
- # 用法: SUM(X,N),统计N周期中X的总和,N=0则从第一个有效值开始.
1535
- # 例如: SUM(VOL,0)表示统计从上市第一天以来的成交量总和
1536
- # N 支持变量数组
1537
- def SUM(self, data,n) :
1538
- if not JSAlgorithm.IsVaildArray(data) :
1539
- return []
1540
-
1541
- dataLen=len(data)
1542
- result=JSAlgorithm.CreateArray(dataLen)
1543
-
1544
- if (JSAlgorithm.IsArray(n)) :
1545
- for i in range(len(n)) :
1546
- period=n[i]
1547
- if (not JSAlgorithm.IsNumber(period)):
1548
- continue
1549
-
1550
- period=int(period)
1551
- if (period<1) :
1552
- period=i+1
1553
-
1554
- value=0
1555
- for j in range(period) :
1556
- index=i-j
1557
- if index<0 :
1558
- break
1559
- if (JSAlgorithm.IsNumber(data[i])) :
1560
- value+=data[i]
1561
-
1562
- result[i]=value
1563
-
1564
- else :
1565
- n=int(n)
1566
- if dataLen<n:
1567
- return []
1568
-
1569
- if n==0 :
1570
- result[0]=data[0]
1571
- for i in range(1,dataLen) :
1572
- result[i] = result[i-1]+data[i]
1573
-
1574
- else :
1575
- j=0
1576
- for i in range(n-1, dataLen) :
1577
- for k in range(n) :
1578
- if k==0:
1579
- result[i]=data[k+j]
1580
- else :
1581
- result[i]+=data[k+j]
1582
- j+=1
1583
-
1584
- return result
1585
-
1586
-
1587
- # BARSCOUNT 有效数据周期数
1588
- # 求总的周期数。
1589
- # 用法: BARSCOUNT(X) 第一个有效数据到当前的天数。
1590
- # 例如: BARSCOUNT(CLOSE) 对于日线数据取得上市以来总交易日数,对于分笔成交取得当日成交笔数,对于1分钟线取得当日交易分钟数。
1591
- def BARSCOUNT(self,data):
1592
- if not JSAlgorithm.IsVaildArray(data) :
1593
- return []
1594
- dataLen=len(data)
1595
- result=JSAlgorithm.CreateArray(dataLen,0)
1596
-
1597
- days=None
1598
- for i in range(dataLen) :
1599
- if days==None :
1600
- if not JSAlgorithm.IsNumber(data[i]) :
1601
- continue
1602
- days=0
1603
-
1604
- result[i]=days
1605
- days+=1
1606
-
1607
- return result
1608
-
1609
- # DEVSQ 数据偏差平方和
1610
- # DEVSQ(X,N)  返回数据偏差平方和。
1611
- def DEVSQ(self,data,n) :
1612
- if not JSAlgorithm.IsVaildArray(data) :
1613
- return []
1614
-
1615
- num = n
1616
- datanum = len(data)
1617
- i,k = 0, 0
1618
- DEV = 0
1619
- for i in range(datanum) : # 第1个有效数
1620
- if JSAlgorithm.IsNumber(data[i]) :
1621
- break
1622
-
1623
- if num < 1 or i+num>datanum:
1624
- return []
1625
-
1626
- result=JSAlgorithm.CreateArray(datanum)
1627
- j, E = 0 ,0
1628
- for i in range(i,datanum) :
1629
- if j>=num :
1630
- break
1631
- E += data[i]/num
1632
- j+=1
1633
-
1634
- if j==num:
1635
- DEV = 0
1636
- i-=1
1637
- for k in range(num) :
1638
- DEV += (data[i-k]-E) * (data[i-k]-E)
1639
- result[i] = DEV
1640
- i+=1
1641
-
1642
- for i in range(i,datanum) :
1643
- E += (data[i] - data[i-num]) / num
1644
- DEV=0
1645
- for k in range(num) :
1646
- DEV += (data[i-k]-E) * (data[i-k]-E)
1647
- result[i] = DEV
1648
-
1649
- return result
1650
-
1651
- # NOT 取反
1652
- # 求逻辑非。
1653
- # 用法: NOT(X) 返回非X,即当X=0时返回1,否则返回0。
1654
- # 例如: NOT(ISUP) 表示平盘或收阴。
1655
- def NOT(self,data) :
1656
- if JSAlgorithm.IsNumber(data) :
1657
- return 0 if data else 1
1658
-
1659
- if not JSAlgorithm.IsVaildArray(data) :
1660
- return []
1661
-
1662
- dataLen=len(data)
1663
- result=JSAlgorithm.CreateArray(dataLen)
1664
-
1665
- for i in range(dataLen) :
1666
- if JSAlgorithm.IsNumber(data[i]) :
1667
- result[i]=0 if data[i] else 1
1668
-
1669
- return result
1670
-
1671
- # FORCAST 线性回归预测值
1672
- # FORCAST(X,N)  返回线性回归预测值。
1673
- def FORCAST(self,data,n):
1674
- if not JSAlgorithm.IsVaildArray(data) :
1675
- return []
1676
-
1677
- num = n
1678
- datanum = len(data)
1679
- if num < 1 or num >= datanum :
1680
- return []
1681
-
1682
- result=JSAlgorithm.CreateArray(datanum)
1683
-
1684
- for j in range(datanum) :
1685
- if JSAlgorithm.IsNumber(data[j]) :
1686
- break
1687
-
1688
- for i in range(j+num-1,datanum) :
1689
- Ex, Ey, Sxy, Sxx =0, 0, 0, 0
1690
- for j in range(num) :
1691
- if j>i :
1692
- break
1693
- Ex += (i - j)
1694
- Ey += data[i - j]
1695
- Ex /= num
1696
- Ey /= num
1697
- for j in range(num) :
1698
- if j>i :
1699
- break
1700
- Sxy += (i-j-Ex)*(data[i-j]-Ey)
1701
- Sxx += (i-j-Ex)*(i-j-Ex)
1702
-
1703
- Slope = Sxy / Sxx
1704
- Const = (Ey - Ex*Slope) / num
1705
- result[i] = Slope * num + Const
1706
-
1707
- return result
1708
-
1709
- # SLOPE 线性回归斜率
1710
- # SLOPE(X,N)  返回线性回归斜率。
1711
- def SLOPE(self,data,n) :
1712
- if not JSAlgorithm.IsVaildArray(data) :
1713
- return []
1714
-
1715
- dataLen=len(data)
1716
- if n<1 or n>=dataLen :
1717
- return []
1718
-
1719
- result=JSAlgorithm.CreateArray(dataLen)
1720
- for start in range(dataLen) :
1721
- if JSAlgorithm.IsNumber(data[start]) :
1722
- break
1723
-
1724
- for i in range(start+n-1,dataLen) :
1725
- x, y, xy, xx = 0,0,0,0
1726
- for j in range(n) :
1727
- if j>i:
1728
- break
1729
- x+=(i-j) # 数据索引相加
1730
- y+=data[i-j] # 数据相加
1731
-
1732
- x=x/n
1733
- y=y/n
1734
-
1735
- for j in range(n) :
1736
- if j>i :
1737
- break
1738
- xy+=(i-j-x)*(data[i-j]-y)
1739
- xx+=(i-j-x)*(i-j-x)
1740
-
1741
- if xx :
1742
- result[i]= xy/xx
1743
- elif i :
1744
- result[i]=result[i-1]
1745
-
1746
- return result
1747
-
1748
- # STDP 总体标准差
1749
- # STDP(X,N)  返回总体标准差。
1750
- def STDP(self,data,n) :
1751
- if not JSAlgorithm.IsVaildArray(data) :
1752
- return []
1753
-
1754
- num = n
1755
- datanum = len(data)
1756
- if num < 1 or num >= datanum :
1757
- return []
1758
-
1759
- result=JSAlgorithm.CreateArray(datanum)
1760
- for i in range(datanum) :
1761
- if JSAlgorithm.IsNumber(data[i]) :
1762
- break
1763
-
1764
- SigmaPowerX ,SigmaX, MidResult =0,0,0
1765
- for j in range(num) :
1766
- if i>=datanum :
1767
- break
1768
- SigmaPowerX += data[i] * data[i]
1769
- SigmaX += data[i]
1770
- i+=1
1771
-
1772
- if j == num:
1773
- MidResult = num*SigmaPowerX - SigmaX*SigmaX
1774
- result[i-1] = math.sqrt(MidResult) / num
1775
-
1776
- for i in range(i,datanum) :
1777
- SigmaPowerX += data[i]*data[i] - data[i-num]*data[i-num]
1778
- SigmaX += data[i] - data[i-num]
1779
- MidResult = num*SigmaPowerX - SigmaX*SigmaX
1780
- result[i] = math.sqrt(MidResult) / num
1781
-
1782
- return result
1783
-
1784
- # VAR 估算样本方差
1785
- # VAR(X,N)  返回估算样本方差。
1786
- def VAR(self,data,n) :
1787
- if not JSAlgorithm.IsVaildArray(data) :
1788
- return []
1789
-
1790
- num = n
1791
- datanum = len(data)
1792
- if num <= 1 or num >= datanum :
1793
- return []
1794
-
1795
- result=JSAlgorithm.CreateArray(datanum)
1796
- for i in range(datanum) :
1797
- if JSAlgorithm.IsNumber(data[i]) :
1798
- break
1799
-
1800
- for i in range(i+num-1,datanum) :
1801
- SigmaPowerX = SigmaX = 0
1802
- for j in range(num) :
1803
- if j>i :
1804
- break
1805
- SigmaPowerX += data[i-j] * data[i-j]
1806
- SigmaX += data[i-j]
1807
-
1808
- result[i] = (num*SigmaPowerX - SigmaX*SigmaX) / num * (num -1)
1809
-
1810
- return result
1811
-
1812
- # VARP 总体样本方差
1813
- # VARP(X,N)  返回总体样本方差 。
1814
- def VARP(self,data,n) :
1815
- if not JSAlgorithm.IsVaildArray(data) :
1816
- return []
1817
-
1818
- num = n
1819
- datanum = len(data)
1820
- if num < 1 or num >= datanum :
1821
- return []
1822
-
1823
- result=JSAlgorithm.CreateArray(datanum)
1824
-
1825
- for i in range(datanum) :
1826
- if JSAlgorithm.IsNumber(data[i]) :
1827
- break
1828
-
1829
- SigmaPowerX , SigmaX = 0,0
1830
- for j in range(num) :
1831
- if i>=datanum :
1832
- break
1833
- SigmaPowerX += data[i] * data[i]
1834
- SigmaX += data[i]
1835
- i+=1
1836
-
1837
- if j == num :
1838
- result[i-1] = (num*SigmaPowerX - SigmaX*SigmaX) / (num*num)
1839
-
1840
- for i in range(i,datanum) :
1841
- SigmaPowerX += data[i]*data[i] - data[i-num]*data[i-num]
1842
- SigmaX += data[i] - data[i-num]
1843
- result[i] = (num*SigmaPowerX - SigmaX*SigmaX) / (num*num)
1844
-
1845
- return result
1846
-
1847
- # RANGE(A,B,C)表示A>B AND A<C;
1848
- def RANGE(self, data,range,range2) :
1849
- isNumber=JSAlgorithm.IsNumber(data)
1850
- isNumber2=JSAlgorithm.IsNumber(range)
1851
- isNumber3=JSAlgorithm.IsNumber(range2)
1852
-
1853
- if isNumber and isNumber2 and isNumber3 :
1854
- if data>min(range,range2) and data<max(range,range2):
1855
- return 1
1856
- else :
1857
- return 0
1858
-
1859
- if not JSAlgorithm.IsVaildArray(data) :
1860
- return []
1861
-
1862
- dataLen=len(data)
1863
- result=JSAlgorithm.CreateArray(dataLen)
1864
-
1865
- for i in range(dataLen) :
1866
- value=data[i]
1867
- if JSAlgorithm.IsNumber(value) :
1868
- continue
1869
-
1870
- if not isNumber2 :
1871
- if i>=len(range) :
1872
- continue
1873
- rangeValue=range[i]
1874
- else :
1875
- rangeValue=range
1876
-
1877
-
1878
- if not JSAlgorithm.IsNumber(rangeValue) :
1879
- continue
1880
-
1881
- if not isNumber3 :
1882
- if i>=len(range2) :
1883
- continue
1884
-
1885
- rangeValue2=range2[i]
1886
- else :
1887
- rangeValue2=range2
1888
-
1889
- if not JSAlgorithm.IsNumber(rangeValue2) :
1890
- continue
1891
-
1892
- result[i]= 1 if value>min(rangeValue,rangeValue2) and value<max(rangeValue,rangeValue2) else 0
1893
-
1894
- return result
1895
-
1896
- def EXIST(self,data,n) :
1897
- if not JSAlgorithm.IsVaildArray(data) :
1898
- return []
1899
-
1900
- if (JSAlgorithm.IsArray(n)) :
1901
- dataLen = len(data)
1902
- result=JSAlgorithm.CreateArray(dataLen,0)
1903
- for i in range(len(n)) :
1904
- if (i>=dataLen):
1905
- break
1906
- period=n[i]
1907
- if (not JSAlgorithm.IsNumber(period)) :
1908
- continue
1909
- period=int(period)
1910
- if (period<=0):
1911
- continue
1912
- if (period>i+1) :
1913
- period=i+1
1914
-
1915
- bFind=False
1916
- for j in range(period):
1917
- index=i-(period-j-1)
1918
- value=data[index]
1919
- if (JSAlgorithm.IsNumber(value) and value>0):
1920
- bFind=True
1921
- break
1922
- if (bFind):
1923
- result[i]=1
1924
- else:
1925
- result[i]=0
1926
-
1927
- return result
1928
-
1929
- else :
1930
- dataLen = len(data)
1931
- result=JSAlgorithm.CreateArray(dataLen)
1932
- latestID=None # 最新满足条件的数据索引
1933
- n=int(n)
1934
- for i in range(dataLen) :
1935
- value=data[i]
1936
- if JSAlgorithm.IsNumber(value) and value>0:
1937
- latestID=i # 最新满足条件的数据索引
1938
-
1939
- if latestID!=None and i-latestID<n :
1940
- result[i]=1
1941
- else :
1942
- result[i]=0
1943
-
1944
- return result
1945
-
1946
- def TFILTER(self, data,data2,n) :
1947
- # TODO: 待完成
1948
- return []
1949
-
1950
- # 过滤连续出现的信号.
1951
- # 用法:FILTER(X,N):X满足条件后,将其后N周期内的数据置为0,N为常量.
1952
- # 例如: FILTER(CLOSE>OPEN,5)查找阳线,5天内再次出现的阳线不被记录在内
1953
- def FILTER(self,data,n) :
1954
- if not JSAlgorithm.IsVaildArray(data) :
1955
- return []
1956
-
1957
- dataLen = len(data)
1958
- result=JSAlgorithm.CreateArray(dataLen)
1959
- for i in range(dataLen) :
1960
- if data[i] :
1961
- result[i]=1
1962
- for j in range(n) :
1963
- if j+i+1>=dataLen :
1964
- break
1965
- result[j+i+1]=0
1966
- i+=n
1967
- else :
1968
- result[i]=0
1969
-
1970
- return result
1971
-
1972
- def BARSLAST(self, data) :
1973
- if not JSAlgorithm.IsVaildArray(data) :
1974
- return []
1975
-
1976
- dataLen = len(data)
1977
- result=JSAlgorithm.CreateArray(dataLen)
1978
- day=None
1979
- for i in range(dataLen) :
1980
- if data[i]>0:
1981
- day=0
1982
- elif day!=None :
1983
- day+=1
1984
-
1985
- if day!=None :
1986
- result[i]=day
1987
-
1988
- return result
1989
-
1990
-
1991
- # N周期内第一个条件成立到当前的周期数.
1992
- # 用法: BARSSINCEN(X,N):N周期内第一次X不为0到现在的天数,N为常量
1993
- # 例如: BARSSINCEN(HIGH>10,10)表示10个周期内股价超过10元时到当前的周期数
1994
- def BARSSINCEN(self, data,n) :
1995
- if not JSAlgorithm.IsVaildArray(data) :
1996
- return []
1997
-
1998
- dataLen = len(data)
1999
- result=JSAlgorithm.CreateArray(dataLen)
2000
-
2001
- day=None
2002
- for i in range(dataLen) :
2003
- if day==None :
2004
- if data[i] :
2005
- day=0
2006
- else :
2007
- if data[i] :
2008
- if day+1<n :
2009
- day+=1
2010
- else :
2011
- day=None
2012
-
2013
- if day:
2014
- result[i]=day
2015
-
2016
- return result
2017
-
2018
-
2019
- # 第一个条件成立到当前的周期数.
2020
- # 用法: BARSSINCE(X):第一次X不为0到现在的天数
2021
- # 例如: BARSSINCE(HIGH>10)表示股价超过10元时到当前的周期数
2022
- def BARSSINCE(self, data) :
2023
- if not JSAlgorithm.IsVaildArray(data) :
2024
- return []
2025
-
2026
- dataLen = len(data)
2027
- result=JSAlgorithm.CreateArray(dataLen)
2028
- day=None
2029
- for i in range(dataLen) :
2030
- if day==None :
2031
- if data[i] :
2032
- day=0
2033
- else :
2034
- day+=1
2035
-
2036
- if day :
2037
- result[i]=day
2038
-
2039
- return result
2040
-
2041
- # 三角函数调用 func 三角函数
2042
- # 反正切值. 用法: ATAN(X)返回X的反正切值
2043
- # 反余弦值. 用法: ACOS(X)返回X的反余弦值
2044
- # 反正弦值. 用法: ASIN(X)返回X的反正弦值
2045
- # 余弦值. 用法: COS(X)返回X的余弦值
2046
- # 正弦值. 用法: SIN(X)返回X的正弦值
2047
- # 正切值. 用法: TAN(X)返回X的正切值
2048
- #
2049
- # 求自然对数. 用法: LN(X)以e为底的对数 例如: LN(CLOSE)求收盘价的对数
2050
- # 求10为底的对数. 用法: LOG(X)取得X的对数 例如: LOG(100)等于2
2051
- # 指数. 用法: EXP(X)为e的X次幂 例如: EXP(CLOSE)返回e的CLOSE次幂
2052
- # 开平方. 用法: SQRT(X)为X的平方根 例如: SQRT(CLOSE)收盘价的平方根
2053
- def Trigonometric(self, data,func) :
2054
- if JSAlgorithm.IsNumber(data) :
2055
- return func(data)
2056
-
2057
- if not JSAlgorithm.IsVaildArray(data) :
2058
- return []
2059
-
2060
- dataLen=len(data)
2061
- result=JSAlgorithm.CreateArray(dataLen)
2062
- for i in range(dataLen) :
2063
- item=data[i]
2064
- if JSAlgorithm.IsNumber(item) :
2065
- result[i]=func(item)
2066
-
2067
- return result
2068
-
2069
- # LAST(X,A,B):持续存在.
2070
- # 用法: LAST(CLOSE>OPEN,10,5)
2071
- # 表示从前10日到前5日内一直阳线
2072
- # 若A为0,表示从第一天开始,B为0,表示到最后日止
2073
- def LAST(self, data,n,n2) :
2074
- if not JSAlgorithm.IsVaildArray(data) :
2075
- return []
2076
-
2077
- dataLen=len(data)
2078
- if n2<=0:
2079
- n2=dataLen-1
2080
- if n2>n :
2081
- return []
2082
-
2083
- result=JSAlgorithm.CreateArray(dataLen,0)
2084
- for i in range(dataLen) :
2085
- day=0
2086
- start=i-n
2087
- end=i-n2
2088
- if start<0 or end<0 :
2089
- continue
2090
-
2091
- for j in range(start, dataLen) :
2092
- if j>end :
2093
- break
2094
- if not data[j] :
2095
- break
2096
- day+=1
2097
-
2098
- if day==end-start+1 : #[start,end]
2099
- result[i]=1
2100
-
2101
- return result
2102
-
2103
- # 返回是否连涨周期数.
2104
- # 用法: UPNDAY(CLOSE,M)
2105
- # 表示连涨M个周期,M为常量
2106
- def UPNDAY(self, data,n) :
2107
- if not JSAlgorithm.IsVaildArray(data) or n<1 :
2108
- return []
2109
-
2110
- dataLen=len(data)
2111
- result=JSAlgorithm.CreateArray(dataLen,0)
2112
- days=0
2113
- for i in range(dataLen) :
2114
- if i-1<0 :
2115
- continue
2116
-
2117
- if not JSAlgorithm.IsNumber(data[i]) or not JSAlgorithm.IsNumber(data[i-1]) : # 无效数都不算连涨
2118
- days=0
2119
- continue
2120
-
2121
- if data[i]>data[i-1] :
2122
- days+=1
2123
- else :
2124
- days=0
2125
-
2126
- if days==n :
2127
- result[i]=1
2128
- days-=1
2129
-
2130
- return result
2131
-
2132
-
2133
- # 返回是否连跌周期.
2134
- # 用法: DOWNNDAY(CLOSE,M)
2135
- # 表示连跌M个周期,M为常量
2136
- def DOWNNDAY(self,data,n) :
2137
- if not JSAlgorithm.IsVaildArray(data) or n<1 :
2138
- return []
2139
-
2140
- dataLen=len(data)
2141
- result=JSAlgorithm.CreateArray(dataLen,0)
2142
- days=0
2143
- for i in range(dataLen) :
2144
- if i-1<0 :
2145
- continue
2146
- if not JSAlgorithm.IsNumber(data[i]) or not JSAlgorithm.IsNumber(data[i-1]) : # 无效数都不算连涨
2147
- days=0
2148
- continue
2149
-
2150
- if data[i]<data[i-1] :
2151
- days+=1
2152
- else :
2153
- days=0
2154
-
2155
- if days==n :
2156
- result[i]=1
2157
- days-=1
2158
-
2159
- return result
2160
-
2161
- #返回是否持续存在X>Y
2162
- #用法:
2163
- #NDAY(CLOSE,OPEN,3)
2164
- #表示连续3日收阳线
2165
- def NDAY(self,data,data2,n):
2166
- if n<1:
2167
- return []
2168
- if not JSAlgorithm.IsArray(data) and not JSAlgorithm.IsArray(data2):
2169
- return []
2170
-
2171
- if JSAlgorithm.IsArray(data) and JSAlgorithm.IsArray(data2) :
2172
- len1 , len2= len(data), len(data2)
2173
- if n>=len1 or n>=len2 :
2174
- return []
2175
-
2176
- count=max(len1,len2)
2177
- result=JSAlgorithm.CreateArray(count,0)
2178
- days=0
2179
- for i in range(count):
2180
- if i>=len1 or i>=len2:
2181
- continue
2182
- if not JSAlgorithm.IsNumber(data[i]) or not JSAlgorithm.IsNumber(data2[i]) :
2183
- days=0
2184
- continue
2185
-
2186
- if data[i]>data2[i] :
2187
- days+=1
2188
- else :
2189
- days=0
2190
-
2191
- if days==n :
2192
- result[i]=1
2193
- days-=1
2194
-
2195
- elif JSAlgorithm.IsArray(data) and JSAlgorithm.IsNumber(data2) :
2196
- len1=len(data)
2197
- if n>=len1 :
2198
- return []
2199
-
2200
- result=JSAlgorithm.CreateArray(len1,0)
2201
- days=0
2202
- for i in range(len1) :
2203
- if not JSAlgorithm.IsNumber(data[i]) :
2204
- days=0
2205
- continue
2206
-
2207
- if data[i]>data2 :
2208
- days+=1
2209
- else :
2210
- days=0
2211
-
2212
- if days==n :
2213
- result[i]=1
2214
- days-=1
2215
-
2216
- elif JSAlgorithm.IsNumber(data) and JSAlgorithm.IsArray(data2) :
2217
- len2=len(data2)
2218
- if n>=len2 :
2219
- return []
2220
-
2221
- result=JSAlgorithm.CreateArray(len2,0)
2222
- days=0
2223
- for i in range(len2) :
2224
- if not JSAlgorithm.IsNumber(data2[i]) :
2225
- days=0
2226
- continue
2227
-
2228
- if data>data2[i] :
2229
- days+=1
2230
- else :
2231
- days=0
2232
-
2233
- if days==n :
2234
- result[i]=1
2235
- days-=1
2236
-
2237
- return result
2238
-
2239
- # 两条线维持一定周期后交叉.
2240
- # 用法:LONGCROSS(A,B,N)表示A在N周期内都小于B,本周期从下方向上穿过B时返回1,否则返回0
2241
- def LONGCROSS(self,data,data2,n) :
2242
- if not JSAlgorithm.IsArray(data) and not JSAlgorithm.IsArray(data2) :
2243
- return []
2244
-
2245
- if n<1 :
2246
- return []
2247
-
2248
- len1 , len2= len(data), len(data2)
2249
- count=max(len1,len2)
2250
- result=JSAlgorithm.CreateArray(count,0)
2251
- for i in range(count) :
2252
- if i-1<0:
2253
- continue
2254
- if i>=len1 or i>=len2 :
2255
- continue
2256
-
2257
- if not JSAlgorithm.Is2Number(data[i], data2[i]) or not JSAlgorithm.Is2Number(data[i-1],data2[i-1]) :
2258
- continue
2259
-
2260
- if data[i]>data2[i] and data[i-1]<data2[i-1] :
2261
- result[i]=1
2262
-
2263
- for i in range(count) :
2264
- if not result[i] :
2265
- continue
2266
- for j in range(n) :
2267
- if i-j<0 :
2268
- break
2269
- if data[i-j]>=data2[i-j] :
2270
- result[i]=0
2271
- break
2272
-
2273
- return result
2274
-
2275
- # EXISTR(X,A,B):是否存在(前几日到前几日间).
2276
- # 例如: EXISTR(CLOSE>OPEN,10,5)
2277
- # 表示从前10日内到前5日内存在着阳线
2278
- # 若A为0,表示从第一天开始,B为0,表示到最后日止
2279
- def EXISTR(self,data,n,n2) :
2280
- if not JSAlgorithm.IsArray(data) :
2281
- return []
2282
-
2283
- dataLen=len(data)
2284
-
2285
- if n<=0 :
2286
- n=dataLen
2287
- if n2<=0:
2288
- n2=1
2289
- if n2>n :
2290
- return []
2291
-
2292
- result=JSAlgorithm.CreateArray(dataLen)
2293
- for i in range(dataLen) :
2294
- if i-n<0 or i-n2<0 :
2295
- continue
2296
-
2297
- result[i]=0
2298
- for j in range(n,n2-1,-1) :
2299
- value=data[i-j]
2300
- if JSAlgorithm.IsNumber(value) and value :
2301
- result[i]=1
2302
- break
2303
-
2304
- return result
2305
-
2306
- # RELATE(X,Y,N) 返回X和Y的N周期的相关系数
2307
- # RELATE(X,Y,N)=(∑[(Xi-Avg(X))(Yi-Avg(y))])/N ÷ √((∑(Xi-Avg(X))^2)/N * (∑(Yi-Avg(Y))^2)/N)
2308
- # 其中 avg(x)表示x的N周期均值: avg(X) = (∑Xi)/N
2309
- # √(...)表示开平方
2310
- def RELATE(self,data,data2,n) :
2311
- if not JSAlgorithm.IsVaildArray(data) or not JSAlgorithm.IsVaildArray(data2) :
2312
- return []
2313
-
2314
- if n<1:
2315
- n=1
2316
-
2317
- dataAverage=JSAlgorithm.ArrayAverage(data,n)
2318
- data2Average=JSAlgorithm.ArrayAverage(data2,n)
2319
-
2320
- count=max(len(data),len(data2))
2321
- result=JSAlgorithm.CreateArray(count)
2322
- for i in range(count) :
2323
- if i>=len(data) or i>=len(data2) or i>=len(dataAverage) or i>=len(data2Average) :
2324
- continue
2325
-
2326
- average=dataAverage[i]
2327
- average2=data2Average[i]
2328
-
2329
- total,total2,total3 = 0,0,0
2330
- for j in range(i-n+1, i+1) :
2331
- total+=(data[j]-average)*(data2[j]-average2) # ∑[(Xi-Avg(X))(Yi-Avg(y))])
2332
- total2+=math.pow(data[j]-average,2) # ∑(Xi-Avg(X))^2
2333
- total3+=math.pow(data2[j]-average2,2) # ∑(Yi-Avg(Y))^2)
2334
-
2335
- result[i]=(total/n)/(math.sqrt(total2/n)*math.sqrt(total3/n))
2336
-
2337
- return result
2338
-
2339
-
2340
- # COVAR(X,Y,N) 返回X和Y的N周期的协方差
2341
- def COVAR(self,data,data2,n) :
2342
- if not JSAlgorithm.IsArray(data) or not JSAlgorithm.IsArray(data2) :
2343
- return []
2344
-
2345
- if n<1:
2346
- n=1
2347
-
2348
- dataAverage=JSAlgorithm.ArrayAverage(data,n)
2349
- data2Average=JSAlgorithm.ArrayAverage(data2,n)
2350
- len1, len2= len(data), len(data2)
2351
- count=max(len1,len2)
2352
- result=JSAlgorithm.CreateArray(count)
2353
-
2354
- for i in range(count) :
2355
- if i>=len1 or i>=len2 or i>=len(dataAverage) or i>=len(data2Average) :
2356
- continue
2357
-
2358
- average=dataAverage[i]
2359
- average2=data2Average[i]
2360
-
2361
- total=0
2362
- for j in range(i-n+1, i+1) :
2363
- total+=(data[j]-average)*(data2[j]-average2)
2364
- result[i]=(total/n)
2365
-
2366
- return result
2367
-
2368
-
2369
-
2370
- # 求上一高点到当前的周期数.
2371
- # 用法: HHVBARS(X,N):求N周期内X最高值到当前周期数,N=0表示从第一个有效值开始统计
2372
- # 例如: HHVBARS(HIGH,0)求得历史新高到到当前的周期数
2373
- def HHVBARS(self,data,n) :
2374
- if not JSAlgorithm.IsVaildArray(data) :
2375
- return []
2376
-
2377
- dataLen=len(data)
2378
- if n<1:
2379
- n=dataLen
2380
-
2381
- result=JSAlgorithm.CreateArray(dataLen)
2382
- nMax=None # 最大值索引
2383
- for i in range(dataLen) :
2384
- if JSAlgorithm.IsNumber(data[i]) :
2385
- nMax=i
2386
- break
2387
-
2388
- j=0
2389
- for i in range(nMax+1,dataLen) : # 求第1个最大值
2390
- if j>=n :
2391
- break
2392
-
2393
- if data[i]>=data[nMax]:
2394
- nMax=i
2395
- if n==dataLen :
2396
- result[i]=(i-nMax)
2397
- j+=1
2398
-
2399
- for i in range(i,dataLen) :
2400
- if i-nMax<n :
2401
- if data[i]>=data[nMax] :
2402
- nMax=i
2403
- else :
2404
- nMax=i-n+1
2405
- for j in range(nMax, i+1) : # 计算区间最大值
2406
- if data[j]>=data[nMax] :
2407
- nMax=j
2408
-
2409
- result[i]=i-nMax
2410
-
2411
- return result
2412
-
2413
-
2414
- # 求上一低点到当前的周期数.
2415
- # 用法: LLVBARS(X,N):求N周期内X最低值到当前周期数,N=0表示从第一个有效值开始统计
2416
- # 例如: LLVBARS(HIGH,20)求得20日最低点到当前的周期数
2417
- def LLVBARS(self, data,n) :
2418
- if not JSAlgorithm.IsVaildArray(data) :
2419
- return []
2420
-
2421
- dataLen=len(data)
2422
- if n<1 :
2423
- n=dataLen
2424
-
2425
- result=JSAlgorithm.CreateArray(dataLen)
2426
- nMin=None # 最小值索引
2427
- for i in range(dataLen) :
2428
- if JSAlgorithm.IsNumber(data[i]) :
2429
- nMin=i
2430
- break
2431
-
2432
- j=0
2433
- for i in range(nMin+1,dataLen) : # 求第1个最大值
2434
- if j>=n :
2435
- break
2436
- if data[i]<=data[nMin] :
2437
- nMin=i
2438
- if n==dataLen :
2439
- result[i]=i-nMin
2440
- j+=1
2441
-
2442
- for i in range(i,dataLen) :
2443
- if i-nMin<n :
2444
- if data[i]<=data[nMin] :
2445
- nMin=i
2446
- else :
2447
- nMin=i-n+1
2448
- for j in range(nMin, i+1): # 计算区间最小值
2449
- if data[j]<=data[nMin] :
2450
- nMin=j
2451
-
2452
- result[i]=i-nMin
2453
-
2454
- return result
2455
-
2456
-
2457
- # β(Beta)系数
2458
- # BETA(N) 返回当前证券N周期收益与对应大盘指数收益相比的贝塔系数
2459
- # 需要下载上证指数历史数据
2460
- # 涨幅(X)=(现价-上一个交易日收盘价)/上一个交易日收盘价
2461
- # 公式=股票和指数协方差/指数方差
2462
- def BETA(self,n) :
2463
- stockData=self.SymbolData.Data
2464
- indexData=self.SymbolData.IndexData
2465
- if n<=0 :
2466
- n=1
2467
-
2468
- dataLen=len(stockData.Data)
2469
- stockProfit=JSAlgorithm.CreateArray(dataLen,0) # 股票涨幅
2470
- indexProfit=JSAlgorithm.CreateArray(dataLen,0) # 指数涨幅
2471
- for i in range(dataLen) :
2472
- stockItem=stockData.Data[i]
2473
- indexItem=indexData.Data[i]
2474
-
2475
- if stockItem.Close>0 and stockItem.YClose>0 :
2476
- stockProfit[i]=(stockItem.Close-stockItem.YClose)/stockItem.YClose
2477
- if indexItem.Close>0 and indexItem.YClose>0 :
2478
- indexProfit[i]=(indexItem.Close-indexItem.YClose)/indexItem.YClose
2479
-
2480
-
2481
- # 计算均值数组
2482
- averageStockProfit=JSAlgorithm.ArrayAverage(stockProfit,n)
2483
- averageIndexProfit=JSAlgorithm.ArrayAverage(indexProfit,n)
2484
-
2485
- result=JSAlgorithm.CreateArray(dataLen)
2486
-
2487
- for i in range(dataLen) :
2488
- if i>=len(stockProfit) or i>=len(indexProfit) or i>=len(averageStockProfit) or i>=len(averageIndexProfit) :
2489
- continue
2490
-
2491
- averageStock=averageStockProfit[i]
2492
- averageIndex=averageIndexProfit[i]
2493
-
2494
- covariance=0 # 协方差
2495
- variance=0 # 方差
2496
- for j in range(i-n+1, i+1) :
2497
- value=(indexProfit[j]-averageIndex)
2498
- value2=(stockProfit[j]-averageStock)
2499
- covariance+=value*value2
2500
- variance+=value*value
2501
-
2502
- if JSAlgorithm.IsDivideNumber(variance) and JSAlgorithm.IsNumber(covariance) :
2503
- result[i]=covariance/variance # (covariance/n)/(variance/n)=covariance/variance;
2504
-
2505
- return result
2506
-
2507
-
2508
- # 用法:BETA2(X,Y,N)为X与Y的N周期相关放大系数,表示Y变化1%,则X将变化N%
2509
- # 例如:BETA2(CLOSE,INDEXC,10)表示收盘价与大盘指数之间的10周期相关放大率
2510
- def BETA2(self,x,y,n) :
2511
- if not JSAlgorithm.IsVaildArray(x) or not JSAlgorithm.IsVaildArray(y) :
2512
- return []
2513
-
2514
- xLen, yLen = len(x), len(y)
2515
- if n<=0 :
2516
- n=1
2517
-
2518
- xProfit=JSAlgorithm.CreateArray(xLen,0) # x数据的涨幅
2519
- yProfit=JSAlgorithm.CreateArray(yLen,0) # y数据的涨幅
2520
-
2521
- count=max(xLen,yLen)
2522
-
2523
- lastX, lastY = x[0], y[0]
2524
- for i in range(count) :
2525
- xItem=x[i]
2526
- yItem=y[i]
2527
-
2528
- if lastX>0 :
2529
- xProfit[i]=(xItem-lastX)/lastX
2530
- if lastY>0 :
2531
- yProfit[i]=(yItem-lastY)/lastY
2532
-
2533
- lastX=xItem
2534
- lastY=yItem
2535
-
2536
- # 计算均值数组
2537
- averageXProfit=JSAlgorithm.ArrayAverage(xProfit,n)
2538
- averageYProfit=JSAlgorithm.ArrayAverage(yProfit,n)
2539
-
2540
- result=JSComplierHelper.CreateArray(count)
2541
-
2542
- for i in range(count) :
2543
- if i>=len(xProfit) or i>=len(yProfit) or i>=len(averageXProfit) or i>=len(averageYProfit) :
2544
- continue
2545
-
2546
- averageX=averageXProfit[i]
2547
- averageY=averageYProfit[i]
2548
-
2549
- covariance=0 # 协方差
2550
- variance=0 # 方差
2551
- for j in range(i-n+1, i+1) :
2552
- value=(xProfit[j]-averageX)
2553
- value2=(yProfit[j]-averageY)
2554
- covariance+=value*value2
2555
- variance+=value*value
2556
-
2557
- if JSAlgorithm.IsDivideNumber(variance) and JSAlgorithm.IsNumber(covariance) :
2558
- result[i]=covariance/variance # (covariance/n)/(variance/n)=covariance/variance;
2559
-
2560
- return result
2561
-
2562
- # 一直存在.
2563
- # 例如: EVERY(CLOSE>OPEN,N)
2564
- # 表示N日内一直阳线(N应大于0,小于总周期数,N支持变量)
2565
- def EVERY(self,data,n):
2566
- if n<1 or not JSAlgorithm.IsVaildArray(data) :
2567
- return []
2568
-
2569
- dataLen=len(data)
2570
- result=JSComplierHelper.CreateArray(dataLen)
2571
- for i in range(dataLen) :
2572
- if JSAlgorithm.IsNumber(data[i]) :
2573
- break
2574
-
2575
- flag=0
2576
- for i in range(i,dataLen) :
2577
- if data[i]:
2578
- flag+=1
2579
- else :
2580
- flag=0
2581
-
2582
- if flag==n :
2583
- result[i]=1
2584
- flag-=1
2585
- else :
2586
- result[i]=0
2587
-
2588
- return result
2589
-
2590
-
2591
- # 抛物转向.
2592
- # 用法: SAR(N,S,M),N为计算周期,S为步长,M为极值
2593
- # 例如: SAR(10,2,20)表示计算10日抛物转向,步长为2%,极限值为20%
2594
- def SAR(self,n,step,exValue) :
2595
- stockData= self.SymbolData.Data
2596
- dataLen=len(stockData.Data)
2597
- if n>=dataLen :
2598
- return []
2599
-
2600
- result=JSComplierHelper.CreateArray(dataLen)
2601
- high, low =None, None
2602
- for i in range(n) :
2603
- item=stockData.Data[i]
2604
- if high==None:
2605
- high=item.High
2606
- elif high<item.High :
2607
- high=item.High
2608
-
2609
- if low==None :
2610
- low=item.Low
2611
- elif low>item.Low :
2612
- low=item.Low
2613
-
2614
- SAR_LONG=0
2615
- SAR_SHORT=1
2616
- position=SAR_LONG
2617
- result[n-1]=low
2618
- nextSar=low
2619
- sip=stockData.Data[0].High
2620
- af=step/100
2621
- for i in range(n,dataLen) :
2622
- ysip=sip
2623
- item=stockData.Data[i]
2624
- yitem=stockData.Data[i-1]
2625
-
2626
- if (position==SAR_LONG) :
2627
- if (item.Low<result[i-1]) :
2628
- position=SAR_SHORT
2629
- sip=item.Low
2630
- af=step/100
2631
- nextSar =max(item.High,yitem.High)
2632
- nextSar =max(nextSar,ysip+af*(sip-ysip))
2633
- else :
2634
- position = SAR_LONG
2635
- if (item.High>ysip) :
2636
- sip=item.High
2637
- af=min(af+step/100,exValue/100)
2638
- nextSar=min(item.Low,yitem.Low)
2639
- nextSar=min(nextSar,result[i-1]+af*(sip-result[i-1]))
2640
- elif (position==SAR_SHORT) :
2641
- if (item.High>result[i-1]) :
2642
- position=SAR_LONG
2643
- sip=item.High
2644
- af=step/100
2645
- nextSar =min(item.Low,yitem.Low)
2646
- nextSar =min(nextSar,result[i-1]+af*(sip-ysip))
2647
- else :
2648
- position = SAR_SHORT
2649
- if(item.Low<ysip) :
2650
- sip=item.Low
2651
- af=min(af+step/100,exValue/100)
2652
- nextSar=max(item.High,yitem.High)
2653
- nextSar=max(nextSar,result[i-1]+af*(sip-result[i-1]))
2654
-
2655
- result[i]=nextSar
2656
-
2657
- return result
2658
-
2659
-
2660
- # 抛物转向点.
2661
- # 用法: SARTURN(N,S,M),N为计算周期,S为步长,M为极值,若发生向上转向则返回1,若发生向下转向则返回-1,否则为0
2662
- # 其用法与SAR函数相同
2663
- def SARTURN(self,n,step,exValue) :
2664
- sar=self.SAR(n,step,exValue)
2665
- stockData= self.SymbolData.Data
2666
- dataLen=len(stockData)
2667
- result=JSAlgorithm.CreateArray(dataLen)
2668
-
2669
- for index in range(len(sar)) :
2670
- if JSAlgorithm.IsNumber(sar[index]) :
2671
- break
2672
-
2673
- flag=0
2674
- if index<dataLen :
2675
- flag=stockData.Data[index].Close>sar[index]
2676
-
2677
- for i in range(index+1,dataLen) :
2678
- item=stockData.Data[i]
2679
- if item.Close<sar[i] and flag :
2680
- result[i]=-1
2681
- else :
2682
- result[i]= 1 if (item.Close>sar[i] and not flag) else 0
2683
-
2684
- flag=item.Close>sar[i]
2685
-
2686
- return result
2687
-
2688
-
2689
- # 属于未来函数,将当前位置到若干周期前的数据设为1.
2690
- # 用法: BACKSET(X,N),若X非0,则将当前位置到N周期前的数值设为1.
2691
- # 例如: BACKSET(CLOSE>OPEN,2)若收阳则将该周期及前一周期数值设为1,否则为0
2692
- def BACKSET(self,condition,n) :
2693
- if not condition :
2694
- return []
2695
- dataCount=len(condition)
2696
- if dataCount<=0 :
2697
- return []
2698
-
2699
- result=JSAlgorithm.CreateArray(dataCount,0) # 初始化0
2700
-
2701
- for pos in range(dataCount) :
2702
- if JSAlgorithm.IsNumber(condition[pos]) :
2703
- break
2704
-
2705
- if pos==dataCount :
2706
- return result
2707
-
2708
- num=min(dataCount-pos,max(n,1))
2709
- for i in range(dataCount-1, -1,-1) :
2710
- value=condition[i]
2711
- if JSAlgorithm.IsNumber(value) and value :
2712
- for j in range(i, i-num,-1) :
2713
- result[j]=1
2714
-
2715
- if condition[i] :
2716
- for j in range(i, pos+1) :
2717
- result[j]=1
2718
-
2719
- return result
2720
-
2721
-
2722
- # 计算截至到某一天的历史所有筹码
2723
- def CalculateChip(self,index,exchangeData,hisData,dRate) :
2724
- result=Variant()
2725
- result.Min, result.Max, result.Data = None, None, []
2726
- seed=1 # 筹码历史衰减换手系数
2727
- max, min= None, None
2728
- result.Data=JSComplierHelper.CreateArray(index+1)
2729
- for i in range(index, -1,-1) :
2730
- item=Variant() # Vol:量 High:最高 Low:最低
2731
- kData=hisData[i]
2732
- if i==index :
2733
- item.Vol=kData.Vol*exchangeData[i]
2734
- else :
2735
- item.Vol=kData.Vol*seed
2736
-
2737
- item.Date=kData.Date
2738
- item.High=kData.High
2739
- item.Low=kData.Low
2740
-
2741
- if max==None :
2742
- max=item.High
2743
- elif max<item.High :
2744
- max=item.High
2745
- if min==None :
2746
- min=item.Low
2747
- elif min<item.Low :
2748
- min=item.Low
2749
-
2750
- result.Data[i]=item
2751
-
2752
- seed*=(1-(exchangeData[i]/100)*dRate) # 换手率累乘
2753
-
2754
- result.Max=max
2755
- result.Min=min
2756
- return result
2757
-
2758
- # 获利盘比例.
2759
- # 用法: WINNER(CLOSE),表示以当前收市价卖出的获利盘比例,例如返回0.1表示10%获利盘;WINNER(10.5)表示10.5元价格的获利盘比例
2760
- # 该函数仅对日线分析周期有效
2761
- def WINNER(self,data,node) :
2762
- kData=self.SymbolData.Data
2763
- if (not kData or kData.GetCount()<=0) :
2764
- return []
2765
- dataLen=kData.GetCount()
2766
- aryCapital=self.SymbolData.GetFinanceCacheData(7,node) # 流通股本
2767
- result=JSAlgorithm.CreateArray(dataLen)
2768
-
2769
- priceRange=kData.GetMaxMin()
2770
- dMaxPrice, dMinPrice = priceRange["Max"], priceRange["Min"]
2771
- if (dMinPrice > 1000 or dMinPrice < 0 or dMaxPrice>1000 or dMinPrice < 0) :
2772
- self.ThrowUnexpectedNode(node,'WINNER() 历史K线最大最小值错误, 超出(0,1000)范围')
2773
-
2774
- lMaxPrice=int(dMaxPrice*100 + 1)
2775
- lMinPrice=int(dMinPrice*100 - 1)
2776
- lLow, lHigh, lClose = 0, 0, 0
2777
- dMaxPrice = lMaxPrice / 100.0
2778
- dMinPrice = lMinPrice / 100.0
2779
- lSpeed = lMaxPrice - lMinPrice + 1
2780
- if (lSpeed < 1) :
2781
- return result
2782
-
2783
- aryVolPrice=JSAlgorithm.CreateArray(lSpeed,0)
2784
- aryPerVol=JSAlgorithm.CreateArray(lSpeed,0)
2785
-
2786
- dHSL, dTotalVol, dVol = 0, 0, 0
2787
- for i in range(dataLen) :
2788
- if (i >= len(aryCapital)) :
2789
- continue
2790
- if (aryCapital[i]<1):
2791
- continue
2792
-
2793
- kItem=kData.GetItem(i)
2794
- dHSL = kItem.Vol/aryCapital[i]
2795
-
2796
- for j in range(lSpeed) :
2797
- aryVolPrice[j]*=(1-dHSL)
2798
-
2799
- lLow=int(min(lMaxPrice,max(lMinPrice,kItem.Low *100)))-lMinPrice
2800
- lHigh=int(min(lMaxPrice,max(lMinPrice,kItem.High*100)))-lMinPrice
2801
- lClose=int(min(lMaxPrice,max(lMinPrice,kItem.Close*100)))-lMinPrice
2802
-
2803
- for j in range(lSpeed) :
2804
- aryPerVol[j]=0
2805
-
2806
- lHalf =int((lLow + lHigh + 2 * lClose) / 4)
2807
- if (lHalf == lHigh or lHalf == lLow) :
2808
- aryPerVol[lHalf] += kItem.Vol
2809
- else :
2810
- dVH = kItem.Vol / (lHalf - lLow)
2811
- for k in range(lLow,lHalf) :
2812
- aryPerVol[k] += (k - lLow)*(dVH / (lHalf - lLow))
2813
- for k in range(lHalf,lHigh+1) :
2814
- aryPerVol[k] += (k - lHigh)*(dVH / (lHalf - lHigh))
2815
-
2816
- dTotalVol = 0
2817
- for j in range(lLow,lHigh+1) :
2818
- aryVolPrice[j] += aryPerVol[j]
2819
-
2820
- for j in range(lSpeed) :
2821
- dTotalVol += aryVolPrice[j]
2822
-
2823
- if isinstance(data,list):
2824
- lHigh = int(min((data[i] * 100) - lMinPrice, lSpeed - 1))
2825
- else :
2826
- lHigh = int(min((data * 100) - lMinPrice, lSpeed - 1))
2827
-
2828
- dVol=0
2829
- for j in range(lHigh+1) :
2830
- dVol += aryVolPrice[j]
2831
-
2832
- if (dTotalVol > 0) :
2833
- result[i]=dVol / dTotalVol
2834
- elif (i - 1 >= 0) :
2835
- result[i] = result[i - 1]
2836
-
2837
- return result
2838
-
2839
-
2840
-
2841
- '''
2842
- def WINNER(self,data,node) :
2843
- exchangeID=201
2844
- exchangeData=self.SymbolData.GetFinanceCacheData(exchangeID,node) # 换手率
2845
- if not exchangeData :
2846
- return []
2847
-
2848
- isNumber=JSComplierHelper.IsNumber(data)
2849
- singleData=None
2850
- if isNumber :
2851
- singleData=int(float(data)*100)
2852
- compareData=None
2853
- klineData=self.SymbolData.Data.Data
2854
- klineLen=len(klineData)
2855
- result=JSComplierHelper.CreateArray(klineLen)
2856
- for i in range(klineLen-1, -1, -1) :
2857
- chipData=self.CalculateChip(i,exchangeData,klineData,1)
2858
- if ( chipData.Max==None or chipData.Min==None or chipData.Max<=0 or chipData.Min<=0) :
2859
- continue
2860
-
2861
- # max=int(chipData.Max*100)
2862
- # min=int(chipData.Min*100)
2863
-
2864
- if (singleData!=None) :
2865
- compareData=singleData
2866
- else :
2867
- if i>=len(data) :
2868
- continue
2869
- compareData=int(data[i]*100)
2870
-
2871
- totalVol, vol= 0,0
2872
- for j in range(i, -1, -1) :
2873
- item=chipData.Data[j]
2874
- start=int(item.Low*100)
2875
- end=int(item.High*100)
2876
- if ((end-start+1)<=0):
2877
- continue
2878
-
2879
- iAverageVolume=item.Vol
2880
- iAverageVolume=iAverageVolume/(end-start+1)
2881
- if (iAverageVolume<=0):
2882
- continue
2883
-
2884
- profitVol=0 # 获利的成交量
2885
- if (compareData>end) :
2886
- profitVol=item.Vol
2887
- elif (compareData<start) :
2888
- profitVol=0
2889
- else :
2890
- profitVol=item.Vol*(compareData-start+1)/(end-start+1)
2891
-
2892
- vol+=profitVol
2893
- totalVol+=item.Vol
2894
-
2895
- if (totalVol>0) :
2896
- result[i]=vol/totalVol
2897
-
2898
- return result
2899
- '''
2900
-
2901
- # 成本分布情况.
2902
- # 用法: COST(10),表示10%获利盘的价格是多少,即有10%的持仓量在该价格以下,其余90%在该价格以上,为套牢盘
2903
- # 该函数仅对日线分析周期有效
2904
- def COST(self,data, node) :
2905
- rate=data/100
2906
- if (rate<0.000001 or rate>1) :
2907
- return []
2908
-
2909
- kData=self.SymbolData.Data
2910
- if (not kData or kData.GetCount()<=0) :
2911
- return []
2912
- dataLen=kData.GetCount()
2913
- aryCapital=self.SymbolData.GetFinanceCacheData(7,node) # 流通股本
2914
- result=JSAlgorithm.CreateArray(dataLen)
2915
-
2916
- priceRange=kData.GetMaxMin()
2917
- dMaxPrice, dMinPrice = priceRange["Max"], priceRange["Min"]
2918
- if (dMinPrice > 1000 or dMinPrice < 0 or dMaxPrice>1000 or dMinPrice < 0) :
2919
- self.ThrowUnexpectedNode(node,'WINNER() 历史K线最大最小值错误, 超出(0,1000)范围')
2920
-
2921
- lMaxPrice=int(dMaxPrice*100 + 1)
2922
- lMinPrice=int(dMinPrice*100 - 1)
2923
- lLow, lHigh, lClose = 0, 0, 0
2924
- dMaxPrice = lMaxPrice / 100.0
2925
- dMinPrice = lMinPrice / 100.0
2926
- lSpeed = lMaxPrice - lMinPrice + 1
2927
- if (lSpeed < 1) :
2928
- return result
2929
-
2930
- aryVolPrice=JSAlgorithm.CreateArray(lSpeed,0)
2931
- aryPerVol=JSAlgorithm.CreateArray(lSpeed,0)
2932
-
2933
- dHSL, dTotalVol, dVol, dCost = 0, 0, 0,0
2934
- for i in range(dataLen) :
2935
- if (i >= len(aryCapital)) :
2936
- continue
2937
-
2938
- if (aryCapital[i]>1):
2939
- kItem=kData.GetItem(i)
2940
- dHSL = kItem.Vol/aryCapital[i]
2941
-
2942
- for j in range(lSpeed) :
2943
- aryVolPrice[j]*=(1-dHSL)
2944
-
2945
- lLow=int(min(lMaxPrice,max(lMinPrice,kItem.Low *100)))-lMinPrice
2946
- lHigh=int(min(lMaxPrice,max(lMinPrice,kItem.High*100)))-lMinPrice
2947
- lClose=int(min(lMaxPrice,max(lMinPrice,kItem.Close*100)))-lMinPrice
2948
-
2949
- for j in range(lSpeed) :
2950
- aryPerVol[j]=0
2951
-
2952
- lHalf =int((lLow + lHigh + 2 * lClose) / 4)
2953
- if (lHalf == lHigh or lHalf == lLow) :
2954
- aryPerVol[lHalf] += kItem.Vol
2955
- else :
2956
- dVH = kItem.Vol / (lHalf - lLow)
2957
- for k in range(lLow,lHalf) :
2958
- aryPerVol[k] += (k - lLow)*(dVH / (lHalf - lLow))
2959
- for k in range(lHalf,lHigh+1) :
2960
- aryPerVol[k] += (k - lHigh)*(dVH / (lHalf - lHigh))
2961
-
2962
- dTotalVol = 0
2963
- for j in range(lLow,lHigh+1) :
2964
- aryVolPrice[j] += aryPerVol[j]
2965
-
2966
- for j in range(lSpeed) :
2967
- dTotalVol += aryVolPrice[j]
2968
-
2969
- dCost, dVol = 0,0
2970
- for j in range(lSpeed) :
2971
- dVol+=aryVolPrice[j]
2972
- if (dVol>=dTotalVol*rate) :
2973
- dCost=(dMaxPrice-dMinPrice)*j/lSpeed+dMinPrice
2974
- break
2975
-
2976
- result[i]=dCost
2977
-
2978
- return result
2979
-
2980
-
2981
- '''
2982
- def COST(self,data, node) :
2983
- exchangeID=201
2984
- exchangeData=self.SymbolData.GetFinanceCacheData(exchangeID,node) # 换手率
2985
- if not exchangeData :
2986
- return []
2987
-
2988
- isNumber=JSComplierHelper.IsNumber(data)
2989
- singleData=None
2990
- if (isNumber) :
2991
- singleData=float(data)
2992
- compareData=None
2993
- klineData=self.SymbolData.Data.Data
2994
- klineLen=len(self.SymbolData.Data.Data)
2995
- result=JSComplierHelper.CreateArray(klineLen)
2996
- for i in range(klineLen-1,-1,-1) :
2997
- chipData=self.CalculateChip(i,exchangeData,klineData,1)
2998
- if (chipData.Max==None or chipData.Min==None or chipData.Max<=0 or chipData.Min<=0) :
2999
- continue
3000
-
3001
- max=int(chipData.Max*100)
3002
- # min=int(chipData.Min*100)
3003
-
3004
- if (singleData!=None) :
3005
- compareData=singleData
3006
- else :
3007
- if (i>=data.length) :
3008
- continue
3009
- compareData=data[i]
3010
-
3011
- totalVol,vol= 0,0
3012
- aryMap={}
3013
- for j in range(i,-1,-1) :
3014
- item=chipData.Data[j]
3015
- start=int(item.Low*100)
3016
- end=int(item.High*100)
3017
- if ((end-start+1)<=0) :
3018
- continue
3019
-
3020
- iAverageVolume=item.Vol
3021
- iAverageVolume=iAverageVolume/(end-start+1)
3022
- if iAverageVolume<=0 :
3023
- continue
3024
-
3025
- k=start # 起始价格
3026
- while k<end and k<=max :
3027
- if k in aryMap :
3028
- vol=aryMap[k]
3029
- aryMap[k]=vol+iAverageVolume
3030
- else :
3031
- aryMap[k]=iAverageVolume
3032
- k+=1
3033
-
3034
- totalVol+=item.Vol
3035
-
3036
- # 计算获利盘
3037
- vol=0
3038
- for key, value in aryMap.items() :
3039
- vol+=value
3040
- result[i]=key/100
3041
- if (vol/totalVol*100>compareData) :
3042
- break
3043
-
3044
- return result
3045
- '''
3046
-
3047
- # 远期成本分布比例.
3048
- # 用法: PPART(10),表示10前的成本占总成本的比例,0.2表示20%
3049
- def PPART(self, n, node) :
3050
- startDay=int(n)
3051
- if (startDay<0):
3052
- return []
3053
-
3054
- kData=self.SymbolData.Data
3055
- if (not kData or kData.GetCount()<=0) :
3056
- return []
3057
-
3058
- dataLen=kData.GetCount()
3059
- aryCapital=self.SymbolData.GetFinanceCacheData(7,node) # 流通股本
3060
- result=JSAlgorithm.CreateArray(dataLen)
3061
-
3062
- for i in range(startDay, dataLen) :
3063
- start = i - startDay
3064
- if (start < 0) :
3065
- continue
3066
-
3067
- #前n日成交量和
3068
- partVol = 0
3069
- for j in range(startDay) :
3070
- kItem=kData.GetItem(j + start)
3071
- partVol += kItem.Vol
3072
-
3073
- if i < len(aryCapital) :
3074
- if (aryCapital[i]>0) :
3075
- value=1 - (partVol / aryCapital[i])
3076
- result[i]=value
3077
-
3078
- return result
3079
-
3080
- # 区间成本.
3081
- # 用法: 例如COSTEX(CLOSE,REF(CLOSE,1)),表示近两日收盘价格间筹码的成本
3082
- # 该函数仅对日线分析周期有效
3083
- def COSTEX(self,data, data2, node):
3084
- kData=self.SymbolData.Data
3085
- if (not kData or kData.GetCount()<=0) :
3086
- return []
3087
- dataLen=kData.GetCount()
3088
- aryCapital=self.SymbolData.GetFinanceCacheData(7,node) # 流通股本
3089
- result=JSAlgorithm.CreateArray(dataLen)
3090
-
3091
- priceRange=kData.GetMaxMin()
3092
- dMaxPrice, dMinPrice = priceRange["Max"], priceRange["Min"]
3093
- if (dMinPrice > 1000 or dMinPrice < 0 or dMaxPrice>1000 or dMinPrice < 0) :
3094
- self.ThrowUnexpectedNode(node,'COSTEX() 历史K线最大最小值错误, 超出(0,1000)范围')
3095
-
3096
- lMaxPrice=int(dMaxPrice*100 + 1)
3097
- lMinPrice=int(dMinPrice*100 - 1)
3098
- lLow, lHigh, lClose = 0, 0, 0
3099
- dMaxPrice = lMaxPrice / 100.0
3100
- dMinPrice = lMinPrice / 100.0
3101
- lSpeed = lMaxPrice - lMinPrice + 1
3102
- if (lSpeed < 1) :
3103
- return result
3104
-
3105
- aryVolPrice=JSAlgorithm.CreateArray(lSpeed,0)
3106
- aryPerVol=JSAlgorithm.CreateArray(lSpeed,0)
3107
-
3108
- dHSL, dTotalVol, dVol, dVola, dPerVola, dVolb, dPerVolb = 0, 0, 0, 0, 0, 0, 0
3109
- for i in range(dataLen) :
3110
- if (i >= len(aryCapital)) :
3111
- continue
3112
-
3113
- if (aryCapital[i]>1):
3114
- kItem=kData.GetItem(i)
3115
- dHSL = kItem.Vol/aryCapital[i]
3116
-
3117
- for j in range(lSpeed) :
3118
- aryVolPrice[j]*=(1-dHSL)
3119
-
3120
- lLow=int(min(lMaxPrice,max(lMinPrice,kItem.Low *100)))-lMinPrice
3121
- lHigh=int(min(lMaxPrice,max(lMinPrice,kItem.High*100)))-lMinPrice
3122
- lClose=int(min(lMaxPrice,max(lMinPrice,kItem.Close*100)))-lMinPrice
3123
-
3124
- for j in range(lSpeed) :
3125
- aryPerVol[j]=0
3126
-
3127
- lHalf =int((lLow + lHigh + 2 * lClose) / 4)
3128
- if (lHalf == lHigh or lHalf == lLow) :
3129
- aryPerVol[lHalf] += kItem.Vol
3130
- else :
3131
- dVH = kItem.Vol / (lHalf - lLow)
3132
- for k in range(lLow,lHalf) :
3133
- aryPerVol[k] += (k - lLow)*(dVH / (lHalf - lLow))
3134
- for k in range(lHalf,lHigh+1) :
3135
- aryPerVol[k] += (k - lHigh)*(dVH / (lHalf - lHigh))
3136
-
3137
- dTotalVol = 0
3138
- for j in range(lLow,lHigh+1) :
3139
- aryVolPrice[j] += aryPerVol[j]
3140
-
3141
- for j in range(lSpeed) :
3142
- dTotalVol += aryVolPrice[j]
3143
-
3144
- if isinstance(data,list):
3145
- if (data[i]==None) :
3146
- continue
3147
- lHigh = int(min((data[i] * 100) - lMinPrice, lSpeed - 1))
3148
- else :
3149
- lHigh = int(min((data * 100) - lMinPrice, lSpeed - 1))
3150
-
3151
- dVola, dPerVola = 0,0
3152
- for j in range(lHigh+1):
3153
- dVola += aryVolPrice[j]
3154
- dPerVola += (0.01*(j + lMinPrice))*aryVolPrice[j]
3155
-
3156
- if isinstance(data2,list) :
3157
- if (data2[i]==None):
3158
- continue
3159
- lHigh = int(min((data2[i] * 100) - lMinPrice, lSpeed - 1))
3160
- else :
3161
- lHigh = int(min((data2 * 100) - lMinPrice, lSpeed - 1))
3162
-
3163
- dVolb, dPerVolb = 0, 0
3164
- for j in range(lHigh+1) :
3165
- dVolb += aryVolPrice[j]
3166
- dPerVolb += (0.01*(j + lMinPrice))*aryVolPrice[j]
3167
-
3168
- dVol = dVola - dVolb
3169
- dPerVolRange = dPerVola - dPerVolb
3170
- if abs(dPerVolRange)>0.001 and dVol!=0 :
3171
- result[i]=dPerVolRange / dVol
3172
- elif (i-1>=0) :
3173
- result[i] = result[i - 1]
3174
-
3175
- return result
3176
-
3177
- # 近期获利盘比例.
3178
- # 用法: LWINNER(5,CLOSE),表示最近5天的那部分成本以当前收市价卖出的获利盘比例
3179
- # 例如: 返回0.1表示10%获利盘
3180
- def LWINNER(self, n, data, node) :
3181
- return []
3182
-
3183
- def PWINNER(self, n, data, node) :
3184
- return []
3185
-
3186
- # 属于未来函数,之字转向.
3187
- # 用法: ZIG(K,N),当价格变化量超过N%时转向,K表示0:开盘价,1:最高价,2:最低价,3:收盘价,其余:数组信息
3188
- # 例如: ZIG(3,5)表示收盘价的5%的ZIG转向
3189
- def ZIG(self,data,n) :
3190
- hisData=self.SymbolData.Data
3191
- if JSComplierHelper.IsNumber(data):
3192
- if data==0 :
3193
- data=hisData.GetOpen()
3194
- elif data==1 :
3195
- data=hisData.GetHigh()
3196
- elif data==2 :
3197
- data=hisData.GetLow()
3198
- elif data==3:
3199
- data=hisData.GetClose()
3200
- else :
3201
- return []
3202
-
3203
- return self.ZIG_Calculate(data,n)
3204
-
3205
- # 获取第1个有效数据索引
3206
- def GetFirstVaildIndex(self, data):
3207
- count=len(data)
3208
- for i in range(count):
3209
- if (JSComplierHelper.IsNumber(data[i])):
3210
- return i
3211
-
3212
- return count
3213
-
3214
- def ZIG_Calculate(self, data,dRate):
3215
- nDataCount=len(data)
3216
- dest=JSAlgorithm.CreateArray(nDataCount)
3217
- m=self.GetFirstVaildIndex(data)
3218
- i, lLastPos, lState, j = 0, 0, 0, 0
3219
- dif = 0
3220
- lLastPos, lState = m, m
3221
- for i in range(m+1, nDataCount-1) :
3222
- if (lState==m):
3223
- break
3224
- if abs(data[i] - data[m]) * 100 >= dRate*data[m]:
3225
- if (data[i]>data[m]) :
3226
- lState=i
3227
- else :
3228
- lState=-1
3229
- else :
3230
- lState=m
3231
-
3232
- for i in range(i, nDataCount-1) :
3233
- if (data[i] >= data[i - 1] and data[i] >= data[i + 1]) :
3234
- if (lState<0) :
3235
- if ((data[i] - data[-lState]) * 100<dRate*data[-lState]) :
3236
- continue
3237
- else :
3238
- j = -lState
3239
- dif = (data[lLastPos] - data[j]) / (-lState - lLastPos)
3240
- dest[j]=data[-lState]
3241
- j-=1
3242
- for j in range(j,lLastPos-1,-1): # for (; j >= lLastPos; j--)
3243
- dest[j]=data[-lState] + (-lState - j)*dif
3244
- lLastPos = -lState
3245
- lState = i
3246
-
3247
- elif (data[i]>data[lState]):
3248
- lState = i
3249
- elif (data[i] <= data[i - 1] and data[i] <= data[i + 1]) :
3250
- if (lState>0) :
3251
- if ((data[lState] - data[i]) * 100<dRate*data[lState]):
3252
- continue
3253
- else :
3254
- j = lLastPos
3255
- dif = (data[lState] - data[j]) / (lState - lLastPos)
3256
- dest[j]=data[lLastPos]
3257
- j+=1
3258
- for j in range(j,lState+1) :
3259
- dest[j]=data[lLastPos] + (j - lLastPos)*dif
3260
- lLastPos = lState
3261
- lState = -i
3262
- elif (data[i]<data[-lState]) :
3263
- lState = -i
3264
-
3265
- if (abs(lState) >= nDataCount - 2) :
3266
- if (lState>0 and data[nDataCount - 1] >= data[lState]) :
3267
- lState = nDataCount - 1
3268
- if (lState<0 and data[nDataCount - 1] <= data[-lState]) :
3269
- lState = 1 - nDataCount
3270
-
3271
- if (lState>0) :
3272
- j = lLastPos
3273
- dif = (data[lState] - data[j]) / (lState - lLastPos )
3274
- dest[j]=data[lLastPos]
3275
- j+=1
3276
- for j in range(j, lState+1) :
3277
- dest[j]=data[lLastPos] + (j - lLastPos)*dif
3278
- else :
3279
- j = -lState
3280
- dif = (data[lLastPos] - data[j]) / (-lState - lLastPos)
3281
- dest[j]=data[-lState]
3282
- j-=1
3283
- for j in range(j,lLastPos-1,-1) : # for (; j >= lLastPos; j--)
3284
- dest[j]=(data[-lState] + (-lState - j)*dif)
3285
-
3286
- lState = abs(lState)
3287
- if (lState<nDataCount - 1) :
3288
- if (data[nDataCount - 1] >= data[lState]) :
3289
- j = lState
3290
- dif = (data[nDataCount - 1] - data[j]) / (nDataCount - lState)
3291
- dest[j]=(data[lState])
3292
- j+=1
3293
- for j in range(j, nDataCount):
3294
- dest[j]=(data[lState] + (j - lState)*dif)
3295
- else :
3296
- j = nDataCount - 1
3297
- dif = (data[lState] - data[j]) / (nDataCount - lState)
3298
- dest[j]=(data[nDataCount - 1])
3299
- j-=1
3300
- for j in range(j, lState-1, -1) : #for (; j >= lState; j--)
3301
- dest[j]=(data[nDataCount - 1] + (nDataCount - j)*dif)
3302
-
3303
- return dest
3304
-
3305
- # 属于未来函数,前M个ZIG转向波谷值.
3306
- # 用法: TROUGH(K,N,M)表示之字转向ZIG(K,N)的前M个波谷的数值,M必须大于等于1
3307
- # 例如: TROUGH(2,5,2)表示%5最低价ZIG转向的前2个波谷的数值
3308
- def TROUGH(self,data,n,n2):
3309
- zigData=self.ZIG(data,n) # 计算ZIG
3310
- lEnd=n2
3311
- if (lEnd<1) :
3312
- return []
3313
-
3314
- nDataCount = len(zigData)
3315
- dest=JSAlgorithm.CreateArray(nDataCount)
3316
- trough = JSAlgorithm.CreateArray(lEnd,0)
3317
- lFlag = 0
3318
- i = self.GetFirstVaildIndex(zigData) + 1
3319
- lEnd-=1
3320
- while i<nDataCount and zigData[i]>zigData[i - 1] :
3321
- i+=1
3322
-
3323
- while i<nDataCount and zigData[i]<zigData[i - 1] :
3324
- i+=1
3325
-
3326
- i-=1
3327
- trough[0] = i
3328
- for i in range(i, nDataCount - 1) :
3329
- if (zigData[i]<zigData[i + 1]) :
3330
- if (lFlag) :
3331
- if (lEnd) :
3332
- tempTrough=copy.deepcopy(trough)
3333
- for j in range(lEnd) :
3334
- trough[j+1]=tempTrough[j]
3335
- lFlag = 0
3336
- trough[lFlag] = i
3337
- else :
3338
- lFlag = 1
3339
- if (trough[lEnd]):
3340
- dest[i]=zigData[trough[lEnd]]
3341
-
3342
- if (trough[lEnd]) :
3343
- dest[i]=zigData[trough[lEnd]]
3344
-
3345
- return dest
3346
-
3347
- # 属于未来函数,前M个ZIG转向波谷到当前距离.
3348
- # 用法: TROUGHBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波谷到当前的周期数,M必须大于等于1
3349
- # 例如: TROUGHBARS(2,5,2)表示%5最低价ZIG转向的前2个波谷到当前的周期数
3350
- def TROUGHBARS(self,data,n,n2) :
3351
- zigData=self.ZIG(data,n) # 计算ZIG
3352
- lEnd=n2
3353
- if (lEnd<1) :
3354
- return []
3355
-
3356
- nDataCount = len(zigData)
3357
- dest=JSAlgorithm.CreateArray(nDataCount)
3358
- trough = JSAlgorithm.CreateArray(lEnd,0)
3359
- lFlag = 0
3360
- i = self.GetFirstVaildIndex(zigData) + 1
3361
- lEnd-=1
3362
- while i<nDataCount and zigData[i]>zigData[i - 1] :
3363
- i+=1
3364
-
3365
- while i<nDataCount and zigData[i]<zigData[i - 1] :
3366
- i+=1
3367
-
3368
- i-=1
3369
- trough[0] = i
3370
- for i in range(i, nDataCount - 1) :
3371
- if (zigData[i]<zigData[i + 1]) :
3372
- if (lFlag) :
3373
- if (lEnd) :
3374
- tempTrough=copy.deepcopy(trough)
3375
- for j in range(lEnd) :
3376
- trough[j+1]=tempTrough[j]
3377
- lFlag = 0
3378
- trough[lFlag] = i
3379
- else :
3380
- lFlag = 1
3381
- if (trough[lEnd]) :
3382
- dest[i]=(i - trough[lEnd])
3383
-
3384
- if (trough[lEnd]) :
3385
- dest[i]=(i - trough[lEnd])
3386
-
3387
- return dest
3388
-
3389
-
3390
- # 属于未来函数,前M个ZIG转向波峰值.
3391
- #用法: PEAK(K,N,M)表示之字转向ZIG(K,N)的前M个波峰的数值,M必须大于等于1
3392
- # 例如: PEAK(1,5,1)表示%5最高价ZIG转向的上一个波峰的数值
3393
- def PEAK(self, data,n,n2) :
3394
- zigData=self.ZIG(data,n) # 计算ZIG
3395
- lEnd=n2
3396
- if (lEnd<1) :
3397
- return []
3398
-
3399
- nDataCount = len(zigData)
3400
- dest=JSAlgorithm.CreateArray(nDataCount)
3401
- trough = JSAlgorithm.CreateArray(lEnd,0)
3402
- lFlag = 0
3403
- i = self.GetFirstVaildIndex(zigData) + 1
3404
- lEnd-=1
3405
- while i<nDataCount and zigData[i]>zigData[i - 1] :
3406
- i+=1
3407
-
3408
- while i<nDataCount and zigData[i]<zigData[i - 1] :
3409
- i+=1
3410
-
3411
- i-=1
3412
- trough[0] = i
3413
- for i in range(i, nDataCount - 1) :
3414
- if (zigData[i]<zigData[i + 1]) :
3415
- if (lFlag) :
3416
- if (lEnd) :
3417
- tempTrough=copy.deepcopy(trough)
3418
- for j in range(lEnd) :
3419
- trough[j+1]=tempTrough[j]
3420
- lFlag = 0
3421
- trough[lFlag] = i
3422
- else :
3423
- lFlag = 1
3424
- if(trough[lEnd]) :
3425
- dest[i]=zigData[trough[lEnd]]
3426
-
3427
- if (trough[lEnd]) :
3428
- dest[i]=zigData[trough[lEnd]]
3429
-
3430
- return dest
3431
-
3432
-
3433
- # 属于未来函数,前M个ZIG转向波峰到当前距离.
3434
- # 用法:
3435
- # PEAKBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波峰到当前的周期数,M必须大于等于1
3436
- # 例如: PEAKBARS(0,5,1)表示%5开盘价ZIG转向的上一个波峰到当前的周期数
3437
- def PEAKBARS(self, data,n,n2) :
3438
- zigData=self.ZIG(data,n) # 计算ZIG
3439
- lEnd=n2
3440
- if (lEnd<1) :
3441
- return []
3442
-
3443
- nDataCount = len(zigData)
3444
- dest=JSAlgorithm.CreateArray(nDataCount)
3445
- trough = JSAlgorithm.CreateArray(lEnd,0)
3446
- lFlag = 0
3447
- i = self.GetFirstVaildIndex(zigData) + 1
3448
- lEnd-=1
3449
- while i<nDataCount and zigData[i]>zigData[i - 1] :
3450
- i+=1
3451
-
3452
- while i<nDataCount and zigData[i]<zigData[i - 1] :
3453
- i+=1
3454
-
3455
- i-=1
3456
- trough[0] = i
3457
- for i in range(i, nDataCount - 1) :
3458
- if (zigData[i]<zigData[i + 1]) :
3459
- if (lFlag) :
3460
- if (lEnd) :
3461
- tempTrough=copy.deepcopy(trough)
3462
- for j in range(lEnd) :
3463
- trough[j+1]=tempTrough[j]
3464
- lFlag = 0
3465
- trough[lFlag] = i
3466
- else :
3467
- lFlag = 1
3468
- if(trough[lEnd]) :
3469
- dest[i]=dest[i]=(i - trough[lEnd])
3470
-
3471
- if (trough[lEnd]) :
3472
- dest[i]=(i - trough[lEnd])
3473
-
3474
- return dest
3475
-
3476
-
3477
-
3478
- # 函数调用
3479
- def CallFunction(self,name,args,node,symbolData=None) :
3480
- if name=='MAX':
3481
- return self.MAX(args[0], args[1])
3482
- elif name=='MIN':
3483
- return self.MIN(args[0], args[1])
3484
- elif name=='REF':
3485
- return self.REF(args[0], args[1])
3486
- elif name=='REFV':
3487
- return self.REFV(args[0], args[1])
3488
- elif name=='REFX':
3489
- return self.REFX(args[0], args[1])
3490
- elif name=='REFXV':
3491
- return self.REFXV(args[0], args[1])
3492
- elif name=='ABS':
3493
- return self.ABS(args[0])
3494
- elif name=='MA':
3495
- return self.MA(args[0], args[1])
3496
- elif name=="EMA":
3497
- return self.EMA(args[0], args[1])
3498
- elif name=="SMA":
3499
- return self.SMA(args[0], args[1],args[2])
3500
- elif name=="DMA":
3501
- return self.DMA(args[0], args[1])
3502
- elif name=='EXPMA':
3503
- return self.EXPMA(args[0], int(args[1]))
3504
- elif name=='EXPMEMA':
3505
- return self.EXPMEMA(args[0], int(args[1]))
3506
- elif name=='COUNT':
3507
- return self.COUNT(args[0], args[1])
3508
- elif name=='LLV':
3509
- return self.LLV(args[0], args[1])
3510
- elif name=='LLVBARS':
3511
- return self.LLVBARS(args[0], int(args[1]))
3512
- elif name=='HHV':
3513
- return self.HHV(args[0], args[1])
3514
- elif name=='HHVBARS':
3515
- return self.HHVBARS(args[0], int(args[1]))
3516
- elif name=='MULAR':
3517
- return self.MULAR(args[0], int(args[1]))
3518
- elif name=='CROSS':
3519
- return self.CROSS(args[0], args[1])
3520
- elif name=='LONGCROSS':
3521
- return self.LONGCROSS(args[0], args[1], int(args[2]))
3522
- elif name=='AVEDEV':
3523
- return self.AVEDEV(args[0], int(args[1]))
3524
- elif name=='STD':
3525
- return self.STD(args[0], int(args[1]))
3526
- elif name in ('IF','IFF'):
3527
- return self.IF(args[0], args[1], args[2])
3528
- elif name=='IFN':
3529
- return self.IFN(args[0], args[1], args[2])
3530
- elif name=='NOT':
3531
- return self.NOT(args[0])
3532
- elif name=='SUM':
3533
- return self.SUM(args[0], args[1])
3534
- elif name=='RANGE':
3535
- return self.RANGE(args[0],args[1],args[2])
3536
- elif name=='EXIST':
3537
- return self.EXIST(args[0],args[1])
3538
- elif name=='EXISTR':
3539
- return self.EXISTR(args[0],int(args[1]),int(args[2]))
3540
- elif name=='FILTER':
3541
- return self.FILTER(args[0],int(args[1]))
3542
- elif name=='TFILTER':
3543
- return self.TFILTER(args[0],args[1],int(args[2]))
3544
- elif name=='SLOPE':
3545
- return self.SLOPE(args[0],int(args[1]))
3546
- elif name=='BARSLAST':
3547
- return self.BARSLAST(args[0])
3548
- elif name=='BARSCOUNT':
3549
- return self.BARSCOUNT(args[0])
3550
- elif name=='BARSSINCEN':
3551
- return self.BARSSINCEN(args[0],int(args[1]))
3552
- elif name=='BARSSINCE':
3553
- return self.BARSSINCE(args[0])
3554
- elif name=='LAST':
3555
- return self.LAST(args[0],int(args[1]),int(args[2]))
3556
- elif name=='EVERY':
3557
- return self.EVERY(args[0],int(args[1]))
3558
- elif name=='DEVSQ':
3559
- return self.DEVSQ(args[0], int(args[1]))
3560
- elif name=='ZIG':
3561
- return self.ZIG(args[0],args[1])
3562
- elif name=='TROUGH':
3563
- return self.TROUGH(args[0],args[1],int(args[2]))
3564
- elif name=='TROUGHBARS':
3565
- return self.TROUGHBARS(args[0],args[1],int(args[2]))
3566
- elif name=='PEAK':
3567
- return self.PEAK(args[0],args[1],int(args[2]))
3568
- elif name=='PEAKBARS':
3569
- return self.PEAKBARS(args[0],args[1],int(args[2]))
3570
- elif name=='COST':
3571
- return self.COST(args[0],node)
3572
- elif name=='WINNER':
3573
- return self.WINNER(args[0],node)
3574
- elif name=='PPART':
3575
- return self.PPART(args[0],node)
3576
- elif name=='COSTEX':
3577
- return self.COSTEX(args[0],args[1],node)
3578
- elif name=='LWINNER':
3579
- return self.LWINNER(args[0],args[1],node)
3580
- elif name=='PWINNER':
3581
- return self.PWINNER(args[0],args[1],node)
3582
- elif name=='FORCAST':
3583
- return self.FORCAST(args[0], int(args[1]))
3584
- elif name=='STDP':
3585
- return self.STDP(args[0], int(args[1]))
3586
- elif name=='VAR':
3587
- return self.VAR(args[0], int(args[1]))
3588
- elif name=='VARP':
3589
- return self.VARP(args[0], int(args[1]))
3590
- elif name=='UPNDAY':
3591
- return self.UPNDAY(args[0],int(args[1]))
3592
- elif name=='DOWNNDAY':
3593
- return self.DOWNNDAY(args[0],int(args[1]))
3594
- elif name=='NDAY':
3595
- return self.NDAY(args[0],args[1],int(args[2]))
3596
- elif name=='RELATE':
3597
- return self.RELATE(args[0],args[1],int(args[2]))
3598
- elif name=='COVAR':
3599
- return self.COVAR(args[0],args[1],int(args[2]))
3600
- elif name=='BETA':
3601
- return self.BETA(int(args[0]))
3602
- elif name=='BETA2':
3603
- return self.BETA2(args[0],args[1],int(args[2]))
3604
- elif name=='WMA':
3605
- return self.WMA(args[0], args[1])
3606
- elif name=='MEMA':
3607
- return self.MEMA(args[0], int(args[1]))
3608
- elif name=='SUMBARS':
3609
- return self.SUMBARS(args[0], args[1])
3610
- elif name=='REVERSE':
3611
- return self.REVERSE(args[0])
3612
- elif name=='SAR':
3613
- return self.SAR(int(args[0]), args[1], args[2])
3614
- elif name=='SARTURN':
3615
- return self.SARTURN(int(args[0]), args[1], args[2])
3616
- elif name=='BACKSET':
3617
- return self.BACKSET(args[0], int(args[1]))
3618
- # 三角函数
3619
- elif name=='ATAN':
3620
- return self.Trigonometric(args[0],math.atan)
3621
- elif name=='ACOS':
3622
- return self.Trigonometric(args[0],math.acos)
3623
- elif name=='ASIN':
3624
- return self.Trigonometric(args[0],math.asin)
3625
- elif name=='COS':
3626
- return self.Trigonometric(args[0],math.cos)
3627
- elif name=='SIN':
3628
- return self.Trigonometric(args[0],math.sin)
3629
- elif name=='TAN':
3630
- return self.Trigonometric(args[0],math.tan)
3631
- elif name=='LN':
3632
- return self.Trigonometric(args[0],math.log)
3633
- elif name=='LOG':
3634
- return self.Trigonometric(args[0],math.log10)
3635
- elif name=='EXP':
3636
- return self.Trigonometric(args[0],math.exp)
3637
- elif name=='SQRT':
3638
- return self.Trigonometric(args[0],math.sqrt)
3639
- else:
3640
- self.ThrowUnexpectedNode(node,'函数'+name+'不存在')
3641
-
3642
-
3643
- def ThrowUnexpectedNode(self, node,message='执行异常') :
3644
- marker=node.Marker
3645
- msg=message
3646
- return self.ErrorHandler.ThrowError(marker.Index,marker.Line,marker.Column,msg)
3647
-
3648
-
3649
- #######################################################################################################
3650
- #
3651
- # 绘图函数
3652
- #
3653
- #######################################################################################################
3654
-
3655
- class DrawItem:
3656
- def __init__(self, drawType, drawData=[], text=None) :
3657
- self.DrawType=drawType
3658
- self.DrawData=drawData
3659
- self.Text=None
3660
-
3661
- class JSDraw():
3662
- def __init__(self, errorHandler, symbolData) :
3663
- self.ErrorHandler=errorHandler
3664
- self.SymbolData=symbolData
3665
-
3666
- @staticmethod
3667
- def IsDrawFunction(name) :
3668
- return name in ("STICKLINE","DRAWTEXT",'SUPERDRAWTEXT','DRAWLINE','DRAWBAND','DRAWKLINE','DRAWKLINE_IF',
3669
- 'PLOYLINE','POLYLINE','DRAWNUMBER','DRAWICON','DRAWCHANNEL')
3670
-
3671
- def DRAWTEXT(self, condition,price,text) :
3672
- result=DrawItem(drawType='DRAWTEXT', text=text)
3673
- if (len(condition)<=0) :
3674
- return result
3675
-
3676
- dataLen=len(condition)
3677
- drawData=JSComplierHelper.CreateArray(dataLen)
3678
- IsNumber=JSComplierHelper.IsNumber(price)
3679
-
3680
- for i in range(dataLen) :
3681
- if JSComplierHelper.IsNaN(condition[i]) or not condition[i] :
3682
- continue
3683
-
3684
- if (IsNumber) :
3685
- drawData[i]=price
3686
- else :
3687
- if (JSComplierHelper.IsNumber(price[i])) :
3688
- drawData[i]=price[i]
3689
-
3690
- result.DrawData=drawData
3691
- return result
3692
-
3693
- # direction 文字Y轴位置 0=middle 1=价格的顶部 2=价格的底部
3694
- # offset 文字Y轴偏移
3695
- def SUPERDRAWTEXT(self,condition,price,text,direction,offset) :
3696
- result=DrawItem(drawType='SUPERDRAWTEXT', text=text)
3697
- result.YOffset=offset
3698
- result.Direction=direction
3699
- result.TextAlign='center'
3700
- if len(condition)<=0 :
3701
- return result
3702
-
3703
- dataLen=len(condition)
3704
- drawData=JSComplierHelper.CreateArray(dataLen)
3705
- IsNumber=JSComplierHelper.IsNumber(price)
3706
-
3707
- for i in range(dataLen) :
3708
- if JSComplierHelper.IsNaN(condition[i]) or not condition[i] :
3709
- continue
3710
-
3711
- if IsNumber :
3712
- drawData[i]=price
3713
- else :
3714
- if JSComplierHelper.IsNumber(price[i]) :
3715
- drawData[i]=price[i]
3716
-
3717
- result.DrawData=drawData
3718
- return result
3719
-
3720
-
3721
- # STICKLINE 绘制柱线
3722
- # 在图形上绘制柱线。
3723
- # 用法: STICKLINE(COND,PRICE1,PRICE2,WIDTH,EMPTY),当COND条件满足时,在PRICE1和PRICE2位置之间画柱状线,宽度为WIDTH(10为标准间距),EMPTH不为0则画空心柱。
3724
- # 例如: STICKLINE(CLOSE>OPEN,CLOSE,OPEN,0.8,1)表示画K线中阳线的空心柱体部分。
3725
- def STICKLINE(self, condition,data,data2,width,type) :
3726
- result=DrawItem(drawType='STICKLINE')
3727
- result.Width=width
3728
- result.Type=int(type)
3729
-
3730
- if len(condition)<=0 :
3731
- return result
3732
-
3733
- dataLen=len(condition)
3734
- drawData=JSComplierHelper.CreateArray(dataLen)
3735
- isNumber=JSComplierHelper.IsNumber(data)
3736
- isNumber2=JSComplierHelper.IsNumber(data2)
3737
-
3738
- for i in range(dataLen) :
3739
- if JSComplierHelper.IsNaN(condition[i]) or not condition[i] :
3740
- continue
3741
-
3742
- if isNumber and isNumber2 :
3743
- item=Variant()
3744
- item.Value,item.Value2 = data,data2
3745
- drawData[i]=item
3746
- elif isNumber and not isNumber2 :
3747
- if JSComplierHelper.IsNaN(data2[i]) :
3748
- continue
3749
- item=Variant()
3750
- item.Value,item.Value2 = data,data2[i]
3751
- drawData[i]=item
3752
- elif not isNumber and isNumber2 :
3753
- if JSComplierHelper.IsNaN(data[i]) :
3754
- continue
3755
- item=Variant()
3756
- item.Value,item.Value2 = data[i],data2
3757
- drawData[i]=item
3758
- else :
3759
- if JSComplierHelper.IsNaN(data[i]) or JSComplierHelper.IsNaN(data2[i]) :
3760
- continue
3761
- item=Variant()
3762
- item.Value,item.Value2 = data[i],data2[i]
3763
- drawData[i]=item
3764
-
3765
- result.DrawData=drawData
3766
- return result
3767
-
3768
- # 画出带状线.
3769
- # 用法: DRAWBAND(VAL1,COLOR1,VAL2,COLOR2),当VAL1>VAL2时,在VAL1和VAL2之间填充COLOR1;当VAL1<VAL2时,填充COLOR2,这里的颜色均使用RGB函数计算得到.
3770
- # 例如: DRAWBAND(OPEN,RGB(0,224,224),CLOSE,RGB(255,96,96));
3771
- def DRAWBAND(self,data,color,data2,color2) :
3772
- result=DrawItem(drawType='DRAWBAND')
3773
- result.Color=[color.lower(),color2.lower()] # 颜色使用小写字符串
3774
- len1, len2=len(data), len(data2)
3775
- count=max(len1, len2)
3776
-
3777
- drawData=[]
3778
- for i in range(count) :
3779
- item=Variant()
3780
- item.Value, item.Value2 = None, None
3781
- if (i<len1) :
3782
- item.Value=data[i]
3783
- if (i<len2) :
3784
- item.Value2=data2[i]
3785
-
3786
- drawData.append(item)
3787
-
3788
- result.DrawData=drawData
3789
- return result
3790
-
3791
- def DRAWKLINE(self,high,open,low,close) :
3792
- result=DrawItem(drawType='DRAWKLINE')
3793
- highLen, openLen, lowLen, closeLen=len(high),len(open), len(low), len(close)
3794
- count=max(highLen, openLen,lowLen,closeLen)
3795
- drawData=JSComplierHelper.CreateArray(count)
3796
- for i in range(count) :
3797
- item=Variant()
3798
- item.Open, item.High, item.Low,item.Close = None, None, None, None
3799
- if (i<highLen and i<openLen and i<lowLen and i<closeLen) :
3800
- item.Open=open[i]
3801
- item.High=high[i]
3802
- item.Low=low[i]
3803
- item.Close=close[i]
3804
-
3805
- drawData[i]=item
3806
-
3807
- result.DrawData=drawData
3808
- return result
3809
-
3810
- # 满足条件画一根K线
3811
- def DRAWKLINE_IF(self, condition,high,open,low,close) :
3812
- result=DrawItem(drawType='DRAWKLINE_IF')
3813
- highLen, openLen, lowLen, closeLen=len(high),len(open), len(low), len(close)
3814
- count=max(highLen, openLen,lowLen,closeLen)
3815
- drawData=JSComplierHelper.CreateArray(count)
3816
-
3817
- for i in range(count) :
3818
- item=Variant()
3819
- item.Open, item.High, item.Low,item.Close = None, None, None, None
3820
-
3821
- if (i<highLen and i<openLen and i<lowLen and i<closeLen and i<len(condition)) :
3822
- if (condition[i]) :
3823
- item.Open=open[i]
3824
- item.High=high[i]
3825
- item.Low=low[i]
3826
- item.Close=close[i]
3827
-
3828
- drawData[i]=item
3829
-
3830
- result.DrawData=drawData
3831
- return result
3832
-
3833
-
3834
- # 画出数字.
3835
- # 用法: DRAWNUMBER(COND,PRICE,NUMBER),当COND条件满足时,在PRICE位置书写数字NUMBER.
3836
- # 例如: DRAWNUMBER(CLOSE/OPEN>1.08,LOW,C)表示当日实体阳线大于8%时在最低价位置显示收盘价.
3837
- def DRAWNUMBER(self, condition,data,data2) :
3838
- drawData=Variant()
3839
- drawData.Value, drawData.Text = [], []
3840
- result=DrawItem(drawType='DRAWNUMBER', drawData=drawData)
3841
-
3842
- isNumber=JSComplierHelper.IsNumber(data2)
3843
- if (isNumber) :
3844
- text= '%.2f' % data2
3845
-
3846
- count=len(condition)
3847
- drawData.Value=JSComplierHelper.CreateArray(count)
3848
- drawData.Text=JSComplierHelper.CreateArray(count)
3849
-
3850
- for i in range(count) :
3851
- if not condition[i] :
3852
- continue
3853
- if i>=len(data) or not JSComplierHelper.IsNumber(data[i]) :
3854
- continue
3855
-
3856
- if (isNumber) :
3857
- drawData.Value[i]=data[i]
3858
- drawData.Text[i]=text
3859
- else :
3860
- if i>=len(data2) or data2[i]==None :
3861
- continue
3862
- drawData.Value[i]=data[i]
3863
- if JSComplierHelper.IsNumber(data2[i]) :
3864
- drawData.Text[i] = '%.2f' % data2[i]
3865
- else :
3866
- drawData.Text[i] = str(data2[i])
3867
-
3868
- result.DrawData=drawData
3869
- return result
3870
-
3871
- # 在图形上绘制小图标.
3872
- # 用法: DRAWICON(COND,PRICE,TYPE),当COND条件满足时,在PRICE位置画TYPE号图标(TYPE为1--41).
3873
- # 例如: DRAWICON(CLOSE>OPEN,LOW,1)表示当收阳时在最低价位置画1号图标.
3874
- def DRAWICON(self, condition,data,type) :
3875
- icon=Variant()
3876
- if (type not in g_JSComplierResource.DrawIcon.Data) :
3877
- type=11 #默认图标
3878
- iconfont=g_JSComplierResource.DrawIcon.Data[type]
3879
- icon=Variant()
3880
- icon.Symbol, icon.Color, icon.Family, icon.IconFont, icon.ID = iconfont.Text, iconfont.Color, g_JSComplierResource.DrawIcon.Family, True, type
3881
-
3882
- result=DrawItem(drawType='DRAWICON')
3883
- result.Icon=icon
3884
- if (len(condition)<=0) :
3885
- return result
3886
-
3887
- isNumber=JSComplierHelper.IsNumber(data)
3888
- if JSComplierHelper.IsNumber(condition) :
3889
- if not condition :
3890
- return result
3891
-
3892
- drawData=JSComplierHelper.CreateArray(len(self.SymbolData.Data.Data))
3893
- for i in range(len(self.SymbolData.Data.Data)) :
3894
- if isNumber :
3895
- drawData[i]=data
3896
- else :
3897
- if i<len(data) and JSComplierHelper.IsNumber(data[i]) :
3898
- drawData[i]=data[i]
3899
- return result
3900
-
3901
- drawData=JSComplierHelper.CreateArray(len(condition))
3902
- for i in range(len(condition)) :
3903
- if not condition[i] :
3904
- continue
3905
-
3906
- if isNumber :
3907
- drawData[i]=data
3908
- else :
3909
- if JSComplierHelper.IsNumber(data[i]) :
3910
- drawData[i]=data[i]
3911
-
3912
- result.DrawData=drawData
3913
- return result
3914
-
3915
- # PLOYLINE 折线段
3916
- # 在图形上绘制折线段。
3917
- # 用法: PLOYLINE(COND,PRICE),当COND条件满足时,以PRICE位置为顶点画折线连接。
3918
- # 例如: PLOYLINE(HIGH>=HHV(HIGH,20),HIGH)表示在创20天新高点之间画折线。
3919
- def POLYLINE(self, condition,data) :
3920
- result=DrawItem(drawType='POLYLINE')
3921
- isNumber=JSComplierHelper.IsNumber(data)
3922
-
3923
- drawData=JSComplierHelper.CreateArray(len(condition))
3924
- bFirstPoint=False
3925
- bSecondPont=False
3926
- if isNumber :
3927
- for i in range(len(condition)) :
3928
- if bFirstPoint==False :
3929
- if not condition[i] :
3930
- continue
3931
-
3932
- drawData[i]=data
3933
- bFirstPoint=True
3934
- else :
3935
- drawData[i]=data
3936
-
3937
- else :
3938
- lineCache=Variant()
3939
- lineCache.Start, lineCache.End, lineCache.List = Variant(), Variant(), []
3940
- for i in range (len(condition)) :
3941
- if (bFirstPoint==False and bSecondPont==False) :
3942
- if condition[i]==None or not condition[i] :
3943
- continue
3944
- if i>=len(data) or not JSComplierHelper.IsNumber(data[i]) :
3945
- continue
3946
-
3947
- bFirstPoint=True
3948
- # 第1个点
3949
- lineCache.Start.ID=int(i)
3950
- lineCache.Start.Value=data[i]
3951
-
3952
- elif (bFirstPoint==True and bSecondPont==False) :
3953
- if condition[i]==None or not condition[i] :
3954
- continue
3955
- if i>=len(data) or not JSComplierHelper.IsNumber(data[i]) :
3956
- continue
3957
-
3958
- # 第2个点
3959
- lineCache.End.ID=int(i)
3960
- lineCache.End.Value=data[i]
3961
- # 根据起始点和结束点 计算中间各个点的数据
3962
- lineData=JSComplierHelper.CalculateDrawLine(lineCache) # 计算2个点的线上 其他点的数值
3963
-
3964
- for item in lineData :
3965
- drawData[item.ID]=item.Value
3966
-
3967
- start=Variant()
3968
- start.ID, start.Value = lineCache.End.ID, lineCache.End.Value
3969
- lineCache=Variant()
3970
- lineCache.Start, lineCache.End = start, Variant()
3971
-
3972
- result.DrawData=drawData
3973
- return result
3974
-
3975
-
3976
- # DRAWLINE 绘制直线段
3977
- # 在图形上绘制直线段。
3978
- # 用法: DRAWLINE(COND1,PRICE1,COND2,PRICE2,EXPAND)
3979
- # 当COND1条件满足时,在PRICE1位置画直线起点,当COND2条件满足时,在PRICE2位置画直线终点,EXPAND为延长类型。
3980
- # 例如: DRAWLINE(HIGH>=HHV(HIGH,20),HIGH,LOW<=LLV(LOW,20),LOW,1) 表示在创20天新高与创20天新低之间画直线并且向右延长。
3981
- def DRAWLINE(self, condition,data,condition2,data2,expand) :
3982
- result=DrawItem(drawType='DRAWLINE')
3983
- result.Expand=expand
3984
-
3985
- if len(condition)<=0 :
3986
- return result
3987
-
3988
- condLen1, condLen2 = len(condition), len(condition2)
3989
- count=max(condLen1,condLen2)
3990
-
3991
- drawData=JSComplierHelper.CreateArray(count)
3992
- bFirstPoint=False
3993
- bSecondPont=False
3994
- lineCache=Variant()
3995
- lineCache.Start, lineCache.End, lineCache.List = Variant(), Variant(), []
3996
-
3997
- for i in range(count) :
3998
- if (i<condLen1 and i<condLen2) :
3999
- if (bFirstPoint==False and bSecondPont==False) :
4000
- if condition[i]==None or not condition[i] :
4001
- continue
4002
-
4003
- bFirstPoint=True
4004
- # 第1个点
4005
- lineCache.Start.ID=i
4006
- lineCache.Start.Value=data[i]
4007
-
4008
- elif (bFirstPoint==True and bSecondPont==False) :
4009
- bCondition=(condition[i]!=None and condition[i]) # 条件1
4010
- bCondition2=(condition2[i]!=None and condition2[i]) # 条件2
4011
-
4012
- if not bCondition and not bCondition2 :
4013
- continue
4014
-
4015
- if bCondition :
4016
- # 移动第1个点
4017
- lineCache.Start.ID=i
4018
- lineCache.Start.Value=data[i]
4019
- elif bCondition2:
4020
- bSecondPont=True
4021
- # 第2个点
4022
- lineCache.End.ID=i
4023
- lineCache.End.Value=data2[i]
4024
-
4025
- elif (bFirstPoint==True and bSecondPont==True) : # 2个点都有了, 等待下一次的点出现
4026
- bCondition=(condition[i]!=None and condition[i]) # 条件1
4027
- bCondition2=(condition2[i]!=None and condition2[i]) # 条件2
4028
-
4029
- if bCondition :
4030
- lineData=JSComplierHelper.CalculateDrawLine(lineCache) # 计算2个点的线上 其他点的数值
4031
-
4032
- for item in lineData :
4033
- drawData[item.ID]=item.Value
4034
-
4035
- bFirstPoint=bSecondPont=False
4036
- lineCache=Variant()
4037
- lineCache.Start, lineCache.End = Variant(), Variant()
4038
- elif bCondition2 :
4039
- lineCache.End.ID=i
4040
- lineCache.End.Value=data2[i] # 移动第2个点
4041
-
4042
- if bFirstPoint==True and bSecondPont==True : # 最后一组数据
4043
- lineData=JSComplierHelper.CalculateDrawLine(lineCache)
4044
- for item in lineData :
4045
- drawData[item.ID]=item.Value
4046
-
4047
- result.DrawData=drawData
4048
- return result
4049
-
4050
-
4051
- # 绘制通道
4052
- # condition:条件
4053
- # data,data2:通道顶部和底部
4054
- # borderColor: 通道顶部和底部线段颜色RGB(24,30,40) 不填就不画
4055
- # borderWidth: 通道顶部和底部线段宽度
4056
- # areaColor: 通道面积颜色 RGB(200,30,44) 不填使用默认颜色
4057
- # dotted: 通道顶部和底部虚线设置 '3,4' , 不填默认 3,3
4058
- def DRAWCHANNEL(self,condition, data, data2, borderColor, borderWidth, dotted, areaColor) :
4059
- result=DrawItem(drawType='DRAWCHANNEL')
4060
- result.Border=Variant()
4061
-
4062
- if borderColor:
4063
- result.Border.Color=borderColor
4064
- if borderWidth>0:
4065
- result.Border.Width=borderWidth
4066
- if areaColor:
4067
- result.AreaColor=areaColor
4068
-
4069
- if dotted :
4070
- ary=dotted.split(',')
4071
- result.Border.Dotted=[]
4072
- for item in ary :
4073
- if not item :
4074
- continue
4075
- value=int(item)
4076
- if value<=0 :
4077
- continue
4078
- result.Border.Dotted.append(value)
4079
- if len(result.Border.Dotted)<=0:
4080
- result.Border.Dotted=None
4081
-
4082
- isNumber=JSComplierHelper.IsNumber(data)
4083
- isNumber2=JSComplierHelper.IsNumber(data2)
4084
- if JSComplierHelper.IsNumber(condition) :
4085
- if not condition :
4086
- return result # 条件是否
4087
-
4088
- drawData=JSComplierHelper.CreateArray(len(self.SymbolData.Data.Data))
4089
- for i in range(len(self.SymbolData.Data.Data)) :
4090
- if (isNumber and isNumber2) :
4091
- item=Variant()
4092
- item.Value, item.Value2 = data, data2
4093
- drawData[i]=item
4094
- elif (isNumber and not isNumber2) :
4095
- if JSComplierHelper.IsNaN(data2[i]) :
4096
- continue
4097
- item=Variant()
4098
- item.Value, item.Value2 = data, data2[i]
4099
- drawData[i]=item
4100
- elif (not isNumber and isNumber2) :
4101
- if JSComplierHelper.IsNaN(data[i]):
4102
- continue
4103
- item=Variant()
4104
- item.Value, item.Value2 = data[i], data2
4105
- drawData[i]=item
4106
- else :
4107
- if JSComplierHelper.IsNaN(data[i]) or JSComplierHelper.IsNaN(data2[i]) :
4108
- continue
4109
- item=Variant()
4110
- item.Value, item.Value2 = data[i], data2[i]
4111
- drawData[i]=item
4112
- else :
4113
- drawData=JSComplierHelper.CreateArray(len(condition))
4114
- for i in range(len(condition)) :
4115
- if JSComplierHelper.IsNaN(condition[i]) or not condition[i] :
4116
- continue
4117
-
4118
- if isNumber and isNumber2 :
4119
- item=Variant()
4120
- item.Value, item.Value2 = data, data2
4121
- drawData[i]=item
4122
- elif (isNumber and not isNumber2) :
4123
- if JSComplierHelper.IsNaN(data2[i]) :
4124
- continue
4125
- item=Variant()
4126
- item.Value, item.Value2 = data, data2[i]
4127
- drawData[i]=item
4128
- elif (not isNumber and isNumber2) :
4129
- if JSComplierHelper.IsNaN(data[i]) :
4130
- continue
4131
- item=Variant()
4132
- item.Value, item.Value2 = data[i], data2
4133
- drawData[i]=item
4134
- else :
4135
- if JSComplierHelper.IsNaN(data[i]) or JSComplierHelper.IsNaN(data2[i]) :
4136
- continue
4137
- item=Variant()
4138
- item.Value, item.Value2 = data[i], data2[i]
4139
- drawData[i]=item
4140
-
4141
- result.DrawData=drawData
4142
- return result
4143
-
4144
-