{"id":2367,"date":"2026-03-31T11:26:31","date_gmt":"2026-03-31T11:26:31","guid":{"rendered":"https:\/\/tetsu811.com\/?page_id=2367"},"modified":"2026-04-07T09:54:22","modified_gmt":"2026-04-07T09:54:22","slug":"ftc-converter","status":"publish","type":"page","link":"https:\/\/tetsu811.com\/ja\/ftc-converter\/","title":{"rendered":"\u53f0\u6307\u671f\u5373\u6642\u63db\u7b97"},"content":{"rendered":"<div id=\"ftcApp\" class=\"ftc-wrap\">\r\n<style>\r\n.ftc-wrap{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Noto Sans TC\",sans-serif;max-width:720px;margin:0 auto;padding:16px;color:#1a1a2e;background:#f5f6fa;border-radius:14px}\r\n.ftc-wrap *{box-sizing:border-box;margin:0;padding:0}\r\n.ftc-hdr{text-align:center;margin-bottom:10px}\r\n.ftc-hdr h2{font-size:1.35em;color:#16213e;margin-bottom:2px}\r\n.ftc-hdr .sub{font-size:.72em;color:#aaa}\r\n\r\n.ftc-bar{display:flex;justify-content:center;align-items:center;gap:14px;flex-wrap:wrap;background:linear-gradient(135deg,#0f3460,#16213e);color:#ccc;padding:9px 16px;border-radius:10px;margin-bottom:12px;font-size:.78em}\r\n.ftc-bar .dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:3px}\r\n.dot.on{background:#2ecc71;box-shadow:0 0 6px #2ecc71}.dot.off{background:#e74c3c}\r\n.ftc-bar .rv{color:#ffd700;font-weight:700;font-size:1.05em}\r\n.ftc-bar .cd{color:#a0c4ff}\r\n\r\n.ftc-err{text-align:center;padding:8px;background:#ffeaea;border-radius:8px;color:#c0392b;font-size:.82em;margin-bottom:10px;display:none}\r\n\r\n\/* \u5bcc\u53f0\u6307\u5373\u6642\u5927\u5361 *\/\r\n.ftc-hero{text-align:center;background:#fff;border-radius:12px;padding:18px 16px 14px;margin-bottom:12px;box-shadow:0 2px 10px rgba(0,0,0,.05)}\r\n.ftc-hero .lbl{font-size:.78em;color:#888;margin-bottom:2px}\r\n.ftc-hero .price{font-size:2.6em;font-weight:800;color:#16213e;line-height:1.1}\r\n.ftc-hero .chg{font-size:.92em;font-weight:600;margin-top:3px}\r\n.chg.up{color:#e74c3c}.chg.dn{color:#27ae60}.chg.fl{color:#999}\r\n.ftc-hero .ohlc{display:flex;justify-content:center;gap:14px;margin-top:8px;font-size:.72em;color:#999}\r\n\r\n\/* \u53f0\u6307\u671f\u9810\u4f30\u5361 *\/\r\n.ftc-cards{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px}\r\n@media(max-width:540px){.ftc-cards{grid-template-columns:1fr}}\r\n\r\n.ftc-card{border-radius:12px;padding:18px 14px;text-align:center;box-shadow:0 2px 10px rgba(0,0,0,.05)}\r\n.ftc-card.day{background:linear-gradient(135deg,#fffcf0,#fff0c0);border-left:5px solid #e6a817}\r\n.ftc-card.ngt{background:linear-gradient(135deg,#f0f4ff,#d4e0f7);border-left:5px solid #3a5ba0}\r\n.ftc-card .ct{font-size:.88em;font-weight:700;margin-bottom:2px}\r\n.ftc-card.day .ct{color:#b8860b}.ftc-card.ngt .ct{color:#2c4a88}\r\n.ftc-card .csub{font-size:.62em;color:#aaa;margin-bottom:10px}\r\n.ftc-card .cval{font-size:2.1em;font-weight:800;line-height:1.1}\r\n.ftc-card.day .cval{color:#c0392b}.ftc-card.ngt .cval{color:#1a3a6b}\r\n.ftc-card .cdiff{font-size:.8em;font-weight:600;margin-top:4px}\r\n.cdiff.up{color:#e74c3c}.cdiff.dn{color:#27ae60}.cdiff.fl{color:#999}\r\n.ftc-card .cref{font-size:.62em;color:#bbb;margin-top:8px;line-height:1.4}\r\n\r\n\/* \u5e95\u90e8\u8aaa\u660e *\/\r\n.ftc-foot{text-align:center;font-size:.62em;color:#bbb;margin-top:6px;line-height:1.5}\r\n<\/style>\r\n\r\n<div class=\"ftc-hdr\">\r\n    <h2>\u5bcc\u53f0\u6307 \u21c4 \u53f0\u6307\u671f \u5373\u6642\u63db\u7b97\u5668<\/h2>\r\n    <div class=\"sub\">\u5168\u81ea\u52d5 \uff5c \u6bcf 10 \u79d2\u66f4\u65b0 \uff5c \u50c5\u4f9b\u53c3\u8003<\/div>\r\n<\/div>\r\n\r\n<div class=\"ftc-bar\">\r\n    <span><span class=\"dot on\" id=\"ftcDot\"><\/span><span id=\"ftcSt\">\u9023\u7dda\u4e2d...<\/span><\/span>\r\n    <span>USD\/TWD <span class=\"rv\" id=\"ftcRate\">\u2014<\/span><\/span>\r\n    <span class=\"cd\"><span id=\"ftcCd\">10<\/span>s<\/span>\r\n    <span style=\"font-size:.72em;color:#888\" id=\"ftcTime\"><\/span>\r\n<\/div>\r\n\r\n<div class=\"ftc-err\" id=\"ftcErr\"><\/div>\r\n\r\n<div class=\"ftc-hero\">\r\n    <div class=\"lbl\">\u5bcc\u53f0\u6307 SGX FTSE Taiwan Futures<\/div>\r\n    <div class=\"price\" id=\"fP\">\u2014<\/div>\r\n    <div class=\"chg fl\" id=\"fC\"><\/div>\r\n    <div class=\"ohlc\">\r\n        <span>\u63db\u7b97\u500d\u6578 <b id=\"fRate\">\u2014<\/b><\/span>\r\n        <span>\u8cc7\u6599\u65e5\u671f <b id=\"fDate\">\u2014<\/b><\/span>\r\n    <\/div>\r\n<\/div>\r\n\r\n<div class=\"ftc-cards\">\r\n    <div class=\"ftc-card day\">\r\n        <div class=\"ct\">\u2600\ufe0f \u65e5\u76e4\u9810\u4f30<\/div>\r\n        <div class=\"csub\">\u53f0\u6307\u671f 08:45\u201313:45<\/div>\r\n        <div class=\"cval\" id=\"dV\">\u2014<\/div>\r\n        <div class=\"cdiff fl\" id=\"dD\"><\/div>\r\n        <div class=\"cref\" id=\"dRef\"><\/div>\r\n    <\/div>\r\n    <div class=\"ftc-card ngt\">\r\n        <div class=\"ct\">\ud83c\udf19 \u591c\u76e4\u9810\u4f30<\/div>\r\n        <div class=\"csub\">\u53f0\u6307\u671f 15:00\u201305:00<\/div>\r\n        <div class=\"cval\" id=\"nV\">\u2014<\/div>\r\n        <div class=\"cdiff fl\" id=\"nD\"><\/div>\r\n        <div class=\"cref\" id=\"nRef\"><\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<div class=\"ftc-foot\">\r\n    \u516c\u5f0f\uff1a\u53f0\u6307\u671f\u9810\u4f30 = \u5bcc\u53f0\u6307\u5373\u6642 \u00d7 \u63db\u7b97\u500d\u6578\uff08\u65e5\u76e4\uff09\uff1b\u591c\u76e4\u500d\u6578\u4f9d\u65e5\u591c\u76e4\u6bd4\u4f8b\u63a8\u7b97<br>\r\n    \u8cc7\u6599\uff1aGoogle Script\uff08\u5bcc\u53f0\u6307\uff09\uff5c \u81fa\u7063\u671f\u8ca8\u4ea4\u6613\u6240 OpenAPI \uff5c ExchangeRate API<br>\r\n    \u5bcc\u53f0\u6307\u53f0\u7a4d\u96fb\u6b0a\u91cd\u4e0a\u9650 20%\u3001\u53f0\u6307\u671f\u7d04 44%\uff0c\u5be6\u969b\u958b\u76e4\u53ef\u80fd\u56e0\u6b0a\u91cd\u5dee\u7570\u504f\u96e2\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<script>\r\n(function(){\r\n'use strict';\r\n\r\nvar API = \"https:\\\/\\\/tetsu811.com\\\/ja\\\/wp-json\\\/ftc\\\/v1\\\/quotes\";\r\nvar NONCE = \"67ca2ee04e\";\r\nvar SEC = 60;\r\nvar cd = SEC;\r\nvar timer = null;\r\n\r\nvar $ = function(id){ return document.getElementById(id); };\r\n\r\nfunction fmt(n, d) {\r\n    if (n == null || isNaN(n)) return '\\u2014';\r\n    return Number(n).toLocaleString(undefined, {minimumFractionDigits:d||0, maximumFractionDigits:d||0});\r\n}\r\n\r\n\/\/ convRate: \u76f4\u63a5\u4f7f\u7528 Google Script \u63d0\u4f9b\u7684\u63db\u7b97\u500d\u6578\r\n\/\/ nightConvRate: \u4f9d\u65e5\u591c\u76e4\u6bd4\u4f8b\u63a8\u7b97\r\nfunction calcCard(prefix, ftLive, convRate, txClose) {\r\n    if (convRate > 0 && ftLive > 0) {\r\n        var est     = ftLive * convRate;\r\n        var rounded = Math.round(est);\r\n        $(prefix + 'V').textContent = fmt(rounded);\r\n\r\n        var el = $(prefix + 'D');\r\n        if (txClose > 0) {\r\n            var diff = rounded - txClose;\r\n            var pct  = (diff \/ txClose * 100).toFixed(2);\r\n            if (diff > 0) {\r\n                el.textContent = '\\u25B2 ' + diff + ' \\u9EDE (+' + pct + '%)';\r\n                el.className = 'cdiff up';\r\n            } else if (diff < 0) {\r\n                el.textContent = '\\u25BC ' + Math.abs(diff) + ' \\u9EDE (' + pct + '%)';\r\n                el.className = 'cdiff dn';\r\n            } else {\r\n                el.textContent = '\\u2014 \\u6301\\u5E73';\r\n                el.className = 'cdiff fl';\r\n            }\r\n            $(prefix + 'Ref').textContent = '\\u53C3\\u8003\\u6536\\u76E4 ' + fmt(txClose) + ' \\u00D7 \\u500D\\u6578 ' + convRate.toFixed(4);\r\n        } else {\r\n            el.textContent = '';\r\n            $(prefix + 'Ref').textContent = '\\u500D\\u6578 ' + convRate.toFixed(4);\r\n        }\r\n    } else {\r\n        $(prefix + 'V').textContent = '\\u2014';\r\n        $(prefix + 'D').textContent = '';\r\n        $(prefix + 'Ref').textContent = '';\r\n    }\r\n}\r\n\r\nfunction update(data) {\r\n    $('ftcDot').className = 'dot on';\r\n    $('ftcSt').textContent = '\\u5DF2\\u9023\\u7DDA';\r\n    $('ftcErr').style.display = 'none';\r\n\r\n    if (data.usdtwd) $('ftcRate').textContent = data.usdtwd;\r\n\r\n    var ft = data.ft;\r\n    if (ft && ft.price) {\r\n        $('fP').textContent = fmt(ft.price, 2);\r\n        $('fC').textContent = '';\r\n        $('fRate').textContent = ft.conversionRate ? ft.conversionRate.toFixed(4) : '\\u2014';\r\n        $('fDate').textContent = ft.updateDate || '\\u2014';\r\n    }\r\n\r\n    var tx  = data.tx;\r\n    var ftLive   = ft ? ft.price : null;\r\n    var convRate = ft ? ft.conversionRate : null;\r\n\r\n    \/\/ \u65e5\u76e4\uff1a\u76f4\u63a5\u7528 Google Script \u7684 conversionRate\r\n    var realDayClose = (data.txLive && data.txLive.price && data.txLive.change != null) ? (parseFloat(data.txLive.price) - parseFloat(data.txLive.change)) : ((tx && tx.day) ? tx.day.last : null);\r\n    calcCard('d', ftLive, convRate, realDayClose);\r\n\r\n    \/\/ \u591c\u76e4\uff1a\u4f9d\u65e5\u591c\u76e4\u6bd4\u4f8b\u63a8\u7b97\uff08nightConvRate = convRate \u00d7 nightClose \/ dayClose\uff09\r\n    \/\/ Night ratio = TX night close \/ FT level when TX night closed (~05:00)\r\n    \/\/ Auto-captured daily at 05:00 Taiwan by WP-cron, served via data.nightFtRef\r\n    var NIGHT_FT_REF = (data && data.nightFtRef && data.nightFtRef.price) ? parseFloat(data.nightFtRef.price) : 0;\r\n    var nightConvRate = convRate;\r\n    if (NIGHT_FT_REF > 0 && tx && tx.night && tx.night.last > 0) {\r\n        nightConvRate = tx.night.last \/ NIGHT_FT_REF;\r\n    } else if (convRate && tx && tx.day && tx.day.last > 0 && tx.night && tx.night.last > 0) {\r\n        nightConvRate = convRate * tx.night.last \/ tx.day.last;\r\n    }\r\n    calcCard('n', ftLive, nightConvRate, (tx && tx.night) ? tx.night.last : null);\r\n    if (data.txLive && data.txLive.price > 0) {\r\n        var txp = parseFloat(data.txLive.price);\r\n        var txr = Math.round(txp);\r\n        var txCh = parseFloat(data.txLive.change);\r\n        var txPct = parseFloat(data.txLive.pct);\r\n        var prevClose = txp - txCh;\r\n        $('nV').textContent = fmt(txr);\r\n        var nEl = $('nD');\r\n        if (nEl && !isNaN(txCh)) {\r\n            var chRound = Math.round(txCh);\r\n            if (txCh > 0) { nEl.textContent = '\\u25B2 ' + chRound + ' (+' + txPct.toFixed(2) + '%)'; nEl.className = 'cdiff up'; }\r\n            else if (txCh < 0) { nEl.textContent = '\\u25BC ' + Math.abs(chRound) + ' (' + txPct.toFixed(2) + '%)'; nEl.className = 'cdiff dn'; }\r\n            else { nEl.textContent = '\\u2014 \\u6301\\u5E73'; nEl.className = 'cdiff fl'; }\r\n        }\r\n        var rEl = $('nRef');\r\n        if (rEl) rEl.textContent = '\\u4ECA\\u65E5\\u6536\\u76E4 ' + fmt(Math.round(prevClose)) + ' \\uFF5C cnyes \\u5373\\u6642';\r\n    }\r\n\r\n    var now = new Date();\r\n    $('ftcTime').textContent = now.toLocaleTimeString('zh-TW', {hour:'2-digit',minute:'2-digit',second:'2-digit'});\r\n}\r\n\r\nfunction fail(msg) {\r\n    $('ftcDot').className = 'dot off';\r\n    $('ftcSt').textContent = '\\u9023\\u7DDA\\u5931\\u6557';\r\n    $('ftcErr').textContent = msg;\r\n    $('ftcErr').style.display = 'block';\r\n}\r\n\r\nfunction fetchData() {\r\n    var xhr = new XMLHttpRequest();\r\n    xhr.open('GET', API);\r\n    xhr.setRequestHeader('X-WP-Nonce', NONCE);\r\n    xhr.onload = function() {\r\n        if (xhr.status === 200) {\r\n            try { update(JSON.parse(xhr.responseText)); } catch(e) { fail('JSON \\u89E3\\u6790\\u5931\\u6557'); }\r\n        } else { fail('HTTP ' + xhr.status); }\r\n    };\r\n    xhr.onerror = function() { fail('\\u7DB2\\u8DEF\\u932F\\u8AA4\\uFF0C\\u5C07\\u81EA\\u52D5\\u91CD\\u8A66...'); };\r\n    xhr.send();\r\n}\r\n\r\nfunction startCd() {\r\n    cd = SEC;\r\n    $('ftcCd').textContent = cd;\r\n    if (timer) clearInterval(timer);\r\n    timer = setInterval(function() {\r\n        cd--;\r\n        if (cd <= 0) { cd = SEC; fetchData(); }\r\n        $('ftcCd').textContent = cd;\r\n    }, 1000);\r\n}\r\n\r\nfetchData();\r\nstartCd();\r\n\r\n})();\r\n<\/script>\r\n\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_gspb_post_css":"","footnotes":""},"class_list":["post-2367","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/pages\/2367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/comments?post=2367"}],"version-history":[{"count":2,"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/pages\/2367\/revisions"}],"predecessor-version":[{"id":2465,"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/pages\/2367\/revisions\/2465"}],"wp:attachment":[{"href":"https:\/\/tetsu811.com\/ja\/wp-json\/wp\/v2\/media?parent=2367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}