def getTkLst(tkLst=None, tgtk='AAPL', dbname='ara', tablename='yh_quote_curr', days=-7): ''' Utility function Get a ticker list of 'yh_quote_curr' from lookback 'days' ''' if tkLst is not None and len(tkLst) > 0: mxdate = int(next_date(days=days, dformat=('%Y%m%d'), dtTF=False)) return tkLst, mxdate mdb = conn2mgdb(dbname=dbname) mCur = mdb[tablename] try: mxdate = max(mCur.find({"ticker": tgtk}).distinct("pbdate")) mxdate = int( next_date(mxdate, days=days, dformat=('%Y%m%d'), dtTF=False)) except: mxdate = int(next_date(days=days, dformat=('%Y%m%d'), dtTF=False)) jo = { 'exchange': { '$ne': 'PNK' }, 'ticker': { '$regex': '^((?![\^|=|0]).)*$' }, 'pbdate': { '$gt': mxdate } } r = mCur.find(jo, {"_id": 0, "ticker": 1}).distinct("ticker") tkLst = [x.replace('-', '.') for x in r] return sorted(tkLst), mxdate
def find_latest_eps(ticker='UNP', cdt=None, dbname='ara', debugTF=False): """ Find eps since monday of the last week """ if not cdt: cdt = next_date() elif not isinstance(cdt, datetime.date): cdt = next_date(cdt) gap = -1 if cdt.weekday() == 0 else -2 xdt = next_date(cdt, weeks=gap, weekday=0) # monday of the last week sundt = next_date(xdt, days=6) # coming sunday from xdt(monday) xdate = int(xdt.strftime('%Y%m%d')) findDct = {"pbdate": {'$gte': xdate}, "ticker": ticker} # use zacks for up-to-date EPS ret, _, errmsg = find_mdb( jobj=findDct, dbname=dbname, tablename='earnings_zacks', field=['ticker', 'Estimate', 'Reported', 'pbdate', 'Time'], sortLst=['pbdate'], ascendingTF=False) if len(ret) > 0: dd = ret[0] dd['eps'] = float(dd['Reported']) pdt = s2dt(dd['pbdate']) if pdt <= xdt: # discard any data less Monday of the week sys.stderr.write("Stale news:{} < {}, disregard!\n".format( pdt, xdt)) return {} currWeekTF = (pdt > sundt) todayTF = (pdt.day == cdt.day) dd.update(weekday=pdt.weekday() + 1, currWeekTF=currWeekTF, todayTF=todayTF) pbdate = dd['pbdate'] else: return {} dh = select_eps_hist(ticker=ticker, pbdate=pbdate, debugTF=debugTF) if len(dh) > 0: ceps = dd['eps'] if dh.shape[0] > 3: xeps = dh['actualEPS'].iloc[3] dd.update(eps_chgFreq='Y') else: xeps = dh['actualEPS'].iloc[0] dd.update(eps_Freq='Q') pchg, chgTF = calc_pchg(ceps, xeps) dd.update(eps_pctChange=pchg, prev_eps=xeps, eps_isPct=chgTF) dd.update(latest2weekTF=True) d1 = dh[['actualEPS', 'pbdate']].set_index('pbdate') d1.loc[pbdate] = {'actualEPS': ceps} dd.update(past_eps=d1.sort_index()) dh = select_eps_hist(ticker=ticker, types='financials', debugTF=debugTF) if len(dh) and 'revenue' in dd: revenueStr = dd['revenue'] revenue = num_en2cn(revenueStr, numTF=True) pchg = revenue / dh['totalRevenue'].iloc[0] - 1 dd.update(revenue_pctChange=pchg, prev_revenue=xeps) dd.update(revenue=revenue, revenueStr=revenueStr) return (dd)
def create_theme_media(dbname="ara", tablename="topic_theme_media", debugTF=False, **optx): ''' create MDB::'topic_theme_media' table based on 'madmoney_hist' info arguments: 'end' default to 2-weeks of today in YYYYMMDD 'callLst' default to ["4","5"] types ''' zpk = getKeyVal(optx, 'zpk', {'ticker', 'pbdate', 'start', 'end'}) start = getKeyVal(optx, 'start', 0) end = getKeyVal(optx, 'end', None) callLst = getKeyVal(optx, 'callLst', ["4", "5"]) if end is None: end = int(dt2ymd(next_date(weeks=-2))) xqTmp = "SELECT pbdate,adjusted as price FROM prc_hist where name='{}' and pbdate>{} and pbdate <={} ORDER BY pbdate" jobj = {"Call": {"$in": callLst}, "pbdate": {"$lte": end, "$gte": start}} df, mdb, emsg = find_mdb(jobj, sortLst=["pbdate"], dbname="ara", tablename="madmoney_hist", dfTF=True) dd = [] for j in df.index: dx = df.iloc[j].to_dict() dx['pbdate'] = int(dx['pbdate']) ticker = dx['ticker'] pbdate = period1 = dx['pbdate'] period2 = int(dt2ymd(next_date(period1, months=1))) xqr = xqTmp.format(ticker, period1, period2) dp = sqlQuery(xqr) vprc = dp['price'].values if len(vprc) < 1: continue vdate = [int(x) for x in dp['pbdate'].values] sPrice, ePrice = vprc[0], vprc[-1] period1, period2 = vdate[0], vdate[-1] rrt = vprc[-1] / vprc[0] * 100. - 100 day_diff = ymd_diff(period1, period2) dx.update(rrt=rrt, day_diff=day_diff, start=period1, end=period2) dx.update(sPrice=sPrice, ePrice=ePrice) sys.stderr.write( "{j:03d}|{ticker:5s}|{Call}|{rrt:8.2f}|{day_diff:3d}|{start:8d}|{end:8d}|{pbdate:8d}|{Company}|\n" .format(j=j, **dx)) dd.append(dx) dy, _, emsg = insert_mdb([dx], tablename=tablename, dbname=dbname, zpk=zpk) if start > 12345678: jobj = {"day_diff": {"$lt": 20}, "pbdate": {"$lte": start}} mdb[dbname][tablename].delete_many(jobj) df = pd.DataFrame(dd) return df
def is_record_hl(dx, colx='pchg', **nd_args): if len(nd_args) < 1: startDT = next_date(dx.index[-1], month=1, day=1) else: startDT = next_date(dx.index[-1], **nd_args) ds = dx.loc[dx.index >= startDT, colx] mnxTF, hilo, idxmnx = find_hilo(ds) startAT = ds.index[0] # actual startDate in datetime #sys.stderr.write("===Act:{}, Start:{}, Args:{}\n".format(startAT,startDT,nd_args)) return mnxTF, hilo, idxmnx, startDT, startAT
def deact_mapping_ticker(lkbk=-14, mxcap=500000000, debugTF=False, saveDB=True, **optx): ''' De-activate tickers with invalid quotes within last 14 days or marketCap < 500MM ''' # de-active stale tickers sys.stderr.write("===STARTING de-active stale tickers\n") pgDB = conn2pgdb(dbname='ara') tkCIK = sqlQuery( "SELECT * FROM mapping_ticker_cik WHERE act_code=1 and ticker not similar to '%%(^|=)%%'" ) tLst = tkCIK['ticker'].values dt7d = int(next_date(days=lkbk, dformat='%Y%m%d', dtTF=False)) df = yqc(tLst, tablename=None, screenerTF=False, dfTF=True) if len(df) < 1: sys.stderr.write("No deactivate list\n") return (0) yqr = 'pbdate<{}|marketCap<{}'.format(dt7d, mxcap) dg = df.query(yqr) newLst = dg['ticker'].values if len(newLst) < 1: sys.stderr.write("No deactivate list\n") return (0) else: sys.stderr.write("New deactivate List:{}\n".format(newLst)) if saveDB: xqTmp = "UPDATE mapping_ticker_cik set act_code=0 where ticker in {}" xqr = xqTmp.format(tuple(newLst)) pgDB.execute(xqr) return newLst
def select_eps_hist(ticker='AAPL', pbdate=None, types='earnings', dbname='ara', **optx): debugTF = optx.pop('debugTF', False) if types.lower() in ['earnings', 'eps']: tablename = 'earnings_yh' elif types.lower() == 'stats': tablename = 'qS_keyStatistics' jobj = {"ticker": ticker} ret, _, errmsg = find_mdb(jobj, dbname=dbname, tablename=tablename) if len(ret) < 1: return {} df = pd.DataFrame(ret) return df else: return {} pbdate = int(next_date(pbdate, dformat='%Y%m%d', dtTF=False, days=-2)) jobj = {"pbdate": {'$lt': pbdate}, "ticker": ticker} ret, _, errmsg = find_mdb(jobj, dbname=dbname, tablename=tablename, sortLst=['pbdate'], ascendingTF=False) df = pd.DataFrame(ret) if debugTF: sys.stderr.write("EPS {} of {}:\n".format(ticker, tablename)) sys.stderr.write("{}\n".format(df)) if 'actualEPS' not in df: return df df = df.dropna(subset=['actualEPS']) df = df[~df['actualEPS'].isin(['-'])] df['actualEPS'] = df['actualEPS'].astype(float) return df
def find_record_hilo(dx, endDT=None, ticker='', colx='pchg', colLst=['close', 'pchg'], debugTF=False, mthLst=[]): if endDT is None: endDT = next_date() pbdate = int(endDT.strftime('%Y%m%d')) kyLst = ["name", "days", "endDT", "mnxTF", "hilo", "startDT"] if debugTF: sys.stderr.write("{}\n".format(dx)) da = db = {} jobj = dict(ticker=ticker, pbdate=pbdate, MTD={}, YTD={}) if endDT.day < 20: # Last MoToDate mnxTF, hilo, idxmnx, startDT, startAT = is_record_hl(dx, colx=colx, months=-1, day=1) ndays = (endDT - startDT).days startYmd = int(startDT.strftime('%Y%m%d')) name = "LastMoToDate" if (mnxTF is True): vaLst = [name, ndays, pbdate, mnxTF, hilo, startYmd] da = dict(zip(kyLst, vaLst)) da.update(dx.loc[idxmnx, colLst].to_dict()) jobj.update(MTD=da) else: # MoToDate mnxTF, hilo, idxmnx, startDT, startAT = is_record_hl(dx, colx=colx, day=1) ndays = (endDT - startDT).days startYmd = int(startDT.strftime('%Y%m%d')) name = "MoToDate" if (mnxTF is True): vaLst = [name, ndays, pbdate, mnxTF, hilo, startYmd] da = dict(zip(kyLst, vaLst)) da.update(dx.loc[idxmnx, colLst].to_dict()) jobj.update(MTD=da) # YrToDate mnxTF, hilo, idxmnx, startDT, startAT = is_record_hl(dx, colx=colx, month=1, day=1) ndays = (endDT - startDT).days startYmd = int(startDT.strftime('%Y%m%d')) name = "YrToDate" if (mnxTF is True) and ndays > 45: vaLst = [name, ndays, pbdate, mnxTF, hilo, startYmd] db = dict(zip(kyLst, vaLst)) db.update(dx.loc[idxmnx, colLst].to_dict()) jobj.update(YTD=db) return jobj
def get_stock_hist(tkLst,ndays=2,xqTmp='',diffTF=False,pgDB=None,end=None,debugTF=False,liveTF=False): ticker=tkLst[0] xqx = "select pbdate from prc_hist where name='{}' {} order by pbdate DESC limit {}" addiClause = '' if end is None else ' AND pbdate<={}'.format(end) dtmp = sqlQuery(xqx.format(ticker,addiClause,ndays),pgDB) currdb_date = dtmp['pbdate'].iloc[0] xdb_date = dtmp['pbdate'].iloc[1] if end is not None and int(end)>currdb_date and liveTF is True: from yh_hist_batch import yh_hist from _alan_date import next_date s = next_date(end,dformat='%Y%m%d',days=-5,dtTF=False) ranged = "{},{}".format(s,end) dtmp = yh_hist(ticker,gap='1d',ranged=ranged,debugTF=debugTF) sys.stderr.write("===LIVE dtmp:\n{}\n".format(dtmp.tail())) curryh_date = dtmp['pbdate'].iloc[-1] else: curryh_date = currdb_date if curryh_date>currdb_date: dx=pd.DataFrame() for ticker in tkLst: ticker = ticker.replace('.','-') dtmp = yh_hist(ticker,gap='1d',ranged=ranged,debugTF=debugTF)[-ndays:] dtmp['chgPct'] = dtmp['close'].pct_change().values*100. dtmp['chgLevel'] = dtmp['close'].diff(periods=1).values dx= pd.concat([dx,dtmp]) dx.rename(columns={'name':'ticker'},inplace=True) dx.reset_index(drop=True,inplace=True) sys.stderr.write("===LIVE dx:\n{}\n".format(dx.tail())) return dx else: start = xdb_date if len(xqTmp)<1: xqTmp = "select * from prc_hist WHERE name in {} and pbdate>={} {} ORDER BY name,pbdate" nmLst = [x.replace('.','-') for x in tkLst] nmPns="('{}')".format("','".join(nmLst)) xqr = xqTmp.format(nmPns,start,addiClause) dx=sqlQuery(xqr,pgDB) dx['ticker']= [x.replace('-','.') for x in dx['name'] ] dx['chgPct']= np.empty(dx['ticker'].shape) if diffTF is True: dx['chgLevel']= np.empty(dx['ticker'].shape) for ticker in tkLst: dx.loc[dx['ticker']==ticker,'chgPct'] = dx.loc[dx['ticker']==ticker,'close'].pct_change().values*100. if diffTF is True: dx.loc[dx['ticker']==ticker,'chgLevel'] = dx.loc[dx['ticker']==ticker,'close'].diff(periods=1).values return dx
def create_headline(dd,ts='',jobj=None,**opts): dd['topLst1']=ast.literal_eval(dd['topLst1']) if hasattr(dd['topLst1'], "__len__") else {} dd['topLst2']=ast.literal_eval(dd['topLst2']) if hasattr(dd['topLst2'], "__len__") else {} if jobj is None: dd['hiloRecord'] = get_hiloRecord(dd['Index1'],dd['pbdate']) else: dd['hiloRecord'] = jobj['YTD'] if jobj['YTD'] else {} hiloName = dd['hiloRecord']['name'] if 'name' in dd['hiloRecord'] else '' sys.stderr.write("{}|{}|".format(dd['pbdate'],hiloName)) dd.update(pcall=popenCall,ticker2label=ticker2label,iex_peers=iex_peers,jj_fmt=jj_fmt) ret = jj_fmt(ts,dd,**opts) opts.update(mp3YN=True) dbname='ara';tablename='mkt_briefing_details' mp3ret = jj_fmt(ts,dd,**opts) block='HEADLLINE';attr='EOD' cdt=next_date() datax=dict(block=block,attr=attr,comment=ret,mp3comment=mp3ret,pbdt=cdt,data={}) for k,v in dd.items(): if not hasattr(v,'__call__'): datax['data'].update({k:v}) write2mdb(datax,dbname=dbname,tablename=tablename) return ret
def gen_chartpath(chartname='', chartdir='US/mp3_hourly', chartformat='svg', epoch=None, **optx): """ Generate 'chartpath', 'chartname' as {chartdir}/{templateName}_{ticker}_{epoch}.{chartformat}, {templateName}_{ticker}_{epoch}.{chartformat} where 'chartdir','chartformat' and 'epoch' are optional Example, gen_chartpath(templateName='stock_performance',ticker='AAPL') Note, 'ticker' with '^' or '=' characters will be removed """ chartname = '' if not isinstance(chartname, str) else chartname if len(chartname) > 0: if len(chartdir) > 0: chartpath = "{}/{}".format(chartdir, chartname) else: chartpath = chartname return chartpath, chartname if epoch is None: epoch = dt2ymd(next_date(), "%s") chartname = chartpath = '' ky = ['templateName', 'ticker'] kLst = getKeyVal(optx, ky, [], extendTF=True) kLst.extend([epoch, chartformat]) if not any([x is None for x in kLst]): chartname = "{}_{}_{}.{}".format(*kLst) chartname = re.sub('[\^=]', '', chartname) if len(chartdir) > 0 and len(chartname) > 0: chartpath = "{}/{}".format(chartdir, chartname) else: chartpath = chartname return chartpath, chartname
def upd_mapping_ticker(lkbk=-7, mxcap=10**9, debugTF=False, saveDB=True, **optx): sys.stderr.write("===STARTING to update ticker list\n") #1. UPDATE sp500 / Dow30 list from theme_list import sp500_component sp500 = sp500_component(saveDB=False) if len(sp500) < 1: sp500 = sqlQuery("SELECT * FROM sp500_component") sLst = sp500['ticker'].values #2. PULL MDB::ara:madmoney_hist dt6mo = int(next_date(months=-6, dformat='%Y%m01', dtTF=False)) mdb = conn2mgdb(dbname='ara') mLst = mdb['madmoney_hist'].find({ "pbdate": { "$gt": dt6mo } }).distinct("ticker") mLst = [x.replace('.', '-') for x in mLst] #3. COMPILE a new list based on madmoney and SP500 new tickers tkCIK = sqlQuery( "SELECT * FROM mapping_ticker_cik WHERE act_code=1 and ticker not similar to '%%(^|=)%%'" ) tLst = tkCIK['ticker'].values n1Lst = set(sLst) - set(tLst) sys.stderr.write("New SP500 List:{}\n".format(n1Lst)) n2Lst = set(mLst) - set(tLst) sys.stderr.write("New madMoney List:{}\n".format(n2Lst)) nLst = list(n1Lst.union(n2Lst)) #4. PULL only valid quotes within last 7 days and marketCap > 1B dt7d = int(next_date(days=lkbk, dformat='%Y%m%d', dtTF=False)) df = yqc(nLst, tablename=None, screenerTF=False, dfTF=True) xqr = 'not(pbdate<{}|marketCap<{})'.format(dt7d, mxcap) dg = df.query(xqr) newLst = dg['ticker'].values if len(newLst) < 1: sys.stderr.write("No Additions\n") return (0) else: sys.stderr.write("New Additional List:{}\n".format(newLst)) #5. PULL new list 'newLst' with cik/sic/sector info if saveDB: newDf = tkmp(newLst) pgDB = conn2pgdb(dbname='ara') newDf.to_sql('ticker_mapping_temp', pgDB, schema='public', index=False, if_exists='replace') xqr = """ DELETE FROM mapping_ticker_cik B USING ticker_mapping_temp C WHERE B.ticker = C.ticker; INSERT INTO mapping_ticker_cik SELECT cik,ticker,company,sic,sector,company_cn,sector_cn,1::int as act_code FROM (SELECT a.*,b.sector,b.sector_cn from ticker_mapping_temp a LEFT JOIN spdr_sector b ON a.sector_alias=b.sector_alias) as s """ pgDB.execute(xqr, pgDB) return newLst
def run_rmc(jobj): """ run Remote-Market-Commentary based on input dict: [jobj] with keys: tmplstr,argstr,ticker,tmplrpt,username,category,tmplname,action return string for Market Commentary """ global username, ticker, lang, dirname if 'username' in jobj: username = jobj['username'] if 'ticker' in jobj: ticker = jobj['ticker'] if 'lang' in jobj: lang = jobj['lang'] dirname = 'templates/' jobj.update(dirname=dirname) jobj.update(mp3YN=False) jobj.update(start=dt2ymd(next_date())) # run rmc based on tmplstr if str(jobj['tmpltype']) == 'pppscf' and str(jobj['action']) == 'run': jobj['tmplrpt'] = batch_pppscf( [jobj['ticker']], optx={ "j2ts": jobj['tmplstr'], "lang": jobj['lang'], "debug": True, "saveDB": False, "category": jobj['category'] }) # run_alan_pppscf.batch_pppscf() 1st then import gData in batch_pppscf() from _alan_pppscf import gData jobj["retcode"] = "run successfully" elif str(jobj['tmpltype']) == 'fcs' and str(jobj['action']) == 'run': jobj['tmplrpt'] = batch_ohlc_fcs( [jobj['ticker']], optx={ "j2ts": jobj['tmplstr'], "lang": jobj['lang'], "debug": True, "saveDB": False, "category": jobj['category'] }) from _alan_ohlc_fcs import gData jobj["retcode"] = "run successfully" elif str(jobj['tmpltype']) == 'eps' and str(jobj['action']) == 'run': from fcs_eps_price import run_eps_fcs gData = run_eps_fcs([jobj['ticker']])[0] jobj['tmplrpt'] = argstr_tmplrpt(jobj['tmplstr'], gData, jobj['argstr'].replace("\n", '')) jobj["retcode"] = "run successfully" elif str(jobj['tmpltype']) == 'mkt' and str(jobj['action']) == 'run': # Same as command line: # headline_writer.py --lang=cn --extra_xs='onTheFly=True;j2ts="{% include \"daily_briefing_cn.j2\" %}";dirname="templates"' --start=20190705 2>/dev/null from headline_writer import generate_headline optx = dict(j2ts=jobj['tmplstr'], onTheFly=True) optx.update(jobj) if jobj['argsflg'] == '1' and len(jobj['argstr']) > 0: gdd = {} exec(jobj['argstr'], globals(), gdd) optx.update(gdd) try: ret = generate_headline(**optx) except Exception as e: err_msg = "**ERROR:{} @ {} ".format(str(e), "generate_headline") pqint(err_msg, file=sys.stderr) ret = err_msg jobj['tmplrpt'] = ret elif str(jobj['tmpltype']) == 'test' and str(jobj['action']) == 'run': optx = {'j2ts_header': jobj['tmplstr']} optx.update(jobj) try: # use 'jobj' as internal object and update jobj's key/val into **optx pqint("===username: {}, argflg: {},argstr: {}".format( username, jobj['argsflg'], jobj['argstr']), file=sys.stderr) if jobj['argsflg'] == '1' and len(jobj['argstr']) > 0: gdd = {} xstr = jobj['argstr'] exec(xstr, globals(), gdd) if 'jobj' in gdd: optx.update(gdd['jobj']) pqint("Add additional:{}".format(gdd['jobj']), file=sys.stderr) else: optx.update(gdd) pqint(gdd, file=sys.stderr) except Exception as e: pqint("**ERROR:{} @ {} ".format(str(e), "exec argstr"), file=sys.stderr) pqint(optx) ret = jj_fmt(jobj['tmplstr'], **optx) jobj['tmplrpt'] = ret # TBD: testing 'get' instead of lsi2nlg_calc() elif str(jobj['action']) == 'get': mobj = find_lsi2nlg_info(jobj=jobj) jobj.update(mobj) jobj['argsflg'] = 1 # TBD: testing 'save' instead of lsi2nlg_calc() #elif str(jobj['action']) == 'save': # mobj = write_lsi2nlg_info(jobj) # jobj['argsflg']=1 else: jobj['argstr'] = jobj['argstr'].replace("\n", '') jobj = lsi2nlg_calc(jobj) jobj['argsflg'] = 1 # run rmc with additional argstr command if str(jobj['tmpltype']) in ['eps', 'fcs', 'pppscf'] and str( jobj['action']) == 'run': if 'itnstr' in jobj: try: jobj['itnstr'] = argstr_set(gData, ['fp']) except Exception as e: pqint("**ERROR:{} @ {} ".format(str(e), "Assign Internal Variables"), file=sys.stderr) try: if 'argsflg' in jobj and int(jobj['argsflg']) == 1: jobj['tmplrpt'] = argstr_tmplrpt( jobj['tmplstr'], gData, jobj['itnstr'], jobj['argstr'].replace("\n", '')) except Exception as e: pqint("**ERROR:{} @ {} ".format(str(e), "Apply Additional Variables"), file=sys.stderr) jobj["retcode"] = str(e) jobj["lastmod"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") jstr = json.dumps(jobj) return jstr
shortName='Company', fiftyTwoWeekRange='Range52Week', changePercent='dayChg%', change='Chg', pbdt='pubDate')) df = mediaD.merge(quoD, on='ticker') #- remove no-quote rows # ,how='left') df.dropna(subset=['marketCap'], inplace=True) df['buyChg%'] = (df['closePrice'] / df['buyPrice'].astype(float) - 1) * 100 colX = [ 'ticker', 'buyCount', 'buyDate', 'marketCap', 'buyPrice', 'closePrice', 'buyChg%', 'dayChg%', 'EPS', 'Company', 'Range52Week', 'pbdate', 'pubDate', 'sector', 'industry' ] #df=subDict(df,colX) print(" --media DF:\n{}".format(df), file=sys.stderr) zpk = optx.pop('zpk', {'ticker'}) upsert_mdb(df, dbname=dbname, tablename=tablename, zpk=zpk) sys.stderr.write(" --DF:\n{}\n".format(df.head().to_string(index=False))) return df if __name__ == '__main__': #start=int(dt2ymd(next_date(weeks=-6))) #df = create_theme_media(debugTF=True,start=start) start = int(dt2ymd(next_date(months=-7, day=31))) df = create_topic_theme_media(debugTF=True, start=start) colx = ['ticker', 'rrt', 'end', 'Company', 'pbdate', 'buyCount'] #print(subDict(df,colx).sort_values(['buyCount'],ascending=False),file=sys.stderr)