commit 9e7c4c973b78222fc01eaabcbc316082e26d3c3b Author: joseph Date: Tue Jul 11 10:25:31 2023 +0800 init diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6db4a88 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.9.6 +WORKDIR /flask +ADD . /flask +RUN apt-get update +RUN apt install nano +RUN pip install --upgrade pip +RUN pip3 install -r requirements.txt + +EXPOSE 8000 diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..66c4d2e --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn main:app --preload --workers 28 --timeout 120 \ No newline at end of file diff --git a/assets_tw.json b/assets_tw.json new file mode 100644 index 0000000..b8f33a5 --- /dev/null +++ b/assets_tw.json @@ -0,0 +1 @@ +{"00707R.TW": "\u5143\u5927S&P\u65e5\u5713\u53cd1", "8147.TWO": "\u6b63\u6de9", "3289.TWO": "\u5b9c\u7279", "2109.TW": "\u83ef\u8c50", "2850.TW": "\u65b0\u7522", "4305.TWO": "\u4e16\u5764", "1203.TW": "\u5473\u738b", "3089.TWO": "\u5143\u70ac", "5543.TWO": "\u6853\u9f0e-KY", "00764B.TWO": "\u7fa4\u76ca25\u5e74\u7f8e\u50b5", "1235.TW": "\u8208\u6cf0", "00861.TW": "\u5143\u5927\u5168\u7403\u672a\u4f86\u901a\u8a0a", "2467.TW": "\u5fd7\u8056", "1568.TW": "\u5009\u4f51", "00875.TW": "\u570b\u6cf0\u7db2\u8def\u8cc7\u5b89", "2027.TW": "\u5927\u6210\u92fc", "8923.TWO": "\u6642\u5831", "8358.TWO": "\u91d1\u5c45", "00833B.TWO": "\u7b2c\u4e00\u91d1\u7f8e\u50b520+", "3313.TWO": "\u6590\u6210", "1522.TW": "\u5824\u7dad\u897f", "3576.TW": "\u806f\u5408\u518d\u751f", "4707.TWO": "\u78d0\u4e9e", "8289.TWO": "\u6cf0\u85dd", "6291.TWO": "\u6c9b\u4ea8", "3019.TW": "\u4e9e\u5149", "1717.TW": "\u9577\u8208", "1268.TWO": "\u6f22\u4f86\u7f8e\u98df", "2413.TW": "\u74b0\u79d1", "3042.TW": "\u6676\u6280", "6210.TWO": "\u6176\u751f", "2468.TW": "\u83ef\u7d93", "2364.TW": "\u502b\u98db", "3021.TW": "\u9d3b\u540d", "2359.TW": "\u6240\u7f85\u9580", "6514.TWO": "\u82ae\u7279-KY", "8182.TWO": "\u52a0\u9ad8", "5704.TWO": "\u8001\u723a\u77e5", "5258.TW": "\u8679\u5821", "1236.TW": "\u5b8f\u4e9e", "3044.TW": "\u5065\u9f0e", "3018.TW": "\u540c\u958b", "8021.TW": "\u5c16\u9ede", "8383.TWO": "\u5343\u9644", "6488.TWO": "\u74b0\u7403\u6676", "1402.TW": "\u9060\u6771\u65b0", "2349.TW": "\u9338\u5fb7", "5604.TWO": "\u4e2d\u9023\u8ca8", "00838B.TWO": "\u6c38\u8c507-10\u5e74\u4e2d\u570b\u50b5", "8426.TWO": "\u7d05\u6728-KY", "6005.TW": "\u7fa4\u76ca\u8b49", "1560.TW": "\u4e2d\u7802", "4919.TW": "\u65b0\u5510", "3332.TWO": "\u5e78\u5eb7", "1618.TW": "\u5408\u6a5f", "3642.TWO": "\u99ff\u71a0\u96fb", "5009.TWO": "\u69ae\u525b", "00695B.TWO": "\u5bcc\u90a6\u7f8e\u50b57-10\u5e74", "2546.TW": "\u6839\u57fa", "1788.TWO": "\u674f\u660c", "2412.TW": "\u4e2d\u83ef\u96fb", "3217.TWO": "\u512a\u7fa4", "5364.TWO": "\u529b\u9e97\u5e97", "4174.TWO": "\u6d69\u9f0e", "9910.TW": "\u8c50\u6cf0", "9908.TW": "\u5927\u53f0\u5317", "8299.TWO": "\u7fa4\u806f", "3029.TW": "\u96f6\u58f9", "3025.TW": "\u661f\u901a", "4973.TWO": "\u5ee3\u7a4e", "5488.TWO": "\u677e\u666e", "6525.TW": "\u6377\u654f-KY", "00706L.TW": "\u5143\u5927S&P\u65e5\u5713\u6b632", "2247.TW": "\u6c4e\u5fb7\u6c38\u696d", "8499.TW": "\u9f0e\u70ab-KY", "3032.TW": "\u5049\u8a13", "4175.TWO": "\u674f\u4e00", "8374.TW": "\u7f85\u6607", "8933.TWO": "\u611b\u5730\u96c5", "2611.TW": "\u5fd7\u4fe1", "1584.TWO": "\u7cbe\u525b", "1587.TW": "\u5409\u8302", "2724.TWO": "\u5bcc\u9a5b-KY", "3005.TW": "\u795e\u57fa", "3484.TWO": "\u5d27\u9a30", "4526.TW": "\u6771\u53f0", "8466.TW": "\u7f8e\u5409\u5409-KY", "2453.TW": "\u51cc\u7fa4", "6542.TWO": "\u9686\u4e2d", "8155.TWO": "\u535a\u667a", "6465.TWO": "\u5a01\u6f64", "00752.TW": "\u4e2d\u4fe1\u4e2d\u570b50", "2002.TW": "\u4e2d\u92fc", "4113.TWO": "\u806f\u4e0a", "1321.TW": "\u5927\u6d0b", "00863B.TWO": "\u4e2d\u4fe1\u5168\u7403\u96fb\u4fe1\u50b5", "3426.TWO": "\u53f0\u8208", "5276.TWO": "\u9054\u8f1d-KY", "1219.TW": "\u798f\u58fd", "00680L.TW": "\u5143\u5927\u7f8e\u50b520\u6b632", "8049.TWO": "\u6676\u91c7", "00846B.TWO": "\u5bcc\u90a6\u6b50\u6d32\u9280\u884c\u50b5", "8222.TW": "\u5bf6\u4e00", "2421.TW": "\u5efa\u6e96", "3536.TW": "\u8aa0\u5275", "3615.TWO": "\u5b89\u53ef", "00851.TW": "\u53f0\u65b0\u5168\u7403AI", "6276.TWO": "\u5b89\u9226\u514b", "6134.TWO": "\u842c\u65ed", "2740.TWO": "\u5929\u8525", "2344.TW": "\u83ef\u90a6\u96fb", "6233.TWO": "\u65fa\u7396", "00744B.TWO": "\u570b\u6cf0\u4e2d\u570b\u653f\u91d1\u50b55+", "5607.TW": "\u9060\u96c4\u6e2f", "4735.TWO": "\u8c6a\u5c55", "4550.TWO": "\u9577\u4f73", "00799B.TWO": "\u570b\u6cf0A\u7d1a\u91ab\u7642\u50b5", "3095.TWO": "\u53ca\u6210", "1324.TW": "\u5730\u7403", "4924.TWO": "\u6b23\u539a-KY", "8024.TWO": "\u4f51\u83ef", "1533.TW": "\u8eca\u738b\u96fb", "00720B.TWO": "\u5143\u5927\u6295\u8cc7\u7d1a\u516c\u53f8\u50b5", "1468.TW": "\u6636\u548c", "3040.TW": "\u9060\u898b", "5522.TW": "\u9060\u96c4", "6221.TWO": "\u6649\u6cf0", "00678.TW": "\u7fa4\u76caNBI\u751f\u6280", "2231.TW": "\u70ba\u5347", "8411.TW": "\u798f\u8c9e-KY", "6158.TWO": "\u79be\u660c", "00841B.TWO": "\u51f1\u57faAAA-AA\u516c\u53f8\u50b5", "2903.TW": "\u9060\u767e", "4722.TW": "\u570b\u7cbe\u5316", "8059.TWO": "\u51f1\u78a9", "6116.TW": "\u5f69\u6676", "3583.TW": "\u8f9b\u8018", "00696B.TWO": "\u5bcc\u90a6\u7f8e\u50b520\u5e74", "5223.TWO": "\u5b89\u529b-KY", "5519.TW": "\u9686\u5927", "6265.TWO": "\u65b9\u571f\u6636", "6706.TW": "\u60e0\u7279", "3052.TW": "\u5906\u5178", "3432.TW": "\u53f0\u7aef", "1418.TW": "\u6771\u83ef", "00722B.TWO": "\u7fa4\u76ca15\u5e74IG\u96fb\u4fe1\u50b5", "2020.TW": "\u7f8e\u4e9e", "1815.TWO": "\u5bcc\u55ac", "3041.TW": "\u63da\u667a", "2379.TW": "\u745e\u6631", "3085.TWO": "\u65b0\u96f6\u552e", "1449.TW": "\u4f73\u548c", "8016.TW": "\u77fd\u5275", "2302.TW": "\u9e97\u6b63", "1472.TW": "\u4e09\u6d0b\u7d21", "3709.TWO": "\u946b\u806f\u5927\u6295\u63a7", "2329.TW": "\u83ef\u6cf0", "3339.TWO": "\u6cf0\u8c37", "2106.TW": "\u5efa\u5927", "4163.TWO": "\u943f\u9226", "3406.TW": "\u7389\u6676\u5149", "1608.TW": "\u83ef\u69ae", "2458.TW": "\u7fa9\u9686", "5508.TWO": "\u6c38\u4fe1\u5efa", "5211.TWO": "\u8499\u606c", "6570.TWO": "\u7dad\u7530", "6499.TWO": "\u76ca\u5b89", "6615.TWO": "\u6167\u667a", "3508.TWO": "\u4f4d\u901f", "2732.TWO": "\u516d\u89d2", "2399.TW": "\u6620\u6cf0", "6217.TWO": "\u4e2d\u63a2\u91dd", "2520.TW": "\u51a0\u5fb7", "00663L.TW": "\u570b\u6cf0\u81fa\u7063\u52a0\u6b0a\u6b632", "6612.TWO": "\u5948\u7c73\u91ab\u6750", "5383.TWO": "\u91d1\u5229", "4540.TW": "\u5168\u7403\u50b3\u52d5", "5344.TWO": "\u7acb\u885b", "6170.TWO": "\u7d71\u632f", "3285.TWO": "\u5fae\u7aef", "1785.TWO": "\u5149\u6d0b\u79d1", "4157.TWO": "\u592a\u666f*-KY", "8064.TWO": "\u6771\u6377", "4161.TWO": "\u807f\u65b0\u79d1", "00732.TW": "\u570b\u6cf0RMB\u77ed\u671f\u5831\u916c", "6442.TW": "\u5149\u8056", "2049.TW": "\u4e0a\u9280", "2022.TW": "\u805a\u4ea8", "1784.TWO": "\u8a0a\u806f", "3176.TWO": "\u57fa\u4e9e", "5243.TW": "\u4e59\u76db-KY", "3003.TW": "\u5065\u548c\u8208", "6264.TWO": "\u5bcc\u88d4", "6109.TWO": "\u4e9e\u5143", "00735.TW": "\u570b\u6cf0\u81fa\u97d3\u79d1\u6280", "2832.TW": "\u53f0\u7522", "8996.TW": "\u9ad8\u529b", "6616.TWO": "\u7279\u6607-KY", "6016.TWO": "\u5eb7\u548c\u8b49", "3528.TW": "\u5b89\u99b3", "6446.TWO": "\u85e5\u83ef\u85e5", "6125.TWO": "\u5ee3\u904b", "1776.TW": "\u5c55\u5b87", "00730.TW": "\u5bcc\u90a6\u81fa\u7063\u512a\u8cea\u9ad8\u606f", "4556.TWO": "\u65ed\u7136", "1539.TW": "\u5de8\u5ead", "4728.TWO": "\u96d9\u7f8e", "1569.TWO": "\u6ff1\u5ddd", "8421.TWO": "\u65ed\u6e90", "6605.TW": "\u5e1d\u5bf6", "8088.TWO": "\u54c1\u5b89", "2883.TW": "\u958b\u767c\u91d1", "2373.TW": "\u9707\u65e6\u884c", "00721B.TWO": "\u5143\u5927\u4e2d\u570b\u50b53-5", "2534.TW": "\u5b8f\u76db", "2243.TW": "\u5b8f\u65ed-KY", "6015.TWO": "\u5b8f\u9060\u8b49", "2459.TW": "\u6566\u5409", "00774B.TW": "\u65b0\u5149\u4e2d\u570b\u653f\u91d1\u7da0\u50b5", "8409.TWO": "\u5546\u4e4b\u5668", "3152.TWO": "\u749f\u5fb7", "4554.TWO": "\u6a59\u7684", "8086.TWO": "\u5b8f\u6377\u79d1", "6561.TWO": "\u662f\u65b9", "2201.TW": "\u88d5\u9686", "00780B.TWO": "\u570b\u6cf0A\u7d1a\u91d1\u878d\u50b5", "2723.TW": "\u7f8e\u98df-KY", "4939.TWO": "\u4e9e\u96fb", "1720.TW": "\u751f\u9054", "4760.TWO": "\u52e4\u51f1", "6504.TW": "\u5357\u516d", "2538.TW": "\u57fa\u6cf0", "2024.TW": "\u5fd7\u806f", "6683.TWO": "\u96cd\u667a\u79d1\u6280", "3288.TWO": "\u9ede\u6676", "0057.TW": "\u5bcc\u90a6\u6469\u53f0", "8183.TWO": "\u7cbe\u661f", "8941.TWO": "\u95dc\u4e2d", "6697.TWO": "\u6771\u6377\u8cc7\u8a0a", "8284.TWO": "\u4e09\u7af9", "8091.TWO": "\u7fd4\u540d", "3504.TW": "\u63da\u660e\u5149", "5880.TW": "\u5408\u5eab\u91d1", "3356.TW": "\u5947\u5076", "1525.TW": "\u6c5f\u7533", "6277.TW": "\u5b8f\u6b63", "8437.TWO": "\u5927\u5730-KY", "6117.TW": "\u8fce\u5ee3", "3593.TW": "\u529b\u9298", "3498.TWO": "\u967d\u7a0b", "8085.TWO": "\u798f\u83ef", "2486.TW": "\u4e00\u8a6e", "2474.TW": "\u53ef\u6210", "4102.TWO": "\u6c38\u65e5", "00834B.TWO": "\u7b2c\u4e00\u91d1\u91d1\u878d\u50b510+", "1434.TW": "\u798f\u61cb", "2323.TW": "\u4e2d\u74b0", "6108.TW": "\u7af6\u570b", "2012.TW": "\u6625\u96e8", "5490.TWO": "\u540c\u4ea8", "3665.TW": "\u8cbf\u806f-KY", "2845.TW": "\u9060\u6771\u9280", "5426.TWO": "\u632f\u767c", "2482.TW": "\u9023\u5b87", "00749B.TWO": "\u51f1\u57fa\u65b0\u8208\u50b510+", "1909.TW": "\u69ae\u6210", "4420.TWO": "\u5149\u660e", "8210.TW": "\u52e4\u8aa0", "1731.TW": "\u7f8e\u543e\u83ef", "8488.TW": "\u5409\u6e90-KY", "6242.TWO": "\u7acb\u5eb7", "00848B.TWO": "\u4e2d\u4fe1\u65b0\u8208\u4e9e\u6d32\u50b5", "6120.TW": "\u9054\u904b", "3169.TWO": "\u4e9e\u4fe1", "8034.TWO": "\u69ae\u7fa4", "6235.TW": "\u83ef\u5b5a", "2104.TW": "\u570b\u969b\u4e2d\u6a61", "3221.TWO": "\u53f0\u5609\u78a9", "6104.TWO": "\u5275\u60df", "3704.TW": "\u5408\u52e4\u63a7", "4114.TWO": "\u5065\u55ac", "3078.TWO": "\u50d1\u5a01", "8042.TWO": "\u91d1\u5c71\u96fb", "2643.TWO": "\u6377\u8fc5", "6527.TWO": "\u660e\u9054\u91ab", "8104.TW": "\u9338\u5bf6", "00636K.TW": "\u570b\u6cf0\u4e2d\u570bA50+U", "00683L.TW": "\u5143\u5927\u7f8e\u5143\u6307\u6578\u6b632", "6588.TWO": "\u6771\u5178\u5149\u96fb", "5345.TWO": "\u5929\u63da", "2937.TWO": "\u96c6\u96c5\u793e", "6594.TWO": "\u5c55\u532f\u79d1", "8112.TW": "\u81f3\u4e0a", "1437.TW": "\u52e4\u76ca\u63a7", "5601.TWO": "\u53f0\u806f\u6ac3", "4555.TW": "\u6c23\u7acb", "3666.TWO": "\u5149\u8000", "3149.TW": "\u6b63\u9054", "4930.TW": "\u71e6\u661f\u7db2", "2033.TW": "\u4f73\u5927", "4416.TWO": "\u4e09\u5713", "3311.TW": "\u958e\u6689", "6128.TW": "\u4e0a\u798f", "8477.TWO": "\u5275\u696d\u5bb6", "8047.TWO": "\u661f\u96f2", "6275.TWO": "\u5143\u5c71", "8011.TW": "\u53f0\u901a", "4513.TWO": "\u798f\u88d5", "3712.TW": "\u6c38\u5d34\u6295\u63a7", "6496.TWO": "\u79d1\u61cb", "2754.TWO": "\u4e9e\u6d32\u85cf\u58fd\u53f8", "6196.TW": "\u5e06\u5ba3", "3014.TW": "\u806f\u967d", "00702.TW": "\u570b\u6cf0\u6a19\u666e\u4f4e\u6ce2\u9ad8\u606f", "00870B.TWO": "\u5143\u592715\u5e74EM\u4e3b\u6b0a\u50b5", "6207.TWO": "\u96f7\u79d1", "3376.TW": "\u65b0\u65e5\u8208", "1726.TW": "\u6c38\u8a18", "4977.TW": "\u773e\u9054-KY", "3374.TWO": "\u7cbe\u6750", "8450.TWO": "\u9739\u9742", "2408.TW": "\u5357\u4e9e\u79d1", "3680.TWO": "\u5bb6\u767b", "3047.TW": "\u8a0a\u821f", "2102.TW": "\u6cf0\u8c50", "2618.TW": "\u9577\u69ae\u822a", "4129.TWO": "\u806f\u5408", "6218.TWO": "\u8c6a\u52c9", "3529.TWO": "\u529b\u65fa", "4934.TW": "\u592a\u6975", "2641.TWO": "\u6b63\u5fb7", "2433.TW": "\u4e92\u76db\u96fb", "0061.TW": "\u5143\u5927\u5bf6\u6eec\u6df1", "00760B.TWO": "FH\u65b0\u8208\u4f01\u696d\u50b5", "3580.TWO": "\u53cb\u5a01\u79d1", "3557.TW": "\u5609\u5a01", "3629.TWO": "\u5730\u5fc3\u5f15\u529b", "1605.TW": "\u83ef\u65b0", "3587.TWO": "\u958e\u5eb7", "8092.TWO": "\u5efa\u6690", "008201.TW": "BP\u4e0a\u8b4950", "8201.TW": "\u7121\u6575", "8463.TW": "\u6f64\u6cf0\u6750", "6672.TW": "\u9a30\u8f1d\u96fb\u5b50-KY", "3088.TWO": "\u827e\u8a0a", "5403.TWO": "\u4e2d\u83f2", "2380.TW": "\u8679\u5149", "9949.TWO": "\u7409\u5712", "2419.TW": "\u4ef2\u7426", "8420.TWO": "\u660e\u63da", "5530.TWO": "\u9f8d\u5dd6", "2504.TW": "\u570b\u7522", "1777.TWO": "\u751f\u6cf0", "6596.TWO": "\u5bec\u5b8f\u85dd\u8853", "00688L.TW": "\u570b\u6cf020\u5e74\u7f8e\u50b5\u6b632", "6576.TWO": "\u9038\u9054", "2332.TW": "\u53cb\u8a0a", "1519.TW": "\u83ef\u57ce", "5201.TWO": "\u51f1\u885b", "1530.TW": "\u4e9e\u5d34", "2706.TW": "\u7b2c\u4e00\u5e97", "5287.TWO": "\u6578\u5b57", "2542.TW": "\u8208\u5bcc\u767c", "1718.TW": "\u4e2d\u7e96", "5347.TWO": "\u4e16\u754c", "6187.TWO": "\u842c\u6f64", "4803.TWO": "VHQ-KY", "3287.TWO": "\u5ee3\u5bf0\u79d1", "9927.TW": "\u6cf0\u9298", "5878.TWO": "\u53f0\u540d", "5703.TWO": "\u4e9e\u90fd", "00734B.TWO": "\u53f0\u65b0JPM\u65b0\u8208\u50b5", "1721.TW": "\u4e09\u6643", "4754.TWO": "\u570b\u78b3\u79d1", "1724.TW": "\u53f0\u785d", "2901.TW": "\u6b23\u6b23", "1714.TW": "\u548c\u6850", "6569.TWO": "\u91ab\u63da", "2712.TW": "\u9060\u96c4\u4f86", "2718.TWO": "\u6676\u6085", "4974.TWO": "\u4e9e\u6cf0", "1445.TW": "\u5927\u5b87", "00762.TW": "\u5143\u5927\u5168\u7403AI", "2836.TW": "\u9ad8\u96c4\u9280", "3533.TW": "\u5609\u6fa4", "00654R.TW": "\u5bcc\u90a6\u5370\u5ea6\u53cd1", "6138.TWO": "\u8302\u9054", "4127.TWO": "\u5929\u826f", "1213.TW": "\u5927\u98f2", "2912.TW": "\u7d71\u4e00\u8d85", "00668.TW": "\u570b\u6cf0\u7f8e\u570b\u9053\u74ca", "3312.TW": "\u5f18\u61b6\u80a1", "1342.TW": "\u516b\u8cab", "5288.TW": "\u8c50\u7965-KY", "00643.TW": "\u7fa4\u76ca\u6df1\u8a3c\u4e2d\u5c0f", "8054.TWO": "\u5b89\u570b", "4527.TWO": "\u65b9\u571f\u9716", "2010.TW": "\u6625\u6e90", "1710.TW": "\u6771\u806f", "8050.TWO": "\u5ee3\u7a4d", "5283.TW": "\u79be\u806f\u78a9", "9931.TW": "\u6b23\u9ad8", "1323.TW": "\u6c38\u88d5", "4530.TWO": "\u5b8f\u6613", "6205.TW": "\u8a6e\u6b23", "9962.TWO": "\u6709\u76ca", "00761B.TWO": "\u570b\u6cf0A\u7d1a\u516c\u53f8\u50b5", "2637.TW": "\u6167\u6d0b-KY", "9942.TW": "\u8302\u9806", "1325.TW": "\u6046\u5927", "6234.TWO": "\u9ad8\u50d1", "2471.TW": "\u8cc7\u901a", "1802.TW": "\u53f0\u73bb", "00763U.TW": "\u8857\u53e3\u9053\u74ca\u9285", "1234.TW": "\u9ed1\u677e", "3073.TWO": "\u5929\u65b9\u80fd\u6e90", "4571.TW": "\u921e\u8208-KY", "8101.TW": "\u83ef\u51a0", "2537.TW": "\u806f\u4e0a\u767c", "2354.TW": "\u9d3b\u6e96", "4528.TWO": "\u6c5f\u8208\u935b", "5388.TW": "\u4e2d\u78ca", "00631L.TW": "\u5143\u5927\u53f0\u706350\u6b632", "6225.TW": "\u5929\u701a", "6485.TWO": "\u9ede\u5e8f", "2498.TW": "\u5b8f\u9054\u96fb", "6215.TW": "\u548c\u693f", "3062.TW": "\u5efa\u6f22", "3630.TWO": "\u65b0\u9245\u79d1", "6477.TW": "\u5b89\u96c6", "1722.TW": "\u53f0\u80a5", "4549.TWO": "\u6853\u9054", "2889.TW": "\u570b\u7968\u91d1", "6236.TWO": "\u5eb7\u5448", "3064.TWO": "\u6cf0\u5049", "5324.TWO": "\u58eb\u958b", "4107.TWO": "\u90a6\u7279", "3705.TW": "\u6c38\u4fe1", "4767.TWO": "\u8aa0\u6cf0\u79d1\u6280", "6668.TW": "\u4e2d\u63da\u5149", "8048.TWO": "\u5fb7\u52dd", "1904.TW": "\u6b63\u9686", "2308.TW": "\u53f0\u9054\u96fb", "1231.TW": "\u806f\u83ef\u98df", "6593.TWO": "\u53f0\u7063\u9298\u677f", "2230.TWO": "\u6cf0\u8302", "3588.TW": "\u901a\u5609", "6512.TWO": "\u555f\u767c\u96fb", "6425.TWO": "\u6613\u767c", "5531.TW": "\u9109\u6797", "00638R.TW": "\u5143\u5927\u6eec\u6df1300\u53cd1", "00715L.TW": "\u8857\u53e3S&P\u5e03\u862d\u7279\u6cb9\u6b632", "00647L.TW": "\u5143\u5927S&P500\u6b632", "2888.TW": "\u65b0\u5149\u91d1", "1732.TW": "\u6bdb\u5bf6", "4904.TW": "\u9060\u50b3", "00765B.TWO": "\u7fa4\u76ca\u4e2d\u570b\u653f\u91d1\u50b5", "1558.TW": "\u4f38\u8208", "1595.TWO": "\u5ddd\u5bf6", "4137.TW": "\u9e97\u8c50-KY", "3465.TWO": "\u9032\u6cf0\u96fb\u5b50", "2420.TW": "\u65b0\u5de8", "3523.TWO": "\u8fce\u8f1d", "2505.TW": "\u570b\u63da", "00878.TW": "\u570b\u6cf0\u6c38\u7e8c\u9ad8\u80a1\u606f", "1535.TW": "\u4e2d\u5b87", "00701.TW": "\u570b\u6cf0\u80a1\u5229\u7cbe\u907830", "6662.TWO": "\u6a02\u65af\u79d1", "2442.TW": "\u65b0\u7f8e\u9f4a", "9921.TW": "\u5de8\u5927", "3419.TW": "\u8b41\u88d5", "2701.TW": "\u842c\u4f01", "4560.TW": "\u5f37\u4fe1-KY", "4532.TW": "\u745e\u667a", "5301.TWO": "\u5bf6\u5f97\u5229", "1808.TW": "\u6f64\u9686", "8418.TWO": "\u6377\u5fc5\u52dd-KY", "9960.TWO": "\u9081\u9054\u5eb7", "00677U.TW": "\u5bcc\u90a6VIX", "1259.TWO": "\u5b89\u5fc3", "1795.TW": "\u7f8e\u6642", "2851.TW": "\u4e2d\u518d\u4fdd", "2352.TW": "\u4f73\u4e16\u9054", "5529.TWO": "\u5fd7\u5609", "5489.TWO": "\u5f69\u5bcc", "2387.TW": "\u7cbe\u5143", "6245.TWO": "\u7acb\u7aef", "6449.TW": "\u923a\u90a6", "00640L.TW": "\u5bcc\u90a6\u65e5\u672c\u6b632", "6186.TWO": "\u65b0\u6f64", "2402.TW": "\u6bc5\u5609", "2338.TW": "\u5149\u7f69", "1603.TW": "\u83ef\u96fb", "4943.TW": "\u5eb7\u63a7-KY", "1474.TW": "\u5f18\u88d5", "3537.TWO": "\u5821\u9054", "2524.TW": "\u4eac\u57ce", "1413.TW": "\u5b8f\u6d32", "3567.TWO": "\u9038\u660c", "1591.TWO": "\u99ff\u5409-KY", "6664.TWO": "\u7fa4\u7fca", "1459.TW": "\u806f\u767c", "6417.TWO": "\u97cb\u50d1", "3293.TWO": "\u920a\u8c61", "00724B.TWO": "\u7fa4\u76ca10\u5e74IG\u91d1\u878d\u50b5", "3611.TWO": "\u9f0e\u7ff0", "3115.TWO": "\u5bf6\u5cf6\u6975", "1326.TW": "\u53f0\u5316", "6279.TWO": "\u80e1\u9023", "3322.TWO": "\u5efa\u821c\u96fb", "6416.TW": "\u745e\u797a\u96fb\u901a", "00853B.TWO": "\u7d71\u4e00\u7f8e\u50b510\u5e74Aa-A", "6206.TW": "\u98db\u6377", "4438.TW": "\u5ee3\u8d8a", "00847B.TWO": "\u4e2d\u4fe1\u7f8e\u570b\u5e02\u653f\u50b5", "3002.TW": "\u6b50\u683c", "2477.TW": "\u7f8e\u9686\u96fb", "6202.TW": "\u76db\u7fa4", "3708.TW": "\u4e0a\u7def\u6295\u63a7", "8454.TW": "\u5bcc\u90a6\u5a92", "6470.TWO": "\u5b87\u667a", "3094.TW": "\u806f\u5091", "00747B.TWO": "FH\u4e2d\u570b\u653f\u7b56\u50b5", "6123.TWO": "\u4e0a\u5947", "3710.TWO": "\u9023\u5c55\u6295\u63a7", "3594.TWO": "\u78d0\u5100", "3211.TWO": "\u9806\u9054", "6411.TWO": "\u6676\u7131", "3226.TWO": "\u81f3\u5bf6\u96fb", "8429.TW": "\u91d1\u9e97-KY", "2314.TW": "\u53f0\u63da", "6023.TWO": "\u5143\u5927\u671f", "4402.TWO": "\u798f\u5927", "6240.TWO": "\u677e\u5d17", "3305.TW": "\u6607\u8cbf", "2929.TW": "\u6dd8\u5e1d-KY", "4155.TW": "\u8a0a\u6620", "3388.TWO": "\u5d07\u8d8a\u96fb", "3259.TWO": "\u946b\u5275", "3260.TWO": "\u5a01\u525b", "1598.TW": "\u5cb1\u5b87", "6629.TWO": "\u6cf0\u91d1-KY", "6532.TWO": "\u745e\u8018", "3479.TWO": "\u5b89\u52e4", "00637L.TW": "\u5143\u5927\u6eec\u6df1300\u6b632", "5608.TW": "\u56db\u7dad\u822a", "4958.TW": "\u81fb\u9f0e-KY", "2441.TW": "\u8d85\u8c50", "00793B.TWO": "\u7fa4\u76caAAA-A\u91ab\u7642\u50b5", "2461.TW": "\u5149\u7fa4\u96f7", "3354.TWO": "\u5f8b\u52dd", "2115.TW": "\u516d\u6689-KY", "0051.TW": "\u5143\u5927\u4e2d\u578b100", "5284.TW": "jpp-KY", "8481.TW": "\u653f\u4f38", "1455.TW": "\u96c6\u76db", "2383.TW": "\u53f0\u5149\u96fb", "5209.TWO": "\u65b0\u9f0e", "8032.TWO": "\u5149\u83f1", "8424.TWO": "\u60e0\u666e", "8431.TWO": "\u532f\u947d\u79d1", "00648R.TW": "\u5143\u5927S&P500\u53cd1", "5215.TW": "\u79d1\u5609-KY", "2849.TW": "\u5b89\u6cf0\u9280", "2305.TW": "\u5168\u53cb", "8076.TWO": "\u4f0d\u8c50", "9905.TW": "\u5927\u83ef", "6680.TWO": "\u946b\u5275\u96fb\u5b50", "2007.TW": "\u71c1\u8208", "2070.TWO": "\u7cbe\u6e5b", "00748B.TWO": "\u51f1\u57fa\u4e2d\u570b\u50b53-10", "00666R.TW": "\u5bcc\u90a6\u6052\u751f\u570b\u4f01\u53cd1", "5443.TWO": "\u5747\u8c6a", "4915.TW": "\u81f4\u4f38", "2886.TW": "\u5146\u8c50\u91d1", "00682U.TW": "\u5143\u5927\u7f8e\u5143\u6307\u6578", "2540.TW": "\u611b\u5c71\u6797", "00639.TW": "\u5bcc\u90a6\u6df1100", "1541.TW": "\u9329\u6cf0", "00712.TW": "FH\u5bcc\u6642\u4e0d\u52d5\u7522", "5321.TWO": "\u53cb\u9293", "00700.TW": "\u5bcc\u90a6\u6046\u751f\u570b\u4f01", "5521.TW": "\u5de5\u4fe1", "3231.TW": "\u7def\u5275", "8935.TWO": "\u90a6\u6cf0", "00880B.TWO": "\u7b2c\u4e00\u91d1\u96fb\u4fe1\u50b515+", "4763.TW": "\u6750\u6599-KY", "3624.TWO": "\u5149\u9821", "3022.TW": "\u5a01\u5f37\u96fb", "1233.TW": "\u5929\u4ec1", "2449.TW": "\u4eac\u5143\u96fb\u5b50", "1526.TW": "\u65e5\u99b3", "1452.TW": "\u5b8f\u76ca", "3031.TW": "\u4f70\u9d3b", "3010.TW": "\u83ef\u7acb", "6139.TW": "\u4e9e\u7fd4", "2548.TW": "\u83ef\u56fa", "1810.TW": "\u548c\u6210", "5609.TWO": "\u4e2d\u83f2\u884c", "5516.TWO": "\u96d9\u559c", "2816.TW": "\u65fa\u65fa\u4fdd", "6803.TWO": "\u5d11\u9f0e", "5227.TWO": "\u7acb\u51f1-KY", "5512.TWO": "\u529b\u9e92", "5511.TWO": "\u5fb7\u660c", "9934.TW": "\u6210\u9716", "6154.TWO": "\u9806\u767c", "5315.TWO": "\u5149\u806f", "00693U.TW": "\u8857\u53e3S&P\u9ec3\u8c46", "3206.TWO": "\u5fd7\u8c50", "6558.TW": "\u8208\u80fd\u9ad8", "1524.TW": "\u803f\u9f0e", "4188.TWO": "\u5b89\u514b", "5904.TWO": "\u5bf6\u96c5", "7402.TWO": "\u9091\u9321", "2481.TW": "\u5f37\u8302", "4916.TW": "\u4e8b\u6b23\u79d1", "8446.TWO": "\u83ef\u7814", "1465.TW": "\u5049\u5168", "6180.TWO": "\u6a58\u5b50", "5309.TWO": "\u7cfb\u7d71\u96fb", "00719B.TWO": "\u5143\u5927\u7f8e\u50b51-3", "3701.TW": "\u5927\u773e\u63a7", "6625.TW": "\u5fc5\u61c9", "00653L.TW": "\u5bcc\u90a6\u5370\u5ea6\u6b632", "3521.TWO": "\u9d3b\u7fca", "00832B.TWO": "\u65b0\u5149\u7f8e\u50b520+", "5289.TWO": "\u5b9c\u9f0e", "3272.TWO": "\u6771\u78a9", "6248.TWO": "\u6c9b\u6ce2", "5864.TWO": "\u81f4\u548c\u8b49", "1109.TW": "\u4fe1\u5927", "4945.TWO": "\u965e\u9054\u79d1\u6280", "5533.TW": "\u7687\u9f0e", "2484.TW": "\u5e0c\u83ef", "2059.TW": "\u5ddd\u6e56", "5272.TWO": "\u7b19\u79d1", "00753L.TW": "\u4e2d\u4fe1\u4e2d\u570b50\u6b632", "2485.TW": "\u5146\u8d6b", "2451.TW": "\u5275\u898b", "3023.TW": "\u4fe1\u90a6", "2908.TW": "\u7279\u529b", "6220.TWO": "\u5cb3\u8c50", "00742.TW": "\u65b0\u5149\u5167\u9700\u6536\u76ca", "2316.TW": "\u6960\u6893\u96fb", "2527.TW": "\u5b8f\u749f", "3306.TWO": "\u9f0e\u5929", "8067.TWO": "\u5fd7\u65ed", "00866.TW": "\u65b0\u5149SHILLER CAPE", "1709.TW": "\u548c\u76ca", "3037.TW": "\u6b23\u8208", "2355.TW": "\u656c\u9d6c", "5484.TW": "\u6167\u53cb", "8163.TW": "\u9054\u65b9", "2342.TW": "\u8302\u77fd", "00862B.TWO": "\u4e2d\u4fe1\u6295\u8cc7\u7d1a\u516c\u53f8\u50b5", "4764.TW": "\u96d9\u9375", "2460.TW": "\u5efa\u901a", "1796.TWO": "\u91d1\u7a4e\u751f\u6280", "8071.TWO": "\u80fd\u7387\u7db2\u901a", "1307.TW": "\u4e09\u82b3", "3229.TW": "\u665f\u9226", "2636.TW": "\u53f0\u9a4a\u6295\u63a7", "4160.TWO": "\u5275\u6e90", "3016.TW": "\u5609\u6676", "2436.TW": "\u5049\u8a6e\u96fb", "1504.TW": "\u6771\u5143", "2356.TW": "\u82f1\u696d\u9054", "6461.TWO": "\u76ca\u5f97", "5245.TWO": "\u667a\u6676", "5392.TWO": "\u61c9\u83ef", "8215.TW": "\u660e\u57fa\u6750", "4950.TWO": "\u7267\u6771", "1102.TW": "\u4e9e\u6ce5", "2640.TWO": "\u5927\u8eca\u968a", "3346.TW": "\u9e97\u6e05", "4545.TW": "\u9298\u923a", "3530.TW": "\u6676\u76f8\u5149", "2362.TW": "\u85cd\u5929", "1225.TW": "\u798f\u61cb\u6cb9", "3687.TWO": "\u6b50\u8cb7\u5c2c", "4912.TW": "\u806f\u5fb7\u63a7\u80a1-KY", "4138.TWO": "\u66dc\u4e9e", "1210.TW": "\u5927\u6210", "6201.TW": "\u4e9e\u5f18\u96fb", "6176.TW": "\u745e\u5100", "2867.TW": "\u4e09\u5546\u58fd", "9802.TW": "\u923a\u9f4a-KY", "4766.TW": "\u5357\u5bf6", "6173.TWO": "\u4fe1\u660c\u96fb", "1589.TW": "\u6c38\u51a0-KY", "4198.TWO": "\u6b23\u5927\u5065\u5eb7", "1314.TW": "\u4e2d\u77f3\u5316", "6177.TW": "\u9054\u9e97", "2430.TW": "\u71e6\u5764", "9911.TW": "\u6afb\u82b1", "4536.TW": "\u62d3\u51f1", "2360.TW": "\u81f4\u8302", "2415.TW": "\u9329\u65b0", "1617.TW": "\u69ae\u661f", "3499.TWO": "\u74b0\u5929\u79d1", "0054.TW": "\u5143\u5927\u53f0\u554650", "4935.TW": "\u8302\u6797-KY", "3057.TW": "\u55ac\u9f0e", "00709.TW": "\u5bcc\u90a6\u6b50\u6d32", "3290.TWO": "\u6771\u6d66", "6292.TWO": "\u8fc5\u5fb7", "8926.TW": "\u53f0\u6c7d\u96fb", "2722.TW": "\u590f\u90fd", "1340.TW": "\u52dd\u6085-KY", "8433.TWO": "\u5f18\u5e06", "9919.TW": "\u5eb7\u90a3\u9999", "3515.TW": "\u83ef\u64ce", "6582.TW": "\u7533\u8c50", "3083.TWO": "\u7db2\u9f8d", "3321.TW": "\u540c\u6cf0", "3360.TWO": "\u5c1a\u7acb", "7556.TWO": "\u610f\u5fb7\u58eb", "4153.TWO": "\u923a\u7def", "5534.TW": "\u9577\u8679", "1531.TW": "\u9ad8\u6797\u80a1", "3219.TWO": "\u501a\u5f37\u80a1\u4efd", "4911.TWO": "\u5fb7\u82f1", "6574.TWO": "\u9708\u65b9", "1762.TW": "\u4e2d\u5316\u751f", "2423.TW": "\u56fa\u7def", "1423.TW": "\u5229\u83ef", "6191.TW": "\u7cbe\u6210\u79d1", "4907.TWO": "\u5bcc\u5b87", "1470.TW": "\u5927\u7d71\u65b0\u5275", "6516.TWO": "\u52e4\u5d34\u570b\u969b", "3236.TWO": "\u5343\u5982", "3609.TWO": "\u6771\u6797", "3252.TWO": "\u6d77\u7063", "00694B.TWO": "\u5bcc\u90a6\u7f8e\u50b51-3\u5e74", "5465.TWO": "\u5bcc\u9a4a", "5314.TWO": "\u4e16\u7d00", "2752.TWO": "\u8c46\u5e9c", "1220.TW": "\u53f0\u69ae", "8040.TWO": "\u4e5d\u6698", "2616.TW": "\u5c71\u9686", "4116.TWO": "\u660e\u57fa\u91ab", "6579.TW": "\u7814\u63da", "4994.TW": "\u50b3\u5947", "00660.TW": "\u5143\u5927\u6b50\u6d3250", "3455.TWO": "\u7531\u7530", "6451.TW": "\u8a0a\u82af-KY", "1460.TW": "\u5b8f\u9060", "2375.TW": "\u51f1\u7f8e", "1529.TW": "\u6a02\u58eb", "00770.TW": "\u570b\u6cf0\u5317\u7f8e\u79d1\u6280", "2455.TW": "\u5168\u65b0", "9925.TW": "\u65b0\u4fdd", "9929.TW": "\u79cb\u96e8", "2374.TW": "\u4f73\u80fd", "8097.TWO": "\u5e38\u73f5", "9935.TW": "\u6176\u8c50\u5bcc", "6472.TWO": "\u4fdd\u745e", "6021.TWO": "\u5927\u6176\u8b49", "00723B.TWO": "\u7fa4\u76ca15\u5e74IG\u79d1\u6280\u50b5", "2506.TW": "\u592a\u8a2d", "3494.TW": "\u8aa0\u7814", "8416.TWO": "\u5be6\u5a01", "8084.TWO": "\u5de8\u8679", "8464.TW": "\u5104\u8c50", "5460.TWO": "\u540c\u5354", "6538.TWO": "\u5009\u548c", "3607.TW": "\u8c37\u5d27", "2535.TW": "\u9054\u6b23\u5de5", "5203.TW": "\u8a0a\u9023", "4942.TW": "\u5609\u5f70", "4429.TWO": "\u805a\u7d21", "8473.TW": "\u5c71\u6797\u6c34", "2312.TW": "\u91d1\u5bf6", "8109.TWO": "\u535a\u5927", "6492.TWO": "\u751f\u83ef\u79d1", "1218.TW": "\u6cf0\u5c71", "6274.TWO": "\u53f0\u71ff", "2911.TW": "\u9e97\u5b30\u623f", "8234.TWO": "\u65b0\u6f22", "2363.TW": "\u77fd\u7d71", "3296.TW": "\u52dd\u5fb7", "4142.TW": "\u570b\u5149\u751f", "2405.TW": "\u6d69\u946b", "2025.TW": "\u5343\u8208", "1256.TW": "\u9bae\u6d3b\u679c\u6c41-KY", "00839B.TWO": "\u51f1\u57fa\u91ab\u7642\u4fdd\u5065\u50b5", "3570.TWO": "\u5927\u585a", "6457.TWO": "\u7d18\u5eb7", "00795B.TWO": "\u4e2d\u4fe1\u7f8e\u570b\u516c\u50b520\u5e74", "2855.TW": "\u7d71\u4e00\u8b49", "3373.TWO": "\u71b1\u6620", "3372.TWO": "\u5178\u7bc4", "6168.TW": "\u5b8f\u9f4a", "3026.TW": "\u79be\u4f38\u5802", "2035.TWO": "\u5510\u69ae", "2838.TW": "\u806f\u90a6\u9280", "1439.TW": "\u4e2d\u548c", "3268.TWO": "\u6d77\u5fb7\u5a01", "3324.TWO": "\u96d9\u9d3b", "8070.TW": "\u9577\u83ef*", "1612.TW": "\u5b8f\u6cf0", "4303.TWO": "\u4fe1\u7acb", "6188.TWO": "\u5ee3\u660e", "5014.TWO": "\u5efa\u9329", "2612.TW": "\u4e2d\u822a", "00836B.TWO": "\u6c38\u8c5010\u5e74A\u516c\u53f8\u50b5", "1532.TW": "\u52e4\u7f8e", "3004.TW": "\u8c50\u9054\u79d1", "4806.TWO": "\u6607\u83ef", "8255.TWO": "\u670b\u7a0b", "6577.TWO": "\u52c1\u8c50", "6649.TWO": "\u53f0\u751f\u6750", "2511.TW": "\u592a\u5b50", "8940.TW": "\u65b0\u5929\u5730", "2596.TWO": "\u7da0\u610f", "1781.TWO": "\u5408\u4e16", "3555.TWO": "\u91cd\u9d6c", "3308.TW": "\u806f\u5fb7", "1708.TW": "\u6771\u9e7c", "1616.TW": "\u5104\u6cf0", "6165.TW": "\u6377\u6cf0", "6118.TWO": "\u5efa\u9054", "5523.TWO": "\u8c50\u8b19", "1201.TW": "\u5473\u5168", "2061.TWO": "\u98a8\u9752", "5011.TWO": "\u4e45\u967d", "3131.TWO": "\u5f18\u5851", "2443.TW": "\u5104\u9e97", "6284.TWO": "\u4f73\u90a6", "4953.TWO": "\u7def\u8edf", "9933.TW": "\u4e2d\u9f0e", "1514.TW": "\u4e9e\u529b", "4557.TW": "\u6c38\u65b0-KY", "1338.TW": "\u5ee3\u83ef-KY", "4743.TWO": "\u5408\u4e00", "1799.TWO": "\u6613\u5a01", "4168.TWO": "\u91a3\u806f", "2208.TW": "\u53f0\u8239", "3323.TWO": "\u52a0\u767e\u88d5", "2605.TW": "\u65b0\u8208", "3128.TWO": "\u6607\u92b3", "006203.TW": "\u5143\u5927MSCI\u53f0\u7063", "6482.TWO": "\u5f18\u715c\u79d1", "4111.TWO": "\u6fdf\u751f", "2444.TW": "\u5146\u52c1", "2812.TW": "\u53f0\u4e2d\u9280", "6142.TW": "\u53cb\u52c1", "1580.TWO": "\u65b0\u9ea5", "8043.TWO": "\u871c\u671b\u5be6", "8390.TWO": "\u91d1\u76ca\u9f0e", "3284.TWO": "\u592a\u666e\u9ad8", "6229.TWO": "\u7814\u901a", "1615.TW": "\u5927\u5c71", "9930.TW": "\u4e2d\u806f\u8cc7\u6e90", "3543.TW": "\u5dde\u5de7", "1308.TW": "\u4e9e\u805a", "2385.TW": "\u7fa4\u5149", "3317.TWO": "\u5c3c\u514b\u68ee", "1626.TW": "\u827e\u7f8e\u7279-KY", "1451.TW": "\u5e74\u8208", "1103.TW": "\u5609\u6ce5", "3276.TWO": "\u5b87\u74b0", "00733.TW": "\u5bcc\u90a6\u81fa\u7063\u4e2d\u5c0f", "1477.TW": "\u805a\u967d", "3522.TWO": "\u5fa1\u9802", "4171.TWO": "\u745e\u57fa", "3027.TW": "\u76db\u9054", "2029.TW": "\u76db\u9918", "6271.TW": "\u540c\u6b23\u96fb", "4807.TW": "\u65e5\u6210-KY", "4568.TWO": "\u79d1\u969b\u7cbe\u5bc6", "3213.TWO": "\u8302\u8a0a", "8176.TWO": "\u667a\u6377", "6150.TWO": "\u64bc\u8a0a", "6609.TWO": "\u7027\u6fa4\u79d1", "1742.TWO": "\u53f0\u881f", "3713.TWO": "\u65b0\u6676\u6295\u63a7", "2476.TW": "\u9245\u7965", "00874B.TWO": "\u51f1\u57faBBB\u516c\u53f8\u50b515+", "1586.TWO": "\u548c\u52e4", "00794B.TWO": "\u7fa4\u76ca7+\u4e2d\u570b\u653f\u91d1\u50b5", "9924.TW": "\u798f\u8208", "6126.TWO": "\u4fe1\u97f3", "8291.TWO": "\u5c1a\u8302", "00840B.TWO": "\u51f1\u57faIG\u7cbe\u907815+", "6237.TWO": "\u9a4a\u8a0a", "5487.TWO": "\u901a\u6cf0", "3481.TW": "\u7fa4\u5275", "6155.TW": "\u921e\u5bf6", "6541.TW": "\u6cf0\u798f-KY", "00860B.TWO": "\u7fa4\u76ca1-5\u5e74IG\u50b5", "4120.TWO": "\u53cb\u83ef", "5907.TW": "\u5927\u6d0b-KY", "2062.TW": "\u6a4b\u693f", "4995.TWO": "\u6676\u9054", "8072.TW": "\u965e\u6cf0", "3035.TW": "\u667a\u539f", "8093.TWO": "\u4fdd\u92b3", "00731.TW": "FH\u5bcc\u6642\u9ad8\u606f\u4f4e\u6ce2", "1711.TW": "\u6c38\u5149", "6147.TWO": "\u980e\u90a6", "2890.TW": "\u6c38\u8c50\u91d1", "2390.TW": "\u4e91\u8fb0", "00661.TW": "\u5143\u5927\u65e5\u7d93225", "6573.TW": "\u8679\u63da-KY", "8404.TW": "\u767e\u548c\u8208\u696d-KY", "8240.TWO": "\u83ef\u5b8f", "6530.TWO": "\u5275\u5a01", "3171.TWO": "\u65b0\u6d32", "4746.TW": "\u53f0\u8000", "2377.TW": "\u5fae\u661f", "00784B.TWO": "\u5bcc\u90a6\u4e2d\u570b\u6295\u7b49\u50b5", "8432.TWO": "\u6771\u751f\u83ef", "3202.TWO": "\u6a3a\u665f", "8044.TWO": "\u7db2\u5bb6", "4706.TWO": "\u5927\u606d", "8341.TW": "\u65e5\u53cb", "0055.TW": "\u5143\u5927MSCI\u91d1\u878d", "6208.TWO": "\u65e5\u63da", "6288.TW": "\u806f\u5609", "6703.TWO": "\u8ed2\u90c1", "4502.TWO": "\u5065\u4fe1", "4128.TWO": "\u4e2d\u5929", "4529.TWO": "\u6df3\u7d33", "00697B.TWO": "\u5143\u5927\u7f8e\u50b57-10", "1476.TW": "\u5112\u9d3b", "3591.TW": "\u827e\u7b1b\u68ee", "4609.TWO": "\u5510\u92d2", "3454.TW": "\u6676\u777f", "2376.TW": "\u6280\u5609", "8087.TWO": "\u83ef\u9382\u946b", "3013.TW": "\u665f\u9298\u96fb", "2617.TW": "\u53f0\u822a", "8931.TWO": "\u5927\u6c7d\u96fb", "2207.TW": "\u548c\u6cf0\u8eca", "8436.TWO": "\u5927\u6c5f", "9955.TW": "\u4f73\u9f8d", "8081.TW": "\u81f4\u65b0", "8410.TWO": "\u68ee\u7530", "2748.TW": "\u96f2\u54c1", "5434.TW": "\u5d07\u8d8a", "2615.TW": "\u842c\u6d77", "5701.TWO": "\u528d\u6e56\u5c71", "8917.TWO": "\u6b23\u6cf0", "4205.TWO": "\u4e2d\u83ef\u98df", "3011.TW": "\u4eca\u7693", "1435.TW": "\u4e2d\u798f", "8349.TWO": "\u6052\u8000", "1713.TW": "\u570b\u5316", "8489.TWO": "\u4e09\u8c9d\u5fb7", "4967.TW": "\u5341\u9293", "6163.TWO": "\u83ef\u96fb\u7db2", "4306.TW": "\u708e\u6d32", "6754.TW": "\u532f\u50d1\u8a2d\u8a08", "1217.TW": "\u611b\u4e4b\u5473", "6732.TWO": "\u6607\u4f73\u96fb\u5b50", "8423.TWO": "\u4fdd\u7da0-KY", "1512.TW": "\u745e\u5229", "5474.TWO": "\u8070\u6cf0", "3188.TWO": "\u946b\u9f8d\u9a30", "5015.TWO": "\u83ef\u797a", "1313.TW": "\u806f\u6210", "2543.TW": "\u7687\u660c", "00842B.TWO": "\u53f0\u65b0\u7f8e\u5143\u9280\u884c\u50b5", "2368.TW": "\u91d1\u50cf\u96fb", "8068.TWO": "\u5168\u9054", "2881.TW": "\u5bcc\u90a6\u91d1", "2425.TW": "\u627f\u555f", "2465.TW": "\u9e97\u81fa", "4729.TWO": "\u7192\u8302", "6640.TWO": "\u5747\u83ef", "3441.TWO": "\u806f\u4e00\u5149", "2340.TW": "\u5149\u78ca", "6591.TW": "\u52d5\u529b-KY", "4417.TWO": "\u91d1\u6d32", "00751B.TWO": "\u5143\u5927AAA\u81f3A\u516c\u53f8\u50b5", "2939.TW": "\u51f1\u7fbf-KY", "5902.TWO": "\u5fb7\u8a18", "6533.TW": "\u6676\u5fc3\u79d1", "00856B.TWO": "\u6c38\u8c501-3\u5e74\u7f8e\u516c\u50b5", "9928.TW": "\u4e2d\u8996", "2601.TW": "\u76ca\u822a", "8111.TWO": "\u7acb\u7881", "6174.TWO": "\u5b89\u7881", "4413.TWO": "\u98db\u5bf6\u4f01\u696d", "8080.TWO": "\u6c38\u5229\u806f\u5408", "2913.TW": "\u8fb2\u6797", "6666.TW": "\u7f85\u9e97\u82ac-KY", "3623.TWO": "\u5bcc\u6676\u901a", "1336.TWO": "\u53f0\u7ff0", "6464.TW": "\u53f0\u6578\u79d1", "00782B.TWO": "\u570b\u6cf0A\u7d1a\u516c\u7528\u50b5", "3178.TWO": "\u516c\u6e96", "5386.TWO": "\u9752\u96f2", "2539.TW": "\u6afb\u82b1\u5efa", "2228.TW": "\u528d\u9e9f", "6590.TWO": "\u666e\u9d3b", "3597.TWO": "\u6620\u8208", "3535.TW": "\u6676\u5f69\u79d1", "2327.TW": "\u570b\u5de8", "3434.TWO": "\u54f2\u56fa", "2321.TW": "\u6771\u8a0a", "00756B.TWO": "\u7fa4\u76ca15\u5e74EM\u4e3b\u6b0a\u50b5", "00871B.TWO": "\u5143\u5927\u4e2d\u570b\u653f\u91d1\u50b5", "2013.TW": "\u4e2d\u92fc\u69cb", "9937.TW": "\u5168\u570b", "3605.TW": "\u5b8f\u81f4", "8927.TWO": "\u5317\u57fa", "4944.TWO": "\u5146\u9060", "3646.TWO": "\u827e\u6069\u7279", "3520.TWO": "\u83ef\u76c8", "2426.TW": "\u9f0e\u5143", "5291.TWO": "\u9091\u6607", "00789B.TWO": "FH\u516c\u53f8\u50b5A3", "00775B.TW": "\u65b0\u5149\u6295\u7b49\u50b515+", "9902.TW": "\u53f0\u706b", "6214.TW": "\u7cbe\u8aa0", "5464.TWO": "\u9716\u5b8f", "3114.TWO": "\u597d\u5fb7", "00757.TW": "\u7d71\u4e00FANG+", "2063.TWO": "\u4e16\u93a7", "00754B.TWO": "\u7fa4\u76caAAA-AA\u516c\u53f8\u50b5", "00778B.TWO": "\u51f1\u57fa\u91d1\u878d\u50b520+", "3631.TWO": "\u665f\u6960", "2009.TW": "\u7b2c\u4e00\u9285", "1528.TW": "\u6069\u5fb7", "3147.TWO": "\u5927\u7d9c", "1773.TW": "\u52dd\u4e00", "3060.TW": "\u9298\u7570", "3266.TW": "\u6607\u967d", "4133.TW": "\u4e9e\u8afe\u6cd5", "5312.TWO": "\u5bf6\u5cf6\u79d1", "5340.TWO": "\u5efa\u69ae", "4721.TWO": "\u7f8e\u742a\u746a", "8277.TWO": "\u5546\u4e1e", "6535.TWO": "\u9806\u85e5", "8928.TWO": "\u9245\u660e", "3501.TW": "\u7dad\u71b9", "4562.TW": "\u7a4e\u6f22", "6219.TWO": "\u5bcc\u65fa", "5351.TWO": "\u923a\u5275", "5007.TW": "\u4e09\u661f", "006201.TWO": "\u5143\u5927\u5bcc\u6ac350", "5285.TW": "\u754c\u9716", "1583.TW": "\u7a0b\u6cf0", "5210.TWO": "\u5bf6\u78a9", "2324.TW": "\u4ec1\u5bf6", "2483.TW": "\u767e\u5bb9", "5016.TWO": "\u677e\u548c", "6655.TW": "\u79d1\u5b9a", "3552.TWO": "\u540c\u81f4", "3511.TWO": "\u77fd\u746a", "00850.TW": "\u5143\u5927\u81fa\u7063ESG\u6c38\u7e8c", "2454.TW": "\u806f\u767c\u79d1", "3066.TWO": "\u674e\u6d32", "3055.TW": "\u851a\u83ef\u79d1", "2347.TW": "\u806f\u5f37", "1414.TW": "\u6771\u548c", "6266.TWO": "\u6cf0\u8a60", "00869B.TWO": "FT10-25\u5e74\u516c\u53f8\u50b5", "8440.TWO": "\u7da0\u96fb", "8937.TWO": "\u5408\u9a0f", "5225.TW": "\u6771\u79d1-KY", "8482.TW": "\u5546\u5104-KY", "6136.TW": "\u5bcc\u723e\u7279", "00670L.TW": "\u5bcc\u90a6NASDAQ\u6b632", "6589.TWO": "\u53f0\u5eb7\u751f\u6280", "9950.TWO": "\u842c\u570b\u901a", "00845B.TWO": "\u5bcc\u90a6\u65b0\u8208\u6295\u7b49\u50b5", "3596.TW": "\u667a\u6613", "2820.TW": "\u83ef\u7968", "3218.TWO": "\u5927\u5b78\u5149", "8105.TW": "\u51cc\u5de8", "6209.TW": "\u4eca\u570b\u5149", "3645.TW": "\u9054\u9081", "3437.TW": "\u69ae\u5275", "4173.TWO": "\u4e45\u88d5", "6216.TW": "\u5c45\u6613", "3122.TWO": "\u7b19\u6cc9", "6204.TWO": "\u827e\u83ef", "1503.TW": "\u58eb\u96fb", "2067.TWO": "\u5609\u92fc", "00652.TW": "\u5bcc\u90a6\u5370\u5ea6", "6486.TWO": "\u4e92\u52d5", "4552.TW": "\u529b\u9054-KY", "2464.TW": "\u76df\u7acb", "1736.TW": "\u55ac\u5c71", "6182.TWO": "\u5408\u6676", "9958.TW": "\u4e16\u7d00\u92fc", "5603.TWO": "\u9678\u6d77", "3071.TWO": "\u5354\u79a7", "4154.TWO": "\u5eb7\u6a02-KY", "3362.TWO": "\u5148\u9032\u5149", "4968.TW": "\u7acb\u7a4d", "3491.TWO": "\u6607\u9054\u79d1", "6241.TWO": "\u6613\u901a\u5c55", "8066.TWO": "\u4f86\u601d\u9054", "5299.TWO": "\u6770\u529b", "3090.TW": "\u65e5\u96fb\u8cbf", "2431.TW": "\u806f\u660c", "2358.TW": "\u5ef7\u946b", "5469.TW": "\u701a\u5b87\u535a", "2236.TW": "\u767e\u9054-KY", "2393.TW": "\u5104\u5149", "2317.TW": "\u9d3b\u6d77", "2450.TW": "\u795e\u8166", "3297.TWO": "\u676d\u7279", "3034.TW": "\u806f\u8a60", "00714.TW": "\u7fa4\u76ca\u9053\u74ca\u7f8e\u570b\u5730\u7522", "2038.TW": "\u6d77\u5149", "8074.TWO": "\u9245\u6a61", "00690.TW": "\u5146\u8c50\u85cd\u7c4c30", "8442.TW": "\u5a01\u5b8f-KY", "3036.TW": "\u6587\u66c4", "00713.TW": "\u5143\u5927\u53f0\u7063\u9ad8\u606f\u4f4e\u6ce2", "3189.TW": "\u666f\u78a9", "6642.TWO": "\u5bcc\u81f4", "2337.TW": "\u65fa\u5b8f", "6143.TWO": "\u632f\u66dc", "3444.TWO": "\u5229\u6a5f", "6598.TW": "ABC-KY", "5234.TW": "\u9054\u8208\u6750\u6599", "3325.TWO": "\u65ed\u54c1", "6133.TW": "\u91d1\u6a4b", "5328.TWO": "\u83ef\u5bb9", "5212.TWO": "\u51cc\u7db2", "2743.TWO": "\u5c71\u5bcc", "8905.TWO": "\u88d5\u570b", "4401.TWO": "\u6771\u9686\u8208", "2489.TW": "\u745e\u8ed2", "2388.TW": "\u5a01\u76db", "6287.TWO": "\u5143\u9686", "2206.TW": "\u4e09\u967d\u5de5\u696d", "6113.TWO": "\u4e9e\u77fd", "00777B.TWO": "\u51f1\u57faAAA\u81f3A\u516c\u53f8\u50b5", "6415.TW": "\u77fd\u529b-KY", "4804.TWO": "\u5927\u7565-KY", "00665L.TW": "\u5bcc\u90a6\u6052\u751f\u570b\u4f01\u6b632", "5438.TWO": "\u6771\u53cb", "5455.TWO": "\u6607\u76ca", "00738U.TW": "\u5143\u5927\u9053\u74ca\u767d\u9280", "2438.TW": "\u7fd4\u8000", "3483.TWO": "\u529b\u81f4", "00876.TW": "\u5143\u5927\u672a\u4f86\u95dc\u9375\u79d1\u6280", "2702.TW": "\u83ef\u5712", "6405.TW": "\u6085\u57ce", "5439.TWO": "\u9ad8\u6280", "6183.TW": "\u95dc\u8cbf", "6127.TWO": "\u4e5d\u8c6a", "6190.TWO": "\u842c\u6cf0\u79d1", "4543.TWO": "\u842c\u5728", "3209.TW": "\u5168\u79d1", "5251.TWO": "\u5929\u925e\u96fb", "2916.TWO": "\u6eff\u5fc3", "00790B.TWO": "FH\u6b21\u9806\u4f4dIG\u91d1\u878d\u50b5", "6568.TWO": "\u5b8f\u89c0", "2472.TW": "\u7acb\u9686\u96fb", "1538.TW": "\u6b63\u5cf0", "8038.TWO": "\u9577\u5712\u79d1", "1590.TW": "\u4e9e\u5fb7\u5ba2-KY", "1108.TW": "\u5e78\u798f", "6121.TWO": "\u65b0\u666e", "00774C.TW": "\u65b0\u5149\u4e2d\u653f\u91d1\u7da0\u50b5+R", "4952.TW": "\u51cc\u901a", "1593.TWO": "\u797a\u9a4a", "1707.TW": "\u8461\u8404\u738b", "6469.TWO": "\u5927\u6a39", "00725B.TWO": "\u570b\u6cf0\u6295\u8cc7\u7d1a\u516c\u53f8\u50b5", "00703.TW": "\u53f0\u65b0MSCI\u4e2d\u570b", "3015.TW": "\u5168\u6f22", "3694.TW": "\u6d77\u83ef", "6263.TWO": "\u666e\u840a\u5fb7", "3228.TWO": "\u91d1\u9e97\u79d1", "2834.TW": "\u81fa\u4f01\u9280", "2745.TWO": "\u4e94\u798f", "5706.TW": "\u9cf3\u51f0", "4576.TW": "\u5927\u9280\u5fae\u7cfb\u7d71", "1315.TW": "\u9054\u65b0", "2028.TW": "\u5a01\u81f4", "3545.TW": "\u6566\u6cf0", "1817.TW": "\u51f1\u6492\u885b", "6148.TWO": "\u9a4a\u5b8f\u8cc7", "1305.TW": "\u83ef\u590f", "8033.TW": "\u96f7\u864e", "4739.TW": "\u5eb7\u666e", "6194.TWO": "\u80b2\u5bcc", "0052.TW": "\u5bcc\u90a6\u79d1\u6280", "00710B.TW": "FH\u5f6d\u535a\u9ad8\u6536\u76ca\u50b5", "3516.TWO": "\u4e9e\u5e1d\u6b50", "1301.TW": "\u53f0\u5851", "8938.TWO": "\u660e\u5b89", "2331.TW": "\u7cbe\u82f1", "4148.TW": "\u5168\u5b87\u751f\u6280-KY", "1309.TW": "\u53f0\u9054\u5316", "1809.TW": "\u4e2d\u91c9", "2924.TWO": "\u6771\u51cc-KY", "3048.TW": "\u76ca\u767b", "2017.TW": "\u5b98\u7530\u92fc", "3105.TWO": "\u7a69\u61cb", "3051.TW": "\u529b\u7279", "00773B.TWO": "\u4e2d\u4fe1\u512a\u5148\u91d1\u878d\u50b5", "3402.TWO": "\u6f22\u79d1", "00645.TW": "\u5bcc\u90a6\u65e5\u672c", "1258.TWO": "\u5176\u7965-KY", "6144.TWO": "\u5f97\u5229\u5f71", "00865B.TW": "\u570b\u6cf0US\u77ed\u671f\u516c\u50b5", "4989.TW": "\u69ae\u79d1", "2427.TW": "\u4e09\u5546\u96fb", "3232.TWO": "\u6631\u6377", "1725.TW": "\u5143\u798e", "3390.TWO": "\u65ed\u8edf", "5536.TWO": "\u8056\u6689", "6244.TWO": "\u8302\u8fea", "6690.TWO": "\u5b89\u7881\u8cc7\u8a0a", "6581.TW": "\u92fc\u806f", "3030.TW": "\u5fb7\u5f8b", "2108.TW": "\u5357\u5e1d", "5471.TW": "\u677e\u7ff0", "2434.TW": "\u7d71\u61cb", "2906.TW": "\u9ad8\u6797", "4542.TWO": "\u79d1\u5da0", "00792B.TWO": "\u7fa4\u76caA\u7d1a\u516c\u53f8\u50b5", "5269.TW": "\u7965\u78a9", "2313.TW": "\u83ef\u901a", "5213.TWO": "\u4e9e\u6615", "6151.TWO": "\u6649\u502b", "2417.TW": "\u5713\u525b", "2707.TW": "\u6676\u83ef", "5876.TW": "\u4e0a\u6d77\u5546\u9280", "3684.TWO": "\u69ae\u660c", "1229.TW": "\u806f\u83ef", "3265.TWO": "\u53f0\u661f\u79d1", "5457.TWO": "\u5ba3\u5fb7", "6671.TW": "\u4e09\u80fd-KY", "1436.TW": "\u83ef\u53cb\u806f", "5274.TWO": "\u4fe1\u9a4a", "5263.TWO": "\u667a\u5d34", "1464.TW": "\u5f97\u529b", "6443.TW": "\u5143\u6676", "00737.TW": "\u570b\u6cf0AI+ROBO", "3711.TW": "\u65e5\u6708\u5149\u6295\u63a7", "2428.TW": "\u8208\u52e4", "5546.TW": "\u6c38\u56fa-KY", "6203.TWO": "\u6d77\u97fb\u96fb", "5356.TWO": "\u5354\u76ca", "2910.TW": "\u7d71\u9818", "4439.TW": "\u51a0\u661f-KY", "3492.TWO": "\u9577\u76db", "4903.TWO": "\u806f\u5149\u901a", "1240.TWO": "\u8302\u751f\u8fb2\u7d93", "00741B.TWO": "\u5bcc\u90a6\u5168\u7403\u9ad8\u6536\u50b5", "3691.TWO": "\u78a9\u79be", "2406.TW": "\u570b\u78a9", "6506.TWO": "\u96d9\u90a6", "4162.TWO": "\u667a\u64ce", "2642.TW": "\u5b85\u914d\u901a", "3550.TW": "\u806f\u7a4e", "1565.TWO": "\u7cbe\u83ef", "6432.TWO": "\u4eca\u5c55\u79d1", "3141.TWO": "\u6676\u5b8f", "3686.TW": "\u9054\u80fd", "5478.TWO": "\u667a\u51a0", "6140.TWO": "\u8a0a\u9054", "00779B.TWO": "\u51f1\u57fa\u7f8e\u50b525+", "6278.TW": "\u53f0\u8868\u79d1", "4304.TWO": "\u52dd\u6631", "3707.TWO": "\u6f22\u78ca", "1232.TW": "\u5927\u7d71\u76ca", "4433.TWO": "\u8208\u91c7", "2904.TW": "\u532f\u50d1", "2301.TW": "\u5149\u5bf6\u79d1", "6230.TW": "\u8d85\u773e", "9907.TW": "\u7d71\u4e00\u5be6", "1312.TW": "\u570b\u55ac", "8354.TWO": "\u51a0\u597d", "2727.TW": "\u738b\u54c1", "3661.TW": "\u4e16\u82af-KY", "006206.TW": "\u5143\u5927\u4e0a\u8b4950", "2492.TW": "\u83ef\u65b0\u79d1", "3693.TWO": "\u71df\u90a6", "3673.TW": "TPK-KY", "00687B.TWO": "\u570b\u6cf020\u5e74\u7f8e\u50b5", "00646.TW": "\u5143\u5927S&P500", "6114.TWO": "\u4e45\u5a01", "6111.TWO": "\u5927\u5b87\u8cc7", "4563.TWO": "\u767e\u5fb7", "1540.TW": "\u55ac\u798f", "2493.TW": "\u63da\u535a", "8478.TW": "\u6771\u54e5\u904a\u8247", "3118.TWO": "\u9032\u968e", "3257.TW": "\u8679\u51a0\u96fb", "8476.TWO": "\u53f0\u5883", "00843B.TWO": "\u53f0\u65b0\u4e2d\u570b\u653f\u7b56\u50b5", "6552.TW": "\u6613\u83ef\u96fb", "6679.TWO": "\u923a\u592a", "6624.TWO": "\u842c\u5e74\u6e05", "1806.TW": "\u51a0\u8ecd", "2401.TW": "\u51cc\u967d", "6197.TW": "\u4f73\u5fc5\u742a", "6195.TWO": "\u8a69\u80af", "4714.TWO": "\u6c38\u6377", "9939.TW": "\u5b8f\u5168", "3438.TWO": "\u985e\u6bd4\u79d1", "6548.TWO": "\u9577\u79d1*", "8467.TW": "\u6ce2\u529b-KY", "3564.TWO": "\u5176\u967d", "2880.TW": "\u83ef\u5357\u91d1", "3086.TWO": "\u83ef\u7fa9", "4106.TW": "\u96c3\u535a", "00726B.TWO": "\u570b\u6cf05Y+\u65b0\u8208\u50b5", "4972.TWO": "\u6e6f\u77f3\u7167\u660e", "6715.TW": "\u5609\u57fa", "5230.TWO": "\u96f7\u7b1b\u514b\u5149\u5b78", "1614.TW": "\u4e09\u6d0b\u96fb", "4131.TWO": "\u6676\u5b87", "00831B.TWO": "\u65b0\u5149\u7f8e\u50b51-3", "6462.TWO": "\u795e\u76fe", "2239.TW": "\u82f1\u5229-KY", "4956.TW": "\u5149\u92d0", "00673R.TW": "\u5143\u5927S&P\u539f\u6cb9\u53cd1", "2014.TW": "\u4e2d\u9d3b", "1264.TWO": "\u5fb7\u9ea5", "4971.TWO": "IET-KY", "2462.TW": "\u826f\u5f97\u96fb", "00674R.TW": "\u5143\u5927S&P\u9ec3\u91d1\u53cd1", "5432.TWO": "\u9054\u5a01", "1316.TW": "\u4e0a\u66dc", "1339.TW": "\u662d\u8f1d", "3577.TWO": "\u6cd3\u683c", "1786.TW": "\u79d1\u598d", "1783.TW": "\u548c\u5eb7\u751f", "6231.TWO": "\u7cfb\u5fae", "5520.TWO": "\u529b\u6cf0", "4908.TWO": "\u524d\u9f0e", "1440.TW": "\u5357\u7d21", "1419.TW": "\u65b0\u7d21", "4991.TWO": "\u74b0\u5b87-KY", "4130.TWO": "\u5065\u4e9e", "2515.TW": "\u4e2d\u5de5", "2114.TW": "\u946b\u6c38\u9293", "1537.TW": "\u5ee3\u9686", "6026.TWO": "\u798f\u90a6\u8b49", "4966.TWO": "\u8b5c\u745e-KY", "00689R.TW": "\u570b\u6cf020\u5e74\u7f8e\u50b5\u53cd1", "2495.TW": "\u666e\u5b89", "6294.TWO": "\u667a\u57fa", "00686R.TW": "\u7fa4\u76ca\u81fa\u7063\u52a0\u6b0a\u53cd1", "4183.TWO": "\u798f\u6c38\u751f\u6280", "00708L.TW": "\u5143\u5927S&P\u9ec3\u91d1\u6b632", "6698.TW": "\u65ed\u6689\u61c9\u6750", "1515.TW": "\u529b\u5c71", "3706.TW": "\u795e\u9054", "8107.TWO": "\u5927\u5104\u91d1\u8302", "3518.TW": "\u67cf\u9a30", "2610.TW": "\u83ef\u822a", "6560.TWO": "\u6b23\u666e\u7f85", "2345.TW": "\u667a\u90a6", "00717.TW": "\u5bcc\u90a6\u7f8e\u570b\u7279\u5225\u80a1", "3443.TW": "\u5275\u610f", "3207.TWO": "\u8000\u52dd", "8930.TWO": "\u9752\u92fc", "8089.TWO": "\u5eb7\u5168\u96fb\u8a0a", "2404.TW": "\u6f22\u5510", "3581.TWO": "\u535a\u78ca", "4737.TW": "\u83ef\u5ee3", "00879B.TWO": "\u7b2c\u4e00\u91d1\u7f8e\u50b50-1", "1215.TW": "\u535c\u8702", "6152.TW": "\u767e\u4e00", "4108.TW": "\u61f7\u7279", "5425.TWO": "\u53f0\u534a", "2609.TW": "\u967d\u660e", "2734.TWO": "\u6613\u98db\u7db2", "1216.TW": "\u7d71\u4e00", "00718B.TWO": "\u5bcc\u90a6\u4e2d\u570b\u653f\u7b56\u50b5", "6112.TW": "\u805a\u78a9", "2926.TWO": "\u8aa0\u54c1\u751f\u6d3b", "1907.TW": "\u6c38\u8c50\u9918", "1582.TW": "\u4fe1\u9326", "6282.TW": "\u5eb7\u8212", "2303.TW": "\u806f\u96fb", "5220.TWO": "\u842c\u9054\u5149\u96fb", "2603.TW": "\u9577\u69ae", "00643K.TW": "\u7fa4\u76ca\u6df1\u8a3c\u4e2d\u5c0f+R", "4105.TWO": "\u6771\u6d0b", "6223.TWO": "\u65fa\u77fd", "4960.TW": "\u8aa0\u7f8e\u6750", "6654.TWO": "\u5929\u6b63\u570b\u969b", "2008.TW": "\u9ad8\u8208\u660c", "6257.TW": "\u77fd\u683c", "6404.TWO": "\u901a\u8a0a-KY", "5871.TW": "\u4e2d\u79df-KY", "9944.TW": "\u65b0\u9e97", "00669R.TW": "\u570b\u6cf0\u7f8e\u570b\u9053\u74ca\u53cd1", "5348.TWO": "\u7cfb\u901a", "1337.TW": "\u518d\u751f-KY", "4905.TWO": "\u53f0\u806f\u96fb", "3093.TWO": "\u6e2f\u5efa", "6412.TW": "\u7fa4\u96fb", "4430.TWO": "\u8000\u5104", "4503.TWO": "\u91d1\u96e8", "5398.TWO": "\u6155\u5eb7\u751f\u91ab", "4938.TW": "\u548c\u78a9", "6122.TWO": "\u64ce\u90a6", "3679.TW": "\u65b0\u81f3\u965e", "2496.TW": "\u5353\u8d8a", "6101.TWO": "\u5bec\u9b5a\u570b\u969b", "5206.TWO": "\u5764\u6085", "2392.TW": "\u6b63\u5d34", "9917.TW": "\u4e2d\u4fdd\u79d1", "8261.TW": "\u5bcc\u9f0e", "4510.TWO": "\u9ad8\u92d2", "6184.TW": "\u5927\u8c50\u96fb", "6270.TWO": "\u500d\u5fae", "3540.TWO": "\u66dc\u8d8a", "2497.TW": "\u6021\u5229\u96fb", "1611.TW": "\u4e2d\u96fb", "4109.TWO": "\u52a0\u6377\u751f\u91ab", "00679B.TWO": "\u5143\u5927\u7f8e\u50b520\u5e74", "4190.TW": "\u4f50\u767b-KY", "00786B.TWO": "\u5143\u592710\u5e74IG\u9280\u884c\u50b5", "5013.TWO": "\u5f37\u65b0", "8916.TWO": "\u5149\u9686", "1516.TW": "\u5ddd\u98db", "6523.TWO": "\u9054\u723e\u819a", "6261.TWO": "\u4e45\u5143", "5202.TWO": "\u529b\u65b0", "1702.TW": "\u5357\u50d1", "1453.TW": "\u5927\u5c07", "9951.TWO": "\u7687\u7530", "3663.TWO": "\u946b\u79d1", "2330.TW": "\u53f0\u7a4d\u96fb", "3628.TWO": "\u76c8\u6b63", "6167.TWO": "\u4e45\u6b63", "00830.TW": "\u570b\u6cf0\u8cbb\u57ce\u534a\u5c0e\u9ad4", "6674.TW": "\u92d0\u5bf6\u79d1\u6280", "6228.TWO": "\u5168\u8b5c", "6641.TW": "\u57fa\u58eb\u5fb7-KY", "6198.TWO": "\u51cc\u6cf0", "4712.TWO": "\u5357\u748b", "6247.TWO": "\u6dc7\u8b7d\u96fb", "4580.TWO": "\u6377\u6d41\u95a5\u696d", "2501.TW": "\u570b\u5efa", "6669.TW": "\u7def\u7a4e", "6124.TWO": "\u696d\u5f37", "6129.TWO": "\u666e\u8aa0", "00867B.TWO": "\u65b0\u5149A-BBB\u96fb\u4fe1\u50b5", "6531.TW": "\u611b\u666e", "1456.TW": "\u6021\u83ef", "1733.TW": "\u4e94\u9f0e", "5475.TWO": "\u5fb7\u5b8f", "4716.TWO": "\u5927\u7acb", "00711B.TW": "FH\u5f6d\u535a\u65b0\u8208\u50b5", "2034.TW": "\u5141\u5f37", "1570.TWO": "\u529b\u80af", "2414.TW": "\u7cbe\u6280", "3531.TWO": "\u5148\u76ca", "00783.TW": "\u5bcc\u90a6\u4e2d\u8a3c500", "00781B.TWO": "\u570b\u6cf0A\u7d1a\u79d1\u6280\u50b5", "2606.TW": "\u88d5\u6c11", "9943.TW": "\u597d\u6a02\u8fea", "3556.TWO": "\u79be\u745e\u4e9e", "1110.TW": "\u6771\u6ce5", "2905.TW": "\u4e09\u5546", "2409.TW": "\u53cb\u9054", "2371.TW": "\u5927\u540c", "00857B.TWO": "\u6c38\u8c5020\u5e74\u7f8e\u516c\u50b5", "6213.TW": "\u806f\u8302", "6418.TWO": "\u8a60\u6607", "8083.TWO": "\u745e\u7a4e", "3033.TW": "\u5a01\u5065", "2891.TW": "\u4e2d\u4fe1\u91d1", "00655L.TW": "\u570b\u6cf0\u4e2d\u570bA50\u6b632", "5525.TW": "\u9806\u5929", "8929.TWO": "\u5bcc\u5821", "3046.TW": "\u5efa\u7881", "2353.TW": "\u5b8f\u7881", "2351.TW": "\u9806\u5fb7", "1521.TW": "\u5927\u5104", "1471.TW": "\u9996\u5229", "3191.TWO": "\u548c\u9032", "2457.TW": "\u98db\u5b8f", "1805.TW": "\u5bf6\u5fa0", "006207.TW": "FH\u6eec\u6df1", "6160.TWO": "\u6b23\u6280", "2369.TW": "\u83f1\u751f", "4909.TWO": "\u65b0\u5fa9\u8208", "2440.TW": "\u592a\u7a7a\u68ad", "5452.TWO": "\u4f76\u512a", "00685L.TW": "\u7fa4\u76ca\u81fa\u7063\u52a0\u6b0a\u6b632", "8099.TWO": "\u5927\u4e16\u79d1", "00758B.TWO": "FH\u80fd\u6e90\u50b5", "2006.TW": "\u6771\u548c\u92fc\u9435", "6212.TWO": "\u7406\u9298", "8069.TWO": "\u5143\u592a", "2739.TW": "\u5bd2\u820d", "2884.TW": "\u7389\u5c71\u91d1", "6592.TW": "\u548c\u6f64\u4f01\u696d", "6185.TWO": "\u5e43\u7fd4", "1319.TW": "\u6771\u967d", "00739.TW": "\u5143\u5927MSCI A\u80a1", "4506.TWO": "\u5d07\u53cb", "4207.TWO": "\u74b0\u6cf0", "6115.TW": "\u93b0\u52dd", "2719.TWO": "\u71e6\u661f\u65c5", "3380.TW": "\u660e\u6cf0", "4741.TWO": "\u6cd3\u701a", "1789.TW": "\u795e\u9686", "6103.TWO": "\u5408\u90a6", "00664R.TW": "\u570b\u6cf0\u81fa\u7063\u52a0\u6b0a\u53cd1", "2015.TW": "\u8c50\u8208", "3622.TW": "\u6d0b\u83ef", "2069.TW": "\u904b\u9329", "5278.TWO": "\u5c1a\u51e1", "3541.TWO": "\u897f\u67cf", "8443.TW": "\u963f\u7626", "2357.TW": "\u83ef\u78a9", "8027.TWO": "\u9226\u6607", "6227.TWO": "\u8302\u7db8", "8444.TWO": "\u7da0\u6cb3-KY", "6578.TWO": "\u9054\u90a6\u86cb\u767d", "5468.TWO": "\u51f1\u923a", "6153.TW": "\u5609\u806f\u76ca", "3672.TWO": "\u5eb7\u806f\u8a0a", "2429.TW": "\u9298\u65fa\u79d1", "8455.TWO": "\u5927\u62d3-KY", "5371.TWO": "\u4e2d\u5149\u96fb", "2491.TW": "\u5409\u7965\u5168", "4744.TWO": "\u7687\u5c07", "3227.TWO": "\u539f\u76f8", "1609.TW": "\u5927\u4e9e", "2801.TW": "\u5f70\u9280", "5302.TWO": "\u592a\u6b23", "4123.TWO": "\u665f\u5fb7", "4119.TW": "\u65ed\u5bcc", "3625.TWO": "\u897f\u52dd", "2597.TW": "\u6f64\u5f18", "1416.TW": "\u5ee3\u8c50", "3038.TW": "\u5168\u53f0", "00668K.TW": "\u570b\u6cf0\u7f8e\u570b\u9053\u74ca+U", "6283.TW": "\u6df3\u5b89", "3017.TW": "\u5947\u92d0", "6224.TW": "\u805a\u9f0e", "3558.TWO": "\u795e\u6e96", "00676R.TW": "\u5bcc\u90a6\u81fa\u7063\u52a0\u6b0a\u53cd1", "00650L.TW": "FH\u9999\u6e2f\u6b632", "3006.TW": "\u6676\u8c6a\u79d1", "0053.TW": "\u5143\u5927\u96fb\u5b50", "2101.TW": "\u5357\u6e2f", "3028.TW": "\u589e\u4f60\u5f37", "2466.TW": "\u51a0\u897f\u96fb", "00849B.TWO": "\u4e2d\u4fe1EM\u4e3b\u6b0a\u50b50-5", "6556.TWO": "\u52dd\u54c1", "2852.TW": "\u7b2c\u4e00\u4fdd", "4551.TW": "\u667a\u4f38\u79d1", "1446.TW": "\u5b8f\u548c", "00750B.TWO": "\u51f1\u57fa\u79d1\u6280\u50b510+", "2608.TW": "\u5609\u91cc\u5927\u69ae", "4167.TWO": "\u677e\u745e\u85e5", "6243.TW": "\u8fc5\u6770", "6141.TW": "\u67cf\u627f", "1443.TW": "\u7acb\u76ca", "3056.TW": "\u7e3d\u592a", "1101.TW": "\u53f0\u6ce5", "6456.TW": "GIS-KY", "9918.TW": "\u6b23\u5929\u7136", "6670.TW": "\u5fa9\u76db\u61c9\u7528", "1517.TW": "\u5229\u5947", "2395.TW": "\u7814\u83ef", "00768B.TWO": "FH20\u5e74\u7f8e\u50b5", "8942.TWO": "\u68ee\u9245", "5355.TWO": "\u4f73\u7e3d", "6414.TW": "\u6a3a\u6f22", "00771.TW": "\u5143\u5927US\u9ad8\u606f\u7279\u5225\u80a1", "00872B.TWO": "\u51f1\u57fa\u7f8e\u50b51-3", "3526.TWO": "\u51e1\u7532", "00796B.TWO": "\u4e2d\u4fe1\u4e2d\u570b\u50b57-10", "6281.TW": "\u5168\u570b\u96fb", "4747.TWO": "\u5f37\u751f", "1599.TWO": "\u5b8f\u4f73\u9a30", "6643.TWO": "M31", "5514.TWO": "\u4e09\u8c50", "2528.TW": "\u7687\u666e", "1463.TW": "\u5f37\u76db", "6716.TWO": "\u61c9\u5ee3", "5498.TWO": "\u51f1\u5d34", "6667.TWO": "\u4fe1\u7d18\u79d1", "00728.TW": "\u7b2c\u4e00\u91d1\u5de5\u696d30", "8403.TWO": "\u76db\u5f18", "8171.TWO": "\u5929\u5b87", "8906.TWO": "\u82b1\u738b", "9906.TW": "\u6b23\u5df4\u5df4", "8249.TW": "\u83f1\u5149", "2397.TW": "\u53cb\u901a", "6156.TWO": "\u677e\u4e0a", "2809.TW": "\u4eac\u57ce\u9280", "2736.TWO": "\u9ad8\u91ce", "3546.TWO": "\u5b87\u5cfb", "8046.TW": "\u5357\u96fb", "00852L.TW": "\u570b\u6cf0\u7f8e\u570b\u9053\u74ca\u6b632", "4999.TW": "\u946b\u79be", "00633L.TW": "\u5bcc\u90a6\u4e0a\u8a3c\u6b632", "4720.TW": "\u5fb7\u6df5", "3685.TWO": "\u5143\u5275\u7cbe\u5bc6", "2065.TWO": "\u4e16\u8c50", "6199.TWO": "\u5929\u54c1", "4406.TWO": "\u65b0\u6615\u7e96", "00634R.TW": "\u5bcc\u90a6\u4e0a\u8a3c\u53cd1", "4906.TW": "\u6b63\u6587", "3703.TW": "\u6b23\u9678", "00844B.TWO": "\u65b0\u514915\u5e74IG\u91d1\u878d\u50b5", "6246.TWO": "\u81fa\u9f8d", "4534.TWO": "\u6176\u9a30", "2227.TW": "\u88d5\u65e5\u8eca", "3689.TWO": "\u6e67\u5fb7", "1734.TW": "\u674f\u8f1d", "5481.TWO": "\u65b0\u83ef", "6130.TWO": "\u661f\u5bf6\u570b\u969b", "4961.TW": "\u5929\u923a", "6024.TW": "\u7fa4\u76ca\u671f", "006208.TW": "\u5bcc\u90a6\u53f050", "2547.TW": "\u65e5\u52dd\u751f", "6259.TWO": "\u767e\u5fbd", "00675L.TW": "\u5bcc\u90a6\u81fa\u7063\u52a0\u6b0a\u6b632", "00772B.TWO": "\u4e2d\u4fe1\u9ad8\u8a55\u7d1a\u516c\u53f8\u50b5", "8401.TWO": "\u767d\u7d17\u79d1", "8271.TW": "\u5b87\u77bb", "2439.TW": "\u7f8e\u5f8b", "2032.TW": "\u65b0\u92fc", "3045.TW": "\u53f0\u7063\u5927", "6192.TW": "\u5de8\u8def", "2235.TWO": "\u8b1a\u6e90", "00873B.TWO": "\u51f1\u57fa\u65b0\u8208\u50b51-5", "6441.TWO": "\u5ee3\u9320", "8932.TWO": "\u5b8f\u5927", "6510.TWO": "\u7cbe\u6e2c", "00657K.TW": "\u570b\u6cf0\u65e5\u7d93225+U", "2103.TW": "\u53f0\u6a61", "2030.TW": "\u5f70\u6e90", "3049.TW": "\u548c\u946b", "3264.TWO": "\u6b23\u9293", "2633.TW": "\u53f0\u7063\u9ad8\u9435", "00868B.TWO": "FT1-3\u5e74\u7f8e\u516c\u50b5", "3450.TW": "\u806f\u921e", "1441.TW": "\u5927\u6771", "2897.TW": "\u738b\u9053\u9280\u884c", "3224.TWO": "\u4e09\u9867", "2516.TW": "\u65b0\u5efa", "3675.TWO": "\u5fb7\u5fae", "00656R.TW": "\u570b\u6cf0\u4e2d\u570bA50\u53cd1", "2367.TW": "\u71ff\u83ef", "00755B.TWO": "\u7fa4\u76ca15\u5e74IG\u516c\u7528\u50b5", "00740B.TWO": "\u5bcc\u90a6\u5168\u7403\u6295\u7b49\u50b5", "6508.TWO": "\u60e0\u5149", "2915.TW": "\u6f64\u6cf0\u5168", "1727.TW": "\u4e2d\u83ef\u5316", "6603.TWO": "\u5bcc\u5f37\u946b", "00662.TW": "\u5bcc\u90a6NASDAQ", "6505.TW": "\u53f0\u5851\u5316", "4535.TWO": "\u81f3\u8208", "8924.TWO": "\u5927\u7530", "4979.TWO": "\u83ef\u661f\u5149", "3043.TW": "\u79d1\u98a8", "1417.TW": "\u5609\u88d5", "1227.TW": "\u4f73\u683c", "6419.TWO": "\u4eac\u6668\u79d1", "3303.TWO": "\u5cb1\u7a1c", "1604.TW": "\u8072\u5bf6", "3490.TWO": "\u55ae\u4e95", "2105.TW": "\u6b63\u65b0", "4711.TWO": "\u6c38\u7d14", "9941.TW": "\u88d5\u878d", "6161.TWO": "\u6377\u6ce2", "4104.TW": "\u4f73\u91ab", "8422.TW": "\u53ef\u5be7\u885b", "1536.TW": "\u548c\u5927", "6171.TWO": "\u4e9e\u92b3\u58eb", "2023.TW": "\u71c1\u8f1d", "00736.TW": "\u570b\u6cf0\u65b0\u8208\u5e02\u5834", "6239.TW": "\u529b\u6210", "2328.TW": "\u5ee3\u5b87", "00727B.TWO": "\u570b\u6cf01-5Y\u9ad8\u6536\u50b5", "1410.TW": "\u5357\u67d3", "6189.TW": "\u8c50\u85dd", "8121.TWO": "\u8d8a\u5cf0", "9904.TW": "\u5bf6\u6210", "6613.TWO": "\u670b\u5104", "2233.TW": "\u5b87\u9686", "1906.TW": "\u5bf6\u9686", "2536.TW": "\u5b8f\u666e", "00745B.TWO": "\u5bcc\u90a6\u4e2d\u653f\u50b50-1", "3532.TW": "\u53f0\u52dd\u79d1", "3512.TWO": "\u7687\u9f8d", "4121.TWO": "\u512a\u76db", "1506.TW": "\u6b63\u9053", "2634.TW": "\u6f22\u7fd4", "00791B.TWO": "FH\u7f8e\u5143\u4fe1\u7528\u50b51-5Y", "3379.TWO": "\u5f6c\u53f0", "5353.TWO": "\u53f0\u6797", "3653.TW": "\u5065\u7b56", "8096.TWO": "\u64ce\u4e9e", "6175.TWO": "\u7acb\u6566", "4572.TW": "\u99d0\u9f8d", "1303.TW": "\u5357\u4e9e", "3413.TW": "\u4eac\u9f0e", "6166.TW": "\u51cc\u83ef", "4927.TW": "\u6cf0\u9f0e-KY", "2882.TW": "\u570b\u6cf0\u91d1", "2107.TW": "\u539a\u751f", "3669.TW": "\u5713\u5c55", "6179.TWO": "\u4e9e\u901a", "8435.TWO": "\u9245\u9081", "8279.TWO": "\u751f\u5c55", "3081.TWO": "\u806f\u4e9e", "00632R.TW": "\u5143\u5927\u53f0\u706350\u53cd1", "5906.TW": "\u53f0\u5357-KY", "2064.TWO": "\u6649\u693f", "6226.TW": "\u5149\u9f0e", "5538.TW": "\u6771\u660e-KY", "4419.TWO": "\u5143\u52dd", "00785B.TWO": "\u5bcc\u90a6\u91d1\u878d\u6295\u7b49\u50b5", "1104.TW": "\u74b0\u6ce5", "2204.TW": "\u4e2d\u83ef", "1475.TW": "\u672c\u76df", "3338.TW": "\u6cf0\u78a9", "4426.TW": "\u5229\u52e4", "00692.TW": "\u5bcc\u90a6\u516c\u53f8\u6cbb\u7406", "3008.TW": "\u5927\u7acb\u5149", "9946.TW": "\u4e09\u767c\u5730\u7522", "3163.TWO": "\u6ce2\u82e5\u5a01", "00859B.TWO": "\u7fa4\u76ca0-1\u5e74\u7f8e\u50b5", "3164.TW": "\u666f\u5cb3", "1409.TW": "\u65b0\u7e96", "3067.TWO": "\u5168\u57df", "6509.TWO": "\u805a\u548c", "3162.TWO": "\u7cbe\u78ba", "00858.TWO": "\u6c38\u8c50\u7f8e\u570b500\u5927", "00788B.TWO": "\u5143\u592710\u5e74IG\u96fb\u80fd\u50b5", "6164.TW": "\u83ef\u8208", "1513.TW": "\u4e2d\u8208\u96fb", "2241.TW": "\u827e\u59c6\u52d2", "3167.TW": "\u5927\u91cf", "2365.TW": "\u6606\u76c8", "6222.TWO": "\u4e0a\u63da", "1903.TW": "\u58eb\u7d19", "8472.TWO": "\u5920\u9ebb\u5409", "6409.TW": "\u65ed\u96bc", "4561.TWO": "\u5065\u693f", "4566.TW": "\u6642\u78a9\u5de5\u696d", "8367.TW": "\u5efa\u65b0\u570b\u969b", "3294.TWO": "\u82f1\u6fdf", "8103.TW": "\u701a\u8343", "4164.TW": "\u627f\u696d\u91ab", "2514.TW": "\u9f8d\u90a6", "2726.TWO": "\u96c5\u8317-KY", "2630.TW": "\u4e9e\u822a", "2731.TW": "\u96c4\u7345", "5515.TW": "\u5efa\u570b", "2424.TW": "\u96b4\u83ef", "8028.TW": "\u6607\u967d\u534a\u5c0e\u9ad4", "2704.TW": "\u570b\u8cd3", "8921.TWO": "\u6c88\u6c0f", "2066.TWO": "\u4e16\u5fb7", "006204.TW": "\u6c38\u8c50\u81fa\u7063\u52a0\u6b0a", "8131.TW": "\u798f\u61cb\u79d1", "3682.TW": "\u4e9e\u592a\u96fb", "6547.TWO": "\u9ad8\u7aef\u75ab\u82d7", "4147.TWO": "\u4e2d\u88d5", "3059.TW": "\u83ef\u6676\u79d1", "1730.TW": "\u82b1\u4ed9\u5b50", "2705.TW": "\u516d\u798f", "2382.TW": "\u5ee3\u9054", "1432.TW": "\u5927\u9b6f\u95a3", "2885.TW": "\u5143\u5927\u91d1", "1438.TW": "\u4e09\u5730\u958b\u767c", "006205.TW": "\u5bcc\u90a6\u4e0a\u8a3c", "6169.TWO": "\u6631\u6cc9", "0050.TW": "\u5143\u5927\u53f0\u706350", "2729.TWO": "\u74e6\u57ce", "00681R.TW": "\u5143\u5927\u7f8e\u50b520\u53cd1", "00864B.TWO": "\u4e2d\u4fe1\u7f8e\u570b\u516c\u50b50-1", "2348.TW": "\u6d77\u6085", "5205.TWO": "\u4e2d\u8302", "4755.TW": "\u4e09\u798f\u5316", "3527.TWO": "\u805a\u7a4d", "9938.TW": "\u767e\u548c", "5493.TWO": "\u4e09\u806f", "3024.TW": "\u61b6\u8072", "00787B.TWO": "\u5143\u592710\u5e74IG\u91ab\u7642\u50b5", "1735.TW": "\u65e5\u52dd\u5316", "5281.TWO": "\u5927\u5cfd\u8c37-KY", "8213.TW": "\u5fd7\u8d85", "4946.TWO": "\u8fa3\u6912", "8462.TW": "\u67cf\u6587", "5410.TWO": "\u570b\u773e", "3310.TWO": "\u4f73\u7a4e", "00759B.TWO": "FH\u88fd\u85e5\u50b5", "1701.TW": "\u4e2d\u5316", "6146.TWO": "\u8015\u8208", "00684R.TW": "\u5143\u5927\u7f8e\u5143\u6307\u6578\u53cd1", "3050.TW": "\u923a\u5fb7", "1527.TW": "\u947d\u5168", "9926.TW": "\u65b0\u6d77", "3130.TW": "\u4e00\u96f6\u56db", "4933.TWO": "\u53cb\u8f1d", "4564.TW": "\u5143\u7fce", "6290.TWO": "\u826f\u7dad", "8908.TWO": "\u6b23\u96c4", "9945.TW": "\u6f64\u6cf0\u65b0", "00743.TW": "\u570b\u6cf0\u4e2d\u570bA150", "00625K.TW": "\u5bcc\u90a6\u4e0a\u8a3c+R", "3054.TW": "\u7acb\u842c\u5229", "1712.TW": "\u8208\u8fb2", "8936.TWO": "\u570b\u7d71", "4726.TWO": "\u6c38\u6615", "2887.TW": "\u53f0\u65b0\u91d1", "1723.TW": "\u4e2d\u78b3", "1473.TW": "\u53f0\u5357", "00657.TW": "\u570b\u6cf0\u65e5\u7d93225", "1304.TW": "\u53f0\u805a", "1444.TW": "\u529b\u9e97", "3234.TWO": "\u5149\u74b0", "00651R.TW": "FH\u9999\u6e2f\u53cd1", "4126.TWO": "\u592a\u91ab", "4702.TWO": "\u4e2d\u7f8e\u5be6", "00635U.TW": "\u5143\u5927S&P\u9ec3\u91d1", "8415.TWO": "\u5927\u570b\u92fc", "5450.TWO": "\u5357\u826f", "3548.TWO": "\u5146\u5229", "00877.TWO": "FH\u4e2d\u570b5G", "8077.TWO": "\u6d1b\u7881", "00636.TW": "\u570b\u6cf0\u4e2d\u570bA50", "1341.TW": "\u5bcc\u6797-KY", "8110.TW": "\u83ef\u6771", "4976.TW": "\u4f73\u51cc", "3702.TW": "\u5927\u806f\u5927", "1760.TW": "\u5bf6\u9f61\u5bcc\u9326", "4432.TWO": "\u9298\u65fa\u5be6", "4745.TWO": "\u5408\u5bcc-KY", "1454.TW": "\u53f0\u5bcc", "8150.TW": "\u5357\u8302", "3466.TWO": "\u81f4\u632f", "4931.TWO": "\u65b0\u76db\u529b", "1466.TW": "\u805a\u9686", "1467.TW": "\u5357\u7def", "3416.TW": "\u878d\u7a0b\u96fb", "6020.TWO": "\u5927\u5c55\u8b49", "9940.TW": "\u4fe1\u7fa9", "3617.TW": "\u78a9\u5929", "5381.TWO": "\u5408\u6b63", "2221.TWO": "\u5927\u7532", "5310.TWO": "\u5929\u525b", "1813.TWO": "\u5bf6\u5229\u5fa0", "2488.TW": "\u6f22\u5e73", "00671R.TW": "\u5bcc\u90a6NASDAQ\u53cd1", "2545.TW": "\u7687\u7fd4", "3632.TWO": "\u7814\u52e4", "8039.TW": "\u53f0\u8679", "3551.TWO": "\u4e16\u79be", "2614.TW": "\u6771\u68ee", "3230.TWO": "\u9326\u660e", "00641R.TW": "\u5bcc\u90a6\u65e5\u672c\u53cd1", "2509.TW": "\u5168\u5764\u5efa", "6494.TWO": "\u4e5d\u9f4a", "3664.TWO": "\u5b89\u745e-KY", "4192.TWO": "\u674f\u570b", "2031.TW": "\u65b0\u5149\u92fc", "6491.TW": "\u6676\u78a9", "2613.TW": "\u4e2d\u6ac3", "2530.TW": "\u83ef\u5efa", "8342.TWO": "\u76ca\u5f35", "5903.TWO": "\u5168\u5bb6", "1457.TW": "\u5b9c\u9032", "1447.TW": "\u529b\u9d6c", "4736.TWO": "\u6cf0\u535a", "4538.TWO": "\u5927\u8a60\u57ce", "6285.TW": "\u555f\u7881", "8114.TW": "\u632f\u6a3a\u96fb", "1737.TW": "\u81fa\u9e7d", "2607.TW": "\u69ae\u904b", "4414.TW": "\u5982\u8208", "4533.TWO": "\u5354\u6613\u6a5f", "4541.TWO": "\u665f\u7530", "6431.TW": "\u5149\u9e97-KY", "3489.TWO": "\u68ee\u5bf6", "1310.TW": "\u53f0\u82ef", "5483.TWO": "\u4e2d\u7f8e\u6676", "4581.TW": "\u5149\u9686\u7cbe\u5bc6-KY", "2892.TW": "\u7b2c\u4e00\u91d1", "2478.TW": "\u5927\u6bc5", "9914.TW": "\u7f8e\u5229\u9054", "0056.TW": "\u5143\u5927\u9ad8\u80a1\u606f", "1442.TW": "\u540d\u8ed2", "3058.TW": "\u7acb\u5fb7", "00642U.TW": "\u5143\u5927S&P\u77f3\u6cb9", "2480.TW": "\u6566\u967d\u79d1", "4523.TWO": "\u6c38\u5f70", "6435.TWO": "\u5927\u4e2d", "3205.TWO": "\u4f70\u7814", "6269.TW": "\u53f0\u90e1", "2923.TW": "\u9f0e\u56fa-KY", "4987.TWO": "\u79d1\u8aa0", "00746B.TWO": "\u5bcc\u90a6A\u7d1a\u516c\u53f8\u50b5", "4139.TWO": "\u99ac\u5149-KY", "3563.TW": "\u7267\u5fb7", "5905.TWO": "\u5357\u4ec1\u6e56", "3363.TWO": "\u4e0a\u8a6e", "1905.TW": "\u83ef\u7d19", "9912.TW": "\u5049\u806f"} \ No newline at end of file diff --git a/assets_us.json b/assets_us.json new file mode 100644 index 0000000..582bc7b --- /dev/null +++ b/assets_us.json @@ -0,0 +1 @@ +{"ABC": "AmerisourceBergen Corporation", "VFC": "V.F. Corporation", "UNM": "Unum Group", "SBUX": "Starbucks Corporation", "RSG": "Republic Services, Inc.", "IVZ": "Invesco Ltd.", "KR": "The Kroger Co.", "TDG": "TransDigm Group Incorporated", "MAA": "Mid-America Apartment Communities, Inc.", "VWO": "Vanguard FTSE Emerging Markets Index Fund ETF Shares", "UDR": "UDR, Inc.", "EXPD": "Expeditors International of Washington, Inc.", "AIG": "American International Group, Inc.", "REG": "Regency Centers Corporation", "CMA": "Comerica Incorporated", "IQV": "IQVIA Holdings Inc.", "OKE": "ONEOK, Inc.", "IPG": "The Interpublic Group of Companies, Inc.", "BSX": "Boston Scientific Corporation", "RJF": "Raymond James Financial, Inc.", "O": "Realty Income Corporation", "LNC": "Lincoln National Corporation", "ANSS": "ANSYS, Inc.", "IFF": "International Flavors & Fragrances Inc.", "BR": "Broadridge Financial Solutions, Inc.", "V": "Visa Inc.", "FITB": "Fifth Third Bancorp", "NWL": "Newell Brands Inc.", "ITW": "Illinois Tool Works Inc.", "CCI": "Crown Castle International Corp. (REIT)", "TRV": "The Travelers Companies, Inc.", "HPE": "Hewlett Packard Enterprise Company", "HP": "Helmerich & Payne, Inc.", "WY": "Weyerhaeuser Company", "AVGO": "Broadcom Inc.", "PFE": "Pfizer Inc.", "EW": "Edwards Lifesciences Corporation", "STZ": "Constellation Brands, Inc.", "PFG": "Principal Financial Group, Inc.", "EFX": "Equifax Inc.", "BF-B": "Brown-Forman Corporation", "ANET": "Arista Networks, Inc.", "LVS": "Las Vegas Sands Corp.", "CSCO": "Cisco Systems, Inc.", "ALLE": "Allegion plc", "ROP": "Roper Technologies, Inc.", "KMB": "Kimberly-Clark Corporation", "EIX": "Edison International", "VRTX": "Vertex Pharmaceuticals Incorporated", "AMP": "Ameriprise Financial, Inc.", "PWR": "Quanta Services, Inc.", "HSY": "The Hershey Company", "AMZN": "Amazon.com, Inc.", "ADSK": "Autodesk, Inc.", "VRSN": "VeriSign, Inc.", "VB": "Vanguard Small-Cap Index Fund ETF Shares", "TT": "Trane Technologies plc", "HD": "The Home Depot, Inc.", "AAP": "Advance Auto Parts, Inc.", "NDAQ": "Nasdaq, Inc.", "BAC": "Bank of America Corporation", "MCHP": "Microchip Technology Incorporated", "DTE": "DTE Energy Company", "NUE": "Nucor Corporation", "LEG": "Leggett & Platt, Incorporated", "EA": "Electronic Arts Inc.", "CE": "Celanese Corporation", "MU": "Micron Technology, Inc.", "MSI": "Motorola Solutions, Inc.", "RCL": "Royal Caribbean Cruises Ltd.", "CAG": "Conagra Brands, Inc.", "JWN": "Nordstrom, Inc.", "HRB": "H&R Block, Inc.", "ADBE": "Adobe Inc.", "QCOM": "QUALCOMM Incorporated", "OMC": "Omnicom Group Inc.", "SYF": "Synchrony Financial", "PCAR": "PACCAR Inc", "BBY": "Best Buy Co., Inc.", "MHK": "Mohawk Industries, Inc.", "SHW": "The Sherwin-Williams Company", "SNPS": "Synopsys, Inc.", "UAL": "United Airlines Holdings, Inc.", "COTY": "Coty Inc.", "AON": "Aon Plc", "CAT": "Caterpillar Inc.", "TXN": "Texas Instruments Incorporated", "DXC": "DXC Technology Company", "DVN": "Devon Energy Corporation", "ZION": "Zions Bancorporation, National Association", "KSS": "Kohl's Corporation", "FCX": "Freeport-McMoRan Inc.", "ES": "Eversource Energy", "STE": "STERIS plc", "NVDA": "NVIDIA Corporation", "BA": "The Boeing Company", "PSX": "Phillips 66", "WM": "Waste Management, Inc.", "BRK-B": "Berkshire Hathaway Inc.", "HAL": "Halliburton Company", "FTI": "TechnipFMC plc", "GS": "The Goldman Sachs Group, Inc.", "MUB": "iShares National Muni Bond ETF", "PHM": "PulteGroup, Inc.", "IP": "International Paper Company", "MPC": "Marathon Petroleum Corporation", "L": "Loews Corporation", "PRU": "Prudential Financial, Inc.", "MKTX": "MarketAxess Holdings Inc.", "UNH": "UnitedHealth Group Incorporated", "MMM": "3M Company", "FOXA": "Fox Corporation", "AIV": "Apartment Investment and Management Company", "SNA": "Snap-on Incorporated", "CB": "Chubb Limited", "FE": "FirstEnergy Corp.", "DD": "DuPont de Nemours, Inc.", "ARNC": "Arconic Corporation", "AKAM": "Akamai Technologies, Inc.", "WELL": "Welltower Inc.", "DG": "Dollar General Corporation", "TFX": "Teleflex Incorporated", "RHI": "Robert Half International Inc.", "PEG": "Public Service Enterprise Group Incorporated", "JKHY": "Jack Henry & Associates, Inc.", "NVR": "NVR, Inc.", "CRM": "salesforce.com, inc.", "BIV": "Vanguard Intermediate-Term Bond Index Fund ETF Shares", "FAST": "Fastenal Company", "DAL": "Delta Air Lines, Inc.", "ZBH": "Zimmer Biomet Holdings, Inc.", "CHRW": "C.H. Robinson Worldwide, Inc.", "PKG": "Packaging Corporation of America", "HOLX": "Hologic, Inc.", "CVS": "CVS Health Corporation", "CPRI": "Capri Holdings Limited", "APD": "Air Products and Chemicals, Inc.", "PRGO": "Perrigo Company plc", "AES": "The AES Corporation", "M": "Macy's, Inc.", "ALGN": "Align Technology, Inc.", "VEA": "Vanguard FTSE Developed Markets Index Fund ETF Shares", "PNR": "Pentair plc", "PLD": "Prologis, Inc.", "GRMN": "Garmin Ltd.", "DUK": "Duke Energy Corporation", "CTSH": "Cognizant Technology Solutions Corporation", "UPS": "United Parcel Service, Inc.", "VRSK": "Verisk Analytics, Inc.", "PAYC": "Paycom Software, Inc.", "MMC": "Marsh & McLennan Companies, Inc.", "BKR": "Baker Hughes Company", "ALB": "Albemarle Corporation", "SWKS": "Skyworks Solutions, Inc.", "D": "Dominion Energy, Inc.", "IDXX": "IDEXX Laboratories, Inc.", "ABMD": "Abiomed, Inc.", "OXY": "Occidental Petroleum Corporation", "CAH": "Cardinal Health, Inc.", "CDW": "CDW Corporation", "RMD": "ResMed Inc.", "FTV": "Fortive Corporation", "ETR": "Entergy Corporation", "TJX": "The TJX Companies, Inc.", "TXT": "Textron Inc.", "ZTS": "Zoetis Inc.", "AAPL": "Apple Inc.", "ARE": "Alexandria Real Estate Equities, Inc.", "LHX": "L3Harris Technologies, Inc.", "BMY": "Bristol-Myers Squibb Company", "HUM": "Humana Inc.", "LDOS": "Leidos Holdings, Inc.", "AMAT": "Applied Materials, Inc.", "TROW": "T. Rowe Price Group, Inc.", "LIN": "Linde plc", "SRE": "Sempra Energy", "AOS": "A. O. Smith Corporation", "HON": "Honeywell International Inc.", "EMN": "Eastman Chemical Company", "PVH": "PVH Corp.", "ADP": "Automatic Data Processing, Inc.", "NEE": "NextEra Energy, Inc.", "HIG": "The Hartford Financial Services Group, Inc.", "ABT": "Abbott Laboratories", "EOG": "EOG Resources, Inc.", "PG": "The Procter & Gamble Company", "ALL": "The Allstate Corporation", "AEE": "Ameren Corporation", "DHI": "D.R. Horton, Inc.", "SLG": "SL Green Realty Corp.", "JCI": "Johnson Controls International plc", "SO": "The Southern Company", "MO": "Altria Group, Inc.", "FOX": "Fox Corporation", "TMO": "Thermo Fisher Scientific Inc.", "QRVO": "Qorvo, Inc.", "JBHT": "J.B. Hunt Transport Services, Inc.", "CLX": "The Clorox Company", "EXPE": "Expedia Group, Inc.", "AMGN": "Amgen Inc.", "USB": "U.S. Bancorp", "WRK": "WestRock Company", "LKQ": "LKQ Corporation", "STT": "State Street Corporation", "PKI": "PerkinElmer, Inc.", "FLS": "Flowserve Corporation", "MLM": "Martin Marietta Materials, Inc.", "SBAC": "SBA Communications Corporation (REIT)", "TSLA": "Tesla Inc.", "IT": "Gartner, Inc.", "HCA": "HCA Healthcare, Inc.", "AFL": "Aflac Incorporated", "GLW": "Corning Incorporated", "EQIX": "Equinix, Inc. (REIT)", "GOOGL": "Alphabet Inc.", "NEM": "Newmont Corporation", "KLAC": "KLA Corporation", "MNST": "Monster Beverage Corporation", "WEC": "WEC Energy Group, Inc.", "DLR": "Digital Realty Trust, Inc.", "FLT": "FLEETCOR Technologies, Inc.", "NWSA": "News Corporation", "MCD": "McDonald's Corporation", "TGT": "Target Corporation", "CNP": "CenterPoint Energy, Inc.", "ED": "Consolidated Edison, Inc.", "SCHW": "The Charles Schwab Corporation", "UAA": "Under Armour, Inc.", "FRC": "First Republic Bank", "TAP": "Molson Coors Beverage Company", "AJG": "Arthur J. Gallagher & Co.", "PYPL": "PayPal Holdings, Inc.", "MRK": "Merck & Co., Inc.", "PPL": "PPL Corporation", "LRCX": "Lam Research Corporation", "TSN": "Tyson Foods, Inc.", "NFLX": "Netflix, Inc.", "MOS": "The Mosaic Company", "EVRG": "Evergy, Inc.", "HII": "Huntington Ingalls Industries, Inc.", "WFC": "Wells Fargo & Company", "ORLY": "O'Reilly Automotive, Inc.", "BLK": "BlackRock, Inc.", "CTAS": "Cintas Corporation", "KO": "The Coca-Cola Company", "XRX": "Xerox Holdings Corporation", "HST": "Host Hotels & Resorts, Inc.", "GIS": "General Mills, Inc.", "CL": "Colgate-Palmolive Company", "WYNN": "Wynn Resorts, Limited", "TMUS": "T-Mobile US, Inc.", "CMS": "CMS Energy Corporation", "GE": "General Electric Company", "CI": "Cigna Corporation", "NTAP": "NetApp, Inc.", "NI": "NiSource Inc.", "MGM": "MGM Resorts International", "CPB": "Campbell Soup Company", "PPG": "PPG Industries, Inc.", "LYV": "Live Nation Entertainment, Inc.", "ROK": "Rockwell Automation, Inc.", "FFIV": "F5 Networks, Inc.", "ADI": "Analog Devices, Inc.", "LMT": "Lockheed Martin Corporation", "CHD": "Church & Dwight Co., Inc.", "BXP": "Boston Properties, Inc.", "WMT": "Walmart Inc.", "STX": "Seagate Technology plc", "KHC": "The Kraft Heinz Company", "AXP": "American Express Company", "PXD": "Pioneer Natural Resources Company", "BK": "The Bank of New York Mellon Corporation", "EL": "The Estee Lauder Companies Inc.", "RF": "Regions Financial Corporation", "JNPR": "Juniper Networks, Inc.", "ATVI": "Activision Blizzard, Inc.", "ABBV": "AbbVie Inc.", "KEYS": "Keysight Technologies, Inc.", "LYB": "LyondellBasell Industries N.V.", "WRB": "W. R. Berkley Corporation", "PAYX": "Paychex, Inc.", "DGX": "Quest Diagnostics Incorporated", "PGR": "The Progressive Corporation", "MSFT": "Microsoft Corporation", "TEL": "TE Connectivity Ltd.", "AEP": "American Electric Power Company, Inc.", "RL": "Ralph Lauren Corporation", "MAS": "Masco Corporation", "AMT": "American Tower Corporation (REIT)", "CSX": "CSX Corporation", "GOOG": "Alphabet Inc.", "VNO": "Vornado Realty Trust", "KIM": "Kimco Realty Corporation", "IRM": "Iron Mountain Incorporated", "WMB": "The Williams Companies, Inc.", "XRAY": "DENTSPLY SIRONA Inc.", "WAB": "Wabtec Corporation", "ACN": "Accenture plc", "TTWO": "Take-Two Interactive Software, Inc.", "RTX": "Raytheon Technologies Corporation", "ODFL": "Old Dominion Freight Line, Inc.", "HLT": "Hilton Worldwide Holdings Inc.", "VNQ": "Vanguard Real Estate Index Fund ETF Shares", "VTR": "Ventas, Inc.", "DLTR": "Dollar Tree, Inc.", "CMCSA": "Comcast Corporation", "FDX": "FedEx Corporation", "TLT": "iShares 20+ Year Treasury Bond ETF", "CHTR": "Charter Communications, Inc.", "C": "Citigroup Inc.", "GILD": "Gilead Sciences, Inc.", "SEE": "Sealed Air Corporation", "NWS": "News Corporation", "MDLZ": "Mondelez International, Inc.", "DHR": "Danaher Corporation", "CVX": "Chevron Corporation", "COP": "ConocoPhillips", "NOC": "Northrop Grumman Corporation", "XOM": "Exxon Mobil Corporation", "KMX": "CarMax, Inc.", "SYY": "Sysco Corporation", "UA": "Under Armour, Inc.", "PEP": "PepsiCo, Inc.", "ATO": "Atmos Energy Corporation", "FRT": "Federal Realty Investment Trust", "EXR": "Extra Space Storage Inc.", "INTU": "Intuit Inc.", "SLB": "Schlumberger Limited", "T": "AT&T Inc.", "TFC": "Truist Financial Corporation", "NSC": "Norfolk Southern Corporation", "HPQ": "HP Inc.", "BIIB": "Biogen Inc.", "ILMN": "Illumina, Inc.", "KEY": "KeyCorp", "CBRE": "CBRE Group, Inc.", "CBOE": "Cboe Global Markets, Inc.", "MSCI": "MSCI Inc.", "MA": "Mastercard Incorporated", "GPN": "Global Payments Inc.", "EQR": "Equity Residential", "AME": "AMETEK, Inc.", "UNP": "Union Pacific Corporation", "TSCO": "Tractor Supply Company", "EMR": "Emerson Electric Co.", "WDC": "Western Digital Corporation", "LNT": "Alliant Energy Corporation", "JPM": "JPMorgan Chase & Co.", "HBI": "Hanesbrands Inc.", "SPY": "SPDR S&P 500 ETF Trust", "AZO": "AutoZone, Inc.", "DOV": "Dover Corporation", "GPS": "The Gap, Inc.", "FANG": "Diamondback Energy, Inc.", "PM": "Philip Morris International Inc.", "IBM": "International Business Machines Corporation", "MTD": "Mettler-Toledo International Inc.", "ICE": "Intercontinental Exchange, Inc.", "GL": "Globe Life Inc.", "CMI": "Cummins Inc.", "CCL": "Carnival Corporation & Plc", "J": "Jacobs Engineering Group Inc.", "ETN": "Eaton Corporation plc", "NCLH": "Norwegian Cruise Line Holdings Ltd.", "VLO": "Valero Energy Corporation", "ORCL": "Oracle Corporation", "SYK": "Stryker Corporation", "LUV": "Southwest Airlines Co.", "BKNG": "Booking Holdings Inc.", "CNC": "Centene Corporation", "IR": "Ingersoll Rand Inc.", "SWK": "Stanley Black & Decker, Inc.", "CF": "CF Industries Holdings, Inc.", "ULTA": "Ulta Beauty, Inc.", "EXC": "Exelon Corporation", "GM": "General Motors Company", "ALK": "Alaska Air Group, Inc.", "LQD": "iShares iBoxx $ Investment Grade Corporate Bond ETF", "APTV": "Aptiv PLC", "COF": "Capital One Financial Corporation", "ZBRA": "Zebra Technologies Corporation", "WHR": "Whirlpool Corporation", "MRO": "Marathon Oil Corporation", "COST": "Costco Wholesale Corporation", "AWK": "American Water Works Company, Inc.", "AIZ": "Assurant, Inc.", "ROL": "Rollins, Inc.", "YUM": "Yum! Brands, Inc.", "VOO": "Vanguard S&P 500 ETF", "ESS": "Essex Property Trust, Inc.", "LLY": "Eli Lilly and Company", "CINF": "Cincinnati Financial Corporation", "AMCR": "Amcor plc", "INCY": "Incyte Corporation", "ECL": "Ecolab Inc.", "BDX": "Becton, Dickinson and Company", "JNJ": "Johnson & Johnson", "FTNT": "Fortinet, Inc.", "WU": "The Western Union Company", "BAX": "Baxter International Inc.", "CME": "CME Group Inc.", "FIS": "Fidelity National Information Services, Inc.", "CMG": "Chipotle Mexican Grill, Inc.", "SJM": "The J. M. Smucker Company", "SIVB": "SVB Financial Group", "HOG": "Harley-Davidson, Inc.", "AVB": "AvalonBay Communities, Inc.", "GPC": "Genuine Parts Company", "MET": "MetLife, Inc.", "CFG": "Citizens Financial Group, Inc.", "CDNS": "Cadence Design Systems, Inc.", "CTVA": "Corteva, Inc.", "URI": "United Rentals, Inc.", "XYL": "Xylem Inc.", "REGN": "Regeneron Pharmaceuticals, Inc.", "MAR": "Marriott International, Inc.", "UHS": "Universal Health Services, Inc.", "SPGI": "S&P Global Inc.", "VZ": "Verizon Communications Inc.", "DFS": "Discover Financial Services", "PEAK": "Healthpeak Properties, Inc.", "MS": "Morgan Stanley", "AMD": "Advanced Micro Devices, Inc.", "AAL": "American Airlines Group Inc.", "NKE": "NIKE, Inc.", "LOW": "Lowe's Companies, Inc.", "WAT": "Waters Corporation", "PH": "Parker-Hannifin Corporation", "NOV": "National Oilwell Varco, Inc.", "NRG": "NRG Energy, Inc.", "IPGP": "IPG Photonics Corporation", "F": "Ford Motor Company", "WBA": "Walgreens Boots Alliance, Inc.", "XEL": "Xcel Energy Inc.", "MTB": "M&T Bank Corporation", "HBAN": "Huntington Bancshares Incorporated", "IEX": "IDEX Corporation", "VMC": "Vulcan Materials Company", "K": "Kellogg Company", "KMI": "Kinder Morgan, Inc.", "BEN": "Franklin Resources, Inc.", "MDT": "Medtronic plc", "INTC": "Intel Corporation", "TWTR": "Twitter, Inc.", "ROST": "Ross Stores, Inc.", "APH": "Amphenol Corporation", "GD": "General Dynamics Corporation", "DISH": "DISH Network Corporation", "A": "Agilent Technologies, Inc.", "HAS": "Hasbro, Inc.", "FMC": "FMC Corporation", "NTRS": "Northern Trust Corporation", "DIS": "The Walt Disney Company", "PNC": "The PNC Financial Services Group, Inc.", "ISRG": "Intuitive Surgical, Inc.", "BTC-USD": "Bitcoin USD", "ETH-USD": "Ethereum USD", "BNB-USD": "BNB USD"} \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..d4c8373 --- /dev/null +++ b/config.py @@ -0,0 +1,46 @@ +import os +import time +from datetime import datetime, date, timedelta +# PARAMETERS +CONFIGS = { +# "ENV": "development", +# "DEBUG": True, + # "SQLALCHEMY_DATABASE_URI" : os.getenv('DATABASE_URL'), + "SECRET_KEY": os.urandom(30), # Set the secret key for session authentication + "PERMANENT_SESSION_LIFETIME": timedelta(minutes=60) +} +# SQL_CONFIG = dict( +# database= os.getenv("PGDATABASE"), +# user=os.getenv("PGUSER"), +# host=os.getenv("PGHOST"), +# port=os.getenv("PGPORT"), +# password=os.getenv("PGPASSWORD") +# ) +# CACHE_CONFIG = { +# 'CACHE_TYPE': 'redis', +# 'CACHE_REDIS_USER': os.getenv("REDISUSER"), +# 'CACHE_REDIS_HOST': os.getenv("REDISHOST"), +# 'CACHE_REDIS_PORT': os.getenv("REDISPORT"), +# 'CACHE_REDIS_PASSWORD': os.getenv("REDISPASSWORD"), +# 'CACHE_KEY_PREFIX': 'railway_redis_' +# } + +SQL_CONFIG = dict( + database="profolio_platform", + user="postgres", + host="db", + port="5432", + password="password" +) +CACHE_CONFIG = { + 'CACHE_TYPE': 'redis', + # 'CACHE_REDIS_USER': 'default', + 'CACHE_REDIS_HOST': 'redis', + 'CACHE_REDIS_PORT': 6379, + # 'CACHE_REDIS_PASSWORD': '5rP99RevPMW94rswBXAL', + # 'CACHE_KEY_PREFIX': 'railway_redis_' +} +role_map = dict(max_sharpe='最大化夏普比率', + max_sortino='最大化索提諾比率', + min_volatility='最小化波動率', + quadratic_utility='最大化效用函數') diff --git a/data_input.py b/data_input.py new file mode 100644 index 0000000..84d6901 --- /dev/null +++ b/data_input.py @@ -0,0 +1,36 @@ +import psycopg2 +import yfinance as yf +import numpy as np +from psycopg2.extensions import register_adapter, AsIs +psycopg2.extensions.register_adapter(np.int64, psycopg2._psycopg.AsIs) + +ticker = 'SPY' +start = '2011-8-1' +end = '2021-9-1' +stock_data = yf.download(ticker, start=start, end=end ) +stock_data.index = np.datetime_as_string(stock_data.index, unit='D') +print(stock_data.index) +stock_data['Ticker'] = ticker +stock_data = stock_data.rename(columns={"Adj Close": "Adj_Close"}) +column = ["Open" , "High" , "Low" , "Close" , "Volume"] +stock_data = stock_data.drop(column, axis=1) +records = stock_data.to_records(index=True) +print(records) + +conn = psycopg2.connect( + database="profolio_platform", user='postgres', password='password', host='db',port ='5432' +) +conn.autocommit = True +cur = conn.cursor() +# print(stock_data["Date"]) +# print(stock_data["Adj_Close"]) +# print(stock_data["Ticker"]) +# print(type(stock_data["Date"])) +# print(type(stock_data["Adj_Close"])) +# print(type(stock_data["Ticker"])) +query = """INSERT INTO stock_price (date,price,ticker) + VALUES (%s, %s, %s)""" +cur = conn.cursor() +cur.executemany(query, records) +conn.close() +print("Data Insert Successfully") diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..09dd244 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,60 @@ +version: "3.7" +services: + db: + build: + context: ./sql_script/ + image: postgres:15.3-alpine + environment: + POSTGRES_DB: porfolio_platform + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + PGDATA: /var/lib/postgresql/data + volumes: + - db-data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - common_network + pgadmin: + image: dpage/pgadmin4:latest + environment: + PGADMIN_DEFAULT_EMAIL: jjjoey020629@gmail.com + PGADMIN_DEFAULT_PASSWORD: password + PGADMIN_LISTEN_PORT: 90 + ports: + - "7070:90" + volumes: + - pgadmin-data:/var/lib/pgadmin + links: + - "db:pgsql-server" + networks: + - common_network + redis: + image: redis:7.0.11-alpine + container_name: myredis + ports: + - 6379:6379 + volumes: + - /data/redis-data:/data + networks: + - common_network + flask: + build: ./ + container_name: flask + command: python main.py runserver 0.0.0.0:8000 + depends_on: + - db + - pgadmin + - redis + ports: + - 8000:8000 + links: + - 'db' + - 'redis' + networks: + - common_network +volumes: + db-data: + pgadmin-data: +networks: + common_network: diff --git a/main.py b/main.py new file mode 100644 index 0000000..fde17b0 --- /dev/null +++ b/main.py @@ -0,0 +1,537 @@ +#coding=utf-8 +from flask import Flask, render_template, request, redirect, url_for, g, session, flash, jsonify +# from flask_login import LoginManager, UserMixin, login_user, current_user, login_required, logout_user +from flask_sqlalchemy import SQLAlchemy +from flask_caching import Cache +from markupsafe import escape +from werkzeug.security import generate_password_hash, check_password_hash +from datetime import datetime, date, timedelta + + +import os +import json +import time +import random +import string +import logging +import numpy as np +import pandas as pd +import psycopg2 +import psycopg2.extras +import plotly +import plotly.express as px +from portfolio_builder import MVO +from config import * +pd.options.plotting.backend = "plotly" + + + +app = Flask(__name__) +app.config.from_mapping(CONFIGS) +app.config.update(CACHE_CONFIG) +cache = Cache(app) + + + +# Load Assets +with open('assets_tw.json') as f: + data_tw = json.load(f) +with open('assets_us.json') as f: + data_us = json.load(f) + +def login_required(): + if not 'username' in session: + return False + else: + return True +def get_stock(conn, stock_list, tw): + ## Query DB + if tw==1: + sql="SELECT ticker, date, price FROM stock_price_tw where ticker = ANY(%s);" + with conn: + with conn.cursor() as curs: + curs.execute(sql, (stock_list, )) + data= curs.fetchall() + else: + sql1="SELECT ticker, date, price FROM stock_price where ticker = ANY(%s)" + sql2="SELECT ticker, date, price FROM stock_price_tw where ticker = ANY(%s) ;" + with conn: + with conn.cursor() as curs: + curs.execute(sql1, (stock_list,)) + data_us= curs.fetchall() + curs.execute(sql2, (stock_list,)) + data_tw= curs.fetchall() + data = data_us+data_tw + dfStock = pd.DataFrame(data, columns=['ticker', 'date', 'price']) + dfStock['date'] = pd.to_datetime(dfStock['date']) + dfStock = dfStock.drop_duplicates() + g = dfStock.groupby('ticker') + port = pd.concat([g.get_group(t).set_index('date')['price'] for t in stock_list], axis=1, join='inner') + port.columns=stock_list + return port +def rolling_optimize(ret, lookback=126, backtest=126, role="max_sharpe", gamma=None): + n, num = ret.shape + period = (n - lookback)//backtest+1 + weights = [] + start = [] + rets = [] + for i in range(period): + curr = i*backtest+lookback + data_train = ret.iloc[curr-lookback:curr, :].to_numpy() + data_test = ret.iloc[curr:curr+backtest, :] + if len(data_test) == 0: + break + w = MVO.opt(data_train, role=role, gamma=gamma) + start.append(data_test.index[0]) + weights.append(w) + rets.append(data_test.to_numpy()@w) + weight = pd.DataFrame(weights, columns=ret.columns, index=pd.to_datetime(start)) + rets = np.hstack(rets) + equally_weighted = ret.iloc[lookback:, :].to_numpy()@np.ones(num)/num + rets = pd.DataFrame(np.vstack([rets, equally_weighted]).T, columns=['Portfolio', 'Equally'], index=ret.index[lookback:]) + return weight, rets + +# Define the route for the index pages +@app.route('/') +# @cache.cached(timeout=300) +def index(): + return render_template('base.html') + +# Login Page +@app.route('/login') +def login(): + if 'username' in session: + return render_template('base.html') + return render_template('login.html') +@app.route('/login', methods=['POST']) +def login_post(): + # Get the username and password from the form + username = request.form.get('username') + password = request.form.get('password') + print(username, password) + ## Connect to the database + conn = psycopg2.connect(**SQL_CONFIG) + with conn: + with conn.cursor() as curs: + curs.execute("select * from users where username = %s;", (username, )) + data = curs.fetchone() + conn.close() + + # Authentication + if (data is None) or (username is None) or (password is None): + flash('使用者代號不對或密碼不對,請再試一次。', 'danger') + return render_template('login.html') + elif check_password_hash(data[2], password): + session['username'] = username.split('@')[0] + session['user_id'] = data[0] + session['privilege'] = data[-1] + session['update_freq'] = 100 + session['lastCreateTime'] = time.time() + session['tw'] = 1 + session['currStockList'] = [] + flash(f"成功登入,歡迎您 {session['username']} !", 'success') + return redirect(url_for('index')) + else: + flash('使用者代號不對或密碼不對,請再試一次。', 'danger') + return render_template('login.html') + +# Registration Page +@app.route('/registration') +def registration(): + if login_required(): + return redirect(url_for('index')) + return render_template('registration.html') +@app.route('/registration', methods=['POST']) +def registration_post(): + # Get the username and password from the form + username = request.form.get('username') + password = request.form.get('password') + rep_password = request.form.get('rep-password') + # check password + if not password is None and password == rep_password: + conn = psycopg2.connect(**SQL_CONFIG) + ## Connect to the database + with conn.cursor() as curs: + curs.execute("select * from users where username = %s;", (username, )) + data = curs.fetchone() + if data is None: + with conn: + with conn.cursor() as curs: + curs.execute("insert into users (username, password) values (%s, %s);", (username, generate_password_hash(password))) + # conn.commit() + else: + flash('使用者已存在。', 'warning') + return redirect(url_for('login')) + conn.close() + name = username.split('@')[0] + flash(f'註冊成功! 歡迎您, {name}。', 'success') + return redirect(url_for('login')) + else: + flash('密碼不符合,請再次輸入。', 'warning') + return redirect(url_for('registration')) + +# Logout Page +@app.route('/logout', methods=['GET']) +def logout(): + if login_required(): + pass + else: + flash('請先登入。', 'warning') + return redirect(url_for('login')) + if 'username' in session: + session.clear() + flash(f"成功登出!", 'success') + return redirect(url_for('index')) + + + +@app.route('/strategy') +# @cache.cached(timeout=60) +def strategy(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + session['tw'] = 0 + return render_template('strategy_tw.html', data_us = data_us, data_tw=data_tw, stock=['TSLA']) + + + + +@app.route('/strategy_tw') +# @cache.cached(timeout=60) +def strategy_tw(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + session['tw'] = 1 + return render_template('strategy_tw.html', data_tw=data_tw, stock=['2330.TW']) + + + + + +@app.route('/postStock', methods=['POST']) +def submit_stock_list(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + if not 'tw' in session: + return redirect(url_for('index')) + # Update Session + # app.logger.info("UPDATE ASSET") + if session['update_freq']==0: + # app.logger.info("Too Frequent") + return 'update to frquent!' + else: + session['update_freq']-=1 + stock_list = request.form.get('stockList') # this is string + stock_list = json.loads(stock_list) # Load stock_list as list + session['currStockList'] = stock_list + + ## Query DB + conn = psycopg2.connect(**SQL_CONFIG) + port = get_stock(conn, stock_list, session['tw']) + if len(port.index) > 1008: + port = port.iloc[-1008:, :] + conn.close() + port = port.iloc[::3, :] + port = port/port.iloc[0, :] + + fig = port.plot(title='資產價格變化', labels=dict(index="Date", value="Price", variable="Assets")) + fig['layout'] = {} + # 序列化 + graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # for key in request.form: + # app.logger.info("KEY: %s, ", key) + # print(key, request.form[key]) + # Do something with the stock list heres + return graphJSON + +@app.route('/postPort', methods=['POST']) +def buildPort(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + if not 'tw' in session: + return redirect(url_for('index')) + # Stop frequently building strategy + if time.time() - session['lastCreateTime'] < 60: + less = round(time.time()-session['lastCreateTime'], 1) + print(f"UNTIL: {less}") + return f'投資組合建立時間間隔(或與登入時間間隔)必須大於60秒!還差: {less} 秒。' + session['lastCreateTime'] = time.time() + # for key in request.form: + # print(key, request.form[key], type(request.form[key])) + + # Portfolio Info , random name generator + name = request.form.get('name') + if name == '': + prefix=''.join(random.choices(string.ascii_uppercase + string.digits, k=6)) + name= prefix + f"-{round(time.time()%100, 2)}" + + # Opt Parameters + comp = request.form.get('comp') + ts = request.form.get('ts') + # ts = datetime.now().strftime("%Y-%m-%d, %H:%M:%S") + role = request.form.get('role') + lookback = int(request.form.get('lookback')) + backtest = int(request.form.get('frequency')) + gamma = float(request.form.get('gamma'))/100 + comment = request.form.get('comment') + stock_list = json.loads(request.form.get('stockList')) + + + # Algorithm MVO + print(f"{'-'*10}Enter Algorithms{'-'*10}") + # Query DB + market_asset = '0050.TW' if session['tw']==1 else 'SPY' + conn = psycopg2.connect(**SQL_CONFIG) + if market_asset in stock_list: + port = get_stock(conn, stock_list, session['tw']) + market = port[market_asset] + else: + port = get_stock(conn, stock_list+[market_asset], session['tw']) + market = port[market_asset] + port = port[stock_list] + # Optimization + n = len(port.index) + if n < lookback+backtest+63: + return f'''投資組合無法建立,資料長度與所選參數不符。''' + elif n > 1009+lookback: + port = port.iloc[-(1009+lookback):, :] + market = market.iloc[-1009:] + else: + market = market.iloc[lookback:] + + length, num = port.shape + ret = port.pct_change().dropna() + weight, rets = rolling_optimize(ret, lookback, backtest, role=role, gamma=gamma) + weight.index = weight.index.astype(str) + + rets.index = rets.index.astype(str) + rets= rets.round(5) + + + # Get portfolio info. + info = MVO.portfolio_info(np.array([1]), rets['Portfolio'].to_numpy().reshape(-1, 1), market.pct_change().dropna().to_numpy()) + data = (ts, name, session.get('username').split('@')[0], comp, role, info['annual_ret'], + info['vol'], info['mdd'], info['annual_sr'], + info['beta'], info['alpha'], info['var10'], info['R2'], gamma, True, comment, stock_list, json.dumps(weight.to_dict(orient="split")), json.dumps(rets.to_dict(orient="split"))) + sql='insert into strategy \ + (date, name, username,\ + competition, role, annual_ret,\ + vol, mdd, annual_sr, beta, alpha,\ + var10, R2, gamma, tw, notes, assets, weight, ret)\ + values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) RETURNING id;' + with conn: + with conn.cursor() as curs: + print("DATA : ",data) + curs.execute(sql, data) + + strategy_id = curs.fetchone()[0] + conn.close() + print(f"{'-'*10}Strategy write in Success{'-'*10}") + return f'''投資組合已完成建立,請點擊 {strategy_id}查詢分析結果。''' + + + +@app.route('/custom') +# @cache.cached(timeout=60) +def custom(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + return render_template('custom.html') +@app.route('/custom', methods=['POST']) +def custom_post(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + port = pd.read_csv(request.files['csv_file'], index_col=0, parse_dates=True) + role = request.form.get('role') + lookback = int(request.form.get('lookback')) + backtest = int(request.form.get('frequency')) + gamma = float(request.form.get('gamma'))/100 + # Optimization + n = len(port.index) + if n < lookback+backtest+63: + return f'''投資組合無法建立,資料長度與所選參數不符。''' + elif n > 1009+lookback: + port = port.iloc[-(1009+lookback):, :] + else: + pass + length, num = port.shape + ret = port.pct_change().dropna() + weight, rets = rolling_optimize(ret, lookback, backtest, role=role, gamma=gamma) + weight.index = weight.index.astype(str) + rets.index = rets.index.astype(str) + rets= rets.round(5) + + info = MVO.portfolio_info(np.array([1]), rets['Portfolio'].to_numpy().reshape(-1, 1), np.zeros(len(ret)-lookback)) + info['username'] = session.get('username').split('@')[0] + info['role'] = role_map[role] + info['id']='Custom data' + info['name']='Custom data' + info['date'] = '-' + info['alpha'] = '-' + info['beta'] = '-' + info['r2'] = '-' + info['assets'] = list(port.columns) + # Plotting weight + fig = px.bar(weight) + fig['layout'] = {} + info['weight'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting weight + fig = (rets+1).cumprod().iloc[::5, :].plot() + fig['layout'] = {} + info['ret'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting ret bars + rets.index.name = 'date' + rets.index = pd.to_datetime(rets.index) + ret_hist = rets.to_period('Q').groupby('date').apply(lambda x: (x+1).prod()-1) + ret_hist.index = ret_hist.index.astype(str) + fig = px.bar(ret_hist) + fig['layout'] = {} + info['bar'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + return render_template('result_view.html', data=info) + +@cache.memoize(60) +def getStrategy(): + conn = psycopg2.connect(**SQL_CONFIG) + with conn: + with conn.cursor() as curs: + sql="select id, date, name, username, annual_ret, vol, annual_sr, mdd\ + from strategy order by id desc limit 50" + curs.execute(sql) + data= curs.fetchall() + conn.close() + return data +@cache.memoize(60) +def getPostStrategy(role, comp): + if role == "my": + conn = psycopg2.connect(**SQL_CONFIG) + with conn: + with conn.cursor() as curs: + sql=f"select id, date, name, username, annual_ret, vol, annual_sr, mdd\ + from strategy where username=%s order by id desc limit 50;" + curs.execute(sql, (session['username'], )) + data= curs.fetchall() + conn.close() + return data + if role in ['id', 'annual_ret', 'annual_sr', 'vol']: + pass + else: + role='id' + if role == 'vol': + order= 'asc' + else: + order= 'desc' + if comp == 'none': + comp=None + conn = psycopg2.connect(**SQL_CONFIG) + with conn: + with conn.cursor() as curs: + if comp is None: + sql=f"select id, date, name, username, annual_ret, vol, annual_sr, mdd\ + from strategy order by {escape(role)} {escape(order)} limit 50" + curs.execute(sql) + else: + sql=f"select id, date, name, username, annual_ret, vol, annual_sr, mdd\ + from strategy where competition=%s order by {escape(role)} {escape(order)} limit 50;" + curs.execute(sql, (comp, )) + data= curs.fetchall() + conn.close() + return data +@app.route('/result', methods=['GET', 'POST']) +def result(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + if request.method=='GET': + data = getStrategy() + return render_template('result.html', strategy_data=data) + elif request.method=='POST': + role = request.form.get('role') + comp = request.form.get('competition') + data = getPostStrategy(role, comp) + return render_template('result.html', strategy_data=data) + +@app.route('/result_view') +def result_view(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + if not 'strategy_id' in request.args: + return redirect(url_for('index')) + else: + sid = request.args.get('strategy_id') + strategy_id = request.args.get('strategy_id') + sql="""select * from strategy where id=%s;""" + conn = psycopg2.connect(**SQL_CONFIG) + with conn: + with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as curs: + curs.execute(sql, (sid, )) + data= curs.fetchone() + conn.close() + # Processing data + data = dict(data) + data['role'] = role_map[data['role']] + w = data['weight'] + r = data['ret'] + w = pd.DataFrame(w['data'], columns=w['columns'], index=w['index']) + r = pd.DataFrame(r['data'], columns=r['columns'], index=r['index']) + # Plotting weight + fig = px.bar(w) + fig['layout'] = {} + data['weight'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting weight + fig = (r+1).cumprod().iloc[::5, :].plot() + fig['layout'] = {} + data['ret'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + # Plotting ret bars + r.index.name = 'date' + r.index = pd.to_datetime(r.index) + ret_hist = r.to_period('Q').groupby('date').apply(lambda x: (x+1).prod()-1) + ret_hist.index = ret_hist.index.astype(str) + fig = px.bar(ret_hist) + fig['layout'] = {} + data['bar'] = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) + session['currStockList'] = data['assets'] + return render_template('result_view.html', data=data) +@app.route('/copy_portfolio') +def copy_portfolio(): + if login_required(): + pass + else: + flash('使用投組功能請先登入。', 'warning') + return redirect(url_for('login')) + if not 'tw' in session: + return redirect(url_for('index')) + session['tw'] = 0 + return render_template('strategy_tw.html', data_us = data_us, data_tw=data_tw, stock=session['currStockList']) + +@app.errorhandler(404) +def page_not_found(e): + # note that we set the 404 status explicitly + return render_template('404.html'), 404 + + + +if __name__ == "__main__": + app.run(host='127.0.0.1', port=8000) diff --git a/portfolio_builder.py b/portfolio_builder.py new file mode 100644 index 0000000..ef6cd8e --- /dev/null +++ b/portfolio_builder.py @@ -0,0 +1,143 @@ +import json +import time +import numpy as np +import pandas as pd +from scipy.optimize import minimize + +class MVO(object): + @staticmethod + def portfolio_info(w, ret, market_ret, rf=0): + # return and drawdown + retPort = ret@w # T-dimensional array + cum_ret = (retPort+1).cumprod() + rolling_max=np.maximum.accumulate(cum_ret) + mdd = np.max((rolling_max - cum_ret)/rolling_max) + + ## Sharpe Ratio + stdPort = np.std(retPort) + vol = stdPort*15.87451 + annual_ret = np.mean(retPort) * 252 + annual_sr = (annual_ret-rf) / vol + + ## alpha, beta + cov = np.cov(retPort, market_ret) + beta = cov[0, 1] / cov[1, 1] + alpha = annual_ret - rf - beta*(np.mean(market_ret) * 252 - rf) + R2 = cov[0, 1]**2/(cov[0, 0] * cov[1, 1]) + + ## n-day 95% VaR + var10 = -annual_ret*(10/252) + 1.645*vol*(10/252)**(1/2) + d = dict(annual_ret = annual_ret, + vol=vol, + mdd=mdd, + annual_sr=annual_sr, + beta=beta, + alpha=alpha, + var10=var10, + R2=R2) + return {key: round(d[key], 2) for key in d} + @staticmethod + def sharpe_ratio(w, ret): + cov = np.cov(ret.T) + # print(cov.shape, w.shape) + retPort = ret@w # T-dimensional array + stdPort = np.std(retPort) + return np.mean(retPort)/stdPort + @staticmethod + def sharpe_grad(w, ret, cov): + manual_ret = np.mean(ret, axis=0) + # print(cov.shape, w.shape) + retPort = ret@w # T-dimensional array + stdPort = np.std(retPort) + g1=manual_ret/stdPort + g2=np.mean(retPort)*stdPort**(-3)*cov@w + return g1-g2 + @staticmethod + def sortino_ratio(w, ret): + retPort = ret@w # T-dimensional array + stdPort = np.std(np.maximum(-retPort, 0)) + return np.mean(retPort)/stdPort + @staticmethod + def sortino_grad(w, ret, cov_sor): + manual_ret = np.mean(ret, axis=0) + # print(cov.shape, w.shape) + retPort = ret@w # T-dimensional arrayss + stdPort = np.std(retPort) + g1=manual_ret/stdPort + g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w + return g1-g2 + @staticmethod + def sortino_ratio(w, ret): + retPort = ret@w # T-dimensional array + stdPort = np.std(np.maximum(-retPort, 0)) + return np.mean(retPort)/stdPort + @staticmethod + def sortino_grad(w, ret, cov_sor): + manual_ret = np.mean(ret, axis=0) + # print(cov.shape, w.shape) + retPort = ret@w # T-dimensional arrayss + stdPort = np.std(retPort) + g1=manual_ret/stdPort + g2=np.mean(retPort)*stdPort**(-3)*cov_sor@w + return g1-g2 + # equivalent opt problem with min vol + @staticmethod + def volatility(w, ret): + retPort = ret@w # T-dimensional array + return np.std(retPort) + @staticmethod + def volatility_grad(w, ret, cov): + retPort = ret@w # T-dimensional array + stdPort = np.std(retPort) + return cov@w/stdPort + @staticmethod + def quadratic_utility(w, ret, gamma): + retPort = ret@w # T-dimensional array + varPort = np.var(retPort) + return np.mean(retPort) - 0.5*gamma*varPort + @staticmethod + def quadratic_utility_grad(w, ret, cov, gamma): + manual_ret = np.mean(ret, axis=0) + return manual_ret - gamma*cov@w + @classmethod + def opt(cls, ret, gamma=0, role="max_sharpe"): + n = ret.shape[1] + init=np.ones(n)/n + if role=="max_sharpe": + cov=np.cov(ret.T) + loss = lambda w: -cls.sharpe_ratio(w, ret) + grad = lambda w: -cls.sharpe_grad(w, ret, cov) + elif role=="max_sortino": + cov = np.cov(np.maximum(ret, 0).T) + loss = lambda w: -cls.sortino_ratio(w, ret) + grad = lambda w: -cls.sortino_grad(w, ret, cov) + elif role=="min_volatility": + cov=np.cov(ret.T) + loss = lambda w: cls.volatility(w, ret) + grad = lambda w: cls.volatility_grad(w, ret, cov) + elif role=="quadratic_utility": + cov=np.cov(ret.T) + loss = lambda w: -cls.quadratic_utility(w, ret, gamma) + grad = lambda w: -cls.quadratic_utility_grad(w, ret, cov, gamma) + else: + return init + bnds = [[0, 0.6] for i in range(n)] + opts = {'maxiter': 1000, 'disp': False} + cons = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1}) + result = minimize(loss, init, method="SLSQP",\ + options=opts, bounds=bnds, tol = None, jac = grad, constraints=cons) + sol = result['x'] + return np.round(sol, 2) + + + + + + + + + + + + + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d448f11 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +Flask==2.2.2 +Flask-Login==0.6.2 +Flask-SQLAlchemy==3.0.3 +Flask-Caching==2.0.2 +redis==4.5.3 +gunicorn==20.0.4 +packaging==23.0 +pandas==1.5.3 +plotly==5.13.1 +psycopg2==2.9.5 +pytz==2022.7.1 +requests==2.28.2 +scipy==1.10.0 +SQLAlchemy==2.0.4 +gevent==22.10.2 +yfinance==0.2.22 diff --git a/sql_command.py b/sql_command.py new file mode 100644 index 0000000..8c6b03d --- /dev/null +++ b/sql_command.py @@ -0,0 +1,5 @@ +insert_strategy = \ + +# insert into strategy (date, name, username, competition, role, ratio, annual_ret, vol, mdd, annual_sr, beta, alpha, var10, R2, tw, comment, assets, assets_position) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s); + +# (date, name, username, competition, role, ratio, annual_ret, vol, mdd, annual_sr, beta, alpha, var10, R2, tw, comment, assets, assets_position) diff --git a/sql_script/Dockerfile b/sql_script/Dockerfile new file mode 100644 index 0000000..106ccc4 --- /dev/null +++ b/sql_script/Dockerfile @@ -0,0 +1,3 @@ +FROM postgres:15.3-alpine + +COPY create_all.sql /docker-entrypoint-initdb.d/ diff --git a/sql_script/create_all.sql b/sql_script/create_all.sql new file mode 100644 index 0000000..6630618 --- /dev/null +++ b/sql_script/create_all.sql @@ -0,0 +1,59 @@ +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + user_id SERIAL PRIMARY KEY, + username VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(128) NOT NULL, + vip BOOLEAN DEFAULT FALSE +); +CREATE INDEX idx_username ON users (username); +DROP TABLE IF EXISTS stock_price; +DROP TABLE IF EXISTS stock_price_tw; + +CREATE TABLE stock_price ( + id SERIAL PRIMARY KEY, + ticker VARCHAR(32) NOT NULL, + date DATE NOT NULL, + price REAL NOT NULL +); +-- you need to add () +CREATE INDEX idx_ticker ON stock_price (ticker); + +CREATE TABLE stock_price_tw ( + id SERIAL PRIMARY KEY, + ticker VARCHAR(32) NOT NULL, + date DATE NOT NULL, + price REAL NOT NULL +); +-- you need to add () +CREATE INDEX idx_ticker_tw ON stock_price_tw (ticker); + +DROP TABLE IF EXISTS strategy; +CREATE TABLE strategy ( + id SERIAL PRIMARY KEY, + date VARCHAR(64) NOT NULL, + name VARCHAR(32) NOT NULL, + username VARCHAR(32) NOT NULL, + competition VARCHAR(32) NOT NULL, + role VARCHAR(20) NOT NULL, + annual_ret REAL NOT NULL, + vol REAL NOT NULL, + mdd REAL NOT NULL, + annual_sr REAL NOT NULL, + beta REAL NOT NULL, + alpha REAL NOT NULL, + var10 REAL NOT NULL, + R2 REAL NOT NULL, + gamma REAL NOT NULL, + tw BOOLEAN DEFAULT TRUE, + notes VARCHAR(255), + assets TEXT[] NOT NULL, + weight JSON NOT NULL, + ret JSON NOT NULL, + comments TEXT[][] +); +CREATE INDEX idx_user ON strategy (username); + + + + + diff --git a/sql_script/create_stockDB.sql b/sql_script/create_stockDB.sql new file mode 100644 index 0000000..4b3f5e8 --- /dev/null +++ b/sql_script/create_stockDB.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS stock_price; +DROP TABLE IF EXISTS stock_price_tw; + + +CREATE TABLE stock_price ( + id SERIAL PRIMARY KEY, + ticker VARCHAR(32) NOT NULL, + date DATE NOT NULL, + price REAL NOT NULL +); +-- you need to add () +CREATE INDEX idx_ticker ON stock_price (ticker); + +CREATE TABLE stock_price_tw ( + id SERIAL PRIMARY KEY, + ticker VARCHAR(32) NOT NULL, + date DATE NOT NULL, + price REAL NOT NULL +); +-- you need to add () +CREATE INDEX idx_ticker_tw ON stock_price_tw (ticker); diff --git a/sql_script/create_strategy.sql b/sql_script/create_strategy.sql new file mode 100644 index 0000000..21efd7c --- /dev/null +++ b/sql_script/create_strategy.sql @@ -0,0 +1,26 @@ +DROP TABLE IF EXISTS strategy; +CREATE TABLE strategy ( + id SERIAL PRIMARY KEY, + date VARCHAR(64) NOT NULL, + name VARCHAR(32) NOT NULL, + username VARCHAR(32) NOT NULL, + competition VARCHAR(32) NOT NULL, + role VARCHAR(20) NOT NULL, + annual_ret REAL NOT NULL, + vol REAL NOT NULL, + mdd REAL NOT NULL, + annual_sr REAL NOT NULL, + beta REAL NOT NULL, + alpha REAL NOT NULL, + var10 REAL NOT NULL, + R2 REAL NOT NULL, + gamma REAL NOT NULL, + tw BOOLEAN DEFAULT TRUE, + notes VARCHAR(255), + assets TEXT[] NOT NULL, + weight JSON NOT NULL, + ret JSON NOT NULL, + comments TEXT[][] +); +CREATE INDEX idx_user ON strategy (username); + diff --git a/sql_script/create_users.sql b/sql_script/create_users.sql new file mode 100644 index 0000000..24be885 --- /dev/null +++ b/sql_script/create_users.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + user_id SERIAL PRIMARY KEY, + username VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(128) NOT NULL, + vip BOOLEAN DEFAULT FALSE +); +CREATE INDEX idx_username ON users (username); +INSERT INTO users (username, password) +VALUES ('R10246002@ntu.edu.tw', 'pbkdf2:sha256:260000$Z5bK5pp0D8HEDAps$abb43b1b1c543ff334de8fb3aeba9c0460c37de5b5363e5210e68b00739d5e2c'); \ No newline at end of file diff --git a/static/img/cat.png b/static/img/cat.png new file mode 100644 index 0000000..2e96417 Binary files /dev/null and b/static/img/cat.png differ diff --git a/static/img/file.jpg b/static/img/file.jpg new file mode 100644 index 0000000..0c50114 Binary files /dev/null and b/static/img/file.jpg differ diff --git a/static/img/file.png b/static/img/file.png new file mode 100644 index 0000000..9a634fa Binary files /dev/null and b/static/img/file.png differ diff --git a/static/img/frontier.jpg b/static/img/frontier.jpg new file mode 100644 index 0000000..077e762 Binary files /dev/null and b/static/img/frontier.jpg differ diff --git a/static/img/growth.ico b/static/img/growth.ico new file mode 100644 index 0000000..d59e906 Binary files /dev/null and b/static/img/growth.ico differ diff --git a/static/img/money.jpeg b/static/img/money.jpeg new file mode 100644 index 0000000..7bb16d3 Binary files /dev/null and b/static/img/money.jpeg differ diff --git a/static/img/stock.jpeg b/static/img/stock.jpeg new file mode 100644 index 0000000..8c9e451 Binary files /dev/null and b/static/img/stock.jpeg differ diff --git a/static/js/addStock.js b/static/js/addStock.js new file mode 100644 index 0000000..a21dbb1 --- /dev/null +++ b/static/js/addStock.js @@ -0,0 +1,174 @@ +// Initialize empty stock list +// let stockList = ['2330.TW']; +var stockList = []; +$('#stock-list span').each(function(){ + stockList.push($(this).text()); +}); +console.log(stockList); +let currentList = []; +const layout={'autosize': true, 'markers':true, +'title': {'text': ''}, +'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'rangeslider': {'visible': true}}, +'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0]}, +'legend': {'yanchor': 'top', 'y': 1.1, 'xanchor': 'left', 'x': 0.01, 'orientation':'h'}, +'margin': {'l': 25, 'r': 5, 't': 10, 'b': 5}, +} +// Cache frequently-used DOM elements +const $stockForm = $('#stock-form'); +const $compSelect = $('#competition'); +const $stockList = $('#stock-list'); +const $submitBtn = $('#submit-btn'); +const $addStockBtn = $('#addStockBtn'); +const $submitPort = $('#submit-port'); +const $sendPort = $('#sendPort'); +const $commentPort = $('#commentPort'); + +// Function to add a new stock item to the list +function addStockItem(stock, text) { + // Add item to array + stockList.push(stock); + // Update HTML list + const $newItem = $(`
  • + ${text} + + + +
  • `); + $stockList.append($newItem); +} +function changeFunc(value) { + console.log(value); + if (value === 'quadratic_utility') { + $('#gamma').css("display", "flex"); + } else { + $('#gamma').css("display", "none"); + } +} +// Function to delete a stock item from the list +function deleteStockItem(itemIndex) { + // Remove item from array + stockList.splice(itemIndex, 1); + + // Update HTML list + $stockList.children().eq(itemIndex).remove(); +} + +// Event listener for delete button clicks +$stockList.on('click', '.delete-btn', function(){ + var itemIndex = $(this).closest('li').index() + deleteStockItem(itemIndex); + // console.log(stockList); + }); +// Event listener for submit button click +$addStockBtn.click(function(event) { + event.preventDefault(); + // console.log($('input[name=assetSelect]').val()) + // Get selected stock from form + var text = $('input[name=assetSelect]').val(); + // const selectedStock = text; + // var text = $('#stock-select option:selected').text(); + // console.log(text) + if (text != null && text!= '' && stockList.indexOf(text)===-1) { + // Add new item to list + addStockItem(text, text); + + // Clear input field + $('#stockAll').val(''); + } + // console.log(stockList); +}); + +// Event listener for submit button click +$submitPort.click(function(event) { + event.preventDefault(); + if (stockList.length > 1){ + $('#portModal').modal('show'); + // console.log('asset confirm'); + // $(this).prop('disabled', true); + } +}); +// Event listener for submit button click +$sendPort.click(function(event) { + if (stockList.length > 1){ + // $('#confirmMes').replaceWith("投資組合已開始建立,請等待完成訊息,或1分鐘後至分析結果區查看!") + // $('#confirmModal').modal('show'); + $submitPort.prop('disabled', true); + $.ajax({ + url: '/postPort', //todo create_strategy + method: 'POST', + data: { + name: $('input[name=portName]').val(), + ts: Date(Date.now()), + comp: $('#competition').val(), + lookback: $('#lookback').val(), + frequency: $('#opt-frequency').val(), + role: $('#role-select').val(), + gamma: $('#util-gamma').val(), + comment: $commentPort.val(), + stockList: JSON.stringify(stockList) + }, + success: function(response) { + // console.log(response); + // var res = JSON.parse(response); + event.preventDefault(); + // $('#modalTitle').text('完成建立') + $('#sucMes').html(response); + // 投資組合建立時間間隔(或與登入時間間隔)必須大於60秒 + $('#confirmModal').modal('show'); + + $submitPort.prop('disabled', false); + }, + error: function(xhr) { + console.log('Error submitting stock list: ' + xhr.responseText); + alert('建立失敗,請確認資產名稱是否正確! 美股代號均為大寫、台股代號為數字後接".TW"或是"TWO"'); + } + }); + $commentPort.val(''); +} + // Get selected stock from form +}); + +// Event listener for submit button click +$submitBtn.click(function(event) { + // Send stock list to server + // console.log(event.target) + // console.log(stockList) + // console.log(cacheList.value, stockList); + var texts = []; + $('#stock-list span').each(function(){ + texts.push($(this).text()); + }); + // alert(currentList.includes(texts)); + if (stockList.length > 0 && JSON.stringify(currentList)!==JSON.stringify(stockList)) { + // cacheList = stockList; + $('#graph').html('
    Loading...
    ') + + $.ajax({ + url: '/postStock', //todo create_strategy + method: 'POST', + data: { stockList: JSON.stringify(stockList) }, + success: function(response) { + $('#graph').html('') + var graphs = JSON.parse(response); + // console.log(graphs.data); + Plotly.newPlot("graph", + graphs.data, layout, {responsive: true}); + // console.log(response.layout); + currentList = stockList.map(obj => obj); + + }, + error: function(xhr) { + $('#graph').html('
    錯誤
    ') + console.log('Error submitting stock list: ' + xhr.responseText); + } + }); + } +}); +$(document).ready(function(){ + $("#search").on("keyup", function() { + var value = $(this).val().toLowerCase(); + $("#stock-select option").filter(function() { + $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) + }); + }); +}); diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000..9b97793 --- /dev/null +++ b/templates/404.html @@ -0,0 +1,14 @@ + + + + + + + Document + + +
    +

    404 Error

    +
    + + \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..f9bc9f9 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,427 @@ + + + + + + + {% block title %}TPM{% endblock title%} + + + + + + {% block link %} + + + {% endblock %} + + + + +
    + + {% set navigation_bar = [ + ('/', 'index', '首頁', 'bi bi-house-fill'), + ('/strategy', 'strategy', '建立策略', 'fa-solid fa-chart-pie'), + ('/strategy_tw', 'strategy_tw', '台股建立策略', 'fa-solid fa-chart-pie'), + ('/custom', 'custom', '自訂數據建立策略', 'bi bi-database-fill-add'), + ('/result', 'result', '分析結果排行', 'fa-solid fa-chart-simple'), + ('mailto:r10246002@ntu.edu.tw', 'error', '錯誤回報', 'bi bi-bug-fill') + ] -%} + + {% set active_page = active_page|default('index') -%} + +
    + + {% block content %} + +
    + + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} + {% cache 300 %} +
    +

    平台簡介

    +
    +

    + 「不要把所有的雞蛋放在一個籃子裡。」 +

    +

    + 分散投資是一種投資策略,旨在通過將資金分散投資在不同的資產類別中,從而降低投資風險。 + 如果兩個資產之間存在高度正相關,則它們的價格通常會同時上漲或下跌。 + 相反,如果它們之間存在高度負相關,則它們的價格通常會發生相反的變化。 + 因此,分散投資應選擇具有低相關性的資產,以實現風險的分散。 + 現代投資組合理論(Modern Portfolio Theory, MPT)由哈利·馬科維茨(Harry Markowitz) + 於1952年首次提出的,他認為投資者應該根據風險和回報的平衡來選擇投資組合。他提出了“有效前緣”(Efficient Frontier)的概念, + +

    +

    + Efficient Frontier的建立基於資產收益率和風險的統計分析和優化理論。資產收益率可以通過歷史數據進行計算,而風險則通常使用標準差、協方差等統計指標進行衡量。 + + 假設有n個資產,它們的收益率分別為 $R_1, R_2, ..., R_n$,協方差矩陣為 $\Sigma$。假設現有一個投資組合,其中各資產的權重分別為 $w_1, w_2, ..., w_n$,則該投資組合的收益率為: +

    + + $$R_p = w_1 R_1 + w_2 R_2 + ... + w_n R_n = w^T R$$ + + +

    + 該投資組合的方差為: +

    + + $$\begin{align}\sigma^2_p + &= w_1^2 \sigma_1^2 + w_2^2 \sigma_2^2 + ... + \\&+ w_n^2 \sigma_n^2 + 2w_1w_2\sigma_{1,2} + + 2w_1w_3\sigma_{1,3} + ... \\&+ 2w_{n-1}w_n\sigma_{n-1,n} = w^T\Sigma w\end{align}$$ + +

    + 其中,$\sigma_i$ 表示第 i 個資產的標準差,$\sigma_{i,j}$ 表示第 i 和第 j 個資產的協方差。 + + 為了尋找最優投資組合,我們可以使用均值-方差優化方法。該方法的核心思想是通過最小化投資組合的方差,來最大化其收益率。假設有一個投資者的風險偏好係數為 $\gamma$,則該投資者所選擇的最優投資組合為: +

    + + $$\text{min}\ \frac{1}{2}w^T \Sigma w - \gamma w^T R$$ + + $$\text{s.t.}\ \sum_{i=1}^n w_i = 1, w_i \geq 0$$ + + +

    + 其中,$w$ 是資產權重向量,$\Sigma$ 是協方差矩陣,$R$ 是收益率向量。目標函數是投資組合方差的一半減去風險偏好係數乘以投資組合收益率,約束條件是權重向量的元素之和為1且每個權重都不小於0。 + + 通過調整風險偏好係數 $\gamma$ + ,可以獲得不同風險水平下的最優投資組合,這些投資組合形成了有效邊界(Efficient Frontier),即在一定風險水平下,可以實現最大化收益的投資組合集合。 +

    +
    +
    + frontier-example +
    +
    +

    + 在實際應用中,通常使用投資組合的夏普比率(Sharpe Ratio)作為評估指標。夏普比率可以看作是投資組合每單位風險所帶來的超額收益,其計算公式為: +

    + + $$\text{Sharpe Ratio} = \frac{R_p - R_f}{\sigma_p}$$ + +

    + 其中,$R_p$ 是投資組合的預期收益率,$R_f$ 是無風險利率,$\sigma_p$ 是投資組合的標準差。 + + Efficient Frontier的建立是現代投資組合理論的基石之一。通過將不同資產的收益率和風險納入考慮, + 投資者可以通過構建有效邊界,實現在不同風險水平下的最優資產配置。 + 這為投資者提供了一個更有效的投資方案,可以實現更穩定的收益和更低的風險水平。 +

    + + + +

    + ------ +

    +
    +
    +
    +
    + 固定預期報酬 $p$,令投資組合權重為 $w$, 則將波動率最小化的數學問題為: +
    +
    +

    + $$\begin{equation} + \begin{aligned} + \min_{w} \quad &\frac{1}{2}w^{T}\Sigma w\quad\\ + \textrm{s.t.} \quad &\sum_{i=1}^{n}w_i = 1\\ + &\sum_{i=1}^{n}w_i R_i \geq p\\ + &0\leq w_i \leq 1 \quad , 1 \leq i \leq n + \end{aligned} + \end{equation}$$ +

    +
    +
    +
    +
    +
    +
    + 令投資組合權重為 $w$, 則將夏普率最大化的數學問題為: +
    +
    +

    + $$\begin{equation} + \begin{aligned} + \min_{w} \quad &\frac{w^T R}{\sqrt{w^{T}\Sigma w}}\quad\\ + \textrm{s.t.} \quad &\sum_{i=1}^{n}w_i = 1\\ + &0\leq w_i \leq 1 \quad , 1 \leq i \leq n + + \end{aligned} + \end{equation}$$ +

    +
    +
    +
    +
    +

    投資組合的$\alpha$、$\beta$值

    +
    +

    + 投資組合報酬率的Alpha和Beta是投資組合評估中常用的指標。 + Alpha代表投資組合的超額收益,Beta則代表投資組合與市場的相關性。 + Beta值是衡量資產相對於整個市場的波動性的指標。Beta值的公式如下: +

    + + $$\beta_i = \frac{\text{Cov}(r_i,r_m)}{\text{Var}(r_m)}$$ + +

    + 其中,$r_i$表示資產i的收益率,$r_m$表示市場收益率, + $Cov(r_i,r_m)$表示資產i的收益率和市場收益率之間的協方差, + $Var(r_m)$表示市場收益率的方差。Beta值越高,表示資產的波動性越大, + 其收益率與市場收益率之間的關聯度也越高。 + Beta值可以用來評估投資組合的風險程度,投資者可以通過控制投資組合中資產的Beta值來實現風險管理。 + Beta值可以與CAPM(Capital Asset Pricing Model)和線性回歸相關聯。在CAPM中,假設資產的預期收益率可以通過以下公式計算: +

    + + $$E(r_i) = r_f + \beta_i(E(r_m) - r_f)$$ + +

    + + 其中,$E(r_i)$表示資產i的預期收益率,$r_f$表示無風險收益率,$E(r_m)$表示市場的預期收益率, + $\beta_i$表示資產i的Beta值。該公式表示,資產的預期收益率是無風險收益率和市場風險溢價的加權平均值, + 其中市場風險溢價的大小與市場風險的大小成正比,且與資產的Beta值相關。 +

    +

    + Alpha 值是指投資組合的實際收益率與其根據 Beta 值預期的收益率之間的差異。如果投資組合的實際收益率高於其根據 Beta 值所預期的收益率,則 Alpha 值為正;反之,如果投資組合的實際收益率低於其預期收益率,則 Alpha 值為負。 + + Alpha 值可以通過線性回歸分析來計算。假設投資組合的收益率可以表示為以下公式: +

    + + $$r_p = \alpha + \beta_p (r_m-f_f) + \epsilon$$ + +

    + 其中,$r_p$ 表示投資組合的收益率,$\alpha$ 表示 Alpha 值,$\beta_p$ 表示投資組合的 Beta 值,$r_m$ 表示市場收益率,$\epsilon$ 表示誤差項。如果我們將上述公式進行線性回歸,可以得到: +

    + + $$\hat{r_p} = \hat{\alpha} + \hat{\beta_p} (r_m-r_f)$$ + +

    + + + 其中,$\hat{r_p}$ 表示預測的投資組合收益率,$\hat{\alpha}$ 表示預測的 Alpha 值,$\hat{\beta_p}$ 表示預測的 Beta 值。如果實際收益率高於預測收益率,則 $\hat{\alpha}$ 為正;反之,如果實際收益率低於預測收益率,則 $\hat{\alpha}$ 為負。 +

    +

    VaR 簡介

    +
    +

    + VaR (Value at Risk) 是用來衡量投資組合或資產在一定時間內可能面臨的最大潛在損失的一種風險管理指標。VaR 通常用機率的形式表達,表示在一定信心水平下,資產或投資組合在未來一定時間內的最大可能損失額。 + + 假設 $X$ 是一個隨機變量,表示資產或投資組合在未來一定時間內的損失額,$p$ 表示所選取的信心水平,VaR 可以表示為: +

    + + $$\text{VaR}_p(X) = - \inf \{ x \in \mathbb{R} : F_X(x) \geq p \}$$ + +

    + 其中,$F_X(x)$ 是 $X$ 的累積分布函數。這個公式的意思是,我們尋找一個最小的數值 $x$,使得資產或投資組合在未來一定時間內的損失額大於 $x$ 的機率不超過 $1-p$。這個最小的數值就是 VaR,通常表示為負數,因為它是損失額。 + + 例如,假設我們選取信心水平 $p=0.95$,並且假設資產或投資組合在未來一周內的報酬率的分布是正態分布 $N(\mu,\sigma^2)$,那麼根據上述公式,VaR 的值為: +

    + + $$\begin{align}\text{VaR}_{0.95}(X) &= -\inf\{ x \in \mathbb{R} : F_X(x) \leq 0.05 \} \\ + &= -\inf \{x \in \mathbb{R} : \mathbb{P}(z\leq\frac{x-\mu}{\sigma}) \leq 0.05) \} \\ + &= -\inf \{x \in \mathbb{R} : \Phi (\frac{x-\mu}{\sigma}) \leq 0.05 \} \\ + &= -(\mu - 1.645\times\sigma)\end{align}$$ + +

    + + + 其中,$\Phi(x)$ 是標準常態分布的累積分布函數。 + 需要注意的是,VaR 是一個單一數字,只反映了資產或投資組合在一定時間內的最大可能損失額, + 不能反映風險的分布情況。因此,在使用 VaR 進行風險管理時, + 還需要結合其他風險指標和風險管理方法來進行綜合分析和決策。 +

    +
    + {% endcache %} +
    + {% endblock content %} + {% cache 300 %} + + {% endcache %} + + + + + + + + + {% block script %} + + + + {% endblock %} + + diff --git a/templates/competitions.html b/templates/competitions.html new file mode 100644 index 0000000..0b43f51 --- /dev/null +++ b/templates/competitions.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/custom.html b/templates/custom.html new file mode 100644 index 0000000..fb05c03 --- /dev/null +++ b/templates/custom.html @@ -0,0 +1,91 @@ +{% extends 'base.html' %} +{% set active_page = 'custom' %} + + +{% block title %}Strategy Page{% endblock%} +{% block content %} +{% cache 300 %} +
    +
    +
    +

    格式規範與上傳檔案

    +
    +
    +
    +
    +
      +
    • 上傳之csv檔需包含header,且第一行為時間資訊。
    • +
    • 價格資訊需長度相同,且資產數量大於1檔才會進行回測。
    • +
    • 範例如下圖所示。
    • +
    + SINGUP IMAGE +
    +
    +
    +
    + 投組最佳化配置 +
    +
    + 滾動視窗大小 + +
    +
    + 最佳化頻率 + +
    +
    + 最佳化目標函數 + +
    + +
    + + +
    +
    +
    +
    +
    +
    +
    +{% endcache %} +{% endblock %} +{% block script %} + + +{% endblock script %} diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..be5e6c5 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,70 @@ +{% extends 'base.html' %} +{% set active_page = none %} + + +{% block title %}Login Page{% endblock %} +{% block style %} +.card-body { + + +} +{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    +
    +
    +
    +

    登入

    +
    + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} +
    + + +
    We'll never share your email with anyone else.
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/templates/registration.html b/templates/registration.html new file mode 100644 index 0000000..e89234e --- /dev/null +++ b/templates/registration.html @@ -0,0 +1,70 @@ +{% extends 'base.html' %} +{% set active_page = none %} + + +{% block title %}Registration Page{% endblock %} + +{% block style %} + +{% endblock style %} +{% block content %} +
    +
    +
    +
    +
    +
    +
    +
    + +

    註冊

    +
    + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} +
    + + +
    We'll never share your email with anyone else.
    +
    +
    + + +
    +
    + + +
    +
    + + + +
    +
    + + +
    +
    + + SINGUP IMAGE + +
    +
    +
    +
    +
    +
    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/templates/result.html b/templates/result.html new file mode 100644 index 0000000..9a45f53 --- /dev/null +++ b/templates/result.html @@ -0,0 +1,99 @@ +{% extends 'base.html' %} +{% set active_page = 'result' %} + +{% block style %} +.card-header { + color: #000093; +} +{% endblock style %} + +{% block title %}Result Page{% endblock%} +{% block content %} +
    +
    + +
    +
    +
    +
      +
    • 點擊ID查看詳細資訊。
    • +
    • 預設依策略建立時間排序方式。
    • +
    • 資料庫每分鐘進行更新,若策略未顯示,請一分鐘後刷新頁面。
    • +
    +
    +
    + + + + + + + + + + + + + + {% for info in strategy_data %} + + + + + + + + + + + + + {% endfor %} +
    #ID投組名稱創建者報酬率夏普率波動率最大回落創建時間
    + + {{ info[0] }} + + {{ info[2] }}{{ info[3] }}{{ info[4] }}{{ info[6] }}{{ info[5] }}{{ info[7] }}{{ info[1]|truncate(16, False, '', 0) }}
    +
    +
    +
    +
    +
    + +{% endblock %} +{% block script %} + + +{% endblock script %} diff --git a/templates/result_view.html b/templates/result_view.html new file mode 100644 index 0000000..8e3a088 --- /dev/null +++ b/templates/result_view.html @@ -0,0 +1,194 @@ +{% extends 'base.html' %} + + +{% block title %}Result View{% endblock %} +{% block style %} +{% endblock %} + +{% block content %} +
    +
    +
    +
    + + +
    +
    +
    + 資產權重變化 +
    +
    +
    + 投組價值走勢 +
    +
    +
    + 投組季報酬率 +
    +
    +
    +
    +
    +
    + {#
    +
    +
    + + +
    +
    + + +
    + +
    +
    +
    #} +
    +
    + +{% endblock %} + +{% block script %} + + +{% endblock script %} \ No newline at end of file diff --git a/templates/strategy_tw.html b/templates/strategy_tw.html new file mode 100644 index 0000000..b0afa12 --- /dev/null +++ b/templates/strategy_tw.html @@ -0,0 +1,259 @@ +{% extends 'base.html' %} +{% if session.tw == 1 %} + {% set active_page = 'strategy_tw' %} +{% else %} + {% set active_page = 'strategy' %} +{% endif %} + + + +{% block title %}Strategy Page{% endblock%} +{% block style %} +div.input-group > * { + border-radius: 0px; +} +div.card{ + border-radius: 2px; +} +.card-header { + color: #000093; +} +.scroll { + max-height: 450px; + overflow-y: auto; +} +@keyframes cursor { + 0% { + opacity: 0; + } + 40% { + opacity: 0; + } + 50% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + opacity: 0.9; + } +} +{% endblock style %} + +{% block content %} +
    +
    + + + +
    +
    +
    + 名稱與選擇資產 +
    + +
    +
    + {% cache 300 %} + + + + + {% endcache %} + +
    + + + + + +
    +
    +
      + {% for s in stock %} +
    1. + {{ s|safe }} + + + +
    2. + {% endfor %} +
    +
    +
    +
    + {% cache 300 %} +
    +
    +
    + 價格動態圖表 +
    +
    + +
    +
    +
    +
    + + 圖表將在此渲染。 + +
    +
    +
    +
    +
    +
    + 投組最佳化配置 +
    +
    + +
    +
    +
    + 滾動視窗大小 + +
    +
    + 最佳化頻率 + +
    +
    + 最佳化目標函數 + +
    + +
    + + + + + {% endcache %} +
    +
    + +{% endblock %} +{% block script %} + + + +{% endblock script %} \ No newline at end of file