def generate_comment_footer_cn(f, ts=None, dotSign='.', prcn=0, usdSign='$', udfLst=None, lang="cn", mp3YN=False): """ macro market comment required required ts fields: currency,indicator,rate,mkt1,mkt2 """ if ts is None: return None for (ky, va) in f.iteritems(): exec("{}=va".format(ky)) mkt1NTrendWd = udfStr(mkt1NChg, udf=udfLst, zs=0.0001, lang=lang) rateNTrendWd = udfStr(rate1NChg, udf=udfLst, zs=0.0001, lang=lang) rhoWd = udfStr(rho, ["正", "負", "獨立不存在"], 0.05, lang=lang) rateIfWd = udfStr(rate1NChg, udf=udfLst, zs=0.0001, lang=lang) mkt1IfWd = udfStr(rho * rate1NChg, udf=udfLst, zs=0.000001, lang=lang) if rho * rate1NChg * mkt1NChg < 0: macro1Adv = ",可能不如原始預期,必須持續觀察利率走向。" else: macro1Adv = ",更勝於原有預期。" if abs(rho * rate1NChg) <= 0.000001: macro1Adv = '' dux = locals() #ret=ts.format(**dux) ret = jj_fmt(ts, dux) return (ret)
def generate_comment_footer_en(f, ts=None, dotSign='.', prcn=0, usdSign='$', udfLst=None, lang="en", mp3YN=False): """ macro market comment required required ts fields: currency,indicator,rate,mkt1,mkt2 """ if ts is None: return None for (ky, va) in f.iteritems(): exec("{}=va".format(ky)) mkt1NTrendWd = udfStr(mkt1NChg, ["an increase", "a decrease", "no change in"], 0.0001) rateNTrendWd = udfStr(rate1NChg, ["a rise", "a fall", "no change in"], 0.0001) rhoWd = udfStr(rho, ["positively", "negatively", "almost not"], 0.05) rateIfWd = udfStr(rate1NChg, ["goes up", "goes down", "stays flat"], 0.0001) mkt1IfWd = udfStr(rho * rate1NChg, ["rise", "fall", "stay flat"], 0.000001) if rho * rate1NChg * mkt1NChg < 0: macro1Adv = 'against our original forecast' else: macro1Adv = 'even more' if mkt1IfWd == "stay flat": macro1Adv = '' dux = locals() #ret=ts.format(**dux) ret = jj_fmt(ts, dux) return (ret)
def dataj2ts(ts, df, opts=None): from _alan_str import jj_fmt import ast dd = subDict(opts, ['j2ts'], reverseTF=True) if df.size > 0 and ts is not None and len(ts) > 1: dd = update(f=df) return jj_fmt(ts, dd) else: return ''
def dat2rptTxt(ts='',dd={},lang='cn',mp3YN=False,ctrlSTRUCT=None,debugTF=False,_pn_={},**optx): rptTxt='' try: if ctrlSTRUCT is not None and ctrlSTRUCT in ['include','extends']: ts='{{% {} "{}" %}}'.format(ctrlSTRUCT,ts) rptTxt = jj_fmt(ts,dd,lang=lang,mp3YN=mp3YN,_pn_=_pn_,**optx) sys.stderr.write("=====dat2rptTxt: {}\n{}\n".format(rptTxt,optx) ) except Exception as e: sys.stderr.write("**ERROR: {} @ {}\n".format(str(e),'dat2rptTxt') ) return rptTxt
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 run_j2ts(optGet={}, optPost={}): pqint(optGet, optPost, file=sys.stderr) dd = {} if optPost is not None: dd.update(optPost) if optGet is not None: dd.update(optGet) if 'j2ts' in dd: j2ts = dd['j2ts'] dd = subDict(dd, ['j2ts'], reverseTF=True) else: j2ts = 'Usage of /?key1=value1&key2=value2 ...' return jj_fmt(j2ts, dd, j2onlyTF=True)
def argstr_tmplrpt(tmplstr, dux, *_xargs_): """ Update list of [_xargs_] command scripts to dict [dux] and then apply [dux] to jinja2 template [tmplstr] and produce [tmplrpt] return text output [tmplrpt] """ try: duy = combine_cmd2dict(*_xargs_) # TBD:,_xdu_=dux) if duy: dux.update(duy) #dux.update({'udfStr':udfStr,'roundUSD':roundUSD}) tmplrpt = jj_fmt(tmplstr, dux) except Exception as e: tmplrpt = str(e) return tmplrpt
def intraday_briefing(args=[], region='US', lang='cn', dirname='templates/', outdir="US/mp3_hourly/", dbname='ara', start=None, mp3YN=False, archiveTest=False, saveDB=True, **optx): if 'tablename' not in locals() or tablename is None: tablename = 'mkt_briefing' from headline_calc import headline_calc if 'cdt' not in optx: cdt = datetime.datetime.now() else: cdt = optx['cdt'] if isinstance(cdt, str): cdt = pd.Timestamp(cdt) hm = int(cdt.strftime("%H00")) end_hm = np.clip(hm, 900, 1600) end_hm = get_cutoff_hm(hm=int(hm), region=region) dd = headline_calc(eqtLst=None, np=3) ts = "{% include 'intraday_briefing.j2' %}" ret = jj_fmt(ts, dd=dd, dirname=dirname, outdir=outdir, end_hm=end_hm, **optx) title = 'intraday_briefing' category = 'IntraDay' dd = dict(comment=ret, pbdt=cdt, title=title, hhmm=hm, category=category) if saveDB: clientM = None mobj, clientM, _ = write2mdb(dd, clientM, dbname=dbname, tablename=tablename, zpk=['hhmm', 'category']) #tablename= tablename+'_hist' #mobj, clientM, _ = write2mdb(dd,clientM,dbname=dbname,tablename=tablename,zpk=['pbdt','category']) return ret
def generate_comment_header_en(f, ts=None, dotSign='.', prcn=0, usdSign='$', udfLst=None, lang="en", mp3YN=False): """ macro1 market comment required ts fields: currency1,indicator1,rate1,mkt1,mkt2 """ if ts is None: return None for (ky, va) in f.iteritems(): exec("{}=va".format(ky)) if 'macro1XChg' not in f: macro1XChg = 0 macro1Vntdate = 20180101 #xsign = 1 if currency1Ticker[-2:] == "US" else -1 xsign = -1 # cn version always use EURO direction currency1XTrendWd = udfStr(xsign * currency1XChg, ["depreciated", "appreciated", "stayed flat"], 0.0001, lang=lang) indicator1XTrendWd = udfStr(indicator1XChg, udf=udfLst, zs=0.0001, lang=lang) rate1XTrendWd = udfStr(rate1XChg, udf=udfLst, zs=0.0001, lang=lang) commodity1XTrendWd = udfStr(commodity1XChg, udf=udfLst, zs=0.0001, lang=lang) currency2XTrendWd = udfStr(xsign * currency2XChg, ["depreciated", "appreciated", "stayed flat"], 0.0001, lang=lang) indicator2XTrendWd = udfStr(indicator2XChg, udf=udfLst, zs=0.0001, lang=lang) rate2XTrendWd = udfStr(rate2XChg, udf=udfLst, zs=0.0001, lang=lang) commodity2XTrendWd = udfStr(commodity2XChg, udf=udfLst, zs=0.0001, lang=lang) mkt1XTrendWd = udfStr(mkt1XChg, udf=udfLst, zs=0.0001, lang=lang) mkt2XTrendWd = udfStr(mkt2XChg, udf=udfLst, zs=0.0001, lang=lang) vntDateWd = ymd2md(str(macro1Vntdate), ym="%B %d", lang=lang) if 'macro1Vntdate' in f else "" unitStr = fq2unit_str(macro1Mfreq, lang) if 'macro1Mfreq' in f else "month" pastTrendWd = udfStr(macro1XChg, udfLst, 0.0001, lang=lang) mkt0Label = mkt0Label[:mkt0Label.find('Index')] (currency1Adv, currency2Adv) = ( 'and', 'also') if currency1XChg * currency2XChg >= 0 else ('', 'yet') (indicator1Adv, indicator2Adv, indicator12Adv) = ( 'and', 'also', 'positively correlated') if indicator1XChg * indicator2XChg > 0 else ( '', 'however', 'negatively correlated') (rate1Adv, rate2Adv) = ('', 'also') if rate1XChg * rate2XChg >= 0 else ('', 'yet') (commodity1Adv, commodity2Adv, commodity12Adv) = ( 'and', 'also', 'positively correlated') if commodity1XChg * commodity2XChg >= 0 else ( '', 'however', 'negatively correlated') (mkt1Adv, mkt2Adv) = ('', 'also') if mkt1XChg * mkt2XChg >= 0 else ('', 'yet') (macro1Adv, macro11Adv) = ('', 'also') if mkt1XChg * mkt2XChg >= 0 else ('but', '') dux = locals() #ret=ts.format(**dux) ret = jj_fmt(ts, dux) return (ret)
closing_price = roundUSD(hh['actual'][-1], 2) print >> sys.stderr, hh.head() #print >> sys.stderr, zh #print >> sys.stderr, xh ts_intraday = """ 昨天{{label}}開盤小幅{{intra1_udf}},早盤{{intra1_udf}}後{{intra2_udf}} 。 基本上在中午{{noon_str}}以前呈現{{noon_udf}}狀態。 {% if end1_sign<0 %} 臨近尾盤時,由{{end2_udf}}轉為{{end1_udf}},收{{closing_price}} 。{{region_index}}集體{{index_trend}},{{sector}}翻{{sector_color}}收了個{{sector_trend}}。 {% else %} 尾盤仍是{{end1_udf}},收{{closing_price}} 。 {% endif %} {%if index_trend %} {{region_index}}集體{{index_trend}},{{sector}}{{xzWd}}收了個{{sector_trend}}終場。 {% endif %} """ label = ticker region_index = '美股大盤' sector = '科技類股' dux = locals() ret = jj_fmt(ts_intraday, dux) #ret.replace('\n',' ') print >> sys.stderr, dux print ret hf, hg, hh = mainTest(ticker=ticker, date=date, debugTF=debugTF, scroll=scroll, ax_text=ret)
def titlehead_backtest(opts={}, **optx): import pandas as pd from _alan_calc import sqlQuery, pull_stock_data as psd from _alan_str import jj_fmt dirname, lang, mp3YN = getKeyVal(optx, ['dirname', 'lang', 'mp3YN'], ['templates', 'cn', False]) nlookback = getKeyVal(optx, 'nlookback', 1) days = getKeyVal(optx, 'days', 3700) searchDB = getKeyVal(optx, 'searchDB', True) debugTF = getKeyVal(optx, 'debugTF', False) dbname = optx.pop('dbname', 'ara') tablename = optx.pop('tablename', None) dLst = optx.pop('args', None) if dLst is None or len(dLst) < 1: dLst = sqlQuery( "SELECT * FROM mapping_series_label WHERE freq='D' and category_label_seq>0" ) else: dLst = sqlQuery( "SELECT * FROM mapping_series_label WHERE freq='D' and category_label_seq>0 and series in ('{}')" .format("','".join(dLst))) ds = [] for lkbx in range(nlookback): dm = [] for jx in range(len(dLst)): ticker, freq, src, label_cn, category_cn = dLst[[ 'series', 'freq', 'source', 'label_cn', 'category_cn' ]].iloc[jx] if freq != 'D': continue df = psd(ticker, days=days, src=src, debugTF=debugTF, pchgTF=True, searchDB=searchDB) try: dx = df.iloc[:-lkbx] if lkbx > 0 else df ret = recordHiLo2(dx, ticker=ticker) if len(ret['YTD']) > 0: dd = dLst.iloc[jx].to_dict() dd.update(ret['YTD']) cmt = jj_fmt('headtitle3_cn.j2', lang=lang, mp3YN=False, dirname=dirname, ctrlSTRUCT='include', **dd) mp3cmt = jj_fmt('headtitle3_cn.j2', lang=lang, mp3YN=True, dirname=dirname, ctrlSTRUCT='include', **dd) dd.pop('_id', None) dd['ticker'] = ticker dd['pbdate'] = dd['endDT'] dd['comment'] = cmt dd['mp3comment'] = mp3cmt emsg = "{}\n".format((jx, category_cn, freq, ticker, src, label_cn, dd['fqWd'], dd['endDT'])) sys.stderr.write(emsg) dm.append(dd) if debugTF: sys.stderr.write("RUNNING {}:{}:{}\n{}\n".format( lkbx, jx, ticker, ret)) except Exception as e: sys.stderr.write("**ERROR:{}:{}:{}\n".format( jx, ticker, str(e))) continue if len(dm) < 1: continue dm = pd.DataFrame(dm) ds = dm.sort_values(by=['days', 'category_seq', 'category_label_seq'], ascending=[False, True, True]) if tablename is not None: zpk = {"ticker", "pbdate"} sys.stderr.write("Save to {}:\n{}\n".format(tablename, dm)) mobj, clientM, msg = upsert_mdb(dm, tablename=tablename, dbname=dbname, zpk=zpk) return ds
def run_api(jobj, engine=None): pd.options.display.float_format = '{:,.2f}'.format sty = "<style>.dataframe {text-align:right;}</style>\n" ret = """Usage of: <H3> ?topic='TOPIC' </H3> Where <PRE> TOPIC = [ipo|theme|priceRange|top10|utdEarningsList|mongo_search|file|write2file|test] """ topic = getKeyVal(jobj, 'topic', '').lower() if topic is None: return ret if topic == 'theme': subtopic = getKeyVal(jobj, 'subtopic', 'majorplayer') if topic == 'theme' and subtopic in ['majorplayer', 'media', 'ipo']: jobj.update(subtopic=subtopic) return run_topic_theme(dfTF=False, **jobj) elif topic == 'pricerange': xqTmp = '''select * from (select ticker,close as price,"trailingPE" as "peRatio","marketCap"::float/1000000 as "marketCapMM","changePercent" as "change%%",change from yh_quote_curr where close>={} and close<={}) as a, (select ticker,company_cn,company,sector_cn from mapping_ticker_cik where act_code>0) as b where a.ticker=b.ticker order by price''' try: vr = jobj['range'].split(",") if 'range' in jobj else [60, 70] if len(vr) >= 2: vr = np.array(vr, dtype=float) lb, ub = (vr.min(), vr.max()) xqr = xqTmp.format(lb, ub) df = sqlQuery(xqr) pd.options.display.float_format = '{:,.2f}'.format cfm = {'marketCapMM': "{:,.0f}".format} ret = df.to_html(formatters=cfm) return sty + ret except Exception as e: pqint(str(e)) return str(e) elif topic == 'top10': return run_top10(jobj, engine=None) elif topic in ['utd_earnings_list', 'utdearningslist']: from utd_earnings_list import utd_earnings_list dd = dict(sector='Technology', pbdate='20190101') dd.update(subDict(jobj, ['sector', 'pbdate'])) df = utd_earnings_list(**dd).sort_values(by=['pbdate', 'marketCap'], ascending=[False, False]) df.rename(columns={'quarter': 'epochs'}, inplace=True) cfm = { 'marketCap': "{:,.0f}".format, 'recdate': "{:.0f}".format, 'epochs': "{:.0f}".format } ret = df.to_html(formatters=cfm) return sty + ret elif topic in ['daily_med', 'dailymed']: from dailyMed_api import drug2labelInfo as dli try: dd = dli(jobj['drug_name']) except Exception as e: sys.stderr.write("**ERROR:{}\n".format(str(e))) return (str(e)) #return dd ts = """{{drug_name}} <P> {{ sec_cn|join('</P><P>\n') }} </P> """ return jj_fmt(ts, **dd) elif topic == 'mongo_search': d = dict(dbname='ara', tablename='lsi2nlg', username='******', field='tmplname', ticker='AAPL') if len(jobj) > 0: d.update(jobj) findDct = {'username': d.get('username')} fieldLst = d.get('field').split(',') fieldDct = {x: 1 for x in fieldLst} xg, _, _ = find_mdb(dbname=d['dbname'], tablename=d['tablename'], jobj=findDct, field=fieldDct) return xg elif topic == 'file': try: dirname = jobj[ 'dirname'] if 'dirname' in jobj else "/apps/fafa/pyx/tst" if 'j2name' in jobj: fname = "{}/{}".format(dirname, jobj['j2name']) ret = open(fname).read() elif 'image' in jobj: fname = "{}/{}".format(dirname, jobj['image']) ret = open(fname).read() except Exception as e: sys.stderr.write("**ERROR:{}".format(str(e))) elif topic == 'write2file': # save 'j2name' to 'dirName' pqint(jobj) try: dirName = "/apps/fafa/pyx/flask/rmc/templates" if 'j2name' in jobj and 'j2ts' in jobj: if 'dirname' in jobj: dirName = jobj['dirname'] fname = "{}/{}".format(dirName, jobj['j2name']) fp = open(fname, 'w+') fp.write(jobj['j2ts']) fp.close() pqint("===Save {} To {}".format(jobj['j2ts'], fname)) ret = "Successfully save to {}".format(fname) except Exception as e: sys.stderr.write("**ERROR:{}".format(str(e))) ret = str(e) elif topic == 'test': if 'tmplrpt' in jobj: ret = jobj['tmplrpt'] return ret
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
return dd def find_hiloRecord(ticker='^GSPC', end=None, days=366, debugTF=False): #from record_hilo import find_record_hilo as frh from record_hilo import recordHiLo as frh from _alan_calc import pull_stock_data as psd df = psd(ticker, end=end, days=days, pchgTF=True) endDT = df.index[-1] jobj = frh(df, endDT, ticker, debugTF=debugTF) hiloRecord = jobj['YTD'] if jobj['YTD'] else {} return (hiloRecord) import numpy as np import datetime if __name__ == '__main__': from _alan_str import jj_fmt cdt = datetime.datetime.now() hm = int(cdt.strftime("%H00")) end_hm = np.clip(hm, 900, 1600) dd = headline_calc() sys.stderr.write("{},{}\n".format(end_hm, dd)) print( jj_fmt("{% include 'intraday_headline_cn.j2' %}", dd, dirname='templates/', outdir="US/mp3_hourly/", end_hm=end_hm)) #print(jj_fmt("{% include 'intraday_briefing_cn.j2' %}",dirname='templates/',outdir="US/mp3_hourly/",end_hm=end_hm,**dd) )
def generate_comment_header_cn(f, ts=None, dotSign='.', prcn=0, usdSign='$', udfLst=None, lang="cn", mp3YN=False): """ macro1 market comment required ts fields: currency1,indicator1,rate1,mkt1,mkt2 """ if ts is None: return None for (ky, va) in f.iteritems(): exec("{}=va".format(ky)) if 'macro1XChg' not in f: macro1XChg = 0 macro1Vntdate = 20180101 #xsign = 1 if currency1Ticker[-2:] == "US" else -1 xsign = -1 # cn version always use EURO direction currency1XTrendWd = udfStr(xsign * currency1XChg, ["貶值", "升值", "持平"], 0.0001, lang=lang) indicator1XTrendWd = udfStr(indicator1XChg, udf=udfLst, zs=0.0001, lang=lang) rate1XTrendWd = udfStr(rate1XChg, udf=udfLst, zs=0.0001, lang=lang) commodity1XTrendWd = udfStr(commodity1XChg, udf=udfLst, zs=0.0001, lang=lang) currency2XTrendWd = udfStr(xsign * currency2XChg, ["貶值", "升值", "持平"], 0.0001, lang=lang) indicator2XTrendWd = udfStr(indicator2XChg, udf=udfLst, zs=0.0001, lang=lang) rate2XTrendWd = udfStr(rate2XChg, udf=udfLst, zs=0.0001, lang=lang) commodity2XTrendWd = udfStr(commodity2XChg, udf=udfLst, zs=0.0001, lang=lang) mkt1XTrendWd = udfStr(mkt1XChg, udf=udfLst, zs=0.0001, lang=lang) mkt2XTrendWd = udfStr(mkt2XChg, udf=udfLst, zs=0.0001, lang=lang) vntDateWd = ymd2md(str(macro1Vntdate), ym="%B %d", lang=lang) if 'macro1Vntdate' in f else "" unitStr = fq2unit_str(macro1Mfreq, lang) if 'macro1Mfreq' in f else "月" pastTrendWd = udfStr(macro1XChg, udfLst, 0.0001, lang=lang) mkt0Label = mkt0Label[:mkt0Label.find('指數基金')] (currency1Adv, currency2Adv) = ('同時', '也在') if currency1XChg * currency2XChg >= 0 else ('然而', '卻在') (indicator1Adv, indicator2Adv, indicator12Adv) = ( '並且', '也在', '正相關') if indicator1XChg * indicator2XChg > 0 else ('然而', '卻在', '負相關') (rate1Adv, rate2Adv) = ('', '也在') if rate1XChg * rate2XChg >= 0 else ('可是', '卻在') (commodity1Adv, commodity2Adv, commodity12Adv) = ( '並且', '也在', '正相關') if commodity1XChg * commodity2XChg >= 0 else ('然而', '卻在', '負相關') (mkt1Adv, mkt2Adv) = ('', '也正') if mkt1XChg * mkt2XChg >= 0 else ('但是', '卻正') (macro1Adv, macro11Adv) = ('', '也正') if mkt1XChg * mkt2XChg >= 0 else ('但是', '卻正') dux = locals() #ret=ts.format(**dux) ret = jj_fmt(ts, dux) return (ret)
def run_lsi_mkt(tkLst=[], opts=None, optx=None): """ Create market commentary based on macro list """ if opts is None: (opts, _) = opt_lsi_mkt([]) if optx is not None: opts.update(optx) #for ky,va in opts.items(): # exec("{}=va".format(ky)) debugTF, lang, j2ts_header, dbname = getKeyVal( opts, ['debugTF', 'lang', 'j2ts_header', 'dbname'], [False, None, None, 'ara']) mp3YN, mp3Make, region, dirname = getKeyVal( opts, ['mp3YN', 'mp3Make', 'region', 'dirname'], ['False', 'False', 'en', './']) if debugTF is True: print("OPTS:\n{}".format(opts), file=sys.stderr) if lang == "en": ts_title = '{currDateWd} Market Closing Report: brought to you by Beyondbond.' headerAddiClause = "{{macro1Label}} published at {{vntDateWd}}, {{pastTrendWd}} from last {{unitStr}}. " ts_header = """{{indicator1Label}} {{indicator1XTrendWd}}, while the {{currency1Label}} {{currency1XTrendWd}} against the US dollar, {{macro1Adv}} the {{rate1Label}} {{macro11Adv}} {{rate1XTrendWd}}. In the stock market, {{mkt1Label}} {{mkt1XTrendWd}}, while the {{mkt2Label}} {{mkt2Adv}} {{mkt2XTrendWd}}. Our AI recommended sector is {{mkt0Label}}. Now, here is our exclusive AICaas market updates and forecasts. """ ts_footer = """Finally, our forecast calls for {mkt1NTrendWd} {mkt1Label} and {rateNTrendWd} {rate1Label} next week. As these two are {rhoWd} correlated, if the {rate1Label} {rateIfWd} further, then the {mkt1Label} is likely to {mkt1IfWd} {macro1Adv}.""" ts_disclaim = """This electronic message is our opinion only and is not intended to be an investment advise.""" ts_stock = ts_indicator = ts_currency = ts_rate = ts_macro = None else: ts_title = '智能伏羲 {currDateWd} 晨間大盤走勢快報:今日值得觀察國際金融走勢如下\n' headerAddiClause = "{macro1Label}在{vntDateWd}公佈,比前一{unitStr}{pastTrendWd} 。" ts_header = """在股市中,隨者{mkt1Label}的{mkt1XTrendWd},{mkt1Adv}{mkt2Label}{mkt2Adv}{mkt2XTrendWd}。 {indicator1Label}在日前{indicator1XTrendWd},{indicator1Adv}{indicator2Label}{indicator2Adv}{indicator2XTrendWd}。 {currency1Label}{currency1XTrendWd},{currency1Adv}{currency2Label}{currency2Adv}{currency2XTrendWd}。 與此同時,{rate1Label}處於{rate1XTrendWd}狀態,{rate1Adv}{rate2Label}{rate2Adv}{rate2XTrendWd}。 有關大宗商品{commodity1Label}和{commodity2Label}基本上呈現{commodity12Adv}的趨勢。 {commodity1Label}目前{commodity1XTrendWd},{commodity1Adv}{commodity2Label}{commodity2Adv}{commodity2XTrendWd}。 依據本週走勢分析,智能伏羲 AI推薦的產業為{mkt0Label} 。 接下來是我們獨家智能伏羲有關市場更新和預測。""" ts_footer = """最後我們總結一下下週預測, {mkt1Label}預期{mkt1NTrendWd},{rate1Label}預期{rateNTrendWd}。由於這兩者呈{rhoWd} 相關關係,如果{rate1Label}價格進一步 {rateIfWd},那麼,{mkt1Label}可能會{mkt1IfWd}{macro1Adv}""" ts_disclaim = "\n以上名單,是經由國際金融中選出重要指標。此一名單,並不代表本公司的任何持有部位,謝謝您的收聽。" ts_stock = "{label}在前一個交易日{xdTrendWd} {xdChgWd},收盤價為{price}元。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" ts_indicator = "{label}在前個一交易日{xdTrendWd} {xdChgWd},目前為{price} 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" #ts_stock="{label}在前一{unitStr}{pastTrendWd} {xwChgWd},收盤價為{price}元{xdTrendWd}{xdChgWd} 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" #ts_indicator="{label}在前一{unitStr}{pastTrendWd} {xwChgWd},目前為{price} {xdTrendWd}{xdChgWd}。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" #ts_stock="{label}在前一{unitStr}{pastTrendWd} {xwChgWd},目前收盤價{price}元 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" #ts_indicator="{label}在前一{unitStr}{pastTrendWd} {xwChgWd},目前為{price} 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" ts_currency = "{label}在前一{unitStr}{pastTrendWd} {xwBpsWd}分,目前為{price} 。其{pastTrendWd}{movingWd}部分{cmpWd} 過去一年歷史波動率{sigmaWd}。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" ts_rate = "{label}在前一{unitStr}{pastTrendWd} {xwBpsWd}基本點,目前為{price} 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" ts_macro = "{label}在{vntDateWd}公佈,比前一{unitStr}{pastTrendWd} {xwDifWd},目前為{price} 。依據{label}波動狀況,預估下一{unitStr}有七成可能{rangeWd}。{posPbWd}" if j2ts_header is not None and len(j2ts_header) > 10: ts_header = j2ts_header for x in [z for z in opts if 'j2name_' == z[:7]]: if x[-6:] == 'footer': ts_footer = readfile_j2name(opts[x], ts_footer) elif x[-6:] == 'header': ts_header = readfile_j2name(opts[x], ts_header) elif x[-5:] == 'title': ts_title = readfile_j2name(opts[x], ts_title) f = {} comment_content = '' vcmt = [] # list of each comment tkLst = [] # list of tickers ct_ts = { "stock": ts_stock, "macro": ts_macro, "rate": ts_rate, "currency": ts_currency, "indicator": ts_indicator } cmt_temp = "SELECT cmt_temp_{} FROM mapping_cmt_temp WHERE category='{}' and cmt_type='{}' AND sub_id={}" # collect stock part (dm, datax, pgDB) = get_index_list(idxLst=None, pgDB=None, dbname=dbname, lang=lang) currdate = dm[0]['pbdate'] for j, xd in enumerate(dm): ky = xd['category'].split()[-1] sqx = cmt_temp.format(lang, ky, "mkt", j % 3) ts_cmt = get_ts_cmt(sqx, ts_rate, pgDB=pgDB, dbname=dbname) #ts_cmt = ct_ts[ky] if ky in ct_ts else ts_rate xcmt, tkS = create_stock_comment(f, j, xd, ts_cmt, pgDB=pgDB, lang=lang, mp3YN=mp3YN, ctky=ky) tkLst += tkS vcmt.append(xcmt) comment_content = "\n".join([comment_content, xcmt]) f['rho'] = -0.333333 f['macroXChg'] = 0 # collect macro part by category (dm, df, pgDB) = get_macro_list(currdate=currdate, pgDB=pgDB, dbname=dbname, lang=lang, debugTF=debugTF) flgAddi = 0 for k, xm in enumerate(dm): for j, xd in enumerate(xm): ky = xd['category'].split()[-1] sqx = cmt_temp.format(lang, ky, "mkt", 2) ts_cmt = get_ts_cmt(sqx, ts_rate, pgDB=pgDB, dbname=dbname, debugTF=debugTF) #ts_cmt = ct_ts[ky] if ky in ct_ts else ts_rate xcmt, flgAddi, tkS = create_macro_comment(f, j + 1, xd, ts_cmt, flgAddi, pgDB=pgDB, lang=lang, mp3YN=mp3YN, debugTF=debugTF) tkLst += tkS vcmt.append(xcmt) comment_content = "\n".join([comment_content, xcmt]) f['inflation_expectation'] = df.query( "freq=='W' & ticker=='T5YIFR'")['prc_cur'].iloc[0] try: f['rate10y3m_dif'] = df.query( "freq=='W' & ticker=='DGS10'")['prc_cur'].iloc[0] - df.query( "freq=='W' & ticker=='DGS3MO'")['prc_cur'].iloc[0] except: f['rate10y3m_dif'] = 0 #if flgAddi>0: # ts_header = headerAddiClause + ts_header currDateWd = ymd2md(currdate, ym="%B %d", ymd="%Y%m%d", lang=lang) comment_header = generate_cmt(f, ts=ts_header, lang=lang, funcname="generate_comment_header", mp3YN=mp3YN) comment_footer = generate_cmt(f, ts=ts_footer, lang=lang, funcname="generate_comment_footer", mp3YN=mp3YN) comment_title = jj_fmt(ts_title, dict(currDateWd=currDateWd)) comment_disclaim = ts_disclaim vcmt = [comment_title, comment_header ] + vcmt + [comment_footer, comment_disclaim] tcmt = prn_mkt_cmt(vcmt, region, lang, mp3YN, mp3Make, dirname) tkLst = ["','".join(tkLst[:3])] * 2 + tkLst open("mktCmt_US.list", "w").write("\n".join(tkLst)) return "\n".join(vcmt)
def daily_briefing(start=None, region='US', dirname='templates/', outdir="US/mp3_hourly/", dbname='ara', saveDB=True, **optx): from headline_writer import generate_headline if 'cdt' not in optx: cdt = datetime.datetime.now() else: cdt = optx['cdt'] if isinstance(cdt, str): cdt = pd.Timestamp(cdt) if start is None: start = cdt.strftime('%Y%m%d') sys.stderr(" --cdt:{}, start:{}\n".format(cdt, start)) opts = { 'lang': 'cn', 'dirname': 'templates', 'end': None, 'nlookback': 1, 'args': [], 'sep': '|', 'debugTF': False, 'hostname': 'localhost', 'tablename': None, 'days': 730, 'saveDB': True, 'extraJS': None, 'j2ts': '{% include "daily_briefing_cn.j2" %}', 'onTheFly': True, 'output': None, 'narg': 0, 'filename': None, 'extraQS': None, 'dbname': 'ara', 'mp3YN': False } del optx['args'] hm = int(cdt.strftime("%H00")) # NOTE: sensative to crontab timing issue hm = get_cutoff_hm(hm=int(hm), region=region) if hm < 1600: start = sqlQuery( "select pbdate from prc_hist where name='AAPL' ORDER BY pbdate DESC limit 1" ).iloc[0].values[0] start = int(start) category = 'SoD' else: category = 'EoD' if not os.path.exists(outdir): outdir = './' #ret=generate_headline(opts,start=start,outdir=outdir,category=category,rpt_time=cdt,**optx) ret = jj_fmt(opts['j2ts'], dirname=dirname, start=start, outdir=outdir, rpt_time=cdt, category=category) if 'tablename' not in locals() or tablename is None: tablename = 'mkt_briefing' title = '{}_briefing'.format(category) dd = dict(comment=ret, pbdt=cdt, title=title, hhmm=hm, category=category, rpt_time=cdt) if saveDB: clientM = None mobj, clientM, _ = write2mdb(dd, clientM, dbname=dbname, tablename=tablename, zpk=['hhmm', 'category']) tablename = tablename + '_hist' mobj, clientM, _ = write2mdb(dd, clientM, dbname=dbname, tablename=tablename, zpk=['pbdt', 'category']) return ret