Splitting Telegram Alerts Into a User Channel and a Developer Channel

🌐 Korean Wiring Telegram notifications into a bot takes about thirty minutes. Get a bot token, call sendMessage , done. The trouble starts afterward: a single notification channel stops being usable very quickly. Buy filled, sell filled, rotation complete — all fine. But then API token expiry warnings, order rejection payloads, exception stacks and trigger failures land in the same room. Buried under messages they cannot interpret, users miss the fill notifications that actually matter. Then they turn notifications off. This post is about splitting alerts into a user channel and a developer channel. Structurally it is two functions, but where you draw that line ended up shaping how the whole thing is operated. The line between them One test: "is there anything the user can do with this message?" User channel — buy and sell fills, rotations, liquidations, bot start/stop. Things that happened in the account. A person can look and decide Developer channel ...

텔레그램 알림 이중화 — 사용자용과 개발자용을 갈라 놓기

🌐 English 봇에 텔레그램 알림을 붙이는 건 30분이면 끝납니다. 봇 토큰 받고, sendMessage 부르고, 끝. 문제는 그 다음입니다. 알림이 하나뿐이면 금방 못 쓰게 됩니다. 매수 체결, 매도 체결, 갈아타기 완료 — 여기까지는 좋습니다. 그런데 API 토큰 만료 경고, 주문 거부 응답, 예외 스택, 트리거 실패도 같은 방으로 들어옵니다. 사용자는 자기가 이해할 수 없는 메시지에 묻혀 정작 중요한 체결 알림을 놓칩니다. 그러다 알림을 꺼 버립니다. 이 글은 알림을 사용자 채널과 개발자 채널로 나눈 기록입니다. 함수 두 개로 갈라지는 단순한 구조지만, 그 경계를 어디에 긋느냐가 실제로는 운영 전체를 좌우했습니다. 둘로 나눈 기준 기준은 "이 메시지를 받고 사용자가 할 수 있는 일이 있는가" 하나입니다. 사용자 채널 — 매수·매도 체결, 갈아타기, 청산, 봇 시작/정지. 계좌에 실제로 일어난 일. 사용자가 보고 판단할 수 있습니다 개발자 채널 — API 오류, 예외, 파라미터 이상, 재시도 실패. 코드가 고쳐야 하는 일. 사용자가 받아 봐야 불안하기만 합니다 애매한 것들이 있습니다. "주문이 거부됐다"는 어느 쪽일까요. 둘 다입니다. 사용자에게는 "매수가 안 됐습니다"로, 개발자에게는 거부 코드와 응답 원문으로 갑니다. 같은 사건을 다른 언어로 두 번 보내는 것 이지, 한쪽으로 몰아 버리면 안 됩니다. 토큰과 chat_id를 어느 스코프에 둘 것인가 이 설계에서 가장 중요한 결정입니다. 두 채널은 봇 토큰부터 다릅니다. // 사용자 채널 — 봇 토큰은 공용, chat_id 는 사용자마다 다르다 function SendBOTUser(body) { if (getchatIdTel() == null || getchatIdTel() == "0") { return; ...

Turning a Monthly-Dividend ETF Rotation Strategy Into Code

이미지
🌐 Korean Up front: this post is about how a strategy gets translated into code . It is not investment advice and it guarantees nothing. The structure below can lose money, and it does. No specific product is recommended, so tickers are referred to only as "mid-month ETF" and "month-end ETF." Which instruments go in those slots is entirely the operator's decision, and so is the outcome. The hard part of automated trading is usually not coming up with a strategy — it is translating the rule already in your head into code. In your head, "rotate around the fifteenth, wait if the gap is wide, otherwise leave it alone" is one sentence. Unfold it into conditionals and it becomes twenty branches. This post covers implementing a rotation between two monthly-dividend ETFs in Apps Script. The short version: collapsing those twenty branches into a single array was the best decision in the whole implementation. Two slots, and why only two To col...

월배당 ETF 갈아타기 전략을 코드로 옮기기 — 날짜 배열 하나로 끝내기

이미지
🌐 English 먼저 밝힙니다. 이 글은 전략을 코드로 옮기는 방법 에 대한 기록이며, 투자 권유가 아니고 수익을 보장하지 않습니다. 아래 구조는 손실이 날 수 있고 실제로 납니다. 특정 종목을 추천하지 않으므로 상품명 대신 "월중 ETF / 월말 ETF"로만 씁니다. 어떤 종목을 넣을지는 전적으로 사용자 판단이며 그 결과도 본인 책임입니다. 자동매매에서 어려운 건 대체로 전략을 생각해 내는 것 이 아니라 이미 머릿속에 있는 규칙을 코드로 옮기는 것 입니다. 사람 머릿속에서는 "15일쯤에 갈아타고, 괴리 벌어지면 기다리고, 애매하면 그냥 둔다"가 한 문장인데, 이걸 조건문으로 펴면 갑자기 분기가 스무 개로 늘어납니다. 이 글은 월배당 ETF 두 종목을 번갈아 타는 규칙 을 Apps Script로 옮기면서 정리한 것들입니다. 결론부터 말하면, 스무 개의 분기를 배열 하나로 줄인 것 이 이 구현에서 가장 잘한 결정이었습니다. 월중과 월말, 두 칸으로 나눈 이유 월배당 ETF는 배당을 받으려면 특정 날짜까지 보유 하고 있어야 합니다. 이 날짜가 상품마다 다릅니다. 그래서 배당락 주기가 어긋나는 두 종목 을 잡으면, 한쪽의 마감일이 지난 뒤 다른 쪽의 마감일 전까지 옮겨 타는 구간이 생깁니다. 봇은 이 두 자리를 "월중" 칸과 "월말" 칸 으로 부릅니다. 화면에도 종목 카드가 두 장뿐이고, 각 카드에 종목번호·현재가·보유수량·괴리율·배당매수마감일이 붙습니다. 슬롯이 두 개로 고정 이라는 점이 중요합니다 — 종목을 몇 개든 담을 수 있게 만들면 "어느 것과 어느 것을 바꿀까"라는 문제가 새로 생기고, 그건 전혀 다른 전략입니다. 슬롯은 두 개로 고정입니다. 각 카드에 배당매수마감일과 괴리율이 함께 보입니다. 스케줄을 배열 하나로 처음에는 이렇게 썼습니다. if (day < 15) { ... } else if (da...

Publishing a Chrome Extension to the Web Store: Getting Through Review

이미지
🌐 Korean After the extension works, one step remains: getting it on the store. Running it locally in developer mode needs nothing but a folder, but handing it to someone else means mailing a zip and explaining "turn on developer mode." Chrome also greets anyone running an unpacked extension with a warning banner on every browser launch. This post covers actually listing the trading bot control panel from the previous two posts and passing review. Less about the click path, more about where it snags. Two numbers to know first A five dollar developer fee. One time per account, independent of how many extensions you publish. You cannot create a dashboard item until it clears, and activation can lag the payment slightly. Review takes days. Sometimes under a day, often a few. The number that matters is not the average but the variance . Ask for a lot of permissions or describe them vaguely and the submission routes to manual review, which is visibly slower. Largely,...

크롬 웹스토어에 확장 프로그램 배포하기 — 심사 통과까지

이미지
🌐 English 확장을 다 만들고 나면 마지막 단계가 남습니다. 스토어에 올리기. 개발자 모드로 로컬에서 쓸 때는 폴더만 있으면 되지만, 다른 사람에게 주려면 매번 zip을 보내고 "개발자 모드 켜세요"를 설명해야 합니다. 그리고 크롬은 개발자 모드로 로드한 확장에 브라우저를 켤 때마다 경고 배너 를 띄웁니다. 이 글은 앞의 두 글에서 만든 매매 봇 컨트롤 패널을 실제로 크롬 웹스토어에 올리고 심사를 통과한 기록입니다. 절차 자체보다 어디서 걸리는지 에 무게를 뒀습니다. 먼저 알아야 할 두 가지 숫자 개발자 등록비 5달러. 계정당 한 번 내는 일회성 비용이고, 확장 개수와 무관합니다. 이걸 내야 대시보드에 아이템을 만들 수 있습니다. 결제 후 계정 활성화까지 잠깐 걸릴 수 있습니다. 심사 기간은 며칠 단위. 빠르면 하루 안, 보통은 며칠입니다. 여기서 중요한 건 평균이 아니라 편차 입니다. 권한을 많이 요구하거나 설명이 모호하면 수동 검토로 넘어가면서 눈에 띄게 길어집니다. "언제 통과되는지"는 대체로 내가 만든 manifest가 결정합니다. 권한 최소화가 곧 심사 속도다 앞 글에서 manifest 권한을 최소로 유지한 이야기를 했는데, 그 효과가 가장 크게 나타나는 곳이 여기입니다. 이 확장의 권한은 이렇습니다. "permissions": [ "windows" ], "host_permissions": [ "https://script.google.com/*" ] 심사에서 문제가 되는 것은 대체로 다음 셋입니다. <all_urls> 또는 넓은 host_permissions — "모든 사이트의 데이터를 읽고 변경" 경고가 뜨고, 왜 필요한지 소명해야 합니다 content_scripts — 남의 페이지에 코드를 주입한다는 뜻이라 검토 강도가 올라갑니다 ...

Building a Trading Bot Control Panel as a Chrome Extension (Manifest V3)

이미지
🌐 Korean Once the backend lives on Google Apps Script, the next question arrives: what do I drive it with? GAS can serve HTML from doGet , so a web app screen is the obvious answer, and that is where this started. A few weeks in, one friction had piled up: checking the bot meant opening a tab, finding the URL, and waiting for a load. Twenty times a session. So the control surface moved into a Chrome extension popup . This post is that migration, and what Manifest V3 had to say about it. Why an extension instead of a web dashboard One reason: it is always one click away . No tab to open — just a toolbar icon No URL to remember — the deployment URL hides inside the extension It appears over whatever page you are on — glance at a chart, act immediately If the browser is open, it is in the same place it always was What you give up is equally clear: the screen is small. A popup is effectively about 400px wide. That decides the character of the thing — this is a re...