SeaWolf-AI commited on
Commit
83d14d7
ยท
verified ยท
1 Parent(s): 0922387

intraday time axis; baselines seeded at season open

Browse files
Files changed (4) hide show
  1. app/anchors.py +103 -84
  2. app/ledger.py +15 -0
  3. app/main.py +2 -1
  4. app/static/index.html +9 -2
app/anchors.py CHANGED
@@ -1,84 +1,103 @@
1
- # -*- coding: utf-8 -*-
2
- """๊ธฐ์ค€์„  ๋ด‡ โ€” ์ฐธ๊ฐ€์ž์™€ ๊ฐ™์€ ํ‘œ์— ๋†“์ผ ์ฒ™๋„.
3
-
4
- ODC๊ฐ€ ์Šน์ธ์•ฝ๊ณผ ๋ถˆํ™œ์„ฑ ํ™”ํ•ฉ๋ฌผ์„ ๊ฐ™์€ ํ‘œ์— ๋„ฃ์–ด ์ฒ™๋„๋ฅผ ๋ณด์—ฌ์ฃผ๋“ฏ,
5
- ๋ฆฌ๋”๋ณด๋“œ์— ๊ธฐ์ค€ ์ „๋žต์„ ํ•จ๊ป˜ ์˜ฌ๋ฆฐ๋‹ค. ์ฒ™๋„๊ฐ€ ์—†๋Š” ์ˆœ์œ„ํ‘œ๋Š” ์ฝ์„ ์ˆ˜ ์—†๋‹ค.
6
-
7
- ๐Ÿ”ด ์ฃผ์ตœ์ธก ๋ชจ๋ธ์€ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค.
8
- ์ด ์ฑŒ๋ฆฐ์ง€์˜ ๋ช…๋ถ„์€ "๋ˆ„๊ฐ€ ๋” ๋‚˜์€ ์˜ˆ์ธก ๋ชจ๋ธ์„ ๋งŒ๋“œ๋Š”๊ฐ€"์ด์ง€
9
- "์ฃผ์ตœ์ž๊ฐ€ ์ œ์ผ ์ž˜ํ•œ๋‹ค"๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ฃผ์ตœ์ž๊ฐ€ ์ž๊ธฐ ๋ชจ๋ธ์„ ์ฐธ๊ฐ€์ž ํ‘œ์— ์˜ฌ๋ฆฌ๋ฉด
10
- ๊ทธ ๋ช…๋ถ„์ด ํ๋ ค์ง„๋‹ค. ๊ธฐ์ค€์„ ์€ ์ฒ™๋„์ด์ง€ ๊ฒฝ์Ÿ์ž๊ฐ€ ์•„๋‹ˆ๋‹ค.
11
-
12
- ๊ธฐ์ค€์„  ์…‹ โ€” ์ „๋ถ€ ๊ณต๊ฐœ๋œ ๊ต๊ณผ์„œ ๊ธฐ๋ฒ•์ด๋‹ค
13
- BUYHOLD ํ•ญ์ƒ +1. ์ด๊ฑธ ๋ชป ์ด๊ธฐ๋ฉด ์•„๋ฌด ์˜๋ฏธ ์—†๋‹ค
14
- VOLTARGET ์ง€์ˆ˜๊ฐ€์ค‘ ๋ณ€๋™์„ฑ์œผ๋กœ ํฌ๊ธฐ๋งŒ ์กฐ์ ˆ. ๋ฐฉํ–ฅ์€ ๋กฑ ๊ณ ์ •
15
- RANDOM ๋งค์ผ -1/0/+1 ๋ฌด์ž‘์œ„. ๋ฐ”๋‹ฅ
16
-
17
- ๐Ÿ”‘ VOLTARGET ์€ ๋ฐฉํ–ฅ์„ ์˜ˆ์ธกํ•˜์ง€ ์•Š๋Š”๋‹ค.
18
- ๋ฐฉํ–ฅ ์˜ˆ์ธก์€ 60๊ฐœ ๋ณ€์ˆ˜๋กœ ๋‹ค์„ฏ ๋‹จ๊ณ„์— ๊ฑธ์ณ ์‹œํ—˜ํ–ˆ๊ณ  ์ „๋ถ€ ์˜ˆ์ธก๋ ฅ์ด ์—†์—ˆ๋‹ค.
19
- ๊ธฐ์ค€์„ ์ด ๋ฐฉํ–ฅ์„ ๋งžํžˆ๋Š” ์ฒ™ํ•˜๋ฉด, ๊ธฐ๊ฐํ•œ ๊ฒƒ์„ ๊ณต๊ฐœ๋ฉด์— ์˜ฌ๋ฆฌ๋Š” ์…ˆ์ด ๋œ๋‹ค.
20
- ๊ทธ๋ž˜์„œ ์ด ๊ธฐ์ค€์„ ์€ '์–ผ๋งˆ๋‚˜ ํฌ๊ฒŒ ๋“ค ๊ฒƒ์ธ๊ฐ€'๋งŒ ์ •ํ•œ๋‹ค.
21
- """
22
- import os, sys
23
- import numpy as np, pandas as pd
24
-
25
- HERE = os.path.dirname(os.path.abspath(__file__))
26
- sys.path[:0] = [HERE, os.path.dirname(HERE)]
27
- import ledger as L
28
-
29
- ANCHORS = {
30
- "BUYHOLD": "๋‹จ์ˆœ ๋ณด์œ ",
31
- "VOLTARGET": "๋ณ€๋™์„ฑ ํƒ€๊ฒŸํŒ…",
32
- "RANDOM": "๋ฌด์ž‘์œ„",
33
- }
34
- SPAN = 60
35
-
36
-
37
- def position(kind, px, seed=0):
38
- """์˜ค๋Š˜ ์žก์„ ํฌ์ง€์…˜. -1 ~ +1."""
39
- if kind == "BUYHOLD":
40
- return 1.0
41
-
42
- if kind == "RANDOM":
43
- # ๋‚ ์งœ๋ฅผ ์‹œ๋“œ์— ๋„ฃ์–ด ๊ฐ™์€ ๋‚  ๊ฐ™์€ ๊ฐ’ โ€” ์ฑ„์ ์ด ์žฌํ˜„ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค
44
- g = np.random.default_rng(
45
- int(pd.Timestamp.utcnow().strftime("%Y%m%d")) * 97 + seed)
46
- return float(g.choice([-1.0, 0.0, 1.0]))
47
-
48
- s = np.log(px).diff().ewm(span=SPAN).std().dropna()
49
- if len(s) < SPAN * 2:
50
- return 0.0
51
- # ๋ชฉํ‘œ ๋ณ€๋™์„ฑ = ๊ทธ ์ข…๋ชฉ ๊ณผ๊ฑฐ ์ค‘์•™๊ฐ’. ๋ณ€๋™์„ฑ์ด ๋‚ฎ์œผ๋ฉด ํฌ๊ฒŒ, ๋†’์œผ๋ฉด ์ž‘๊ฒŒ ๋“ ๋‹ค.
52
- target = float(s.iloc[:len(s) // 2].median())
53
- return float(max(0.0, min(1.0, target / float(s.iloc[-1]))))
54
-
55
-
56
- def run(assets, prices_fn, dry=False):
57
- """๊ธฐ์ค€์„  ์…‹์˜ ์˜ค๋Š˜ ํฌ์ง€์…˜์„ ๊ณ„์‚ฐํ•ด ์›์žฅ์— ๋„ฃ๋Š”๋‹ค."""
58
- if not dry:
59
- for name in ANCHORS:
60
- L.register(name, ANCHORS[name], "anchor", list(assets))
61
- out = []
62
- for i, a in enumerate(assets):
63
- px = prices_fn(a)
64
- if px is None or len(px) < SPAN * 2:
65
- continue
66
- for name in ANCHORS:
67
- p = position(name, px, seed=i)
68
- if not dry:
69
- L.submit(name, a, p, "anchor")
70
- out.append({"anchor": name, "asset": a, "position": round(p, 4)})
71
- return out
72
-
73
-
74
- if __name__ == "__main__":
75
- import main as M
76
- dry = "--dry" in sys.argv
77
- rows = run(list(M.ASSETS), lambda a: M.prices(a, "1d", 1500), dry=dry)
78
- print("๊ธฐ์ค€์„  ํฌ์ง€์…˜ %s\n" % ("(๋ชจ์˜)" if dry else "์ œ์ถœ ์™„๋ฃŒ"))
79
- by = {}
80
- for r in rows:
81
- by.setdefault(r["asset"], {})[r["anchor"]] = r["position"]
82
- print(" %-6s" % "์ข…๋ชฉ" + "".join("%12s" % k for k in ANCHORS))
83
- for a, v in by.items():
84
- print(" %-6s" % a + "".join("%12.3f" % v.get(k, 0) for k in ANCHORS))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """๊ธฐ์ค€์„  ๋ด‡ โ€” ์ฐธ๊ฐ€์ž์™€ ๊ฐ™์€ ํ‘œ์— ๋†“์ผ ์ฒ™๋„.
3
+
4
+ ODC๊ฐ€ ์Šน์ธ์•ฝ๊ณผ ๋ถˆํ™œ์„ฑ ํ™”ํ•ฉ๋ฌผ์„ ๊ฐ™์€ ํ‘œ์— ๋„ฃ์–ด ์ฒ™๋„๋ฅผ ๋ณด์—ฌ์ฃผ๋“ฏ,
5
+ ๋ฆฌ๋”๋ณด๋“œ์— ๊ธฐ์ค€ ์ „๋žต์„ ํ•จ๊ป˜ ์˜ฌ๋ฆฐ๋‹ค. ์ฒ™๋„๊ฐ€ ์—†๋Š” ์ˆœ์œ„ํ‘œ๋Š” ์ฝ์„ ์ˆ˜ ์—†๋‹ค.
6
+
7
+ ๐Ÿ”ด ์ฃผ์ตœ์ธก ๋ชจ๋ธ์€ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค.
8
+ ์ด ์ฑŒ๋ฆฐ์ง€์˜ ๋ช…๋ถ„์€ "๋ˆ„๊ฐ€ ๋” ๋‚˜์€ ์˜ˆ์ธก ๋ชจ๋ธ์„ ๋งŒ๋“œ๋Š”๊ฐ€"์ด์ง€
9
+ "์ฃผ์ตœ์ž๊ฐ€ ์ œ์ผ ์ž˜ํ•œ๋‹ค"๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ฃผ์ตœ์ž๊ฐ€ ์ž๊ธฐ ๋ชจ๋ธ์„ ์ฐธ๊ฐ€์ž ํ‘œ์— ์˜ฌ๋ฆฌ๋ฉด
10
+ ๊ทธ ๋ช…๋ถ„์ด ํ๋ ค์ง„๋‹ค. ๊ธฐ์ค€์„ ์€ ์ฒ™๋„์ด์ง€ ๊ฒฝ์Ÿ์ž๊ฐ€ ์•„๋‹ˆ๋‹ค.
11
+
12
+ ๊ธฐ์ค€์„  ์…‹ โ€” ์ „๋ถ€ ๊ณต๊ฐœ๋œ ๊ต๊ณผ์„œ ๊ธฐ๋ฒ•์ด๋‹ค
13
+ BUYHOLD ํ•ญ์ƒ +1. ์ด๊ฑธ ๋ชป ์ด๊ธฐ๋ฉด ์•„๋ฌด ์˜๋ฏธ ์—†๋‹ค
14
+ VOLTARGET ์ง€์ˆ˜๊ฐ€์ค‘ ๋ณ€๋™์„ฑ์œผ๋กœ ํฌ๊ธฐ๋งŒ ์กฐ์ ˆ. ๋ฐฉํ–ฅ์€ ๋กฑ ๊ณ ์ •
15
+ RANDOM ๋งค์ผ -1/0/+1 ๋ฌด์ž‘์œ„. ๋ฐ”๋‹ฅ
16
+
17
+ ๐Ÿ”‘ VOLTARGET ์€ ๋ฐฉํ–ฅ์„ ์˜ˆ์ธกํ•˜์ง€ ์•Š๋Š”๋‹ค.
18
+ ๋ฐฉํ–ฅ ์˜ˆ์ธก์€ 60๊ฐœ ๋ณ€์ˆ˜๋กœ ๋‹ค์„ฏ ๋‹จ๊ณ„์— ๊ฑธ์ณ ์‹œํ—˜ํ–ˆ๊ณ  ์ „๋ถ€ ์˜ˆ์ธก๋ ฅ์ด ์—†์—ˆ๋‹ค.
19
+ ๊ธฐ์ค€์„ ์ด ๋ฐฉํ–ฅ์„ ๋งžํžˆ๋Š” ์ฒ™ํ•˜๋ฉด, ๊ธฐ๊ฐํ•œ ๊ฒƒ์„ ๊ณต๊ฐœ๋ฉด์— ์˜ฌ๋ฆฌ๋Š” ์…ˆ์ด ๋œ๋‹ค.
20
+ ๊ทธ๋ž˜์„œ ์ด ๊ธฐ์ค€์„ ์€ '์–ผ๋งˆ๋‚˜ ํฌ๊ฒŒ ๋“ค ๊ฒƒ์ธ๊ฐ€'๋งŒ ์ •ํ•œ๋‹ค.
21
+ """
22
+ import os, sys
23
+ import numpy as np, pandas as pd
24
+
25
+ HERE = os.path.dirname(os.path.abspath(__file__))
26
+ sys.path[:0] = [HERE, os.path.dirname(HERE)]
27
+ import ledger as L
28
+
29
+ ANCHORS = {
30
+ "BUYHOLD": "๋‹จ์ˆœ ๋ณด์œ ",
31
+ "VOLTARGET": "๋ณ€๋™์„ฑ ํƒ€๊ฒŸํŒ…",
32
+ "RANDOM": "๋ฌด์ž‘์œ„",
33
+ }
34
+ SPAN = 60
35
+
36
+
37
+ def position(kind, px, seed=0):
38
+ """์˜ค๋Š˜ ์žก์„ ํฌ์ง€์…˜. -1 ~ +1."""
39
+ if kind == "BUYHOLD":
40
+ return 1.0
41
+
42
+ if kind == "RANDOM":
43
+ # ๋‚ ์งœ๋ฅผ ์‹œ๋“œ์— ๋„ฃ์–ด ๊ฐ™์€ ๋‚  ๊ฐ™์€ ๊ฐ’ โ€” ์ฑ„์ ์ด ์žฌํ˜„ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค
44
+ g = np.random.default_rng(
45
+ int(pd.Timestamp.utcnow().strftime("%Y%m%d")) * 97 + seed)
46
+ return float(g.choice([-1.0, 0.0, 1.0]))
47
+
48
+ s = np.log(px).diff().ewm(span=SPAN).std().dropna()
49
+ if len(s) < SPAN * 2:
50
+ return 0.0
51
+ # ๋ชฉํ‘œ ๋ณ€๋™์„ฑ = ๊ทธ ์ข…๋ชฉ ๊ณผ๊ฑฐ ์ค‘์•™๊ฐ’. ๋ณ€๋™์„ฑ์ด ๋‚ฎ์œผ๋ฉด ํฌ๊ฒŒ, ๋†’์œผ๋ฉด ์ž‘๊ฒŒ ๋“ ๋‹ค.
52
+ target = float(s.iloc[:len(s) // 2].median())
53
+ return float(max(0.0, min(1.0, target / float(s.iloc[-1]))))
54
+
55
+
56
+ def run(assets, prices_fn, dry=False, opens=None):
57
+ """๊ธฐ์ค€์„  ์…‹์˜ ์˜ค๋Š˜ ํฌ์ง€์…˜์„ ๊ณ„์‚ฐํ•ด ์›์žฅ์— ๋„ฃ๋Š”๋‹ค.
58
+
59
+ ๐Ÿ”ด ๊ธฐ์ค€์„ ์€ **์‹œ์ฆŒ ๊ฐœ๋ง‰ ์‹œ์ ๋ถ€ํ„ฐ** ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์ฒ˜์Œ ๋œฌ ์ˆœ๊ฐ„์—
60
+ ๋„ฃ์œผ๋ฉด ๊ทธ ์ „ ๊ตฌ๊ฐ„์ด ๋น„์–ด, ๋‹จ์ˆœ ๋ณด์œ ๊ฐ€ ์‹œ์žฅ์„ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€์ง€ ์•Š๋Š”๋‹ค.
61
+ ์‹ค์ œ๋กœ ๊ฐœ๋ง‰์ผ์— ์‹œ์žฅ โˆ’0.82% ์ธ๋ฐ ๋‹จ์ˆœ ๋ณด์œ ๊ฐ€ +0.12% ๋กœ ๋‚˜์™”๋‹ค โ€”
62
+ ๊ธฐ์ค€์„ ์ด ํ•˜๋ฝ ๊ตฌ๊ฐ„์„ ํ†ต์งธ๋กœ ๋น„์ผœ๊ฐ„ ๊ฒƒ์ด๋ผ ์ฒ™๋„ ๊ตฌ์‹ค์„ ๋ชป ํ•œ๋‹ค.
63
+
64
+ ๐Ÿ”‘ ๊ฐ’์ด ๊ทธ๋Œ€๋กœ๋ฉด ๋‹ค์‹œ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. ์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ™์€ ํฌ์ง€์…˜์„
65
+ ์Œ“์œผ๋ฉด ์›์žฅ์ด ๋ถ€ํ’€๊ณ , ๋ฌด์—‡์ด ์‹ค์ œ ํŒ๋‹จ ๋ณ€๊ฒฝ์ธ์ง€ ์ฝ์„ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.
66
+ """
67
+ if not dry:
68
+ for name in ANCHORS:
69
+ L.register(name, ANCHORS[name], "anchor", list(assets))
70
+ out = []
71
+ for i, a in enumerate(assets):
72
+ px = prices_fn(a)
73
+ if px is None or len(px) < SPAN * 2:
74
+ continue
75
+ for name in ANCHORS:
76
+ p = round(position(name, px, seed=i), 4)
77
+ note = ""
78
+ if not dry:
79
+ if opens and not L.positions(a, name):
80
+ # ๊ฐœ๋ง‰ ์‹œ์ ์— ๋จผ์ € ์‹ฌ๋Š”๋‹ค. ๊ทธ๋ž˜์•ผ ์ฒ™๋„๊ฐ€ ์ „ ๊ตฌ๊ฐ„์„ ๋ฎ๋Š”๋‹ค.
81
+ L.seed(name, a, p, opens, "anchor-open")
82
+ note = "๊ฐœ๋ง‰ ์‹œ์  ๊ธฐ๋ก"
83
+ last = L.latest(a, name)
84
+ if last is None or abs(last["p"] - p) > 1e-9:
85
+ L.submit(name, a, p, "anchor")
86
+ note = note or "๊ฐฑ์‹ "
87
+ else:
88
+ note = note or "๋ณ€๋™ ์—†์Œ"
89
+ out.append({"anchor": name, "asset": a, "position": p, "note": note})
90
+ return out
91
+
92
+
93
+ if __name__ == "__main__":
94
+ import main as M
95
+ dry = "--dry" in sys.argv
96
+ rows = run(list(M.ASSETS), lambda a: M.prices(a, "1d", 1500), dry=dry)
97
+ print("๊ธฐ์ค€์„  ํฌ์ง€์…˜ %s\n" % ("(๋ชจ์˜)" if dry else "์ œ์ถœ ์™„๋ฃŒ"))
98
+ by = {}
99
+ for r in rows:
100
+ by.setdefault(r["asset"], {})[r["anchor"]] = r["position"]
101
+ print(" %-6s" % "์ข…๋ชฉ" + "".join("%12s" % k for k in ANCHORS))
102
+ for a, v in by.items():
103
+ print(" %-6s" % a + "".join("%12.3f" % v.get(k, 0) for k in ANCHORS))
app/ledger.py CHANGED
@@ -233,6 +233,21 @@ def submit(user_id, asset, position, source="api"):
233
  return rec
234
 
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  def positions(asset, user_id=None):
237
  out = []
238
  p = _p("positions", "%s.jsonl" % asset)
 
233
  return rec
234
 
235
 
236
+ def seed(user_id, asset, position, at, source="seed"):
237
+ """์ง€์ •ํ•œ ์‹œ๊ฐ์œผ๋กœ ํฌ์ง€์…˜์„ ๊ธฐ๋กํ•œ๋‹ค. ๊ธฐ์ค€์„ ์„ ์‹œ์ฆŒ ๊ฐœ๋ง‰ ์‹œ์ ์— ์‹ฌ์„ ๋•Œ๋งŒ ์“ด๋‹ค.
238
+
239
+ ๐Ÿ”ด ์ฐธ๊ฐ€์ž์—๊ฒŒ๋Š” ์ ˆ๋Œ€ ์—ด์–ด ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ๊ณผ๊ฑฐ ์‹œ๊ฐ์œผ๋กœ ํฌ์ง€์…˜์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์œผ๋ฉด
240
+ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ  ๋‚˜์„œ ์œ ๋ฆฌํ•œ ์‹œ์ ์— ์ง„์ž…ํ•œ ๊ฒƒ์œผ๋กœ ๊พธ๋ฐ€ ์ˆ˜ ์žˆ๋‹ค.
241
+ """
242
+ pos = max(-1.0, min(1.0, float(position)))
243
+ rec = {"t": str(at), "u": user_id, "a": asset, "p": pos, "src": source}
244
+ with LOCK:
245
+ with open(_p("positions", "%s.jsonl" % asset), "a", encoding="utf-8") as f:
246
+ f.write(json.dumps(rec, ensure_ascii=False) + "\n")
247
+ _MIR["dirty"] = True
248
+ return rec
249
+
250
+
251
  def positions(asset, user_id=None):
252
  out = []
253
  p = _p("positions", "%s.jsonl" % asset)
app/main.py CHANGED
@@ -644,7 +644,8 @@ def _anchor_loop():
644
  import anchors as A
645
  while True:
646
  try:
647
- A.run(list(ASSETS), lambda a: prices(a, "1d", 1500))
 
648
  _SC.clear()
649
  except Exception:
650
  traceback.print_exc()
 
644
  import anchors as A
645
  while True:
646
  try:
647
+ A.run(list(ASSETS), lambda a: prices(a, "1d", 1500),
648
+ opens=S1["opens"] + "T00:00:00+00:00")
649
  _SC.clear()
650
  except Exception:
651
  traceback.print_exc()
app/static/index.html CHANGED
@@ -739,7 +739,14 @@ async function drawChart(a){
739
  rightPriceScale:{borderColor:C.line},
740
  timeScale:{borderColor:C.line, timeVisible:false},
741
  crosshair:{mode:1}, height:el.clientHeight});
742
- var t = d.t.map(function(x){ return x.slice(0, 10); });
 
 
 
 
 
 
 
743
  var mk = function(vals, color, dash){
744
  var ss = chart.addLineSeries({color:color, lineWidth:2, lineStyle:dash ? 2 : 0,
745
  priceLineVisible:false, lastValueVisible:false});
@@ -794,7 +801,7 @@ async function drawBaselines(a){
794
  rightPriceScale:{borderColor:C.line},
795
  timeScale:{borderColor:C.line, timeVisible:false},
796
  crosshair:{mode:1}, height:el.clientHeight});
797
- var t = d.t.map(function(x){ return x.slice(0, 10); });
798
  var add = function(vals, color, w, dash){
799
  var ss = chart.addLineSeries({color:color, lineWidth:w, lineStyle:dash ? 2 : 0,
800
  priceLineVisible:false, lastValueVisible:false});
 
739
  rightPriceScale:{borderColor:C.line},
740
  timeScale:{borderColor:C.line, timeVisible:false},
741
  crosshair:{mode:1}, height:el.clientHeight});
742
+ /* ๐Ÿ”ด ์‹œ๊ฐ์„ ๋‚ ์งœ๋กœ ์ž๋ฅด๋ฉด ํ•˜๋ฃจ ์•ˆ์˜ ์‹œ๊ฐ„๋ด‰์ด ์ „๋ถ€ ๊ฐ™์€ ํ‚ค๊ฐ€ ๋˜์–ด ํ•œ ์ ์œผ๋กœ
743
+ ๋ญ‰์นœ๋‹ค โ€” ๊ฐœ๋ง‰์ผ BTC ์ฐจํŠธ๊ฐ€ ์„ธ๋กœ์„  ํ•˜๋‚˜๋กœ ๋ณด์ธ ์›์ธ์ด๋‹ค. ํ•˜๋ฃจ๋ฅผ ๋„˜์ง€ ์•Š๋Š”
744
+ ๊ฒฉ์ž๋ฉด ์ดˆ ๋‹จ์œ„ ์ •์ˆ˜ ์‹œ๊ฐ์„ ์“ฐ๊ณ  ์‹œ๊ฐ„ ์ถ•์„ ์ผ ๋‹ค. */
745
+ var intraday = d.t.length > 1 && d.t[0].slice(0,10) === d.t[d.t.length-1].slice(0,10);
746
+ var t = d.t.map(function(x){
747
+ return intraday ? Math.floor(Date.parse(x + "Z") / 1000) : x.slice(0, 10);
748
+ });
749
+ if (intraday) chart.applyOptions({timeScale:{timeVisible:true, secondsVisible:false}});
750
  var mk = function(vals, color, dash){
751
  var ss = chart.addLineSeries({color:color, lineWidth:2, lineStyle:dash ? 2 : 0,
752
  priceLineVisible:false, lastValueVisible:false});
 
801
  rightPriceScale:{borderColor:C.line},
802
  timeScale:{borderColor:C.line, timeVisible:false},
803
  crosshair:{mode:1}, height:el.clientHeight});
804
+ var t = d.t.map(function(x){ return x.slice(0, 10); }); /* ์ฐธ๊ณ  ์ „๋žต์€ ํ•ญ์ƒ ์ผ๋ด‰ */
805
  var add = function(vals, color, w, dash){
806
  var ss = chart.addLineSeries({color:color, lineWidth:w, lineStyle:dash ? 2 : 0,
807
  priceLineVisible:false, lastValueVisible:false});