EmQuantAPI.py 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797
  1. # -*- coding:utf-8 -*-
  2. __author__ = 'weijie'
  3. """
  4. * EmQuantAPI for python
  5. * version 2.4.2.0
  6. * c++ version 2.4.2.0
  7. * Copyright(c)2016-2020, EastMoney Information Co,. Ltd. All Rights Reserved.
  8. """
  9. from ctypes import *
  10. import platform as _platform
  11. import sys as _sys, os as _os
  12. from datetime import datetime as _datetime, date as _date
  13. OS_Window = 1
  14. OS_Linux = 2
  15. OS_Mac = 3
  16. OS_Bit32 = 1
  17. OS_Bit64 = 2
  18. PY_Python2 = 1
  19. PY_Python3 = 2
  20. PY_Bit32 = 1
  21. PY_Bit64 = 2
  22. eVT_null = 0
  23. eVT_char = 1
  24. eVT_byte = 2
  25. eVT_bool = 3
  26. eVT_short = 4
  27. eVT_ushort = 5
  28. eVT_int = 6
  29. eVT_uInt = 7
  30. eVT_int64 = 8
  31. eVT_uInt64 = 9
  32. eVT_float = 10
  33. eVT_double = 11
  34. eVT_byteArray = 12
  35. eVT_asciiString = 13
  36. eVT_unicodeString = 14
  37. ePT_NONE = 0 #不使用代理
  38. ePT_HTTP = 1 #HTTP代理
  39. ePT_HTTPS = 2 #HTTPS代理
  40. ePT_SOCK4 = 3 #SOCK4代理
  41. ePT_SOCK5 = 4 #SOCK5代理
  42. eOT_default = 0 # 默认(默认则根据传入数量的正负标志买入eOT_buy卖出eOT_Sell,其余类型对数量作正负转换)
  43. eOT_buy = 1 # 买入
  44. eOT_sell = 2 # 卖出
  45. eOT_purchase = 3 # 申购
  46. eOT_redemption = 4 # 赎回
  47. eCfnMode_StartToEnd = 1 # starttime和endtime中间的所有资讯
  48. eCfnMode_EndCount = 2 # 提取endtime的近count条数据
  49. class c_safe_union(Union):
  50. _fields_ = [
  51. ("charValue", c_char),
  52. ("boolValue", c_bool),
  53. ("shortValue", c_short),
  54. ("uShortValue", c_ushort),
  55. ("intValue", c_int),
  56. ("uIntValue", c_uint),
  57. ("int64Value", c_longlong),
  58. ("uInt64Value", c_ulonglong),
  59. ("floatValue", c_float),
  60. ("doubleValue", c_double)
  61. ]
  62. class stEQChar(Structure):
  63. _fields_ = [
  64. ("pChar", c_char_p),
  65. ("nSize", c_uint)
  66. ]
  67. class stEQCharArray(Structure):
  68. _fields_ = [
  69. ("pChArray", POINTER(stEQChar)),
  70. ("nSize", c_uint)
  71. ]
  72. class stEQVarient(Structure):
  73. _fields_ = [
  74. ("vtype", c_int),
  75. ("unionValues", c_safe_union),
  76. ("eqchar", stEQChar)
  77. ]
  78. class stEQVarientArray(Structure):
  79. _fields_ = [
  80. ("pEQVarient", POINTER(stEQVarient)),
  81. ("nSize", c_uint)
  82. ]
  83. class stEQData(Structure):
  84. _fields_ = [
  85. ("codeArray", stEQCharArray),
  86. ("indicatorArray", stEQCharArray),
  87. ("dateArray", stEQCharArray),
  88. ("valueArray", stEQVarientArray)
  89. ]
  90. class stEQLoginInfo(Structure):
  91. _fields_ = [
  92. ("userName", c_char * 255),
  93. ("password", c_char * 255)
  94. ]
  95. class stEQMessage(Structure):
  96. _fields_ = [
  97. ("version", c_int),
  98. ("msgType", c_int),
  99. ("err", c_int),
  100. ("requestID", c_int),
  101. ("serialID", c_int),
  102. ("pEQData", POINTER(stEQData))
  103. ]
  104. class stEQCtrData(Structure):
  105. _fields_ = [
  106. ("row", c_int),
  107. ("column", c_int),
  108. ("indicatorArray", stEQCharArray),
  109. ("valueArray", stEQVarientArray)
  110. ]
  111. class stOrderInfo(Structure):
  112. _pack_=8
  113. _fields_ = [
  114. ("code", c_char*20),
  115. ("volume", c_double),
  116. ("price", c_float),
  117. ("date", c_int),
  118. ("time", c_int),
  119. ("optype", c_int),
  120. ("cost", c_float),
  121. ("rate", c_float),
  122. ("reserve", c_int)
  123. ]
  124. class Adapter:
  125. def __init__(self):
  126. self.__os_name = OS_Window
  127. self.__os_bit = OS_Bit32
  128. self.__py_name = PY_Python2
  129. self.__py_bit = PY_Bit32
  130. self.InitSysInfo()
  131. def InitSysInfo(self):
  132. osname = _platform.system()
  133. osbit = _platform.machine()
  134. pyname = _platform.python_version()
  135. pybit = _platform.architecture()[0]
  136. if(osname == "Windows"):
  137. self.__os_name = OS_Window
  138. elif osname == "Linux":
  139. self.__os_name = OS_Linux
  140. elif osname == "Darwin":
  141. self.__os_name = OS_Mac
  142. self.__os_bit = OS_Bit32
  143. if(self.__os_name == OS_Window and osbit == "AMD64") or (self.__os_name == OS_Linux and osbit == "x86_64") or (self.__os_name == OS_Mac and osbit == "x86_64"):
  144. self.__os_bit = OS_Bit64
  145. if pyname[0] == "2":
  146. self.__py_name = PY_Python2
  147. elif pyname[0] == "3":
  148. self.__py_name = PY_Python3
  149. if pybit == "32bit":
  150. self.__py_bit = PY_Bit32
  151. elif pybit == "64bit":
  152. self.__py_bit = PY_Bit64
  153. def get_os_name(self):
  154. return self.__os_name
  155. def get_os_bit(self):
  156. return self.__os_bit
  157. def get_py_name(self):
  158. return self.__py_name
  159. def get_py_bit(self):
  160. return self.__py_bit
  161. class UtilAccess:
  162. adapter = Adapter()
  163. @staticmethod
  164. def GetLibraryPath():
  165. os_name = UtilAccess.adapter.get_os_name()
  166. if os_name == OS_Window:
  167. return UtilAccess.__getLibraryPath_window()
  168. elif os_name == OS_Linux:
  169. return UtilAccess.__getLibraryPath_linux()
  170. elif os_name == OS_Mac:
  171. return UtilAccess.__getLibraryPath_mac()
  172. @staticmethod
  173. def GetEncodeType():
  174. if UtilAccess.adapter.get_os_name() == OS_Window:
  175. return "gbk"
  176. else:
  177. return "utf-8"
  178. @staticmethod
  179. def GetLanguageVersion():
  180. os_name = UtilAccess.adapter.get_os_name()
  181. if os_name == OS_Window:
  182. return "LANGUAGEVERSION=403"
  183. elif os_name == OS_Linux:
  184. return "LANGUAGEVERSION=503"
  185. elif os_name == OS_Mac:
  186. return "LANGUAGEVERSION=603"
  187. @staticmethod
  188. def __getLibraryPath_window():
  189. apiPackagePath = "."
  190. for x in _sys.path:
  191. xx = x.find("site-packages")
  192. if(xx >= 0 and x[xx:] == "site-packages"):
  193. apiPackagePath = x
  194. break
  195. apiPackagePath = _os.path.join(apiPackagePath, "EmQuantAPI.pth")
  196. if not _os.path.exists(apiPackagePath):
  197. return ""
  198. pthFile = open(apiPackagePath, "r")
  199. baseDir = pthFile.readline().strip()
  200. pthFile.close()
  201. apiDllPath = ""
  202. if baseDir != "":
  203. libsDir = _os.path.join(baseDir, "libs", "windows")
  204. if UtilAccess.adapter.get_py_bit() == PY_Bit32:
  205. apiDllPath = _os.path.join(libsDir, "EmQuantAPI.dll")
  206. else:
  207. apiDllPath = _os.path.join(libsDir, "EmQuantAPI_x64.dll")
  208. return apiDllPath
  209. @staticmethod
  210. def __getLibraryPath_linux():
  211. baseDir = ""
  212. site_pkg_names = ["site-packages", "dist-packages"]
  213. for site_pkg_name in site_pkg_names:
  214. if baseDir != "":
  215. break
  216. for spath in _sys.path:
  217. pos = spath.find(site_pkg_name)
  218. if(pos >= 0 and spath[pos:]==site_pkg_name):
  219. apiPackagePath = _os.path.join(spath, "EmQuantAPI.pth")
  220. if not _os.path.exists(apiPackagePath):
  221. continue
  222. pthFile = open(apiPackagePath, "r")
  223. baseDir = pthFile.readline().strip()
  224. pthFile.close()
  225. break
  226. apiDllPath = ""
  227. if baseDir != "":
  228. libsDir = _os.path.join(baseDir, "libs", "linux")
  229. if UtilAccess.adapter.get_py_bit() == PY_Bit32:
  230. apiDllPath = _os.path.join(libsDir, "x86", "libEMQuantAPI.so")
  231. else:
  232. apiDllPath = _os.path.join(libsDir, "x64", "libEMQuantAPIx64.so")
  233. return apiDllPath
  234. @staticmethod
  235. def __getLibraryPath_mac():
  236. baseDir = ""
  237. site_pkg_name = "site-packages"
  238. for x in _sys.path:
  239. xi = x.find(site_pkg_name)
  240. if(xi >= 0 and x[xi:] == site_pkg_name):
  241. apiPackagePath = x
  242. apiPackagePath = _os.path.join(apiPackagePath, "EmQuantAPI.pth")
  243. if not _os.path.exists(apiPackagePath):
  244. continue
  245. pthFile = open(apiPackagePath, "r")
  246. baseDir = pthFile.readline().strip()
  247. pthFile.close()
  248. if len(baseDir) > 0:
  249. break
  250. apiDllPath = ""
  251. if baseDir != "":
  252. apiDllPath = _os.path.join(baseDir, "libs", "mac", "libEMQuantAPIx64.dylib")
  253. return apiDllPath
  254. def DemoCallback(quantdata):
  255. """
  256. DemoCallback 是csq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata
  257. :param quantdata:cls.EmQuantData
  258. :return:
  259. """
  260. print("QuoteCallback,", str(quantdata))
  261. '''
  262. def cstCallBack(quantdata):
  263. cstCallBack 是日内跳价服务提供的回调函数模板
  264. for i in range(0, len(quantdata.Codes)):
  265. length = len(quantdata.Dates)
  266. for it in quantdata.Data.keys():
  267. print(it)
  268. for k in range(0, length):
  269. for j in range(0, len(quantdata.Indicators)):
  270. print(quantdata.Data[it][j * length + k], " ", end = "")
  271. print()
  272. '''
  273. def cnqdemoCallBack(quantdata):
  274. """
  275. cnqdemoCallBack 是cnq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata
  276. :param quantdata:c.EmQuantData
  277. :return:
  278. """
  279. # print("InfoCallback,", str(quantdata))
  280. print("cnqCallback,")
  281. for code in quantdata.Data:
  282. total = len(quantdata.Data[code])
  283. for k in range(0, len(quantdata.Data[code])):
  284. print(quantdata.Data[code][k])
  285. class c:
  286. class EmQuantData:
  287. def __init__(self, NullValue = None):
  288. self.ErrorCode = 0
  289. self.ErrorMsg = "success"
  290. self.Codes = list()
  291. self.Indicators = list()
  292. self.Dates = list()
  293. self.RequestID = 0
  294. self.SerialID = 0
  295. self.Data = dict()
  296. self.__NullValue = NullValue
  297. def __str__(self):
  298. return "ErrorCode=%s, ErrorMsg=%s, Data=%s" % (self.ErrorCode, self.ErrorMsg, str(self.Data))
  299. def __repr__(self):
  300. return "ErrorCode=%s, ErrorMsg=%s, Data=%s" % (self.ErrorCode, self.ErrorMsg, str(self.Data))
  301. def resolve2RankData(self, indicatorData, **arga):
  302. for i in range(0, indicatorData.codeArray.nSize):
  303. self.Codes.append(indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType))
  304. for k in range(0, indicatorData.indicatorArray.nSize):
  305. self.Indicators.append(indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType))
  306. for j in range(0, indicatorData.dateArray.nSize):
  307. self.Dates.append(indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType))
  308. self.Data = []
  309. for i in range(0, len(self.Codes)):
  310. for j in range(0, len(self.Indicators)):
  311. for k in range(0, len(self.Dates)):
  312. self.Data.append(self.getIndicatorDataByIndex(i, j, k, indicatorData))
  313. def resolve25RankData(self, indicatorData, **arga):
  314. for i in range(0, indicatorData.codeArray.nSize):
  315. self.Codes.append(indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType))
  316. for k in range(0, indicatorData.indicatorArray.nSize):
  317. self.Indicators.append(indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType))
  318. for j in range(0, indicatorData.dateArray.nSize):
  319. self.Dates.append(indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType))
  320. for i in range(0, len(self.Codes)):
  321. stockCode = self.Codes[i]
  322. self.Data[stockCode] = []
  323. for j in range(0, len(self.Indicators)):
  324. tempData = None
  325. for k in range(0, len(self.Dates)):
  326. tempData = self.getIndicatorDataByIndex(i, j, k, indicatorData)
  327. self.Data[stockCode].append(tempData)
  328. def resolve25RankDataEx(self, indicatorData, **arga):
  329. for i in range(0, indicatorData.codeArray.nSize):
  330. self.Codes.append(indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType))
  331. for k in range(0, indicatorData.indicatorArray.nSize):
  332. self.Indicators.append(indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType))
  333. for j in range(0, indicatorData.dateArray.nSize):
  334. self.Dates.append(indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType))
  335. for i in range(0, len(self.Codes)):
  336. stockCode = self.Codes[i]
  337. if not (stockCode in self.Data.keys()):
  338. self.Data[stockCode] = []
  339. thislist = []
  340. for j in range(0, len(self.Indicators)):
  341. tempData = None
  342. for k in range(0, len(self.Dates)):
  343. tempData = self.getIndicatorDataByIndex(i, j, k, indicatorData)
  344. thislist.append(tempData)
  345. self.Data[stockCode].append(thislist)
  346. def resolve26RankData(self, indicatorData, **arga):
  347. for i in range(0, indicatorData.codeArray.nSize):
  348. self.Codes.append(indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType))
  349. for k in range(0, indicatorData.indicatorArray.nSize):
  350. self.Indicators.append(indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType))
  351. for j in range(0, indicatorData.dateArray.nSize):
  352. self.Dates.append(indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType))
  353. self.Data = []
  354. for i in range(0, len(self.Codes)):
  355. for j in range(0, len(self.Indicators)):
  356. tempData = []
  357. for k in range(0, len(self.Dates)):
  358. tempData.append(self.getIndicatorDataByIndex(i, j, k, indicatorData))
  359. self.Data.append(tempData)
  360. def resolve3RankData(self, indicatorData, **arga):
  361. for i in range(0, indicatorData.codeArray.nSize):
  362. self.Codes.append(indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType))
  363. for k in range(0, indicatorData.indicatorArray.nSize):
  364. self.Indicators.append(indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType))
  365. for j in range(0, indicatorData.dateArray.nSize):
  366. self.Dates.append(indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType))
  367. for i in range(0, len(self.Codes)):
  368. stockCode = self.Codes[i]
  369. self.Data[stockCode] = []
  370. for j in range(0, len(self.Indicators)):
  371. tempData = []
  372. for k in range(0, len(self.Dates)):
  373. tempData.append(self.getIndicatorDataByIndex(i, j, k, indicatorData))
  374. self.Data[stockCode].append(tempData)
  375. def resolveCtrData(self, indicatorData, **arga):
  376. for i in range(0, indicatorData.column):
  377. self.Indicators.append(indicatorData.indicatorArray.pChArray[i].pChar.decode(c.EncodeType))
  378. for r in range(0, indicatorData.row):
  379. list1 = []
  380. for n in range(0, indicatorData.column):
  381. list1.append(self.resolve(indicatorData.valueArray.pEQVarient[indicatorData.column * r + n]))
  382. self.Data[str(r)] = list1
  383. def resolve(self, variant):
  384. if variant.vtype == eVT_null:
  385. return self.__NullValue
  386. elif variant.vtype == eVT_char:
  387. return variant.unionValues.charValue
  388. elif variant.vtype == eVT_bool:
  389. return variant.unionValues.boolValue
  390. elif variant.vtype == eVT_short:
  391. return variant.unionValues.shortValue
  392. elif variant.vtype == eVT_ushort:
  393. return variant.unionValues.uShortValue
  394. elif variant.vtype == eVT_int:
  395. return variant.unionValues.intValue
  396. elif variant.vtype == eVT_uInt:
  397. return variant.unionValues.uIntValue
  398. elif variant.vtype == eVT_int64:
  399. return variant.unionValues.int64Value
  400. elif variant.vtype == eVT_uInt64:
  401. return variant.unionValues.uInt64Value
  402. elif variant.vtype == eVT_float:
  403. return round(variant.unionValues.floatValue, 6)
  404. elif variant.vtype == eVT_double:
  405. return round(variant.unionValues.doubleValue, 6)
  406. elif variant.vtype == eVT_asciiString:
  407. if variant.eqchar.pChar != None:
  408. return variant.eqchar.pChar.decode(c.EncodeType)
  409. else:
  410. return ""
  411. elif variant.vtype == eVT_unicodeString:
  412. if variant.eqchar.pChar != None:
  413. return variant.eqchar.pChar.decode(c.EncodeType)
  414. else:
  415. return ""
  416. return self.__NullValue
  417. def getIndicatorDataByIndex(self, codeIndex, indicatorIndex, dateIndex, indicatorData):
  418. if indicatorData.valueArray.nSize == 0:
  419. return self.__NullValue
  420. codeSize = indicatorData.codeArray.nSize
  421. indicatorSize = indicatorData.indicatorArray.nSize
  422. dateSize = indicatorData.dateArray.nSize
  423. valueSize = indicatorData.valueArray.nSize
  424. if valueSize != codeSize * dateSize * indicatorSize:
  425. return self.__NullValue
  426. if codeIndex <= codeSize * indicatorSize * dateIndex + indicatorSize * codeIndex + indicatorIndex:
  427. tempIndex = codeSize * indicatorSize * dateIndex + indicatorSize * codeIndex + indicatorIndex
  428. return self.resolve(indicatorData.valueArray.pEQVarient[tempIndex])
  429. EncodeType = ""
  430. Type_logOutFunc = CFUNCTYPE(c_int, c_char_p)
  431. Type_AsynDataFunc = CFUNCTYPE(c_int, POINTER(stEQMessage), c_void_p)
  432. __InitSucceed = False
  433. __apiDllPath = ""
  434. __quantLib = None
  435. __QuantFuncDict = {}
  436. __logOutFunc = None
  437. __AsynDataFunc = None
  438. __HandleAsynDataFuncDict = {0:{}, 10000:{}, 10001:{}, 10002:{}} # 0:main 10000:csq 10001:cst 10002:cnq
  439. __setCsqSerialID = set()
  440. @classmethod
  441. def __Init(cls):
  442. if cls.__InitSucceed:
  443. return
  444. cls.EncodeType = UtilAccess.GetEncodeType()
  445. cls.__InitSucceed = True
  446. cls.__apiDllPath = UtilAccess.GetLibraryPath()
  447. cls.__quantLib = CDLL(cls.__apiDllPath)
  448. cls.__AsynDataFunc = cls.Type_AsynDataFunc(cls.__HandleAsynData)
  449. quantLib = cls.__quantLib
  450. quant_start = quantLib.start
  451. quant_start.restype = c_int
  452. quant_start.argtypes = [c_void_p, c_char_p, cls.Type_logOutFunc]
  453. quant_stop = quantLib.stop
  454. quant_stop.restype = c_int
  455. quant_stop.argtypes = []
  456. quant_setcallback = quantLib.setcallback
  457. quant_setcallback.restype = c_int
  458. quant_setcallback.argtypes = [cls.Type_AsynDataFunc]
  459. quant_geterrstring = quantLib.geterrstring
  460. quant_geterrstring.restype = c_char_p
  461. quant_geterrstring.argtypes = [c_int, c_int]
  462. quant_csd = quantLib.csd
  463. quant_csd.restype = c_int
  464. quant_csd.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_void_p]
  465. quant_css = quantLib.css
  466. quant_css.restype = c_int
  467. quant_css.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  468. quant_tradedates = quantLib.tradedates
  469. quant_tradedates.restype = c_int
  470. quant_tradedates.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  471. quant_sector = quantLib.sector
  472. quant_sector.restype = c_int
  473. quant_sector.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  474. quant_getdate = None
  475. if UtilAccess.adapter.get_os_name() == OS_Window:
  476. quant_getdate = quantLib.getdate
  477. else:
  478. quant_getdate = quantLib.gettradedate
  479. quant_getdate.restype = c_int
  480. quant_getdate.argtypes = [c_char_p, c_int, c_char_p, c_void_p]
  481. quant_csc = quantLib.csc
  482. quant_csc.restype = c_int
  483. quant_csc.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_void_p]
  484. quant_cmc = quantLib.cmc
  485. quant_cmc.restype = c_int
  486. quant_cmc.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_void_p]
  487. quant_chmc = quantLib.chmc
  488. quant_chmc.restype = c_int
  489. quant_chmc.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_void_p]
  490. quant_releasedata = quantLib.releasedata
  491. quant_releasedata.restype = c_int
  492. quant_releasedata.argtypes = [c_void_p]
  493. quant_csq = quantLib.csq
  494. quant_csq.restype = c_int
  495. quant_csq.argtypes = [c_char_p, c_char_p, c_char_p, cls.Type_AsynDataFunc, c_void_p, c_void_p]
  496. quant_csqcancel = quantLib.csqcancel
  497. quant_csqcancel.restype = c_int
  498. quant_csqcancel.argtypes = [c_int]
  499. quant_cst = quantLib.cst
  500. quant_cst.restype = c_int
  501. quant_cst.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, cls.Type_AsynDataFunc, c_void_p, c_void_p]
  502. quant_csqsnapshot = quantLib.csqsnapshot
  503. quant_csqsnapshot.restype = c_int
  504. quant_csqsnapshot.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  505. quant_ctr = quantLib.ctr
  506. quant_ctr.restype = c_int
  507. quant_ctr.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  508. quant_cps = quantLib.cps
  509. quant_cps.restype = c_int
  510. quant_cps.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_void_p]
  511. quant_setserverlistdir = quantLib.setserverlistdir
  512. quant_setserverlistdir.restype = c_voidp
  513. quant_setserverlistdir.argtypes = [c_char_p]
  514. quant_setproxy = quantLib.setproxy
  515. quant_setproxy.restype = c_int
  516. quant_setproxy.argtypes = [c_int, c_char_p, c_ushort, c_bool, c_char_p, c_char_p]
  517. quant_manualactivate = quantLib.manualactivate
  518. quant_manualactivate.restype = c_int
  519. quant_manualactivate.argtypes = [POINTER(stEQLoginInfo), c_char_p, cls.Type_logOutFunc]
  520. quant_pquery = quantLib.pquery
  521. quant_pquery.restype = c_int
  522. quant_pquery.argtypes = [c_char_p, c_void_p]
  523. quant_porder = quantLib.porder
  524. quant_porder.restype = c_int
  525. quant_porder.argtypes = [POINTER(stOrderInfo), c_int, c_char_p, c_char_p, c_char_p]
  526. quant_edb = quantLib.edb
  527. quant_edb.restype = c_int
  528. quant_edb.argtypes = [c_char_p, c_char_p, c_void_p]
  529. quant_edbquery = quantLib.edbquery
  530. quant_edbquery.restype = c_int
  531. quant_edbquery.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  532. quant_pcreate = quantLib.pcreate
  533. quant_pcreate.restype = c_int
  534. quant_pcreate.argtypes = [c_char_p, c_char_p, c_int64, c_char_p, c_char_p]
  535. quant_pdelete = quantLib.pdelete
  536. quant_pdelete.restype = c_int
  537. quant_pdelete.argtypes = [c_char_p, c_char_p]
  538. quant_preport = quantLib.preport
  539. quant_preport.restype = c_int
  540. quant_preport.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  541. quant_tradedatesnum = quantLib.tradedatesnum
  542. quant_tradedatesnum.restype = c_int
  543. quant_tradedatesnum.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p]
  544. quant_cfn = quantLib.cfn
  545. quant_cfn.restype = c_int
  546. quant_cfn.argtypes = [c_char_p, c_char_p, c_int, c_char_p, c_void_p]
  547. quant_cfnquery = quantLib.cfnquery
  548. quant_cfnquery.restype = c_int
  549. quant_cfnquery.argtypes = [c_char_p, c_void_p]
  550. quant_cnq = quantLib.cnq
  551. quant_cnq.restype = c_int
  552. quant_cnq.argtypes = [c_char_p, c_char_p, c_char_p, cls.Type_AsynDataFunc, c_void_p, c_void_p]
  553. quant_cnqcancel = quantLib.cnqcancel
  554. quant_cnqcancel.restype = c_int
  555. quant_cnqcancel.argtypes = [c_int]
  556. quant_pctransfer = quantLib.pctransfer
  557. quant_pctransfer.restype = c_int
  558. quant_pctransfer.argtypes = [c_char_p, c_char_p, c_char_p, c_double, c_char_p, c_char_p]
  559. ####################################
  560. cls.__QuantFuncDict["start"] = quant_start
  561. cls.__QuantFuncDict["stop"] = quant_stop
  562. cls.__QuantFuncDict["setcallback"] = quant_setcallback
  563. cls.__QuantFuncDict["geterrstring"] = quant_geterrstring
  564. cls.__QuantFuncDict["csd"] = quant_csd
  565. cls.__QuantFuncDict["css"] = quant_css
  566. cls.__QuantFuncDict["tradedates"] = quant_tradedates
  567. cls.__QuantFuncDict["sector"] = quant_sector
  568. cls.__QuantFuncDict["getdate"] = quant_getdate
  569. cls.__QuantFuncDict["csc"] = quant_csc
  570. cls.__QuantFuncDict["cmc"] = quant_cmc
  571. cls.__QuantFuncDict["chmc"] = quant_chmc
  572. cls.__QuantFuncDict["releasedata"] = quant_releasedata
  573. cls.__QuantFuncDict["csq"] = quant_csq
  574. cls.__QuantFuncDict["csqcancel"] = quant_csqcancel
  575. cls.__QuantFuncDict["cst"] = quant_cst
  576. cls.__QuantFuncDict["csqsnapshot"] = quant_csqsnapshot
  577. cls.__QuantFuncDict["ctr"] = quant_ctr
  578. cls.__QuantFuncDict["cps"] = quant_cps
  579. cls.__QuantFuncDict["setserverlistdir"] = quant_setserverlistdir
  580. cls.__QuantFuncDict["setproxy"] = quant_setproxy
  581. cls.__QuantFuncDict["manualactivate"] = quant_manualactivate
  582. cls.__QuantFuncDict["pquery"] = quant_pquery
  583. cls.__QuantFuncDict["porder"] = quant_porder
  584. cls.__QuantFuncDict["edb"] = quant_edb
  585. cls.__QuantFuncDict["edbquery"] = quant_edbquery
  586. cls.__QuantFuncDict["pcreate"] = quant_pcreate
  587. cls.__QuantFuncDict["pdelete"] = quant_pdelete
  588. cls.__QuantFuncDict["preport"] = quant_preport
  589. cls.__QuantFuncDict["tradedatesnum"] = quant_tradedatesnum
  590. cls.__QuantFuncDict["cfn"] = quant_cfn
  591. cls.__QuantFuncDict["cfnquery"] = quant_cfnquery
  592. cls.__QuantFuncDict["cnq"] = quant_cnq
  593. cls.__QuantFuncDict["cnqcancel"] = quant_cnqcancel
  594. cls.__QuantFuncDict["pctransfer"] = quant_pctransfer
  595. @classmethod
  596. def __Fun(cls, funcname):
  597. return cls.__QuantFuncDict[funcname]
  598. @classmethod
  599. def __Exec(cls, funcname, *args):
  600. if not cls.__InitSucceed:
  601. cls.__Init()
  602. args = list(args)
  603. for index in range(0, len(args)):
  604. if(type(args[index]) == str):
  605. args[index] = args[index].encode(cls.EncodeType)
  606. return cls.__Fun(funcname)(*args)
  607. @classmethod
  608. def start(cls, options="", logcallback=None, mainCallBack=None):
  609. """
  610. 初始化和登陆(开始时调用) options:附加参数 "TestLatency=1"
  611. :param uname: 用户名
  612. :param password: 密码
  613. :param options:可选参数
  614. :param logcallback:启动结果提示回调函数
  615. :return EmQuantData:
  616. """
  617. if not cls.__InitSucceed:
  618. cls.__Init()
  619. if(options.upper().find("LANGUAGEVERSION") == -1):
  620. options = UtilAccess.GetLanguageVersion()+","+options
  621. data = cls.EmQuantData()
  622. cls.__HandleAsynDataFuncDict[0][0] = mainCallBack
  623. if callable(logcallback):
  624. cls.__logOutFunc = cls.Type_logOutFunc(logcallback)
  625. else:
  626. def log(logMessage):
  627. print("[EmQuantAPI Python]", logMessage.decode(cls.EncodeType))
  628. return 1
  629. cls.__logOutFunc = cls.Type_logOutFunc(log)
  630. cls.__Exec("setserverlistdir", _os.path.dirname(cls.__apiDllPath))
  631. cls.__Exec("setcallback", cls.__AsynDataFunc)
  632. loginResult = cls.__Exec("start", 0, options, cls.__logOutFunc)
  633. if loginResult != 0:
  634. data.ErrorCode = loginResult
  635. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  636. return data
  637. @classmethod
  638. def stop(cls):
  639. """
  640. 退出(结束时调用)
  641. :return: 0-成功
  642. """
  643. data = cls.EmQuantData()
  644. data.ErrorCode = cls.__Exec("stop")
  645. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  646. return data
  647. @classmethod
  648. def geterrstring(cls, errcode, lang=1):
  649. """
  650. 获取错误码文本说明
  651. :param errcode:错误代码
  652. :param lang:语言类型 0-中文 1-英文
  653. :return:
  654. """
  655. return cls.__Exec("geterrstring", errcode, lang).decode(cls.EncodeType)
  656. @classmethod
  657. def csd(cls, codes, indicators, startdate=None, enddate=None, options="", *arga, **argb):
  658. """
  659. 序列数据查询(同步请求)
  660. :param codes: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  661. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  662. :param startdate:开始日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D
  663. :param enddate:截止日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D
  664. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  665. :return EmQuantData:
  666. """
  667. codes = cls.__toString(codes)
  668. indicators = cls.__toString(indicators)
  669. result = cls.__PandasOptionFilter(options)
  670. options = result[0]
  671. ShowBlank = cls.__ShowBlankOption(options)
  672. data = cls.EmQuantData(ShowBlank)
  673. if(enddate == None):
  674. enddate = _datetime.today().strftime("%Y-%m-%d")
  675. if(startdate == None):
  676. startdate = enddate
  677. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  678. startdate = startdate.strftime("%Y-%m-%d")
  679. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  680. enddate = enddate.strftime("%Y-%m-%d")
  681. eqData = stEQData()
  682. refEqData = byref(pointer(eqData))
  683. coutResult = cls.__Exec("csd", codes, indicators, startdate, enddate, options, refEqData)
  684. if coutResult != 0:
  685. data.ErrorCode = coutResult
  686. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  687. return data
  688. tempData = refEqData._obj.contents
  689. if not isinstance(tempData, stEQData):
  690. data.ErrorCode = coutResult
  691. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  692. else:
  693. data.resolve3RankData(tempData)
  694. cls.__Exec("releasedata", pointer(tempData))
  695. return cls.__tryResolvePandas(data, result[1])
  696. @classmethod
  697. def css(cls, codes, indicators, options="", *arga, **argb):
  698. """
  699. 截面数据查询(同步请求)
  700. :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  701. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  702. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  703. :return EmQuantData:
  704. """
  705. codes = cls.__toString(codes)
  706. indicators = cls.__toString(indicators)
  707. result = cls.__PandasOptionFilter(options)
  708. options = result[0]
  709. ShowBlank = cls.__ShowBlankOption(options)
  710. data = cls.EmQuantData(ShowBlank)
  711. eqData = stEQData()
  712. refEqData = byref(pointer(eqData))
  713. coutResult = cls.__Exec("css", codes, indicators, options, refEqData)
  714. if coutResult != 0:
  715. data.ErrorCode = coutResult
  716. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  717. return data
  718. tempData = refEqData._obj.contents
  719. if not isinstance(tempData, stEQData):
  720. data.ErrorCode = coutResult
  721. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  722. else:
  723. data.resolve25RankData(tempData)
  724. cls.__Exec("releasedata", pointer(tempData))
  725. return cls.__tryResolvePandas(data, result[1])
  726. @classmethod
  727. def tradedates(cls, startdate=None, enddate=None, options=None, *arga, **argb):
  728. """
  729. 获取区间日期内的交易日(同步请求)
  730. :param startdate:开始日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D
  731. :param enddate:截止日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D
  732. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  733. :return EmQuantData:
  734. """
  735. if options == None:
  736. options = ""
  737. data = cls.EmQuantData()
  738. if(enddate == None):
  739. enddate = _datetime.today().strftime("%Y-%m-%d")
  740. if(startdate == None):
  741. startdate = enddate
  742. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  743. startdate = startdate.strftime("%Y-%m-%d")
  744. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  745. enddate = enddate.strftime("%Y-%m-%d")
  746. eqData = stEQData()
  747. refEqData = byref(pointer(eqData))
  748. coutResult = cls.__Exec("tradedates", startdate, enddate, options, refEqData)
  749. if coutResult != 0:
  750. data.ErrorCode = coutResult
  751. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  752. return data
  753. tempData = refEqData._obj.contents
  754. if not isinstance(tempData, stEQData):
  755. data.ErrorCode = coutResult
  756. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  757. else:
  758. data.resolve2RankData(tempData)
  759. cls.__Exec("releasedata", pointer(tempData))
  760. return data
  761. @classmethod
  762. def sector(cls, pukeycode, tradedate, options="", *arga, **argb):
  763. """
  764. 获取系统板块成分(同步请求)
  765. :param pukeycode:
  766. :param tradedate:交易日
  767. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  768. :param arga:
  769. :param argb:
  770. :return EmQuantData:
  771. """
  772. data = cls.EmQuantData()
  773. if(tradedate == None):
  774. tradedate = _datetime.today().strftime("%Y-%m-%d")
  775. if(isinstance(tradedate, _datetime) or isinstance(tradedate, _date)):
  776. tradedate = tradedate.strftime("%Y-%m-%d")
  777. eqData = stEQData()
  778. refEqData = byref(pointer(eqData))
  779. coutResult = cls.__Exec("sector", pukeycode, tradedate, options, refEqData)
  780. if coutResult != 0:
  781. data.ErrorCode = coutResult
  782. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  783. return data
  784. tempData = refEqData._obj.contents
  785. if not isinstance(tempData, stEQData):
  786. data.ErrorCode = coutResult
  787. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  788. else:
  789. data.resolve2RankData(tempData)
  790. cls.__Exec("releasedata", pointer(tempData))
  791. return data
  792. @classmethod
  793. def getdate(cls, tradedate, offday=0, options="", *arga, **argb):
  794. """
  795. 获取偏移N的交易日(同步请求)
  796. :param tradedate:交易日期
  797. :param offday:偏移天数
  798. :param options:
  799. :param arga:
  800. :param argb:
  801. :return EmQuantData:
  802. """
  803. data = cls.EmQuantData()
  804. if(tradedate == None):
  805. tradedate = _datetime.today().strftime("%Y-%m-%d")
  806. if(isinstance(tradedate, _datetime) or isinstance(tradedate, _date)):
  807. tradedate = tradedate.strftime("%Y-%m-%d")
  808. eqData = stEQData()
  809. refEqData = byref(pointer(eqData))
  810. coutResult = cls.__Exec("getdate", tradedate, offday, options, refEqData)
  811. if coutResult != 0:
  812. data.ErrorCode = coutResult
  813. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  814. return data
  815. tempData = refEqData._obj.contents
  816. if not isinstance(tempData, stEQData):
  817. data.ErrorCode = coutResult
  818. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  819. else:
  820. data.resolve2RankData(tempData)
  821. cls.__Exec("releasedata", pointer(tempData))
  822. return data
  823. @classmethod
  824. def csc(cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb):
  825. """
  826. 历史分钟K线(同步请求) //code只支持单个股票
  827. :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ"
  828. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  829. :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式
  830. :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式
  831. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  832. :return EmQuantData:
  833. """
  834. code = cls.__toString(code)
  835. indicators = cls.__toString(indicators)
  836. result = cls.__PandasOptionFilter(options)
  837. options = result[0]
  838. data = cls.EmQuantData()
  839. if(enddate == None):
  840. enddate = _datetime.today().strftime("%Y-%m-%d")
  841. if(startdate == None):
  842. startdate = enddate
  843. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  844. startdate = startdate.strftime("%Y-%m-%d")
  845. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  846. enddate = enddate.strftime("%Y-%m-%d")
  847. eqData = stEQData()
  848. refEqData = byref(pointer(eqData))
  849. coutResult = cls.__Exec("csc", code, indicators, startdate, enddate, options, refEqData)
  850. if coutResult != 0:
  851. data.ErrorCode = coutResult
  852. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  853. return data
  854. tempData = refEqData._obj.contents
  855. if not isinstance(tempData, stEQData):
  856. data.ErrorCode = coutResult
  857. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  858. else:
  859. data.resolve26RankData(tempData)
  860. cls.__Exec("releasedata", pointer(tempData))
  861. return cls.__tryResolvePandas(data, result[1])
  862. @classmethod
  863. def cmc(cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb):
  864. """
  865. 历史分钟K线(同步请求) //code只支持单个股票
  866. :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ"
  867. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  868. :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式
  869. :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式
  870. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  871. :return EmQuantData:
  872. """
  873. code = cls.__toString(code)
  874. indicators = cls.__toString(indicators)
  875. result = cls.__PandasOptionFilter(options)
  876. options = result[0]
  877. data = cls.EmQuantData()
  878. if(enddate == None):
  879. enddate = _datetime.today().strftime("%Y-%m-%d")
  880. if(startdate == None):
  881. startdate = enddate
  882. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  883. startdate = startdate.strftime("%Y-%m-%d")
  884. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  885. enddate = enddate.strftime("%Y-%m-%d")
  886. eqData = stEQData()
  887. refEqData = byref(pointer(eqData))
  888. coutResult = cls.__Exec("cmc", code, indicators, startdate, enddate, options, refEqData)
  889. if coutResult != 0:
  890. data.ErrorCode = coutResult
  891. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  892. return data
  893. tempData = refEqData._obj.contents
  894. if not isinstance(tempData, stEQData):
  895. data.ErrorCode = coutResult
  896. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  897. else:
  898. data.resolve26RankData(tempData)
  899. cls.__Exec("releasedata", pointer(tempData))
  900. return cls.__tryResolvePandas(data, result[1])
  901. @classmethod
  902. def chmc(cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb):
  903. """
  904. 历史分钟K线(同步请求) //code只支持单个股票
  905. :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ"
  906. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  907. :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式
  908. :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式
  909. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  910. :return EmQuantData:
  911. """
  912. code = cls.__toString(code)
  913. indicators = cls.__toString(indicators)
  914. result = cls.__PandasOptionFilter(options)
  915. options = result[0]
  916. data = cls.EmQuantData()
  917. if(enddate == None):
  918. enddate = _datetime.today().strftime("%Y-%m-%d")
  919. if(startdate == None):
  920. startdate = enddate
  921. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  922. startdate = startdate.strftime("%Y-%m-%d")
  923. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  924. enddate = enddate.strftime("%Y-%m-%d")
  925. eqData = stEQData()
  926. refEqData = byref(pointer(eqData))
  927. coutResult = cls.__Exec("chmc", code, indicators, startdate, enddate, options, refEqData)
  928. if coutResult != 0:
  929. data.ErrorCode = coutResult
  930. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  931. return data
  932. tempData = refEqData._obj.contents
  933. if not isinstance(tempData, stEQData):
  934. data.ErrorCode = coutResult
  935. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  936. else:
  937. data.resolve26RankData(tempData)
  938. cls.__Exec("releasedata", pointer(tempData))
  939. return cls.__tryResolvePandas(data, result[1])
  940. @classmethod
  941. def csq(cls, codes, indicators, options="", fncallback=None, userparams=None, *arga, **argb):
  942. """
  943. 实时行情(异步) 每次indicators最多为64个
  944. :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  945. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  946. :param options:Pushtype=0 增量推送 1全量推送 2增量模式2(证券增量,指标全量)
  947. :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的主回调函数
  948. :param userparams:用户参数,回调时原样返回
  949. :param arga:
  950. :param argb:
  951. :return EmQuantData:
  952. """
  953. codes = cls.__toString(codes)
  954. indicators = cls.__toString(indicators)
  955. data = cls.EmQuantData()
  956. cbfunc = None
  957. if not callable(fncallback):
  958. cbfunc = DemoCallback
  959. else:
  960. cbfunc = fncallback
  961. cls.__HandleAsynDataFuncDict[10000][0] = cbfunc
  962. ErrorCode = c_int(0)
  963. data.SerialID = cls.__Exec("csq", codes, indicators, options, cls.__AsynDataFunc, userparams, byref(ErrorCode))
  964. data.ErrorCode = ErrorCode.value
  965. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  966. cls.__HandleAsynDataFuncDict[10000][data.SerialID] = cbfunc
  967. if options.replace(' ', '').upper().find("ALLTICK=1") >= 0:
  968. cls.__setCsqSerialID.add(data.SerialID)
  969. return data
  970. @classmethod
  971. def csqcancel(cls, serialID):
  972. """
  973. 取消实时行情订阅
  974. :param serialID:
  975. :return EmQuantData:
  976. """
  977. data = cls.EmQuantData()
  978. data.ErrorCode = cls.__Exec("csqcancel", serialID)
  979. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  980. cls.__setCsqSerialID.discard(serialID)
  981. return data
  982. @classmethod
  983. def cst(cls, codes, indicators, startdatetime, enddatetime, options = "", fncallback=None, userparams=None):
  984. '''
  985. 日内跳价服务(异步) startdatetime和enddatetime格式(YYYYMMDDHHMMSS或HHMMSS表示系统日期当天的时间,两者需使用同一种格式)
  986. :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  987. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  988. :param startdate:开始时间
  989. :param enddate:结束时间
  990. :param options:
  991. :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的主回调函数
  992. :param userparams:用户参数,回调时原样返回
  993. :param arga:
  994. :param argb:
  995. :return EmQuantData:
  996. '''
  997. codes = cls.__toString(codes)
  998. indicators = cls.__toString(indicators)
  999. data = cls.EmQuantData()
  1000. cbfunc = None
  1001. if not callable(fncallback):
  1002. cbfunc = cstCallBack
  1003. else:
  1004. cbfunc = fncallback
  1005. cls.__HandleAsynDataFuncDict[10001][0] = cbfunc
  1006. ErrorCode = c_int(0)
  1007. data.SerialID = cls.__Exec("cst", codes, indicators, startdatetime, enddatetime,options, cls.__AsynDataFunc, userparams, byref(ErrorCode))
  1008. data.ErrorCode = ErrorCode.value
  1009. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1010. cls.__HandleAsynDataFuncDict[10001][data.SerialID] = cbfunc
  1011. return data
  1012. @classmethod
  1013. def csqsnapshot(cls, codes, indicators, options=""):
  1014. '''
  1015. 行情快照(同步请求) 每次indicators最多为64个
  1016. :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  1017. :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high"
  1018. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  1019. '''
  1020. codes = cls.__toString(codes)
  1021. indicators = cls.__toString(indicators)
  1022. result = cls.__PandasOptionFilter(options)
  1023. options = result[0]
  1024. data = cls.EmQuantData()
  1025. eqData = stEQData()
  1026. refEqData = byref(pointer(eqData))
  1027. coutResult = cls.__Exec("csqsnapshot", codes, indicators, options, refEqData)
  1028. if coutResult != 0:
  1029. data.ErrorCode = coutResult
  1030. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1031. return data
  1032. tempData = refEqData._obj.contents
  1033. if not isinstance(tempData, stEQData):
  1034. data.ErrorCode = coutResult
  1035. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1036. else:
  1037. data.resolve25RankData(tempData)
  1038. cls.__Exec("releasedata", pointer(tempData))
  1039. return cls.__tryResolvePandas(data, result[1])
  1040. @classmethod
  1041. def ctr(cls, ctrName, indicators="", options=""):
  1042. '''
  1043. 获取专题报表(同步请求)
  1044. :param ctrName:
  1045. :param startdate:开始日期
  1046. :param enddate:截止日期
  1047. :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1"
  1048. '''
  1049. indicators = cls.__toString(indicators)
  1050. data = cls.EmQuantData()
  1051. eqData = stEQCtrData()
  1052. refEqData = byref(pointer(eqData))
  1053. coutResult = cls.__Exec("ctr", ctrName, indicators, options, refEqData)
  1054. if coutResult != 0:
  1055. data.ErrorCode = coutResult
  1056. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1057. return data
  1058. tempData = refEqData._obj.contents
  1059. if not isinstance(tempData, stEQCtrData):
  1060. data.ErrorCode = coutResult
  1061. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1062. else:
  1063. data.resolveCtrData(tempData)
  1064. cls.__Exec("releasedata", pointer(tempData))
  1065. return data
  1066. @classmethod
  1067. def cps(cls, cpsCodes, cpsIndicators, cpsConditions, cpsOptions=''):
  1068. '''
  1069. 条件选股函数
  1070. :param cpsCodes 代码
  1071. :param cpsIndicators 指标
  1072. :param cpsConditions 条件
  1073. :param cpsOptions 附加参数
  1074. '''
  1075. cpsCodes = cls.__toString(cpsCodes)
  1076. cpsIndicators = cls.__toString(cpsIndicators)
  1077. cpsConditions = cls.__toString(cpsConditions)
  1078. data = cls.EmQuantData()
  1079. eqData = stEQData()
  1080. refEqData = byref(pointer(eqData))
  1081. coutResult = cls.__Exec("cps", cpsCodes, cpsIndicators, cpsConditions, cpsOptions, refEqData)
  1082. if coutResult != 0:
  1083. data.ErrorCode = coutResult
  1084. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1085. return data
  1086. tempData = refEqData._obj.contents
  1087. if not isinstance(tempData, stEQData):
  1088. data.ErrorCode = coutResult
  1089. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1090. else:
  1091. data.resolve2RankData(tempData)
  1092. cls.__Exec("releasedata", pointer(tempData))
  1093. return data
  1094. @classmethod
  1095. def setserverlistdir(cls, serlistpath):
  1096. """
  1097. 设置serverlist.json函数
  1098. :param serlistpath 文件的路径
  1099. """
  1100. cls.__Exec("setserverlistdir", serlistpath)
  1101. @classmethod
  1102. def setproxy(cls, type, proxyip, port, verify, usr, pwd):
  1103. """
  1104. 设置代理函数
  1105. :param type 代理类型
  1106. :param proxyip 代理ip
  1107. :param port 端口
  1108. :param verify 是否验证
  1109. :param usr 代理用户名
  1110. :param pwd 密码
  1111. """
  1112. data = cls.EmQuantData()
  1113. coutResult = cls.__Exec("setproxy", type, proxyip, port, verify, usr, pwd)
  1114. if coutResult != 0:
  1115. data.ErrorCode = coutResult
  1116. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1117. return data
  1118. @classmethod
  1119. def manualactivate(cls, uname, password, options="", logcallback = None):
  1120. """
  1121. 手动激活函数
  1122. :param uname 用户名
  1123. :param propasswordxyip 密码
  1124. """
  1125. if not cls.__InitSucceed:
  1126. cls.__Init()
  1127. data = cls.EmQuantData()
  1128. loginInfo = stEQLoginInfo()
  1129. uname = uname.encode(cls.EncodeType)
  1130. password = password.encode(cls.EncodeType)
  1131. loginInfo.userName = uname
  1132. loginInfo.password = password
  1133. appLogCallback = None
  1134. if callable(logcallback):
  1135. appLogCallback = cls.Type_logOutFunc(logcallback)
  1136. else:
  1137. def log(logMessage):
  1138. print("[EmQuantAPI Python]", logMessage.decode(cls.EncodeType))
  1139. return 1
  1140. appLogCallback = cls.Type_logOutFunc(log)
  1141. cls.__Exec("setserverlistdir", _os.path.dirname(cls.__apiDllPath))
  1142. loginResult = cls.__Exec("manualactivate", pointer(loginInfo), options, appLogCallback)
  1143. if loginResult != 0:
  1144. data.ErrorCode = loginResult
  1145. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1146. return data
  1147. @classmethod
  1148. def pquery(cls, options=""):
  1149. '''
  1150. 查询函数
  1151. :param options 可选参数
  1152. '''
  1153. data = cls.EmQuantData()
  1154. eqData = stEQData()
  1155. refEqData = byref(pointer(eqData))
  1156. coutResult = cls.__Exec("pquery", options, refEqData)
  1157. if coutResult != 0:
  1158. data.ErrorCode = coutResult
  1159. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1160. return data
  1161. tempData = refEqData._obj.contents
  1162. if not isinstance(tempData, stEQData):
  1163. data.ErrorCode = coutResult
  1164. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1165. else:
  1166. data.resolve25RankData(tempData)
  1167. cls.__Exec("releasedata", pointer(tempData))
  1168. return data
  1169. @classmethod
  1170. def porder(cls, combincode, orderdict, remark="",options=""):
  1171. '''
  1172. 下单函数
  1173. :param combincode 组合代码
  1174. :param orderdict 下单参数
  1175. :param remark 备注
  1176. :param options 可选参数
  1177. '''
  1178. if not isinstance(orderdict, dict):
  1179. return None
  1180. OrderMode = 0
  1181. num = len(orderdict["code"])
  1182. size = sizeof(stOrderInfo)
  1183. orderinfo = (stOrderInfo*num)()
  1184. data = cls.EmQuantData()
  1185. volumenum = 0
  1186. destvolumenum = 0
  1187. weightnum = 0
  1188. for index in range(0, num):
  1189. for key,value in orderdict.items():
  1190. if key == "destvolume":
  1191. destvolumenum = destvolumenum + 1
  1192. elif key == "weight":
  1193. weightnum = weightnum + 1
  1194. elif key == "volume":
  1195. volumenum = volumenum + 1
  1196. if options.replace(' ', '').upper().find("ORDERMODE=1") >= 0:
  1197. OrderMode = 1
  1198. if destvolumenum != num:
  1199. data.ErrorCode = 10003003
  1200. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1201. return data
  1202. if options.replace(' ', '').upper().find("ORDERMODE=2") >= 0:
  1203. OrderMode = 2
  1204. if weightnum != num:
  1205. data.ErrorCode = 10003003
  1206. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1207. return data
  1208. if OrderMode == 0:
  1209. if volumenum != num:
  1210. data.ErrorCode = 10003003
  1211. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1212. return data
  1213. for index in range(0, num):
  1214. for key,value in orderdict.items():
  1215. if key == "code":
  1216. if isinstance(value[index], str):
  1217. setattr(orderinfo[index], key, str.encode(value[index]))
  1218. elif isinstance(value[index], bytes):
  1219. setattr(orderinfo[index], key, value[index])
  1220. else:
  1221. data.ErrorCode = 10003003
  1222. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1223. return data
  1224. elif key == "volume":
  1225. setattr(orderinfo[index], key, value[index])
  1226. elif key == "price":
  1227. setattr(orderinfo[index], key, value[index])
  1228. elif key == "date":
  1229. setattr(orderinfo[index], key, int(value[index].replace("-", "").replace("/", "")))
  1230. elif key == "time":
  1231. setattr(orderinfo[index], key, int(value[index].replace(":", "")))
  1232. elif key == "optype":
  1233. setattr(orderinfo[index], key, value[index])
  1234. elif key == "cost":
  1235. setattr(orderinfo[index], key, value[index])
  1236. elif key == "rate":
  1237. setattr(orderinfo[index], key, value[index])
  1238. elif key == "reserve":
  1239. setattr(orderinfo[index], key, value[index])
  1240. elif key == "destvolume" and OrderMode == 1:
  1241. setattr(orderinfo[index], "volume", value[index])
  1242. elif key == "weight" and OrderMode == 2:
  1243. setattr(orderinfo[index], "volume", value[index])
  1244. else:
  1245. continue
  1246. coutResult = cls.__Exec("porder", pointer(orderinfo[0]), num, combincode, remark, options)
  1247. if coutResult != 0:
  1248. data.ErrorCode = coutResult
  1249. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1250. return data
  1251. @classmethod
  1252. def edb(cls, edbids, options):
  1253. '''
  1254. 宏观指标服务
  1255. '''
  1256. edbids = cls.__toString(edbids)
  1257. result = cls.__PandasOptionFilter(options)
  1258. options = result[0]
  1259. data = cls.EmQuantData()
  1260. eqData = stEQData()
  1261. refEqData = byref(pointer(eqData))
  1262. coutResult = cls.__Exec("edb", edbids, options, refEqData)
  1263. if coutResult != 0:
  1264. data.ErrorCode = coutResult
  1265. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1266. return data
  1267. tempData = refEqData._obj.contents
  1268. if not isinstance(tempData, stEQData):
  1269. data.ErrorCode = coutResult
  1270. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1271. else:
  1272. data.resolve3RankData(tempData)
  1273. cls.__Exec("releasedata", pointer(tempData))
  1274. return cls.__tryResolvePandas(data, result[1])
  1275. @classmethod
  1276. def edbquery(cls, edbids, indicators="", options=""):
  1277. '''
  1278. 宏观指标id详情查询
  1279. '''
  1280. edbids = cls.__toString(edbids)
  1281. indicators = cls.__toString(indicators)
  1282. data = cls.EmQuantData()
  1283. eqData = stEQData()
  1284. refEqData = byref(pointer(eqData))
  1285. coutResult = cls.__Exec("edbquery", edbids, indicators, options, refEqData)
  1286. if coutResult != 0:
  1287. data.ErrorCode = coutResult
  1288. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1289. return data
  1290. tempData = refEqData._obj.contents
  1291. if not isinstance(tempData, stEQData):
  1292. data.ErrorCode = coutResult
  1293. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1294. else:
  1295. data.resolve3RankData(tempData)
  1296. cls.__Exec("releasedata", pointer(tempData))
  1297. return data
  1298. @classmethod
  1299. def pcreate(cls, combinCode, combinName, initialFound, remark, options=""):
  1300. '''
  1301. 新建组合
  1302. '''
  1303. combinCode = cls.__toString(combinCode)
  1304. data = cls.EmQuantData()
  1305. coutResult = cls.__Exec("pcreate", combinCode, combinName, initialFound, remark, options)
  1306. if coutResult != 0:
  1307. data.ErrorCode = coutResult
  1308. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1309. return data
  1310. return data
  1311. @classmethod
  1312. def pdelete(cls, combinCode, options=""):
  1313. '''
  1314. 删除组合
  1315. '''
  1316. combinCode = cls.__toString(combinCode)
  1317. data = cls.EmQuantData()
  1318. coutResult = cls.__Exec("pdelete", combinCode, options)
  1319. if coutResult != 0:
  1320. data.ErrorCode = coutResult
  1321. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1322. return data
  1323. return data
  1324. @classmethod
  1325. def preport(cls, combinCode, indicator, options=""):
  1326. '''
  1327. 组合报表查询
  1328. '''
  1329. combinCode = cls.__toString(combinCode)
  1330. data = cls.EmQuantData()
  1331. eqData = stEQData()
  1332. refEqData = byref(pointer(eqData))
  1333. coutResult = cls.__Exec("preport", combinCode, indicator, options, refEqData)
  1334. if coutResult != 0:
  1335. data.ErrorCode = coutResult
  1336. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1337. return data
  1338. tempData = refEqData._obj.contents
  1339. if not isinstance(tempData, stEQData):
  1340. data.ErrorCode = coutResult
  1341. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1342. else:
  1343. data.resolve25RankData(tempData)
  1344. cls.__Exec("releasedata", pointer(tempData))
  1345. return data
  1346. @classmethod
  1347. def tradedatesnum(cls, startdate, enddate, options=""):
  1348. """
  1349. 获取区间日期内的交易日天数(同步请求)
  1350. """
  1351. data = cls.EmQuantData()
  1352. if(startdate == None):
  1353. startdate = _datetime.today().strftime("%Y-%m-%d")
  1354. if(isinstance(startdate, _datetime) or isinstance(startdate, _date)):
  1355. startdate = startdate.strftime("%Y-%m-%d")
  1356. if(enddate == None):
  1357. enddate = _datetime.today().strftime("%Y-%m-%d")
  1358. if(isinstance(enddate, _datetime) or isinstance(enddate, _date)):
  1359. enddate = enddate.strftime("%Y-%m-%d")
  1360. nSumDays = c_int(0)
  1361. refSumDays = byref(nSumDays)
  1362. coutResult = cls.__Exec("tradedatesnum", startdate, enddate, options, refSumDays)
  1363. if coutResult != 0:
  1364. data.ErrorCode = coutResult
  1365. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1366. return data
  1367. data.Data = refSumDays._obj.value
  1368. return data
  1369. @classmethod
  1370. def pctransfer(cls, combinCode, transferdirect, date, opCash, remark, options=""):
  1371. """
  1372. 组合资金调配(同步请求)
  1373. :param combinCode:组合代码
  1374. :param transferdirect:调配方向 in 增加资金 out 减少资金
  1375. :param date: 调配日期
  1376. :param opCash: 增量或减少的资金量
  1377. :param remark: 备注说明
  1378. :param options:附加参数 多个参数以半角逗号隔开
  1379. :return EmQuantData:
  1380. """
  1381. combinCode = cls.__toString(combinCode)
  1382. if (date == None):
  1383. date = _datetime.today().strftime("%Y-%m-%d")
  1384. data = cls.EmQuantData()
  1385. coutResult = cls.__Exec("pctransfer", combinCode, transferdirect, date, opCash, remark, options)
  1386. if coutResult != 0:
  1387. data.ErrorCode = coutResult
  1388. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1389. return data
  1390. return data
  1391. @classmethod
  1392. def cfn(cls, codes, content, mode, options=""):
  1393. """
  1394. 资讯数据查询(同步请求)
  1395. :param codes:东财代码或板块代码(不可混合) 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  1396. :param content:查询内容 多个指标间用半角逗号隔开,支持大小写。如 "companynews,industrynews,report,regularreport,tradeinfo" or "sectornews"
  1397. :param mode: 查询模式 eCfnMode_StartToEnd 和 eCfnMode_EndCount
  1398. :param options:附加参数 多个参数以半角逗号隔开,"starttime=20190501010000,endtime=20190725,count=10"
  1399. :return EmQuantData:
  1400. """
  1401. codes = cls.__toString(codes)
  1402. content = cls.__toString(content)
  1403. result = cls.__PandasOptionFilter(options)
  1404. options = result[0]
  1405. ShowBlank = cls.__ShowBlankOption(options)
  1406. data = cls.EmQuantData(ShowBlank)
  1407. eqData = stEQData()
  1408. refEqData = byref(pointer(eqData))
  1409. coutResult = cls.__Exec("cfn", codes, content, mode, options, refEqData)
  1410. if coutResult != 0:
  1411. data.ErrorCode = coutResult
  1412. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1413. return data
  1414. tempData = refEqData._obj.contents
  1415. if not isinstance(tempData, stEQData):
  1416. data.ErrorCode = coutResult
  1417. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1418. else:
  1419. data.resolve25RankDataEx(tempData)
  1420. cls.__Exec("releasedata", pointer(tempData))
  1421. return cls.__tryResolvePandas(data, result[1])
  1422. @classmethod
  1423. def cfnquery(cls, options=""):
  1424. """
  1425. 板块树查询(同步请求)
  1426. :param options:附加参数 多个参数以半角逗号隔开
  1427. :return EmQuantData:
  1428. """
  1429. result = cls.__PandasOptionFilter(options)
  1430. options = result[0]
  1431. ShowBlank = cls.__ShowBlankOption(options)
  1432. data = cls.EmQuantData(ShowBlank)
  1433. eqData = stEQData()
  1434. refEqData = byref(pointer(eqData))
  1435. coutResult = cls.__Exec("cfnquery", options, refEqData)
  1436. if coutResult != 0:
  1437. data.ErrorCode = coutResult
  1438. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1439. return data
  1440. tempData = refEqData._obj.contents
  1441. if not isinstance(tempData, stEQData):
  1442. data.ErrorCode = coutResult
  1443. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1444. else:
  1445. data.resolve25RankData(tempData)
  1446. cls.__Exec("releasedata", pointer(tempData))
  1447. return cls.__tryResolvePandas(data, result[1])
  1448. @classmethod
  1449. def cnq(cls, codes, content, options="", fncallback=None, userparams=None):
  1450. """
  1451. 资讯订阅(异步)
  1452. :param codes:东财代码或板块代码(不可混合) 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ"
  1453. :param content:查询内容 多个指标间用半角逗号隔开,支持大小写。如 "companynews,industrynews,report,regularreport,tradeinfo" or "sectornews"
  1454. :param options:附加参数
  1455. :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的示例回调函数
  1456. :param userparams:用户参数,回调时原样返回
  1457. :return EmQuantData:
  1458. """
  1459. codes = cls.__toString(codes)
  1460. content = cls.__toString(content)
  1461. data = cls.EmQuantData()
  1462. cbfunc = None
  1463. if not callable(fncallback):
  1464. cbfunc = cnqdemoCallBack
  1465. else:
  1466. cbfunc = fncallback
  1467. cls.__HandleAsynDataFuncDict[10002][0] = cbfunc
  1468. ErrorCode = c_int(0)
  1469. data.SerialID = cls.__Exec("cnq", codes, content, options, cls.__AsynDataFunc, userparams, byref(ErrorCode))
  1470. data.ErrorCode = ErrorCode.value
  1471. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1472. cls.__HandleAsynDataFuncDict[10002][data.SerialID] = cbfunc
  1473. return data
  1474. @classmethod
  1475. def cnqcancel(cls, serialID):
  1476. """
  1477. 取消资讯订阅
  1478. :param serialID:
  1479. :return EmQuantData:
  1480. """
  1481. data = cls.EmQuantData()
  1482. data.ErrorCode = cls.__Exec("cnqcancel", serialID)
  1483. data.ErrorMsg = cls.geterrstring(data.ErrorCode)
  1484. return data
  1485. @staticmethod
  1486. def __ShowBlankOption(options=""):
  1487. pos = options.lower().find("showblank")
  1488. ShowBlank = None
  1489. if(pos >= 0):
  1490. info = options[pos:]
  1491. pos = info.find(",")
  1492. if(pos > 0):
  1493. info = info[0:pos]
  1494. snum = info.split("=")[1]
  1495. if(snum.isdigit() or (snum.startswith('-') and snum[1:].isdigit())):
  1496. ShowBlank = int(snum)
  1497. return ShowBlank
  1498. @staticmethod
  1499. def __PandasOptionFilter(arg=""):
  1500. # Ispandas=1,RowIndex=1
  1501. result_list = []
  1502. pdDict = {}
  1503. up_str = arg.upper()
  1504. pos = up_str.find("ISPANDAS")
  1505. if(pos >= 0):
  1506. item = up_str[pos:pos+10]
  1507. pdDict["ISPANDAS"] = item[9:10]
  1508. arg = arg[0:pos]+arg[pos+10:]
  1509. else:
  1510. pdDict["ISPANDAS"] = "0"
  1511. up_str = arg.upper()
  1512. pos = up_str.find("ROWINDEX")
  1513. if(pos >= 0):
  1514. item = up_str[pos:pos+10]
  1515. pdDict[item[0:8]] = item[9:10]
  1516. arg = arg[0:pos]+arg[pos+10:]
  1517. else:
  1518. pdDict["ROWINDEX"] = "1"
  1519. result_list.append(arg)
  1520. result_list.append(pdDict)
  1521. return result_list
  1522. @staticmethod
  1523. def __tryResolvePandas(data, args={}, fun_name=None):
  1524. if data.ErrorCode != 0:
  1525. return data
  1526. if not (args != None and len(args) > 0 and "ISPANDAS" in args.keys() and "ROWINDEX" in args.keys() and args["ISPANDAS"] == "1"):
  1527. return data
  1528. if fun_name == None:
  1529. import inspect
  1530. fun_name = inspect.stack()[1][3]
  1531. import pandas as pd
  1532. code_list = []
  1533. date_list = []
  1534. data_list = []
  1535. indictor_list = ["CODES", "DATES"]
  1536. for ind in data.Indicators:
  1537. data_list.append([])
  1538. indictor_list.extend(data.Indicators)
  1539. if(fun_name == "csc" or fun_name == "cmc" or fun_name == "chmc"):
  1540. for code_index in range(0, len(data.Codes)):
  1541. code = data.Codes[code_index]
  1542. date_list.extend(data.Dates)
  1543. for nIndex in range(0, len(data.Dates)):
  1544. code_list.append(code)
  1545. for cIndex in range(0, len(data.Data)):
  1546. data_list[cIndex].extend(data.Data[cIndex])
  1547. elif(fun_name == "csd" or fun_name == "edb"):
  1548. data.Dates = [_datetime.strptime(it,"%Y/%m/%d").strftime("%Y/%m/%d") for it in data.Dates]
  1549. for code_index in range(0, len(data.Codes)):
  1550. code = data.Codes[code_index]
  1551. date_list.extend(data.Dates)
  1552. for nIndex in range(0, len(data.Dates)):
  1553. code_list.append(code)
  1554. for cIndex in range(0, len(data.Data[code])):
  1555. data_list[cIndex].extend(data.Data[code][cIndex])
  1556. elif(fun_name == "css" or fun_name == "csqsnapshot"):
  1557. for code_index in range(0, len(data.Codes)):
  1558. code = data.Codes[code_index]
  1559. date_list.extend(data.Dates)
  1560. for nIndex in range(0, len(data.Dates)):
  1561. code_list.append(code)
  1562. for cIndex in range(0, len(data.Data[code])):
  1563. data_list[cIndex].append(data.Data[code][cIndex])
  1564. else:
  1565. return data
  1566. data_list.insert(0, date_list)
  1567. data_list.insert(0, code_list)
  1568. table = pd.DataFrame(data_list, indictor_list)
  1569. table = table.T
  1570. if(args["ROWINDEX"] == "1"):
  1571. table = table.sort_values(by=["CODES","DATES"]).set_index(["CODES"])
  1572. elif(args["ROWINDEX"] == "2"):
  1573. table = table.sort_values(by=["DATES","CODES"]).set_index(["DATES"])
  1574. return table
  1575. @staticmethod
  1576. def __toStrArray(args):
  1577. if(args==None or args == ""):
  1578. return [""]
  1579. if(isinstance(args, str)):
  1580. return [args]
  1581. if(isinstance(args, int) or isinstance(args, float)) :
  1582. return [str(args)]
  1583. if(isinstance(args, tuple) or isinstance(args, list)):
  1584. result = []
  1585. for item in args:
  1586. result.extend(c.__toStrArray(item))
  1587. return result
  1588. return [str(args)]
  1589. @staticmethod
  1590. def __toNumArray(args):
  1591. if(args == None or args == ""): return None
  1592. if(isinstance(args, tuple)): return [int(x) for x in args]
  1593. if(isinstance(args, list)): return [int(x) for x in args]
  1594. if(isinstance(args, int)): return [args]
  1595. return None
  1596. @staticmethod
  1597. def __toString(args, joinStr = ","):
  1598. v = c.__toStrArray(args)
  1599. if(v == None): return None
  1600. return joinStr.join(v)
  1601. @staticmethod
  1602. def __HandleAsynData(quotemessage, userparams):
  1603. """
  1604. 实时行情回调处理函数
  1605. :param quotemessage:
  1606. :param userparams:
  1607. :return:
  1608. """
  1609. quoteReceiveData = quotemessage.contents
  1610. quotecallbackhandle = None
  1611. data =c.EmQuantData()
  1612. data.SerialID = quoteReceiveData.serialID
  1613. data.RequestID = quoteReceiveData.requestID
  1614. if quoteReceiveData.msgType == 0 or quoteReceiveData.msgType == 3:
  1615. data.ErrorCode = quoteReceiveData.err
  1616. data.ErrorMsg = c.geterrstring(data.ErrorCode)
  1617. quotecallbackhandle = c.__HandleAsynDataFuncDict[quoteReceiveData.requestID].get(0)
  1618. else:
  1619. if(data.SerialID in c.__setCsqSerialID or quoteReceiveData.requestID == 10002):
  1620. data.resolve25RankDataEx(quoteReceiveData.pEQData[0])
  1621. else:
  1622. data.resolve25RankData(quoteReceiveData.pEQData[0])
  1623. quotecallbackhandle = c.__HandleAsynDataFuncDict[quoteReceiveData.requestID].get(quoteReceiveData.serialID)
  1624. if not callable(quotecallbackhandle):
  1625. quotecallbackhandle = DemoCallback
  1626. quotecallbackhandle(data)
  1627. return 1