Форум сайта python.su
Дорогие коллеги-товарищи, очень нуждаюсь в помощи.
В Питоне я, в общем-то, новичок, но полюбил его сразу, и считаю его почти идеальным инструментом для решения моей задачи.
Пишу привод для торговли на бирже, и сейчас разбираю биржевые данные, которые приезжают в формате “почти” XML (без заголовка)
Данные примерно такие:
<securities><security secid="2326" active="true"><seccode>LK13500BE3</seccode><shortname>LKOH-6.13M140513CA 13500</shortname><decimals>0</decimals><market>4</market><sectype>OPT</sectype><opmask usecredit="no" bymarket="no" nosplit="no" immorcancel="no" cancelbalance="yes"/><minstep>1</minstep><lotsize>1</lotsize><point_cost>100</point_cost></security><security secid="2327" active="true"><seccode>RU000A0JTFZ1</seccode><shortname>СтаврКрай1</shortname><decimals>2</decimals><market>1</market><sectype>BOND</sectype><opmask usecredit="yes" bymarket="no" nosplit="yes" immorcancel="yes" cancelbalance="yes"/><minstep>0.01</minstep><lotsize>1</lotsize><point_cost>10</point_cost></security></securities>
<quotations><quotation secid="907"><accruedintvalue>0.00</accruedintvalue><closeprice>6510</closeprice><volatility>22.06</volatility><theoreticalprice>6790</theoreticalprice><buydeposit>9397.46</buydeposit><selldeposit>5328.24</selldeposit></quotation></quotations>
#coding=utf8 import sqlite3 import xml.etree.cElementTree as ET ## now parse encs = '<?xml version="1.0" encoding="UTF-8"?>' mybase = sqlite3.connect('stock.db') sqlres = mybase.execute('SELECT [recv].[rawtext] FROM [recv] ORDER BY [time] ASC') # LIMIT 10 for row in sqlres: sqlanswer = encs + str(row[0]) try: root = ET.fromstring(sqlanswer) except: print('Error parsing XML: %s' % sqlanswer) # если где-то вдруг косяк pass for elem in root.iter(): print(' TAG -> ' + elem.tag, end='') if elem.text: print(' TEXT = ' + elem.text, end='') # TEXT for attr in elem.attrib: print(' ATTR ' + attr + " = " + elem.attrib[attr])
TAG -> seccode TEXT = TATNP TAG -> shortname TEXT = Татнфт 3ап TAG -> decimals TEXT = 2 TAG -> market TEXT = 1 TAG -> sectype TEXT = SHARE TAG -> opmask ATTR cancelbalance = yes
ATTR bymarket = yes
ATTR usecredit = yes
ATTR nosplit = yes
ATTR immorcancel = yes
TAG -> minstep TEXT = 0.01 TAG -> lotsize TEXT = 10 TAG -> point_cost TEXT = 1 TAG -> security ATTR active = true
ATTR secid = 29
TAG -> quotations TAG -> quotation ATTR secid = 907
TAG -> accruedintvalue TEXT = 0.00 TAG -> closeprice TEXT = 6510 TAG -> volatility TEXT = 22.06 TAG -> theoreticalprice TEXT = 6790 TAG -> buydeposit TEXT = 9397.46 TAG -> selldeposit TEXT = 5328.24
Отредактировано pmus (Май 8, 2013 15:35:49)
Офлайн
Какие именно данные вам нужны из этой пачки?
Кроме кортежей есть еще словари и именованные кортежи (namedtuple)
Офлайн
Там все данные важны, разве что OPMASK черт бы с ними.
Пока представляю что-то типа:
sec[n]['name', 'shortname', 'minstep', 'lotsize', 'point_cost'] = 'TATNP', ' Татнфт 3ап', '0.01', '10', '1'
quotations['TATNP', 'lastprice'] += lastprice
class sec(object): ''' class that handles security ''' def __init__(self, secname): self.secname = secname self.last = [] self.stakan = [] def addlastprice(self, price): self.last.append (price) def addstakan(self, price): self.stakan.append (price) rim = sec('RIM3') rim.addlastprice(145000) rim.addlastprice(144000) rim.addlastprice(144300) print rim.last
Отредактировано pmus (Май 9, 2013 09:09:36)
Офлайн
Проще использовать lxml и его модуль objectify
# -*- coding: utf-8 -*- from lxml import etree, objectify text = '<securities>...</securities>' securities = objectify.fromstring(text) for security in securities.security: print( security.get('secid'), security.shortname.text, security.market, security.opmask.get('usecredit'), # ... )
Офлайн
reclosedev, спасибище Вам огромное! Наконец-то мои жалкие потуги сдвинулись с места.
Офлайн
seclist = {} ... try: for security in tree.security: seclist[security.seccode] = ( {'seccode':security.seccode, 'secid': security.get('secid'), 'shortname': security.shortname, 'market': security.market}) except: pass .... print(seclist['RIM3']) .... >{'shortname': 'RTS-6.13', 'seccode': 'RIM3', 'secid': '4016', 'market': 4}
print(seclist['RIM3'].'secid') >4016
Отредактировано pmus (Май 9, 2013 14:21:43)
Офлайн
Ну, конечно!
print(seclist['RIM3']['secid'])
Отредактировано pmus (Май 9, 2013 15:09:19)
Офлайн
Вдогонку (для тех, кому попадется подобная задача)
tree = objectify.fromstring (text) def result(): global tree print tree.text print tree.attrib #и так далее... def server_status(): global tree #и так далее... def security(): global tree for s in tree.security : seclist.append (s.seccode) secdict [s.seccode] = ( { 'secid' : s.get ('secid') , 'active' : s.get ('active') , 'seccode' : s.seccode , #и так далее... options = {'result' : result, 'server_status' : server_status, 'security' : security } options[tree.tag]()
Отредактировано pmus (Май 18, 2013 20:54:58)
Офлайн