服務條款
生效日期:2026-XX-XX(上架日確認前為草稿,上架前將請法務 review)
1. 服務性質與範圍
AllocLab(以下簡稱「本平台」)為 AI 輔助的台股研究工作台,提供歷史資料查詢、
AI 摘要解讀、選股篩選、回測模擬及個人研究記錄等功能。
重要聲明:本平台非投資顧問,不提供個股買賣建議。
所有 AI 判讀、資料摘要及回測結果均僅供參考,不構成任何投資建議、
推薦或要約。投資有風險,請在做出任何投資決策前自行評估,必要時諮詢合格的持牌
投資顧問。
2. 免責聲明
- 本平台不擔保 AI 判讀結果之正確性、即時性或完整性
- 回測結果為歷史數據模擬,不代表未來實際績效
- 資料可能存在延遲、錯誤或遺漏,請以各官方來源資料為準
- 本平台不負責因使用本平台資訊而導致的任何投資損失或損害
- 第三方 API 不可用、資料延遲或服務中斷,本平台一概免責
3. 訂閱條款
- 訂閱期:以月為單位,自付款成功日起算
- 自動續訂:訂閱到期前若未取消,將自動以當時有效方案費率續訂
-
退款政策:依消費者保護法第 19 條,數位服務訂閱類商品之 7 日猶豫期
適用條件詳見金流付款頁說明。已啟用使用的數位內容服務,依法得不提供退款,
詳細條件以付款頁所載為準。
- 終止:您可隨時於帳號設定取消訂閱;本平台亦保留因違反條款終止帳號之權利
4. 用戶責任與禁止事項
- 不得對本平台進行逆向工程、反組譯或嘗試取得原始程式碼
- 不得轉售、再授權或以商業目的重新包裝 AI 輸出內容
- 不得以自動化方式(爬蟲、機器人)大量存取本平台 API 或資料
- 不得利用本平台進行任何違法活動或傷害他人之行為
- 帳號為個人使用,不得轉讓或共享帳號
- 使用者須自行承擔依本平台資訊所做投資決策之一切風險與損失
- 未滿 18 歲者不得使用本平台
5. 智慧財產權
本平台之所有軟體、介面設計、AI 模型設定、演算法及品牌資產(包含「AllocLab」名稱
及標誌)之智慧財產權均屬本平台所有或經授權使用。
未經書面授權,不得以任何形式複製、散布或再利用上述資產。
用戶自行輸入的研究筆記及資料屬用戶所有,本平台不主張所有權。
6. 服務變更、中斷與終止
本平台保留隨時修改、暫停或終止全部或部分服務之權利。
計劃性維護將提前公告;緊急維護或第三方 API 不可用導致的服務中斷一概免責。
服務終止時,本平台將以合理方式協助用戶匯出個人資料。
7. 條款修訂
本平台保留隨時修訂本條款之權利。重大變更將於 30 日前透過 email 及站內公告通知用戶。
繼續使用本平台即表示您接受修訂後之條款。
8. 準據法與管轄法院
本條款依中華民國法律解釋及執行。如有爭議,以台灣台北地方法院為第一審管轄法院。
如有任何疑問,請聯絡
support@alloclab.tw。
window.AllocLab = window.AllocLab || {};
AllocLab.initFancyChart = function (containerId, opts) {
const el = document.getElementById(containerId);
if (!el || !window.LightweightCharts) return null;
const data = (opts && opts.data) || [];
if (data.length < 2) return null;
const LW = window.LightweightCharts;
const mode = opts.mode || 'apple';
const volume = opts.volume || null;
const support = Array.isArray(opts.support) ? opts.support : [];
const resistance = Array.isArray(opts.resistance) ? opts.resistance : [];
const unit = opts.unit || 'NT$';
const rangesRoot = opts.rangesRoot || el.parentElement;
const legendEl = opts.legendEl || (el.parentElement && el.parentElement.querySelector('.al-chart__legend-value'));
const legendDateEl = opts.legendDateEl || (el.parentElement && el.parentElement.querySelector('.al-chart__legend-date'));
const tipEl = opts.tooltipEl || (el.parentElement && el.parentElement.querySelector('.al-chart__tooltip'));
const first = data[0].value;
const last = data[data.length - 1].value;
const isUp = last >= first;
const mainColor = isUp ? '#c0392b' : '#2a7a50';
const mainTop = isUp ? 'rgba(192,57,43,0.22)' : 'rgba(42,122,80,0.22)';
const ghostTop = isUp ? 'rgba(192,57,43,0.04)' : 'rgba(42,122,80,0.04)';
const ghostLine = isUp ? 'rgba(192,57,43,0.25)' : 'rgba(42,122,80,0.25)';
const chart = LW.createChart(el, {
autoSize: true,
layout: {
background: { type: 'solid', color: '#FFFFFF' },
textColor: 'rgba(39,48,67,0.50)',
fontFamily: 'IBM Plex Mono, ui-monospace, monospace',
},
grid: {
vertLines: { color: 'rgba(39,48,67,0.04)' },
horzLines: { color: 'rgba(39,48,67,0.04)' },
},
crosshair: {
mode: LW.CrosshairMode.Normal,
vertLine: { color: 'rgba(39,48,67,0.25)', width: 1, labelBackgroundColor: mainColor },
horzLine: { color: 'rgba(39,48,67,0.15)', width: 1, labelBackgroundColor: mainColor },
},
rightPriceScale: { borderColor: 'rgba(39,48,67,0.10)' },
timeScale: { borderColor: 'rgba(39,48,67,0.10)', timeVisible: true, fixRightEdge: true },
handleScroll: false,
handleScale: false,
});
// 底圖(ghost)— Apple 模式時整條都畫,但色極淡
const ghost = chart.addAreaSeries({
lineColor: ghostLine,
topColor: ghostTop,
bottomColor: 'rgba(0,0,0,0)',
lineWidth: 2,
priceLineVisible: false,
lastValueVisible: false,
crosshairMarkerVisible: false,
});
ghost.setData(data);
// 高亮(active)— 游標前鮮明、游標後在 apple 模式下會被 setData 截短
const active = chart.addAreaSeries({
lineColor: mainColor,
topColor: mainTop,
bottomColor: 'rgba(0,0,0,0)',
lineWidth: 2,
priceLineVisible: false,
lastValueVisible: false,
crosshairMarkerRadius: 5,
crosshairMarkerBorderColor: '#ffffff',
crosshairMarkerBackgroundColor: mainColor,
});
active.setData(data);
// 成交量 histogram(選配)
let volSeries = null;
if (volume && volume.length) {
volSeries = chart.addHistogramSeries({
priceFormat: { type: 'volume' },
priceScaleId: '',
scaleMargins: { top: 0.82, bottom: 0 },
});
volSeries.setData(volume.map(function (v) {
return { time: v.time, value: v.value, color: 'rgba(39,48,67,0.18)' };
}));
}
// 支撐 / 壓力線(AI 或人工標記)
// 台灣慣例:壓力(resistance)偏多頂 → 紅;支撐(support)偏空底 → 綠
const priceLines = [];
support.forEach(function (p) {
priceLines.push(active.createPriceLine({
price: p,
color: '#2a7a50',
lineWidth: 1,
lineStyle: LW.LineStyle.Dashed,
axisLabelVisible: true,
title: '支撐',
}));
});
resistance.forEach(function (p) {
priceLines.push(active.createPriceLine({
price: p,
color: '#c0392b',
lineWidth: 1,
lineStyle: LW.LineStyle.Dashed,
axisLabelVisible: true,
title: '壓力',
}));
});
// Legend & tooltip 格式化
function fmtVal(v) {
if (v == null || isNaN(v)) return '—';
return unit + ' ' + Number(v).toLocaleString('zh-TW', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
function setLegend(time, value) {
if (legendEl) legendEl.textContent = fmtVal(value);
if (legendDateEl) legendDateEl.textContent = time || '';
}
setLegend(data[data.length - 1].time, last);
// Apple 高亮 + tooltip
const byTime = new Map(data.map(function (d, i) { return [d.time, i]; }));
chart.subscribeCrosshairMove(function (param) {
if (!param.time || !param.point || param.point.x < 0 || param.point.y < 0) {
if (mode === 'apple') active.setData(data);
setLegend(data[data.length - 1].time, last);
if (tipEl) tipEl.style.display = 'none';
return;
}
const idx = byTime.get(param.time);
if (idx == null) return;
const d = data[idx];
if (mode === 'apple') active.setData(data.slice(0, idx + 1));
setLegend(d.time, d.value);
if (tipEl) {
tipEl.style.display = 'block';
tipEl.innerHTML =
'