def get_moneyflow_by_code(code):

    passage = ""
    code = code.lstrip("0")
    rdicts = []

    for desc in DATE_DESCS:
        try:
            rdicts.append(search_stock(code, file_util.load_obj(desc)))
        except:
            passage = "Moneyflow data not found!"
            return passage
    #print(rdicts)
    if (rdicts[0] and rdicts[1] and rdicts[2] and rdicts[3]):
        r1 = rdicts[0][0]
        r3 = rdicts[1][0]
        r7 = rdicts[2][0]
        r14 = rdicts[3][0]
        #r30 = rdicts[4][0]

        passage = "<b>" + code.zfill(5) + ".HK - " + stock_db.get_stock_name(
            code) + "</b> (" + stock_db.get_stock_industry(code) + ")" + DEL
        passage = passage + "Shares (Latest): " + stock_util.rf2s(
            int(r1['shs'])) + " / " + r1['percentage'] + EL
        passage = passage + "Shares (3 Days): " + stock_util.rf2s(
            int(r3['shs'])) + " / " + r3['percentage'] + EL
        passage = passage + "Shares (7 Days): " + stock_util.rf2s(
            int(r7['shs'])) + " / " + r7['percentage'] + EL
        passage = passage + "Shares (14 Days): " + stock_util.rf2s(
            int(r14['shs'])) + " / " + r14['percentage'] + EL
        #passage = passage + "Shares (30 Days): " + r30['shs'] + "/" + r30['percentage'] + EL

        passage = passage + EL
        passage = passage + "Growth (3 Days): " + stock_util.rfDeltaPercentage(
            r1['shs'], r3['shs']) + EL
        passage = passage + "Growth (7 Days): " + stock_util.rfDeltaPercentage(
            r1['shs'], r7['shs']) + EL
        passage = passage + "Growth (14 Days): " + stock_util.rfDeltaPercentage(
            r1['shs'], r14['shs']) + EL

        passage = passage + EL
        passage = passage + "Q: /qQ" + code + " C: /qd" + code + " N: /qn" + code + DEL
        passage = passage + "Last Updated: " + r1['date'] + EL
    else:
        passage = "No Moneyflow data found for " + code
        return passage

    if (passage):
        passage = "<i>Southbound Moneyflow Trend for %s.HK</i>" % code.zfill(
            5) + DEL + passage
        return passage
Example #2
0
def get_us_stock_quote(code):

    code = code.upper().strip()
    url = "https://api.iextrading.com/1.0/stock/market/batch?symbols=%s&types=quote,stats" % code

    print("URL: [" + url + "]")
    quote_result = {}

    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

    r = requests.get(url, headers=headers)
    jsondata = r.text 
    data = json.loads(jsondata)
    #print(data)
    
    if (not code in data):
        return quote_result
        
    quote_obj = data[code]["quote"]
    stats_obj = data[code]["stats"]

    name = quote_obj["companyName"]

    if quote_obj["low"] == None: quote_obj["low"] = 0
    if quote_obj["high"] == None: quote_obj["high"] = 0
   
    l_range = str("%.2f - %.2f " % (quote_obj["low"], quote_obj["high"]))
    l_open = quote_obj["open"] if quote_obj["open"] else 0
    l_close = quote_obj["iexRealtimePrice"] if quote_obj["iexRealtimePrice"] else 0
    
    if (l_close == 0 ):
        l_close = quote_obj["close"] if quote_obj["close"] else 0

    if (quote_obj["latestUpdate"]): 
        last_update = str(datetime.fromtimestamp(quote_obj["latestUpdate"]/1000.0).strftime('%Y-%m-%d %H:%M:%S'))
    else:
        last_update = None

    change_val = quote_obj["change"] if quote_obj["change"] else 0
    quote_obj["changePercent"] = quote_obj["changePercent"] if quote_obj["changePercent"] else 0
 
    if quote_obj["changePercent"]:
        change_pct = ("%.2f" % (quote_obj["changePercent"]*100)) + "%"
    else:
        change_pct = 0

    volume = str(quote_obj["latestVolume"])
    mean_vol = str(quote_obj["avgTotalVolume"])

    if (mean_vol):
        f_vol_now = stock_util.rf(volume)
        f_vol_avg = stock_util.rf(mean_vol)
        quote_result["V2V"] = 0
        
        if float(f_vol_avg) > 0:
            quote_result["V2V"] = "%.2f" % (float(f_vol_now) / float(f_vol_avg))

    if ("0.00" in volume):
        turnover = "N/A"
        quote_result["Volume"] = volume
        quote_result["Turnover"] = turnover
    else:
        turnover = "%.2f" % (float(volume) * float(l_close))
        quote_result["Volume"] = stock_util.rf2s(float(volume.strip("\r\n")))
        quote_result["Turnover"] = stock_util.rf2s(float(turnover))

    mkt_cap = stock_util.rf2s(quote_obj["marketCap"])
    pe_ratio = quote_obj["peRatio"]
    
    wk_low = quote_obj["week52Low"]
    wk_high = quote_obj["week52High"]

    dividend = stats_obj["dividendRate"]
    _yield = stats_obj["dividendYield"]
    
    #print("div %s, yield %s" % (dividend, _yield))

    eps = stats_obj["ttmEPS"]
    shares = stats_obj["sharesOutstanding"]
    beta = stats_obj["beta"]
        
    quote_result["CodeName"] = name
    quote_result["Close"] = l_close
    quote_result["ChangeVal"] = change_val
    quote_result["ChangePercent"] = change_pct

    if (quote_result["ChangeVal"] < 0):
        quote_result["Direction"] = "DOWN"
    elif (quote_result["ChangeVal"] == 0):
        quote_result["Direction"] = "NONE"
    else:
        quote_result["Direction"] = "UP"
        quote_result["ChangeVal"] = "+" + str(quote_result["ChangeVal"])
        quote_result["ChangePercent"] = "+" + str(quote_result["ChangePercent"])
    
    quote_result["MktCap"] = mkt_cap

    quote_result["Range"] = l_range

    quote_result["Open"] = l_open

    quote_result["LastUpdate"] = last_update

    quote_result["PE"] = pe_ratio
    
    if (_yield):
        quote_result["Yield"] = _yield
    if (dividend):
        quote_result["DivRatio"] = dividend
    quote_result["EPS"] = eps
    quote_result["Shares"] = shares
    quote_result["Beta"] = beta

    quote_result["52WeekLow"] = wk_low
    quote_result["52WeekHigh"] = wk_high
   
    return quote_result
Example #3
0
def generate(region="HK"):

    locale.setlocale(locale.LC_ALL, '')
    now = datetime.datetime.now()

    if (region == "US"):
        stocks = stock_us_mag8_db.get_full_stocks_by_vol()
    else:
        stocks = stock_mag8_db.get_full_stocks_by_vol()

    html = """<html>
    <head>
        <meta charset="UTF-8">
        <title>V-8 Report</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

        <style>

            .table-condensed, .row {
                font-size: 11px;
            }
            
            .overlay {
                position: fixed;
                display: none;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: rgba(0,0,0,0.5);
                z-index: 2;
                cursor: pointer;
            }

            #text{
                position: absolute;
                top: 50%;
                left: 50%;
                font-size: 50px;
                color: white;
                transform: translate(-50%,-50%);
                -ms-transform: translate(-50%,-50%);
            }
            
        </style>
    </head>
    <body>"""

    html = html + """<div class="container-fluid">
    <h3><img height="40" src="http://www.really-learn-english.com/image-files/xletter-v.jpg.pagespeed.ic.Z99fucjP4w.jpg"/>V-8 Report</h3>
    <p style="font-size: 11px">TO: 0m+ / MktCap: 0B+<small> (Last updated: """ + now.strftime(
        "%Y-%m-%d %H:%M") + """)</small></p>
        """

    stk_html = """<table class="table table-striped table-bordered table-hover table-condensed">
            <tr>
                <th>Code</th><th>Name</th><th>LC</th><th>LPC</th>
                <th>V/AV</th><th>NAV</th><th>PE</th><th>YIELD</th>
                <th>1mΔ%</th><th>3mΔ%</th><th>1yΔ%</th><th>1mRS%</th>
                <th>3mRS%</th><th>1yRS%</th><th>MktCap</th><th>52WkL</th>
                <th>52WkH</th><th>3mVol</th><th>ma30</th>
                <th>ma50</th><th>ma150</th><th>ma200</th>
            </tr>

                """

    for stock in stocks:
        print(stock["CODE"] + " - " + str(stock["LAST_CLOSE"]) + " - " +
              str(stock["_52WEEK_HIGH"]))
        if (stock["_52WEEK_HIGH"]
                and stock["LAST_CLOSE"] > stock["_52WEEK_HIGH"]):
            img_sup = "<img src='http://images.emojiterra.com/emojione/v2/512px/1f525.png' width='15' style='vertical-align: top'/>"
        else:
            img_sup = ""

        if (region == "US"):
            surl = "https://finance.google.com/finance?q="
            sector = stock["INDUSTRY_LV1"]
            industry = stock["INDUSTRY_LV2"]
        else:
            sector = stock["INDUSTRY_LV2"]
            industry = stock["INDUSTRY_LV3"]
            surl = "http://aastocks.com/tc/stocks/analysis/company-fundamental/?symbol="

        name_text = "<a href='" + surl + stock[
            "CODE"] + "' target='_blank'>" + stock[
                "stockname"] + "</a>" + img_sup + " (" + sector + ">" + industry + ")"

        lcp = stock["LAST_CHANGE_PCT"]
        lvr = stock["LAST_VOL_RATIO"]

        vol_ratio = "-"
        style_bg = ""

        if (lvr):
            if (float(lvr) > 5):
                style_bg = "background-color: yellow;"
            elif (float(lvr) > 1.5):
                style_bg = "background-color: LawnGreen;"
            elif (float(lvr) > 1.0):
                style_bg = "background-color: PowderBlue;"

            vol_ratio = "x" + "%.1f" % (lvr)

        row_text = ""
        style_bg = ""

        if (region == "US"):
            nav = "N/A"
        else:
            nav = su.rfNum(stock["NAV"], 2)

        try:
            row_text = """<tr style='""" + style_bg + """'>
                      <td><a href="/streaming.html?code=%s" target="_blank">%s</a></td>
                      <td class='text-nowrap'>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td>
                  </tr>""" % (
                stock["CODE"], stock["CODE"], name_text, stock["LAST_CLOSE"],
                fpct(lcp), vol_ratio, nav, stock["PE"], stock["YIELD"],
                fnum(stock["_1MONTH_CHANGE"]), fnum(
                    stock["_3MONTH_CHANGE"]), fnum(stock["_52WEEK_CHANGE"]),
                fnum(stock["_1MONTH_HSI_RELATIVE"]),
                fnum(stock["_3MONTH_HSI_RELATIVE"]),
                fnum(stock["_52WEEK_HSI_RELATIVE"]),
                su.rf2s(stock["MARKET_CAPITAL"]), stock["_52WEEK_LOW"],
                stock["_52WEEK_HIGH"], su.rf2s(stock["_3MONTH_AVG_VOL"]),
                su.rfNum(stock["_30_DAY_MA"],
                         2), su.rfNum(stock["_50_DAY_MA"],
                                      2), su.rfNum(stock["_150_DAY_MA"], 2),
                su.rfNum(stock["_200_DAY_MA"], 2))

        except:
            logging.error(" Error generating html")
            logging.error(traceback.format_exc())

        stk_html = stk_html + row_text

    stk_html = stk_html + """</table>"""
    html = html + stk_html
    html = html + """</div>"""
    html = html + """</body></html>"""
    #print(html)
    print("Generating Report ...")
    #print(html)
    soup = BeautifulSoup(html, "html.parser")

    reg = ""

    if (region == "US"):
        reg = "_us"

    text_file = open("/var/www/eggyolk.tech/html/screener%s.html" % reg, "w")
    text_file.write(soup.prettify())
    text_file.close()
Example #4
0
def generate(region="HK"):

    locale.setlocale(locale.LC_ALL, '')
    now = datetime.datetime.now()

    if (region == "US"):
        stock_us_mag8_db.update_mag8_stocks_entry()
        stocks = stock_us_mag8_db.get_mag8_stocks()
        #stocks_dict = stock_us_mag8_db.get_mag8_stocks_dict(100)
        #print(stocks)
        #print(stocks_dict)

    else:
        stock_mag8_db.update_mag8_stocks_entry()
        stocks = stock_mag8_db.get_mag8_stocks()
        #stocks_dict = stock_mag8_db.get_mag8_stocks_dict(100)

    html = """<html>
    <head>
        <meta charset="UTF-8">
        <title>Gen-Y Sector Screener</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="https://rawgithub.com/padolsey/jQuery-Plugins/master/sortElements/jquery.sortElements.js"></script>  

        <style>

            .table-condensed, .row {
                font-size: 11px;
            }
            
            .flink {
                 cursor: pointer;
                 color: #337ab7;
                 text-decoration: underline;
            }
            
            .overlay {
                position: fixed;
                display: none;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: rgba(0,0,0,0.5);
                z-index: 2;
                cursor: pointer;
            }

            #text{
                position: absolute;
                top: 50%;
                left: 50%;
                font-size: 50px;
                color: white;
                transform: translate(-50%,-50%);
                -ms-transform: translate(-50%,-50%);
            }
            
        </style>
        <script>
   
          $(document).ready(function() {
            var table = $('table');
            
            $('#1_header, #2_header, #2a_header, #3_header, #4_header, #4a_header, #5_header, #6_header, #7_header, #8_header, #9_header, #10_header, #11_header, #12_header, #13_header, #14_header, #15_header, #17_header, #18_header, #19_header, #20_header, #21_header, #22_header, #23_header')
                .wrapInner('<span title="Sort this column"/>')
                .each(function(){
                    
                    var th = $(this),
                        thIndex = th.index(),
                        inverse = false;
                    
                    th.click(function(){
                        
                        table.find('td').filter(function(){
                            
                            return $(this).index() === thIndex;
                            
                        }).sortElements(function(a, b){
    
                            if( $.text([a]) == $.text([b]) )
                                return 0;
                            if(isNaN($.text([a])) && isNaN($.text([b]))){
                            
                                if (($.text([a]).includes('/') && $.text([b]).includes('/')) 
                                    || ($.text([a]).includes('(') && $.text([b]).includes('('))
                                    || ($.text([a]).includes('d') && $.text([b]).includes('d'))) {
                                
                                    //alert("[" + $.text([a]).split('/')[0].split('(')[0].replace("d", "").replace(/^\s+|\s+$/g, '') + "]")                 
                                    ta = $.text([a]).split('/')[0].split('(')[0].replace("d", "").replace("-", "0").replace(/^\s+|\s+$/g, '')
                                    tb = $.text([b]).split('/')[0].split('(')[0].replace("d", "").replace("-", "0").replace(/^\s+|\s+$/g, '')
                                
                                    return parseFloat(ta) > parseFloat(tb) ? 
                                        inverse ? -1 : 1
                                        : inverse ? 1 : -1;
                                } 

                                if (($.text([a]).includes('M') && $.text([b]).includes('M')) 
                                    || ($.text([a]).includes('B') && $.text([b]).includes('B'))) {
                                
                                    ta = $.text([a]).replace("M", "").replace("B", "").replace("None", "0").replace(/^\s+|\s+$/g, '')
                                    tb = $.text([b]).replace("M", "").replace("B", "").replace("None", "0").replace(/^\s+|\s+$/g, '')
                                    //alert("[" + ta + ", " + tb + "]")
                                    return parseInt(ta) > parseInt(tb) ? 
                                        inverse ? -1 : 1
                                        : inverse ? 1 : -1;
                                } 
                                
                                return $.text([a]) > $.text([b]) ? 
                                   inverse ? -1 : 1
                                   : inverse ? 1 : -1;
                            }
                            else{
                                return parseFloat($.text([a])) > parseFloat($.text([b])) ? 
                                  inverse ? -1 : 1
                                  : inverse ? 1 : -1;
                            }
                            
                        }, function(){
                            
                            // parentNode is the element we want to move
                            return this.parentNode; 
                            
                        });
                        
                        inverse = !inverse;
                            
                    });
                        
                });   
          });
          
        </script>         
    </head>
    <body>"""

    html = html + """<div class="container-fluid">
    <h3><img height="40" src="https://www.ytravelblog.com/wp-content/themes/ytravelblog/images/favicon.ico"/>Gen-Y Sector Screener</h3>
    <p style="font-size: 11px">TO: 1.5m+ / MktCap: 0B+<small> (Last updated: """ + now.strftime(
        "%Y-%m-%d %H:%M") + """)</small></p>
        """

    stk_html = """<table class="table table-striped table-bordered table-hover table-condensed">
            <tr class="flink">
                <th id="1_header">Code</th><th id="2_header">Name</th><th id="2a_header">Sector</th><th id="3_header">Last Close</th>
                <th id="4_header">V/AV</th> <th id="4a_header">RoC</th><th id="6_header">PE</th>
                <th id="8_header">1mC%</th><th id="9_header">3mC%</th><th id="10_header">1yC%</th><th id="11_header">1mRS%</th>
                <th id="12_header">3mRS%</th><th id="13_header">1yRS%</th><th id="14_header">MktCap</th><th id="15_header">52WkLH</th>
                <th id="17_header">3mVol</th><!--th id="18_header">ma30</th>
                <th id="19_header">ma50</th><th id="20_header">ma150</th><th id="21_header">ma200</th--><th id="22_header">macd Xup</th><th id="23_header">since</th>
            </tr>

                """

    for stock in stocks:

        #print(stock["_52WEEK_HIGH"])
        if (stock["_52WEEK_HIGH"]
                and (stock["LAST_CLOSE"] > stock["_52WEEK_HIGH"])):
            img_sup = "<img src='http://images.emojiterra.com/emojione/v2/512px/1f525.png' width='15' style='vertical-align: top'/>"
        else:
            img_sup = ""

        if (region == "US"):
            surl = "http://money.cnn.com/quote/profile/profile.html?symb="
        else:
            surl = "http://aastocks.com/tc/stocks/analysis/company-fundamental/?symbol="
        if (options.is_option_code(stock["CODE"])):
            img_option = "<img src='https://33qpzx1dk8tt1qlds735ez93-wpengine.netdna-ssl.com/wp-content/uploads/2016/10/op-256x256.png' width='15' style='vertical-align: top'/>"
        else:
            img_option = ""

        if (region == "US"):
            stock["stockname"] = " ".join(stock["stockname"].split()[:2])

        name_text = "<a href='" + surl + stock[
            "CODE"] + "' target='_blank'>" + stock[
                "stockname"] + "</a>" + img_sup + img_option

        lcp = stock["LAST_CHANGE_PCT"]
        lvr = stock["LAST_VOL_RATIO"]

        vol_ratio = "-"
        style_bg = ""

        if (lvr):
            if (float(lvr) > 5):
                style_bg = "background-color: yellow;"
            elif (float(lvr) > 1.5):
                style_bg = "background-color: LawnGreen;"
            elif (float(lvr) > 1.0):
                style_bg = ""
                #style_bg = "background-color: PowderBlue;"

        vol_ratio = "x" + "%.1f" % (lvr)

        macd_text = "-"
        macd_div = stock["MACD_DIVERGENCE"]

        if (macd_div):
            macd_div = fnum(macd_div, "3")
        else:
            macd_div = "-"

        if (region == "US" and stock["MARKET_CAPITAL"] == 0):
            continue
        elif (region == "US"):
            stock["MKT_CAP"] = stock["MARKET_CAPITAL"]

        if (stock["MACD_X_OVER_DATE"]
                and not stock["MACD_X_OVER_DATE"] == "-"):
            macd_text = fdaysago(
                stock["MACD_X_OVER_DATE"]) + " (" + macd_div + ")"
        else:
            macd_text = macd_text + " (" + macd_div + ")"
        print("making row for code[%s]" % stock["CODE"] + "/" +
              str(stock["MKT_CAP"]))
        row_text = """<tr style='""" + style_bg + """'>
                      <td><a name='%s'/><a href="/streaming.html?code=%s" target="_blank">%s</a></td>
                      <td class='text-nowrap'>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><!--td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td--><td>%s</td><td>%s</td>
                  </tr>""" % (
            stock["CODE"], stock["CODE"],
            stock["CODE"], name_text, stock["INDUSTRY_LV2"],
            str(stock["LAST_CLOSE"]) + " /" + fpct(lcp).strip(), vol_ratio,
            "%.2f" % stock["Y8_ROC_MARK"], stock["PE"],
            fnum(stock["_1MONTH_CHANGE"]), fnum(stock["_3MONTH_CHANGE"]),
            fnum(stock["_52WEEK_CHANGE"]), fnum(stock["_1MONTH_HSI_RELATIVE"]),
            fnum(stock["_3MONTH_HSI_RELATIVE"]),
            fnum(stock["_52WEEK_HSI_RELATIVE"]), su.rf2s(stock["MKT_CAP"]),
            str(stock["_52WEEK_LOW"]) + " - " + str(stock["_52WEEK_HIGH"]),
            su.rf2s(stock["_3MONTH_AVG_VOL"]), su.rfNum(
                stock["_30_DAY_MA"], 2), su.rfNum(stock["_50_DAY_MA"], 2),
            su.rfNum(stock["_150_DAY_MA"], 2), su.rfNum(
                stock["_200_DAY_MA"],
                2), macd_text, fdaysago(stock["Y8_ENTRY_DATE"]))

        #su.rfNum(stock["_30_DAY_MA"], 2), su.rfNum(stock["_50_DAY_MA"], 2),
        #su.rfNum(stock["_150_DAY_MA"], 2), su.rfNum(stock["_200_DAY_MA"], 2),

        stk_html = stk_html + row_text

    stk_html = stk_html + """</table>"""
    html = html + stk_html
    html = html + """</div>"""
    html = html + """</body></html>"""

    print("Generating Report ...")
    #print(html)
    soup = BeautifulSoup(html, "html.parser")

    reg = ""
    if (region == "US"):
        reg = "_us"

    text_file = open("/var/www/eggyolk.tech/html/y8%s.html" % reg, "w")
    text_file.write(soup.prettify())
    text_file.close()

    text_file = open("/var/www/eggyolk.tech/html/sector%s.html" % reg, "w")
    text_file.write(soup.prettify())
    text_file.close()
def generate():

    locale.setlocale(locale.LC_ALL, '')
    now = datetime.datetime.now()

    industries = stock_us_sector_db.get_hot_industries(period)
    y8_dict = stock_us_mag8_db.get_mag8_stocks_dict(100)

    html = """<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="refresh" content="300">        
        <title>Sector Heatmap</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script>
            
            $(document).ready(function(){
            
                if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
                    $("div[class='col-sm-3']").toggleClass('col-sm-3 col-sm-6');
                }
            });
            
            function on(layer) {
                document.getElementById("overlay" + layer).style.display = "block";
            }

        </script>

        <style>

            .table-condensed, .row {
                font-size: 11px;
            }
            
            .overlay {
                position: fixed;
                display: none;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: rgba(0,0,0,0.5);
                z-index: 2;
                cursor: pointer;
            }

            #text{
                position: absolute;
                top: 50%;
                left: 50%;
                font-size: 50px;
                color: white;
                transform: translate(-50%,-50%);
                -ms-transform: translate(-50%,-50%);
            }
            
        </style>
    </head>
    <body>"""

    html = html + """<div class="container-fluid">
    <h3><img height="40" src="https://s.w.org/images/core/emoji/2.3/svg/1f413.svg"/>Sector Heatmap</h3>
    <p style="font-size: 11px"><small> (Last updated: """ + now.strftime(
        "%Y-%m-%d %H:%M") + """)</small></p>
        """
    num_rows = math.ceil(len(industries) / 4)

    for i in range(0, num_rows):
        html = html + """<div class="row">"""

        for j in range(0, 4):
            if (i * 4 + j < len(industries)):
                # determine background color
                bgcolor = "lavender"
                if (j % 2 == 1):
                    bgcolor = "lavenderblush"

                html = html + """<div class="col-sm-3" style="background-color:""" + bgcolor + """;">"""

                # if industry found
                if (i * 4 + j < len(industries)):
                    stocks = stock_us_sector_db.get_hot_stocks_by_industry(
                        industries[i * 4 + j], period)
                    html = html + (
                        """<h6><b><a href="#" onclick="on('%s')">%s</a></b> (%s)</h6>"""
                        % (industries[i * 4 + j], industries[i * 4 + j],
                           len(stocks)))

                    # get industry stock list
                    stk_html = """<table class="table table-striped table-bordered table-hover table-condensed">"""
                    stk_overlay_html = """<table class="table bg-info table-condensed">
                                    <tr>
                                        <th>Code</th><th>Name</th><th>LC</th><th>LPC</th>
                                        <th>V/AV</th><th>PE</th><th>YIELD</th>
                                        <th>1mΔ%</th><th>3mΔ%</th><th>1yΔ%</th><th>1mRS%</th>
                                        <th>3mRS%</th><th>1yRS%</th><th>MktCap</th><th>52WkH</th>
                                        <th>52WkLow</th><th>1mVol</th><th>3mVol</th><th>ma10</th>
                                        <th>ma50</th><th>ma90</th><th>ma250</th><th>rsi14</th>
                                    </tr>"""
                    #print(len(stock_sector_db.get_hot_stocks_by_industry(industries[i*4 + j], period)))
                    for stock in stocks:
                        #print(stock)
                        #print(stock["code"])
                        lcp = stock["LAST_CHANGE_PCT"]
                        lvr = stock["LAST_VOL_RATIO"]

                        style_bg = ""
                        vol_ratio = "-"
                        #print(lcp)
                        if (lvr):
                            if (datetime.datetime.now().hour >= 13
                                    and float(lcp.replace("%", "")) < 0
                                    and float(lvr) < 0.5):
                                style_bg = "background-color: #FFFFB2;"
                            elif (float(lcp.replace("%", "")) < -2
                                  and float(lvr) > 3):
                                style_bg = "background-color: #F1B3B3;"
                            elif (float(lcp.replace("%", "")) < -2
                                  and float(lvr) > 1):
                                style_bg = "background-color: #FEC5E5;"
                            elif (float(lvr) > 5):
                                style_bg = "background-color: GreenYellow;"
                            elif (float(lvr) > 1.5):
                                style_bg = "background-color: #66FF66;"
                            elif (float(lvr) > 1.0):
                                style_bg = "background-color: #99FF99;"

                            vol_ratio = "x" + "%.1f" % (lvr)

                        if (not stock["_52WEEK_HIGH"] == None and
                            (stock["LAST_CLOSE"] > stock["_52WEEK_HIGH"])):
                            img_sup = "<img src='http://images.emojiterra.com/emojione/v2/512px/1f525.png' width='15' style='vertical-align: top'/>"
                        else:
                            img_sup = ""

                        #if (not stock["Y8_ENTRY_DATE"] == None):
                        if (stock["code"] in y8_dict):
                            img_sup_2 = "&nbsp;<a href='./y8_us.html#%s' target='_blank' title='%s'><img src='./images/ycon.png' width='15' style='vertical-align: top' /></a>" % (
                                stock["code"], y8_dict[stock["code"]])
                        else:
                            img_sup_2 = ""

                        img_sup_3 = ""

                        name_text = "<a href='http://money.cnn.com/quote/profile/profile.html?symb=" + stock[
                            "code"] + "' target='_blank'>" + " ".join(
                                stock["name"].split()[:2]
                            ) + "</a>" + img_sup + img_sup_2 + img_sup_3
                        row_text = """<tr style='""" + style_bg + """'>
                                        <td><a href="/streaming.html?code=%s" target="_blank">%s</a></td>
                                        <td>%s</td><td>%s</td>
                                        <td>%s</td>
                                        <td>%s</td>
                                        </tr>""" % (
                            stock["code"], stock["code"], name_text,
                            stock["LAST_CLOSE"], fpct(lcp), vol_ratio)
                        stk_html = stk_html + row_text

                        row_text_overlay = """<tr style='""" + style_bg + """'>
                                        <td><a href="/streaming.html?code=%s" target="_blank">%s</a></td>
                                        <td class='text-nowrap'>%s</td><td>%s</td><td>%s</td>
                                        <td>%s</td><td>%s</td><td>%s</td>
                                        <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                                        <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                                        <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                                        <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                                        </tr>""" % (
                            stock["code"], stock["code"], " ".join(
                                stock["name"].split()[:2]),
                            stock["LAST_CLOSE"], fpct(lcp), vol_ratio,
                            stock["PE"], stock["YIELD"],
                            fnum(stock["_1MONTH_CHANGE"]),
                            fnum(stock["_3MONTH_CHANGE"]),
                            fnum(stock["_52WEEK_CHANGE"]),
                            fnum(stock["_1MONTH_HSI_RELATIVE"]),
                            fnum(stock["_3MONTH_HSI_RELATIVE"]),
                            fnum(stock["_52WEEK_HSI_RELATIVE"]),
                            su.rf2s(stock["MARKET_CAPITAL"]),
                            stock["_52WEEK_HIGH"], stock["_52WEEK_LOW"],
                            su.rf2s(stock["_1MONTH_AVG_VOL"]),
                            su.rf2s(stock["_3MONTH_AVG_VOL"]),
                            fnum(stock["_10_DAY_MA"]), fnum(
                                stock["_50_DAY_MA"]), fnum(
                                    stock["_90_DAY_MA"]),
                            fnum(stock["_250_DAY_MA"]), stock["_14_DAY_RSI"])

                        stk_overlay_html = stk_overlay_html + row_text_overlay

                    stk_html = stk_html + """</table>"""
                    stk_overlay_html = stk_overlay_html + """</table>"""
                    html = html + stk_html + """<div id="%s" class="overlay" onclick="javascript: this.style.display = 'none'"><div id="text">""" % (
                        "overlay" + industries[i * 4 + j]
                    ) + stk_overlay_html + """</div></div>"""

                html = html + """</div>"""

        html = html + """</div>"""

    html = html + """</div>"""
    html = html + """</body></html>"""

    print("Generating Report ...")
    #print(html)
    soup = BeautifulSoup(html, "html.parser")

    text_file = open("/var/www/eggyolk.tech/html/heatmap_us.html", "w")
    text_file.write(soup.prettify())
    text_file.close()
def get_jp_stock_quote(code):

    code = code.upper().strip()
    url = "https://quotes.wsj.com/JP/%s" % code

    print("URL: [" + url + "]")
    quote_result = {}

    headers = {
        'User-Agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
    }

    r = requests.get(url, headers=headers)
    html = r.text
    soup = BeautifulSoup(html, "html.parser")

    nameSpan = soup.find('span', {"class": "companyName"})

    if (not nameSpan):
        return quote_result

    infoUl = soup.findAll('ul', {"class": "cr_data_collection"})[0]
    cDataUl = soup.findAll('ul', {"class": "cr_data_collection"})[1]

    name = nameSpan.text
    l_range = infoUl.findAll('li', {"class": "cr_data_row"})[2].find(
        'span', {
            "class": "data_data"
        }).text.replace(",", "")
    l_open = cDataUl.findAll('span',
                             {"class": "data_data"})[0].text.replace(",", "")
    l_close = str(
        soup.find('span', {
            "class": "cr_curr_price"
        }).text.replace(",", "").replace("¥", ""))

    last_update = soup.find('li', {"class": "crinfo_time"}).text.strip()

    change_val = soup.find('span', {"class": "diff_price"}).text
    change_pct = soup.find('span', {"class": "diff_percent"}).text

    volume = infoUl.findAll('li', {"class": "cr_data_row"})[0].find(
        'span', {
            "class": "data_data"
        }).text.replace(",", "")
    mean_vol = infoUl.findAll('li', {"class": "cr_data_row"})[1].find(
        'span', {
            "class": "data_data"
        }).text.replace(",", "")

    if (mean_vol):
        f_vol_now = stock_util.rf(volume)
        f_vol_avg = stock_util.rf(mean_vol)
        quote_result["V2V"] = "%.2f" % (float(f_vol_now) / float(f_vol_avg))

    if ("0" == volume):
        turnover = "N/A"
        quote_result["Volume"] = volume
        quote_result["Turnover"] = turnover
    else:
        turnover = "%.2f" % (float(volume) * float(l_close))
        quote_result["Volume"] = stock_util.rf2s(float(volume.strip("\r\n")))
        quote_result["Turnover"] = stock_util.rf2s(float(turnover))

    keyDataUl = soup.find('div', {
        "class": "cr_keystock_drawer"
    }).findAll("ul", {"class": "cr_data_collection"})[0]

    mkt_cap = str(
        keyDataUl.findAll("li", {"class": "cr_data_row"})[2].find("span").text)
    pe_ratio = str(
        keyDataUl.findAll("li", {"class": "cr_data_row"})[0].find("span").text)

    range52 = infoUl.findAll('li', {"class": "cr_data_row"})[3].find(
        'span', {
            "class": "data_data"
        }).text.replace(",", "")
    wk_low = range52.split("-")[0].strip()
    wk_high = range52.split("-")[1].strip()

    _yield = str(
        keyDataUl.findAll("li", {"class": "cr_data_row"})[5].find("span").text)

    #print("div %s, yield %s" % (dividend, _yield))

    eps = str(
        keyDataUl.findAll(
            "li",
            {"class": "cr_data_row"})[1].find("span").text.replace(",",
                                                                   "").strip())
    shares = str(
        keyDataUl.findAll(
            "li",
            {"class": "cr_data_row"})[3].find("span").text.replace(",", ""))

    quote_result["CodeName"] = name
    quote_result["Close"] = l_close
    quote_result["ChangeVal"] = change_val
    quote_result["ChangePercent"] = change_pct

    if ("-" in quote_result["ChangeVal"]):
        quote_result["Direction"] = "DOWN"
    elif (quote_result["ChangeVal"] == "0"):
        quote_result["Direction"] = "NONE"
    else:
        quote_result["Direction"] = "UP"
        quote_result["ChangeVal"] = "+" + quote_result["ChangeVal"]
        quote_result["ChangePercent"] = "+" + quote_result["ChangePercent"]

    quote_result["MktCap"] = mkt_cap

    quote_result["Range"] = l_range

    quote_result["Open"] = l_open

    quote_result["LastUpdate"] = last_update

    quote_result["PE"] = pe_ratio

    if (_yield):
        quote_result["Yield"] = _yield
    quote_result["EPS"] = eps
    quote_result["Shares"] = shares

    quote_result["52WeekLow"] = wk_low
    quote_result["52WeekHigh"] = wk_high

    return quote_result
Example #7
0
def get_us_stock_quote(code):

    url = "https://finance.google.com/finance?q=" + code

    #print("URL: [" + url + "]")
    quote_result = {}

    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

    r = requests.get(url, headers=headers)
    html = r.text 
    #print(html)
    soup = BeautifulSoup(html, "html.parser")
    
    div = soup.find("div", {"class": "appbar"})

    if (not div):
        return quote_result

    appdiv = soup.find("div", {"class": "appbar-snippet-primary"})

    if (not appdiv):
        return quote_result

    name = appdiv.text
    price_panel = soup.find("div", {"id": "price-panel"})
    snap_table = soup.findAll("table", {"class": "snap-data"})[0]
    snap_rows = snap_table.findAll("tr")
    l_range = snap_rows[0].findAll("td")[1].text.strip()
    l_open = snap_rows[2].findAll("td")[1].text.strip()
    l_close = price_panel.find("span", {"class": "pr"}).text.strip()

    if price_panel.find("span", {"class": "nwp"}): 
        last_update = price_panel.find("span", {"class": "nwp"}).text
    else:
        last_update = "N/A"
    #print(price_panel)
    change_info = price_panel.find("div", {"class": "id-price-change"}).text.strip()

    if change_info:
        change_val = change_info.split("(")[0].strip()
        change_pct = change_info.split("(")[1].replace(")","").strip()
    else:
        change_val = "0.00"
        change_pct = "0.00%"

    volume = snap_rows[3].findAll("td")[1].text.split("/")[0].replace(",","")
    if (len(snap_rows[3].findAll("td")[1].text.split("/")) > 1):
        mean_vol = snap_rows[3].findAll("td")[1].text.split("/")[1]
    else:
        mean_vol = None 

    if (mean_vol):
        f_vol_now = stock_util.rf(volume)
        f_vol_avg = stock_util.rf(mean_vol)
        quote_result["V2V"] = "%.2f" % (float(f_vol_now) / float(f_vol_avg))

    l_close = l_close.replace(",","").strip('\n')
 
    if ("0.00" in volume):
        turnover = "N/A"
        quote_result["Volume"] = volume.strip("\r\n")
        quote_result["Turnover"] = turnover
    elif (not stock_util.is_number(volume) and not stock_util.is_float(volume)): 
        volume = volume.strip()
        #print("[" + volume + "]")
        #print("[" + volume.strip()[:-1] + "]")
        turnover = "%.2f" % (float(volume[:-1]) * float(l_close)) + volume[-1]
        quote_result["Volume"] = volume.strip("\r\n")
        quote_result["Turnover"] = turnover
    else:
        turnover = "%.2f" % (float(volume) * float(l_close))
        quote_result["Volume"] = stock_util.rf2s(float(volume.strip("\r\n")))
        quote_result["Turnover"] = stock_util.rf2s(float(turnover))

    mkt_cap = snap_rows[4].findAll("td")[1].text.split("/")[0]
    pe_ratio = snap_rows[5].findAll("td")[1].text.split("/")[0]
    
    wk_low = snap_rows[1].findAll("td")[1].text.split("-")[0]
    wk_high = snap_rows[1].findAll("td")[1].text.split("-")[1]
    
    snap_table = soup.findAll("table", {"class": "snap-data"})[1]
    snap_rows = snap_table.findAll("tr")


    if (snap_rows[0].findAll("td")[1].text.strip() == "-"):
        dividend = None
        _yield = None
    elif (len(snap_rows[0].findAll("td")[1].text.split("/")) > 1):
        dividend = snap_rows[0].findAll("td")[1].text.split("/")[0]
        _yield = snap_rows[0].findAll("td")[1].text.split("/")[1]
    else:
        dividend = snap_rows[0].findAll("td")[1].text.split("/")[0]
        _yield = None 

    eps = snap_rows[1].findAll("td")[1].text.strip()
    shares = snap_rows[2].findAll("td")[1].text.strip()
    beta = snap_rows[3].findAll("td")[1].text.strip()
    inst_own = snap_rows[4].findAll("td")[1].text.strip()
    
    quote_result["CodeName"] = name.strip("\r\n")
    quote_result["Close"] = l_close.strip("\r\n")
    quote_result["ChangeVal"] = change_val.strip("\r\n")
    quote_result["ChangePercent"] = change_pct.strip("\r\n")

    if ("+" in quote_result["ChangeVal"]):
        quote_result["Direction"] = "UP"
    elif ("-" in quote_result["ChangeVal"]):
        quote_result["Direction"] = "DOWN"
    else:
        quote_result["Direction"] = "NONE"

    quote_result["MktCap"] = mkt_cap.strip("\r\n")

    quote_result["Range"] = l_range.strip("\r\n")

    quote_result["Open"] = l_open.strip("\r\n")

    quote_result["LastUpdate"] = last_update.replace("Real-time:","").strip("\r").strip("\n")

    quote_result["PE"] = pe_ratio.strip("\r\n")
    
    if (_yield):
        quote_result["Yield"] = _yield.strip("\r\n")
    if (dividend):
        quote_result["DivRatio"] = dividend.strip("\r\n")
    quote_result["EPS"] = eps.strip("\r\n")
    quote_result["Shares"] = shares.strip("\r\n")
    quote_result["Beta"] = beta.strip("\r\n")

    quote_result["52WeekLow"] = wk_low.strip()
    quote_result["52WeekHigh"] = wk_high.strip()
   
    return quote_result
Example #8
0
def get_hk_stock_quote(code):

    code = code.zfill(5)
    durl = "http://money18.on.cc/js/daily/hk/quote/%s_d.js" % code
    rurl = "http://money18.on.cc/js/real/quote/%s_r.js" % code

    #print(durl)
    #print(rurl)

    #print("Code: [" + code + "]")
    quote_result = {}

    headers = {
        'User-Agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
    }

    try:
        r = requests.get(durl, headers=headers, timeout=5)
    except requests.exceptions.Timeout:
        # retry once more
        r = requests.get(durl, headers=headers, timeout=5)

    r.encoding = "big5hkscs"
    html = r.text

    dd = rd = {}

    if ("DOCTYPE" in html):
        return quote_result
    else:
        s = html.split("=")[1]
        dd = demjson.decode(s)
        #print(dd)

    try:
        r = requests.get(rurl, headers=headers, timeout=5)
    except requests.exceptions.Timeout:
        # retry once more
        r = requests.get(rurl, headers=headers, timeout=5)

    r.encoding = "big5hkscs"
    html = r.text
    if ("DOCTYPE" in html):
        return quote_result
    else:
        s = html.split("=")[1].replace(";", "")
        rd = demjson.decode(s)
        #print(rd)

    # both daily dict and real time dict exists
    if (not dd or not rd):
        return quote_result

    name = dd['name'] + EL + dd['nameChi']
    l_range = rd['dyl'] + ' - ' + rd['dyh']
    l_open = dd['preCPrice']
    l_close = rd['ltp']

    #if float(l_close) == 0:
    l_close = rd['np']

    if "issuedShare" in dd:
        mkt_cap = float(l_close) * float(dd["issuedShare"])
        quote_result['MktCap'] = stock_util.rf2s(mkt_cap)

    last_update = rd['ltt']

    if l_open and not l_open == "null" and l_close and not float(l_close) == 0:
        change_val_f = float(l_close) - float(l_open)

        if (change_val_f > 0):
            pfx = "+"
        else:
            pfx = ""
        change_val = pfx + "%.3f" % (change_val_f)
        change_pct = pfx + ("%.3f" %
                            (change_val_f / float(l_open) * 100)) + "%"
    else:
        change_val = "0.00"
        change_pct = "0.00%"

    volume = stock_util.rf2s(float(rd['vol']))

    f_vol_now = f_vol_avg_3mth = None
    f_vol_now = float(rd['vol'])

    stk = stock_tech_db.get_stock_tech(code)
    #print(stk)
    if (stk and stk["_3MONTH_AVG_VOL"]):
        f_vol_avg_3mth = float(stk["_3MONTH_AVG_VOL"])

    if (f_vol_now and f_vol_avg_3mth):
        quote_result["V2V"] = "%.2f" % (f_vol_now / f_vol_avg_3mth)

    turnover = stock_util.rf2s(float(rd['tvr']))

    pe_ratio = mkt_cap = None

    if (stk and stk["MARKET_CAPITAL"]):
        mkt_cap = stock_util.rf2s(float(stk["MARKET_CAPITAL"]))
    if (stk and stk["PE"]):
        pe_ratio = stk["PE"]

    wk_low = dd['wk52Low']
    wk_high = dd['wk52High']

    dividend = dd['dividend']

    eps = dd['eps']

    quote_result["CodeName"] = name.strip("\r\n")
    quote_result["Close"] = l_close.strip("\r\n")
    quote_result["ChangeVal"] = str(change_val)
    quote_result["ChangePercent"] = change_pct.strip("\r\n")

    if ("+" in quote_result["ChangeVal"]):
        quote_result["Direction"] = "UP"
    elif ("-" in quote_result["ChangeVal"]):
        quote_result["Direction"] = "DOWN"
    else:
        quote_result["Direction"] = "NONE"

    quote_result["Range"] = "L/H " + l_range.strip("\r\n")

    quote_result["Open"] = l_open.strip("\r\n")
    quote_result["Volume"] = str(volume)
    quote_result["LastUpdate"] = last_update.strip("\r\n")

    quote_result["Turnover"] = str(turnover)
    quote_result["PE"] = pe_ratio

    if (dividend):
        dividend = "%.2f" % (float(dividend.strip("\r\n")) / float(l_close) *
                             100) + "%"
        quote_result["DivRatio"] = dividend.strip("\r\n")
    quote_result["EPS"] = eps

    quote_result["52WeekLow"] = wk_low.strip()
    quote_result["52WeekHigh"] = wk_high.strip()

    quote_result["LotSize"] = dd['lotSize']

    if "cbbcCPrice" in dd and not dd['cbbcCPrice'] == "0.00":
        quote_result["CallPrice"] = dd['cbbcCPrice']

    if "stkPrice" in dd and not dd['stkPrice'] == "0.00":
        quote_result["Strike"] = dd['stkPrice']

    if "usCode" in dd:
        quote_result["Underlying"] = dd['usCode']
    elif "uaCode" in dd:
        quote_result["Underlying"] = dd['uaCode']

    if "cnvRatio" in dd and not dd['cnvRatio'] == "0.000":
        quote_result["ConversionRatio"] = dd['cnvRatio']

    if "gearing" in dd and not dd['gearing'] == "0.000":
        quote_result["EffGearing"] = dd['gearing']

    if "premium" in dd and not dd['premium'] == "0.000":
        quote_result["Premium"] = dd['premium']

    if "maturity" in dd and not dd['maturity'] == "null":
        quote_result["Expiry"] = dd['maturity']

    if "relatedStock" in dd and not dd['relatedStock'] == "":
        quote_result["RelatedStock"] = "/qq" + dd['relatedStock']
        #print(quote_result["RelatedStock"])

    if "relatedSZStock" in dd and not dd['relatedSZStock'] == "":
        quote_result["RelatedSZStock"] = "/qq" + dd['relatedSZStock']

    return quote_result
Example #9
0
def generate():

    locale.setlocale(locale.LC_ALL, '')
    now = datetime.datetime.now()

    stocks = stock_mf_db.get_mf_stocks()

    html = """<html>
    <head>
        <meta charset="UTF-8">
        <title>Southbound Moneyflow Tracker</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="https://rawgithub.com/padolsey/jQuery-Plugins/master/sortElements/jquery.sortElements.js"></script>  

        <style>

            .table-condensed, .row {
                font-size: 11px;
            }
            
            .flink {
                 cursor: pointer;
                 color: #337ab7;
                 text-decoration: underline;
            }
            
            .overlay {
                position: fixed;
                display: none;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: rgba(0,0,0,0.5);
                z-index: 2;
                cursor: pointer;
            }

            #text{
                position: absolute;
                top: 50%;
                left: 50%;
                font-size: 50px;
                color: white;
                transform: translate(-50%,-50%);
                -ms-transform: translate(-50%,-50%);
            }
            
        </style>
        <script>
   
          $(document).ready(function() {
            var table = $('table');
            
            $('#1_header, #2_header, #3_header, #4_header, #4a_header, #5_header, #6_header, #7_header, #8_header, #9_header, #10_header, #11_header, #12_header, #13_header, #14_header, #15_header, #17_header, #18_header, #19_header, #20_header, #21_header, #22_header, #23_header')
                .wrapInner('<span title="Sort this column"/>')
                .each(function(){
                    
                    var th = $(this),
                        thIndex = th.index(),
                        inverse = false;
                    
                    th.click(function(){
                        
                        table.find('td').filter(function(){
                            
                            return $(this).index() === thIndex;
                            
                        }).sortElements(function(a, b){
    
                            if( $.text([a]) == $.text([b]) )
                                return 0;
                            if(isNaN($.text([a])) && isNaN($.text([b]))){
                            
                                if (($.text([a]).includes('/') && $.text([b]).includes('/')) 
                                    || ($.text([a]).includes('(') && $.text([b]).includes('('))
                                    || ($.text([a]).includes('days') && $.text([b]).includes('days'))) {
                                
                                    //alert("[" + $.text([a]).split('/')[0].split('(')[0].replace("days", "").replace(/^\s+|\s+$/g, '') + "]")                 
                                    ta = $.text([a]).split('/')[0].split('(')[0].replace("days", "").replace("-", "0").replace(/^\s+|\s+$/g, '')
                                    tb = $.text([b]).split('/')[0].split('(')[0].replace("days", "").replace("-", "0").replace(/^\s+|\s+$/g, '')
                                
                                    return parseFloat(ta) > parseFloat(tb) ? 
                                        inverse ? -1 : 1
                                        : inverse ? 1 : -1;
                                } 

                                if (($.text([a]).includes('M') && $.text([b]).includes('M')) 
                                    || ($.text([a]).includes('B') && $.text([b]).includes('B'))
                                    || ($.text([a]).includes('%') && $.text([b]).includes('%'))) {
                                
                                    ta = $.text([a]).replace("M", "").replace("B", "").replace("None", "0").replace(/^\s+|\s+$/g, '')
                                    tb = $.text([b]).replace("M", "").replace("B", "").replace("None", "0").replace(/^\s+|\s+$/g, '')
                                    tb = $.text([b]).replace("%", "").replace(/^\s+|\s+$/g, '')
                                    //alert("[" + ta + ", " + tb + "]")
                                    return parseInt(ta) > parseInt(tb) ? 
                                        inverse ? -1 : 1
                                        : inverse ? 1 : -1;
                                } 
                                
                                return $.text([a]) > $.text([b]) ? 
                                   inverse ? -1 : 1
                                   : inverse ? 1 : -1;
                            }
                            else{
                                return parseFloat($.text([a])) > parseFloat($.text([b])) ? 
                                  inverse ? -1 : 1
                                  : inverse ? 1 : -1;
                            }
                            
                        }, function(){
                            
                            // parentNode is the element we want to move
                            return this.parentNode; 
                            
                        });
                        
                        inverse = !inverse;
                            
                    });
                        
                });   
          });
          
        </script>         
    </head>
    <body>"""

    html = html + """<div class="container-fluid">
    <h3><img height="40" src="http://warrants-hk.credit-suisse.com/home/img/cn_to_hk.jpg"/>Southbound Moneyflow Track</h3>
    <p style="font-size: 11px"><small>(Last updated: """ + now.strftime(
        "%Y-%m-%d %H:%M") + """)</small></p>
        """

    stk_html = """<table class="table table-striped table-bordered table-hover table-condensed">
            <tr class="flink">
                <th id="1_header">Code</th><th id="2_header">Name</th><th id="3_header">Last Close</th>
                <th id="4_header">V/AV</th> <th id="4a_header">RoC</th><th id="6_header">PE</th>
                <th id="8_header">Shs3d%</th><th id="9_header">Shs7d%</th><th id="10_header">Shs14d%</th><th id="11_header">1mRS%</th>
                <th id="12_header">3mRS%</th><th id="13_header">1yRS%</th><th id="14_header">MktCap</th><th id="15_header">52WkLH</th>
                <th id="17_header">3mVol</th><th id="18_header">Shs</th>
                <th id="19_header">Shs3d</th><th id="20_header">Shs7d</th><th id="21_header">Shs14d</th><th id="22_header">MacdX</th><th id="23_header">Stake</th>
            </tr>

                """

    for stock in stocks:
        #print(stock["_52WEEK_HIGH"])
        if (stock["_52WEEK_HIGH"]
                and (stock["LAST_CLOSE"] > stock["_52WEEK_HIGH"])):
            img_sup = "<img src='http://images.emojiterra.com/emojione/v2/512px/1f525.png' width='15' style='vertical-align: top'/>"
        else:
            img_sup = ""

        surl = "http://aastocks.com/tc/stocks/analysis/company-fundamental/?symbol="

        name_text = "<a href='" + surl + stock[
            "CODE"] + "' target='_blank'>" + stock[
                "stockname"] + "</a>" + img_sup

        lcp = stock["LAST_CHANGE_PCT"]
        lvr = stock["LAST_VOL_RATIO"]

        vol_ratio = "-"
        style_bg = ""

        if (lvr):
            if (float(lvr) > 5):
                style_bg = "background-color: yellow;"
            elif (float(lvr) > 1.5):
                style_bg = "background-color: LawnGreen;"
            elif (float(lvr) > 1.0):
                style_bg = ""
                #style_bg = "background-color: PowderBlue;"

            vol_ratio = "x" + "%.1f" % (lvr)

        macd_text = "-"
        macd_div = stock["MACD_DIVERGENCE"]

        if (macd_div):
            macd_div = fnum(macd_div, "3")
        else:
            macd_div = "-"

        if (stock["MACD_X_OVER_DATE"]
                and not stock["MACD_X_OVER_DATE"] == "-"):
            macd_text = fdaysago(
                stock["MACD_X_OVER_DATE"]) + " (" + macd_div + ")"
        else:
            macd_text = macd_text + " (" + macd_div + ")"

        if not stock["Y8_ROC_MARK"]:
            stock["Y8_ROC_MARK"] = 0

        stockmf = mutual_market.get_moneyflow_map_by_code(
            stock["CODE"].zfill(5))
        if (not '3dshsg' in stockmf):
            print("Skipping " + stock["CODE"])
            continue
        else:
            print("Printing " + stock["CODE"])
        row_text = """<tr style='""" + style_bg + """'>
                      <td><a name='%s'/><a href="/streaming.html?code=%s" target="_blank">%s</a></td>
                      <td class='text-nowrap'>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td>
                      <td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>
                  </tr>""" % (
            stock["CODE"], stock["CODE"], stock["CODE"], name_text,
            str(stock["LAST_CLOSE"]) + " /" + fpct(lcp).strip(), vol_ratio,
            "%.2f" % stock["Y8_ROC_MARK"], stock["PE"], fnum(
                stockmf["3dshsg"]), fnum(stockmf["7dshsg"]),
            fnum(stockmf["14dshsg"]), fnum(stock["_1MONTH_HSI_RELATIVE"]),
            fnum(stock["_3MONTH_HSI_RELATIVE"]),
            fnum(stock["_52WEEK_HSI_RELATIVE"]),
            su.rf2s(stock["MARKET_CAPITAL"]),
            str(stock["_52WEEK_LOW"]) + " - " + str(stock["_52WEEK_HIGH"]),
            su.rf2s(stock["_3MONTH_AVG_VOL"]), su.rf2s(stockmf["shs"]),
            su.rf2s(stockmf["3dshs"]), su.rf2s(stockmf["7dshs"]),
            su.rf2s(stockmf["14dshs"]), macd_text, stockmf["stake"])

        stk_html = stk_html + row_text

    stk_html = stk_html + """</table>"""
    html = html + stk_html
    html = html + """</div>"""
    html = html + """</body></html>"""

    print("Generating Report ...")
    #print(html)
    soup = BeautifulSoup(html, "html.parser")

    text_file = open("/var/www/eggyolk.tech/html/moneyflow.html", "w")
    text_file.write(soup.prettify())
    text_file.close()