You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.1 KiB

import csv
import config
import grequests
import re
from lxml import html
from lazyme.string import color_print
from tqdm import tqdm
def importData():
with open(config.data, 'rb') as f:
reader = csv.reader(f)
return list(reader)
def getSymbol(data):
print "Getting Symbol ..."
symbolsWithHeader = map(lambda x: x[0], data)
symbols = symbolsWithHeader[ 2: len(symbolsWithHeader) ]
return map(lambda x: {'symbol': x}, symbols)
def toNakedShareNumber(word):
return float(re.sub("\D", "", word))
def toNakedPriceNumber(word):
word = word.replace(',', '')
return float(word)
def toNakedFinanceNumber(word):
return float(word.replace(',',''))
def getProfileUrl(data):
return config.url['profile'](data['symbol'])
def getPriceUrl(data):
return config.url['highlights'](data['symbol'])
def getFinanceUrl(data):
return config.url['finance'](data['symbol'])
def scrapeAndFormatShare(page):
if(page == None): return '-1'
tree = html.fromstring(page.content)
share = tree.xpath('//div[text()="Listed Share"]/following-sibling::div/text()')
share = '0' if not share else share[0]
return toNakedShareNumber(share)
def getShare(datas):
print "Getting Share ..."
urls = map(getProfileUrl, datas)
rs = (grequests.get(u) for u in urls)
pages = tqdm(grequests.map(rs))
shares = map(scrapeAndFormatShare, pages)
for i in range(len(datas)):
datas[i].update({'share': shares[i]})
return datas
def scrapeAndFormatPrice(page):
if(page == None): return '-1'
tree = html.fromstring(page.content)
prices = tree.xpath('//td[text()="Last Price(Baht)"]/following-sibling::td/text()')
try:
price = prices[len(prices) - 1]
except:
price = '0'
return toNakedPriceNumber(price)
def getPrice(datas):
print "Getting Price ..."
urls = map(getPriceUrl, datas)
rs = (grequests.get(u) for u in urls)
pages = tqdm(grequests.map(rs))
prices = map(scrapeAndFormatPrice, pages)
for i in range(len(datas)):
datas[i].update({'price': prices[i]})
return datas
def scrapeAndFormatFinance(page):
if(page == None): return {}
t = html.fromstring(page.content).xpath
finance = {
"cash": t('//td[text()="CASH AND CASH EQUIVALENTS"]/following-sibling::td/text()'),
"investment": t('//td[text()="SHORT-TERM INVESTMENTS"]/following-sibling::td/text()'),
"recievable": t('//td[text()="TRADE ACCOUNTS AND OTHER RECEIVABLE"]/following-sibling::td/text()'),
"asset": t('//td[text()="TOTAL CURRENT ASSETS"]/following-sibling::td/text()'),
"inventory": t('//td[text()="INVENTORIES"]/following-sibling::td/text()'),
"liability": t('//td[text()="TOTAL LIABILITIES"]/following-sibling::td/text()')
}
finance = dict(zip(finance, map(lambda x: 0 if not x else x[0], finance.values())))
finance = dict(zip(finance, map(lambda x: 0 if x==0 else toNakedFinanceNumber(x), finance.values())))
finance = dict(zip(finance, map(lambda x: x*1000000, finance.values())))
return finance
def getFinance(datas):
print "Getting Finance ..."
urls = map(getFinanceUrl, datas)
rs = (grequests.get(u) for u in urls)
pages = tqdm(grequests.map(rs))
finances = map(scrapeAndFormatFinance, pages)
for i in range(len(datas)):
datas[i].update(finances[i])
return datas
def calculateNCAV(data):
try:
return (data['asset'] - data['liability'])/data['share']
except:
return 'N/A'
def getNCAV(datas):
print "Getting NCAV ..."
ncav = map(calculateNCAV, datas)
for i in range(len(datas)):
datas[i].update({'ncav': ncav[i]})
return datas
def calculateNNWC(data):
try:
return ((data['cash'] + data['investment']) +\
(0.75 * data['recievable']) +\
(0.5 * data['inventory']) -\
(data['liability']))/data['share']
except:
return 'N/A'
def getNNWC(datas):
print "Getting NNWC ..."
nnwc = map(calculateNNWC, datas)
for i in range(len(datas)):
datas[i].update({'nnwc': nnwc[i]})
return datas
def calculatePercent(data):
try:
nnwc = str(round((data['price']/data['nnwc'])*100, 2))
except:
nnwc = -1
try:
ncav = str(round((data['price']/data['ncav'])*100, 2))
except:
ncav = -1
return {
'symbol': data['symbol'],
'nnwc_percent': 'N/A' if data['nnwc'] < 0 else nnwc,
'ncav_percent': 'N/A' if data['ncav'] < 0 else ncav
}
def displayEach(data):
print "================="
print data['symbol']
if(data['nnwc_percent'] == 'N/A'):
pass
elif(data['nnwc_percent'] >= 0 and data['nnwc_percent'] < 70):
color_print("nnwc " + data['nnwc_percent'] + "%", color='green')
elif(data['nnwc_percent'] >= 70 and data['nnwc_percent'] < 100):
color_print("nnwc " + data['nnwc_percent'] + "%", color='yellow')
elif(data['nnwc_percent'] >= 100):
color_print("nnwc " + data['nnwc_percent'] + "%", color='red')
if(data['ncav_percent'] == 'N/A'):
pass
elif(data['ncav_percent'] >= 0 and data['ncav_percent'] < 70):
color_print("ncav " + data['ncav_percent'] + "%", color='green')
elif(data['ncav_percent'] >= 70 and data['ncav_percent'] < 100):
color_print("ncav " + data['ncav_percent'] + "%", color='yellow')
elif(data['ncav_percent'] >= 100):
color_print("ncav " + data['ncav_percent'] + "%", color='red')
def getPercent(datas):
percents = map(calculatePercent, datas)
for i in range(len(datas)):
datas[i].update(percents [i])
return datas
def display(datas):
map(displayEach, datas)
def main():
datas = importData()
datas = getSymbol(datas)
datas = getShare(datas)
datas = getPrice(datas)
datas = getFinance(datas)
datas = getNCAV(datas)
datas = getNNWC(datas)
datas = getPercent(datas)
toCSV(datas)
def toCSV(datas):
keys = datas[0].keys()
with open('final.csv', 'wb') as output_file:
dict_writer = csv.DictWriter(output_file, keys)
dict_writer.writeheader()
dict_writer.writerows(datas)
main()