提交 0f7c9b23 编写于 作者: J jones

ver 6166

上级 09e2f2f9
......@@ -14,6 +14,13 @@ class JSComplierHelper:
return False
return JSComplierHelper.IsNumber(jsData[name])
@staticmethod # 是否存在字段
def IsJsonExist(jsData,name) :
if name in jsData.keys() :
return True
return False
@staticmethod
def IsDivideNumber(value):
return isinstance(value,(int,float)) and value!=0
......
......@@ -2194,6 +2194,137 @@ class JSAlgorithm() :
return result
# 抛物转向.
# 用法: SAR(N,S,M),N为计算周期,S为步长,M为极值
# 例如: SAR(10,2,20)表示计算10日抛物转向,步长为2%,极限值为20%
def SAR(self,n,step,exValue) :
stockData= self.SymbolData.Data
dataLen=len(stockData.Data)
if n>=dataLen :
return []
result=JSAlgorithm.CreateArray(dataLen)
high, low =None, None
for i in range(n) :
item=stockData.Data[i]
if high==None:
high=item.High
elif high<item.High :
high=item.High
if low==None :
low=item.Low
elif low>item.Low :
low=item.Low
SAR_LONG=0
SAR_SHORT=1
position=SAR_LONG
result[n-1]=low
nextSar=low
sip=stockData.Data[0].High
af=exValue/100
for i in range(n,dataLen) :
ysip=sip
item=stockData.Data[i]
yitem=stockData.Data[i-1]
if (position==SAR_LONG) :
if (item.Low<result[i-1]) :
position=SAR_SHORT
sip=item.Low
af=step/100
nextSar =max(item.High,yitem.High)
nextSar =max(nextSar,ysip+af*(sip-ysip))
else :
position = SAR_LONG
if (item.High>ysip) :
sip=item.High
af=min(af+step/100,exValue/100)
nextSar=min(item.Low,yitem.Low)
nextSar=min(nextSar,result[i-1]+af*(sip-result[i-1]))
elif (position==SAR_SHORT) :
if (item.High>result[i-1]) :
position=SAR_LONG
sip=item.High
af=step/100
nextSar =min(item.Low,yitem.Low)
nextSar =min(nextSar,result[i-1]+af*(sip-ysip))
else :
position = SAR_SHORT
if(item.Low<ysip) :
sip=item.Low
af=min(af+step/100,exValue/100)
nextSar=max(item.High,yitem.High)
nextSar=max(nextSar,result[i-1]+af*(sip-result[i-1]))
result[i]=nextSar
return result
# 抛物转向点.
# 用法: SARTURN(N,S,M),N为计算周期,S为步长,M为极值,若发生向上转向则返回1,若发生向下转向则返回-1,否则为0
# 其用法与SAR函数相同
def SARTURN(self,n,step,exValue) :
sar=self.SAR(n,step,exValue)
stockData= self.SymbolData.Data
dataLen=len(stockData)
result=JSAlgorithm.CreateArray(dataLen)
for index in range(len(sar)) :
if JSAlgorithm.IsNumber(sar[index]) :
break
flag=0
if index<dataLen :
flag=stockData.Data[index].Close>sar[index]
for i in range(index+1,dataLen) :
item=stockData.Data[i]
if item.Close<sar[i] and flag :
result[i]=-1
else :
result[i]= 1 if (item.Close>sar[i] and not flag) else 0
flag=item.Close>sar[i]
return result
# 属于未来函数,将当前位置到若干周期前的数据设为1.
# 用法: BACKSET(X,N),若X非0,则将当前位置到N周期前的数值设为1.
# 例如: BACKSET(CLOSE>OPEN,2)若收阳则将该周期及前一周期数值设为1,否则为0
def BACKSET(self,condition,n) :
if not condition :
return []
dataCount=len(condition)
if dataCount<=0 :
return []
result=JSAlgorithm.CreateArray(dataCount,0) # 初始化0
for pos in range(dataCount) :
if JSAlgorithm.IsNumber(condition[pos]) :
break
if pos==dataCount :
return result
num=min(dataCount-pos,max(n,1))
for i in range(dataCount-1, -1,-1) :
value=condition[i]
if JSAlgorithm.IsNumber(value) and value :
for j in range(i, i-num,-1) :
result[j]=1
if condition[i] :
for j in range(i, pos+1) :
result[j]=1
return result
# 函数调用
......@@ -2313,11 +2444,11 @@ class JSAlgorithm() :
elif name=='REVERSE':
return self.REVERSE(args[0])
elif name=='SAR':
return self.SAR(args[0], args[1], args[2])
return self.SAR(int(args[0]), args[1], args[2])
elif name=='SARTURN':
return self.SARTURN(args[0], args[1], args[2])
return self.SARTURN(int(args[0]), args[1], args[2])
elif name=='BACKSET':
return self.BACKSET(args[0], args[1])
return self.BACKSET(args[0], int(args[1]))
# 三角函数
elif name=='ATAN':
return self.Trigonometric(args[0],math.atan)
......@@ -2750,4 +2881,98 @@ class JSDraw():
result.DrawData=drawData
return result
# 绘制通道
# condition:条件
# data,data2:通道顶部和底部
# borderColor: 通道顶部和底部线段颜色RGB(24,30,40) 不填就不画
# borderWidth: 通道顶部和底部线段宽度
# areaColor: 通道面积颜色 RGB(200,30,44) 不填使用默认颜色
# dotted: 通道顶部和底部虚线设置 '3,4' , 不填默认 3,3
def DRAWCHANNEL(self,condition, data, data2, borderColor, borderWidth, dotted, areaColor) :
result=DrawItem(drawType='DRAWCHANNEL')
result.Border=Variant()
if borderColor:
result.Border.Color=borderColor
if borderWidth>0:
result.Border.Width=borderWidth
if areaColor:
result.AreaColor=areaColor
if dotted :
ary=dotted.split(',')
result.Border.Dotted=[]
for item in ary :
if not item :
continue
value=int(item)
if value<=0 :
continue
result.Border.Dotted.append(value)
if len(result.Border.Dotted)<=0:
result.Border.Dotted=None
isNumber=JSComplierHelper.IsNumber(data)
isNumber2=JSComplierHelper.IsNumber(data2)
if JSComplierHelper.IsNumber(condition) :
if not condition :
return result # 条件是否
drawData=JSComplierHelper.CreateArray(len(self.SymbolData.Data.Data))
for i in range(len(self.SymbolData.Data.Data)) :
if (isNumber and isNumber2) :
item=Variant()
item.Value, item.Value2 = data, data2
drawData[i]=item
elif (isNumber and not isNumber2) :
if JSComplierHelper.IsNaN(data2[i]) :
continue
item=Variant()
item.Value, item.Value2 = data, data2[i]
drawData[i]=item
elif (not isNumber and isNumber2) :
if JSComplierHelper.IsNaN(data[i]):
continue
item=Variant()
item.Value, item.Value2 = data[i], data2
drawData[i]=item
else :
if JSComplierHelper.IsNaN(data[i]) or JSComplierHelper.IsNaN(data2[i]) :
continue
item=Variant()
item.Value, item.Value2 = data[i], data2[i]
drawData[i]=item
else :
drawData=JSComplierHelper.CreateArray(len(condition))
for i in range(len(condition)) :
if JSComplierHelper.IsNaN(condition[i]) or not condition[i] :
continue
if isNumber and isNumber2 :
item=Variant()
item.Value, item.Value2 = data, data2
drawData[i]=item
elif (isNumber and not isNumber2) :
if JSComplierHelper.IsNaN(data2[i]) :
continue
item=Variant()
item.Value, item.Value2 = data, data2[i]
drawData[i]=item
elif (not isNumber and isNumber2) :
if JSComplierHelper.IsNaN(data[i]) :
continue
item=Variant()
item.Value, item.Value2 = data[i], data2
drawData[i]=item
else :
if JSComplierHelper.IsNaN(data[i]) or JSComplierHelper.IsNaN(data2[i]) :
continue
item=Variant()
item.Value, item.Value2 = data[i], data2[i]
drawData[i]=item
result.DrawData=drawData
return result
\ No newline at end of file
import sys
import json
from umychart_complier_scanner import Error
from umychart_complier_jsparser import JSParser, Tokenizer
from umychart_complier_jssymboldata import g_JSComplierResource
......@@ -79,7 +80,6 @@ class ScriptIndexConsole:
self.OutVar=None
def ExecuteScript(self, obj=SymbolOption()) :
try :
print('[ScriptIndexConsole::ExecuteScript] ', self.Script)
parser=JSParser(self.Script)
......@@ -107,20 +107,21 @@ class ScriptIndexConsole:
if (obj.HQDataType==HQ_DATA_TYPE.KLINE_ID) :
result.Time=execute.SymbolData.Data.GetTime() # 数据对应的时间
return result
except Error as error :
ErrorInfo=Variant()
ErrorInfo.Error=error
return ErrorInfo
ErrorInfo=Variant()
ErrorInfo.Error=error
return ErrorInfo
except ValueError as error:
ErrorInfo=Variant()
ErrorInfo.Error=error
return ErrorInfo
except :
return None
except BaseException as error :
ErrorInfo=Variant()
ErrorInfo.Error=error
return ErrorInfo
......@@ -173,7 +173,7 @@ class JSExecute :
varName=itemExpression.Left.Name
varValue=self.VarTable[varName]
if not JSComplierHelper.IsArray(varValue) :
varValue=self.SingleDataToArrayData(varValue);
varValue=self.SingleDataToArrayData(varValue)
self.VarTable[varName]=varValue # 把单数值转化成数组放到变量表里
elif (itemExpression.Type==Syntax.Identifier) :
......@@ -330,7 +330,7 @@ class JSExecute :
# console.log('[JSExecute::VisitCallExpression]' , funcName, '(', args.toString() ,')');
if funcName=='DYNAINFO': # 行情最新数据
node.Out=self.SymbolData.GetLatestCacheData(args[0])
node.Out=self.SymbolData.GetLatestCacheData(int(args[0]))
elif funcName=='STICKLINE':
node.Draw=self.Draw.STICKLINE(args[0],args[1],args[2],args[3],args[4])
node.Out=[]
......@@ -362,7 +362,7 @@ class JSExecute :
node.Draw=self.Draw.DRAWNUMBER(args[0],args[1],args[2])
node.Out=node.Draw.DrawData.Value
elif funcName=="DRAWCHANNEL":
node.Draw=self.Draw.DRAWCHANNEL(args[0],args[1],args[2],args[3],args[4],args[5],args[6])
node.Draw=self.Draw.DRAWCHANNEL(args[0],args[1],args[2],args[3],int(args[4]),args[5],args[6])
node.Out=[]
elif funcName=='CODELIKE':
node.Out=self.SymbolData.CODELIKE(args[0])
......
......@@ -58,6 +58,19 @@ class FinanceData :
value=self.Finance[name]
return value
# http://www.newone.com.cn/helpcontroller/index?code=zszy_pc
class DYNAINFO_ARGUMENT_ID :
YCLOSE=3
OPEN=4
HIGH=5
LOW=6
CLOSE=7
VOL=8
AMOUNT=10
AMPLITUDE=13 # 振幅
INCREASE=14 # 涨幅
EXCHANGERATE=37 # 换手率
class JSSymbolData() :
def __init__(self, ast, option=SymbolOption(), procThrow=None) :
......@@ -76,6 +89,7 @@ class JSSymbolData() :
self.IndexData=None # 大盘指数
self.FinanceData={} # 财务数据
self.MarketValue=None # 市值
self.LatestData=None # 最新行情
self.MaxRequestDataCount=option.MaxRequestDataCount # 读取日线数据天数
self.MaxRequestMinuteDayCount=option.MaxRequestMinuteDayCount # 读取分钟数据天数
......@@ -105,6 +119,8 @@ class JSSymbolData() :
JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_DIVIDEND_YIELD_DATA
) :
self.GetFinanceData(job.ID)
elif job.ID==JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_SYMBOL_LATEST_DATA : # 最新行情数据
self.GetLatestData()
# 下载股票数据
......@@ -641,6 +657,74 @@ class JSSymbolData() :
return []
# 下载最新行情
def GetLatestData(self) :
if self.LatestData:
return
url=self.RealtimeApiUrl
postData={
"field": ["name","symbol","yclose","open","price","high","low","vol","amount","date","time","increase","exchangerate","amplitude"],
"symbol": [self.Symbol] }
print('[JSSymbolData::GetLatestData] ',url, postData)
response=requests.post(url,postData)
jsonData=response.json()
if not JSComplierHelper.IsJsonExist(jsonData,'stock') :
return
if (len(jsonData['stock'])!=1) :
return
stock=jsonData['stock'][0]
item=Variant()
item.Symbol=stock['symbol']
item.Name=stock['name']
item.Date=stock['date']
item.Time=stock['time']
item.YClose=stock['yclose']
item.Price=stock['price']
item.Open:stock['open']
item.High:stock['high']
item.Low:stock['low']
item.Vol:stock['vol']
item.Amount=stock['amount']
item.Increase=stock['increase']
item.Exchangerate=stock['exchangerate']
item.Amplitude=stock['amplitude']
self.LatestData=item
# 最新行情
def GetLatestCacheData(self, dataname) :
if not self.LatestData :
return None
if dataname==DYNAINFO_ARGUMENT_ID.YCLOSE:
return self.LatestData.YClose
elif dataname==DYNAINFO_ARGUMENT_ID.OPEN:
return self.LatestData.Open
elif dataname==DYNAINFO_ARGUMENT_ID.HIGH:
return self.LatestData.High
elif dataname==DYNAINFO_ARGUMENT_ID.LOW:
return self.LatestData.Low
elif dataname==DYNAINFO_ARGUMENT_ID.VOL:
return self.LatestData.Vol
elif dataname==DYNAINFO_ARGUMENT_ID.AMOUNT:
return self.LatestData.Amount
elif dataname==DYNAINFO_ARGUMENT_ID.INCREASE:
return self.LatestData.Increase
elif dataname==DYNAINFO_ARGUMENT_ID.EXCHANGERATE:
return self.LatestData.Exchangerate
elif dataname==DYNAINFO_ARGUMENT_ID.AMPLITUDE:
return self.LatestData.Amplitude
elif dataname==DYNAINFO_ARGUMENT_ID.CLOSE:
return self.LatestData.Price
else :
return None
# CODELIKE 模糊股票代码
def CODELIKE(self, value) :
if self.Symbol and self.Symbol.find(value)==0 :
......@@ -686,6 +770,18 @@ class JSSymbolData() :
return result
return self.Data.GetWeek()
def REFDATE(self,data,date) :
index=None
for i in range(len(self.Data.Data)) : # 查找日期对应的索引
if self.Data.Data[i].Date==date :
index=i
break
if index==None or index>=len(data) :
return None
return data[index]
# 用法:结果从0到11,依次分别是1/5/15/30/60分钟,日/周/月,多分钟,多日,季,年
def PERIOD(self) :
# Period周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟
......
......@@ -242,6 +242,10 @@ def Test_FINANCE(): # 财务数据测试
'DRAWICON(CLOSE>OPEN,LOW,1);',
'PLOYLINE(HIGH>=HHV(HIGH,20),HIGH);',
'CYW: SUM(VAR4,10)/10000, COLORSTICK;',
"DRAWCHANNEL(C>O,C,O,'rgb(20,20,20)',1,'3,4','rgb(40,40,40)');",
'SAR(10,2,20);',
'BACKSET(CLOSE>OPEN,2);',
'TT:DYNAINFO(13);',
])
result=case.Run()
......@@ -271,6 +275,6 @@ def Test_ScriptIndexConsole():
#Test_Add()
#Test_Multiply()
#Test_MAX_MIN()
#Test_FINANCE()
Test_FINANCE()
Test_ScriptIndexConsole()
\ No newline at end of file
......@@ -4620,7 +4620,7 @@ function JSAlgorithm(errorHandler,symbolData)
{
var item=stockData.Data[i];
if (high==null) high=item.High;
else if (high<item.High) high=item=high;
else if (high<item.High) high=item.High;
if (low==null) low=item.Low;
else if (low>item.Low) low=item.Low;
}
......@@ -5704,7 +5704,7 @@ function JSSymbolData(ast,option,jsExecute)
case DYNAINFO_ARGUMENT_ID.AMPLITUDE:
return this.LatestData.Amplitude;
case DYNAINFO_ARGUMENT_ID.CLOSE:
return this.LatestData.Close;
return this.LatestData.Price;
default:
return null;
}
......
......@@ -4620,7 +4620,7 @@ function JSAlgorithm(errorHandler,symbolData)
{
var item=stockData.Data[i];
if (high==null) high=item.High;
else if (high<item.High) high=item=high;
else if (high<item.High) high=item.High;
if (low==null) low=item.Low;
else if (low>item.Low) low=item.Low;
}
......@@ -5704,7 +5704,7 @@ function JSSymbolData(ast,option,jsExecute)
case DYNAINFO_ARGUMENT_ID.AMPLITUDE:
return this.LatestData.Amplitude;
case DYNAINFO_ARGUMENT_ID.CLOSE:
return this.LatestData.Close;
return this.LatestData.Price;
default:
return null;
}
......
......@@ -4620,7 +4620,7 @@ function JSAlgorithm(errorHandler,symbolData)
{
var item=stockData.Data[i];
if (high==null) high=item.High;
else if (high<item.High) high=item=high;
else if (high<item.High) high=item.High;
if (low==null) low=item.Low;
else if (low>item.Low) low=item.Low;
}
......@@ -5704,7 +5704,7 @@ function JSSymbolData(ast,option,jsExecute)
case DYNAINFO_ARGUMENT_ID.AMPLITUDE:
return this.LatestData.Amplitude;
case DYNAINFO_ARGUMENT_ID.CLOSE:
return this.LatestData.Close;
return this.LatestData.Price;
default:
return null;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册