אשתי ואני סחרנו דרך חשבונות Robinhood נפרדים. אחד מאיתנו היה קונה משהו, מספר לשני אחר כך, ומקווה שלא עשינו את אותו הדבר פעמיים. כל אחד ראה את החשבון שלו. כדי לראות מה אנחנו מחזיקים ביחד, היינו צריכים להשוות ביניהם ידנית.
Robinhood מתאים לאדם אחד. המערכת לא בנויה לשני אנשים.
אז בניתי משהו שכן בנוי לזה. הגרסה הראשונה לקחה בערך שעתיים. בהמשך הפוסט מופיעות גם תוספות שבנינו אחר כך.
האוטומציה החדשה יותר רצה עם עסקאות מדומות. צילומי המסך מציגים דוגמאות לשימוש, לא תוצאות השקעה.
למה בנינו את זה
היו לנו החשבונות והיו לנו הפוזיציות, ומה שלא יכולנו לעשות הוא להסתכל על שניהם בו זמנית: אין API שאפשר לשאול, אין היסטוריה משותפת, ואין דרך לדעת איך נראית התמונה המשולבת בלי להשוות ידנית שתי אפליקציות בשני טלפונים. אחד מאיתנו היה בודק משהו; השני היה מקבל החלטה נפרדת באותו יום.
היינו צריכים חשבון שמדבר HTTP.
מעטים מהמשקיעים הפרטיים יודעים שלחברת Charles Schwab יש API חינמי ומתועד למפתחים. נרשמים בפורטל המפתחים שלהם, מחכים יום-יומיים לאישור, ומקבלים גישת OAuth2 לחשבון המסחר שלכם: מחירים, פוזיציות, שליחת פקודות מסחר, היסטוריית עסקאות, הכל. העברנו את שני חשבונות Robinhood שלנו ל-Schwab. כולל העברת ACATS, כל ההעברה לקחה שבוע.
מה בנינו
בגרסה הראשונה היו כ-1,500 שורות Python בליבת המסחר, בלי תלויות pip, ועוד 1,400 שורות בבוט הטלגרם.
ל-CLI יש כעשרים פקודות בערך: quote, research, theme, buy, sell, pnl, audit ועוד. הוא מדבר ישירות עם ה-REST API של Schwab, בלי ספריית מסחר של צד שלישי בדרך.
בודק סיכונים שרץ לפני כל פקודת מסחר. מגבלות קשיחות מוגדרות כאן בקוד Python, לא בפרומפט: מינוף מקסימלי של פי 2, היקף כספי מקסימלי של 250,000 דולר לפקודה, מנגנון עצירה אחרי הפסד יומי של 10%, מנגנון עצירה אחרי ירידה של 20% מהשיא. אי אפשר לעקוף אותן, לא משנה מה ה-AI אומר.
בוט טלגרם שעוטף את ה-CLI ומשמש כממשק המשותף שלנו. שנינו באותה קבוצה; שנינו יכולים לשאול שאלות ולראות את אותן התשובות. Claude Sonnet מבצע את הניתוח, עם תקרה יומית קשיחה של 5 דולר להוצאות AI.
טוקני OAuth נשמרים ב-Cloudflare KV. פקודות המסחר נכתבות לקובץ JSONL מקומי לפני שהן מגיעות ל-Cloudflare D1, כך שתקלה במסד הנתונים לבדה לא אמורה למחוק את התיעוד.
בדיקת הסיכון
ה-Reviewer הוא קוד, לא פרומפט.
רציתי שבדיקת הסיכון תרוץ לפני שאחד מאיתנו יוכל לאשר עסקה, אז ה-Reviewer רץ בקוד Python לפני כל קריאה ל-API לשליחת פקודות מסחר של Schwab. הוא קורא את מצב התיק הנוכחי, מעריך את המינוף אחרי העסקה, בודק כל מגבלה קשיחה, מתעד את ההחלטה שלו במסד הנתונים, ואו מאפשר לפקודה לעבור או חוסם אותה ומסביר למה. מודל השפה מציע; הקוד מחליט אם בטוח להמשיך.
הצע ← בדוק ← אשר ← בצע: ה-AI מציע, הקוד בודק, אתה מאשר, Schwab מבצע.
ההחלטות שנובעות מזה
ברגע שבדיקת ה-Reviewer מקובעת בקוד כמנגנון קבוע, כמה דברים נוספים מסתדרים. ה-Reviewer אוכף מגבלות לכל פקודה בנפרד, אז פוזיציה גדולה שהייתה חורגת מתקרת המניות לפקודה בודדת צריכה מסלול אחר. המערכת מריצה קודם בדיקת סיכון ברמת כל החשבון על הכמות הכוללת, מפצלת אותה לחלקים שעומדים בתקרה, ואז מעבירה כל חלק דרך ה-Reviewer בנפרד לפני השליחה ל-Schwab. עסקאות גדולות שתקינות עוברות; עסקאות גדולות מדי לא.
אפשר להגדיר מגבלות שונות לגודל עסקה ולריכוזיות בתיק המשנה, שנמצא בתוך אותו חשבון; המגבלות שמגינות על החשבון כולו ממשיכות לחול על כל עסקה: מינוף, הפסדים וכוח קנייה.
בתהליך שמתואר כאן, כללי היציאה פועלים אוטומטית: Stop Loss ב-8% הפסד, Trailing Stop, יציאת זמן אחרי חמישה ימים, ומימוש רווח ב-15%. כניסה חדשה ממתינה ללחיצת אישור בטלגרם לפני שהפקודה נשלחת ל-Schwab. הניסויים המאוחרים יותר באוטומציה מתוארים בהערות הבנייה למטה.
פרומפטי המחקר יכולים להשתפר עם הזמן, אבל יש בקוד חוזה כתוב שקובע מה ניתן לשינוי ומה לא: פרומפטים יכולים להשתנות, פרמטרים רכים יכולים להתהדק, אבל ה-Reviewer וכל מגבלה קשיחה לא ניתנים לשינוי. כל שינוי מוצע צריך בדיקות שעוברות ואישור אנושי. יש חזרה לגרסה קודמת בלחיצה אחת אם משהו לא עובד.
כל קריאה ל-API של Schwab ולמודל ה-AI מתועדת לפי תפקיד, עם תקרה יומית על הוצאות ה-AI, והפקודה costs מציגה בדיוק כמה עלה המחקר של השבוע, בחלוקה לפי מי ביקש מה. אם מגיעים לתקרה, הוצאות ה-AI נעצרות. עלות המחשוב שהמערכת צורכת גלויה באותה מידה כמו הכסף שהיא מנהלת.
גם החלטה שלא לסחור מתועדת באותו יומן עסקאות כמו הפקודות שיצאו לפועל: עסקאות שנבדקו ולא בוצעו, תזות שנפסלו, עסקאות שה-Reviewer חסם. אפשר לשאול למה המערכת לא סחרה בדיוק כמו שאפשר לשאול למה כן.
איך אנחנו משתמשים בזה
יש לנו קבוצת טלגרם משותפת: אני, אשתי, והבוט.
היא שולחת לקבוצה שאלה על מניה, והבוט מביא בריף: מחיר, יעדי אנליסטים, הקשר לענף או למגמה, דגלי סיכון. שנינו קוראים את אותה תשובה באותו שרשור, ומדברים על זה. אם רוצים לעשות משהו, היא מציעה עסקה; הבוט קובע את גודל הפוזיציה, מריץ את ה-Reviewer, ומציג את תוצאת הבדיקה לפני שמשהו נשלח ל-Schwab.
היא לוחצת אישור והפקודה הולכת ל-Schwab. שנינו רואים את אישור הביצוע בקבוצה; שנינו יכולים לבדוק את הרווח וההפסד ולראות את אותה תמונה.
פתאום יכולנו לדבר על אותה עסקה, עם אותם נתונים מול העיניים.
מה השתנה
האם משהו מכל זה הופך אותנו למשקיעים טובים יותר? אין לי מושג. השווקים קשים, ומי שאומר שהמערכת שלו מנצחת אותם באופן אמין, או משקר, או לא הריץ אותה מספיק זמן.
לפני כן, השקעה הייתה משהו שאחד מאיתנו עשה וסיפר לשני עליו בדיעבד; עכשיו זו שיחה משותפת. היא שואלת שאלה, אני קורא את אותה תשובה, אנחנו לא מסכימים על משהו, שואלים שאלת המשך, ומחליטים ביחד או לא בכלל.
ה-AI הוא הקול השלישי בשיחה הזו. הוא עושה את המחקר, מריץ את המספרים, מציף את מה שה-Reviewer מצא, ומציע את העסקה. אנחנו מקבלים את ההחלטה.
זה היה שווה את השעתיים.
הערות בנייה ומצב נוכחי
מה נוסף מאז הגרסה הראשונה
כל מה שלמטה נוסף אחרי שהפוסט הזה עלה לראשונה, מעבר ל-Reviewer ולתהליך הטלגרם שמתואר למעלה.
- לולאת אוטופיילוט. תהליך מתוזמן שעוקב אחרי השוק, הפוזיציות, ומצב החשבון. כללי יציאה קבועים (Stop Loss, Trailing Stop, יציאת זמן, Take Profit) פועלים בלי מעורבות של מודל. רעיונות חדשים עוברים דרך Scanner, ואז Strategist שמציע, ואז Critic שרואה רק את ההצעה ואת נתוני השוק, אבל לא את הנימוקים של ה-Strategist, ומנסה לפסול אותה. כל מה ששניהם מאשרים עדיין דורש לחיצה שלכם לפני שהוא מגיע לחשבון.
- תוכניות מסחר, לא רק פקודות בודדות. מבקשים משהו כמו "לפצל 10 אלף דולר בין ארבע מניות שבבים" והבוט בונה תוכנית אחת על כל ארבעת החלקים, מריץ הרצת בדיקה של ה-Reviewer על כל אחד, ומציג את הכול לפני שפקודה כלשהי נשלחת. אישור אחד מבצע כל חלק ברצף. תוכניות פגות מעצמן: חמש דקות לבקשת טלגרם, שלושים לכניסת אוטופיילוט. תוכנית שפג תוקפה לא מתבצעת.
- זיכרון ארוך טווח, בשתי שכבות. כל החלטה ואירוע נכתבים ליומן שאפשר רק להוסיף אליו, בלי יוצאים מן הכלל. מנגנון עריכה מקדם תובנה למעמד של "לקח" רק אחרי שהיא חזרה על עצמה בלפחות שלושה מקרים דומים, והיא פגה כעבור 45 יום אלא אם היא מאומתת מחדש. שכבה נוספת, קטנה יותר, של אמונות מגובשות מאחדת כפילויות, מתייחסת אחרת לסתירות בהתאם למצב השוק במקום למחוק את הישן, ודועכת עם הזמן. שולחים
/why NVDAבקבוצה וזה שולף את היסטוריית ההחלטות שלה על המניה הזאת. - בדיקה עצמית שלא יכולה לשכתב היסטוריה. כל כניסה נועלת את התזה, את התנאי שמבטל אותה, ואת רמת הביטחון לפני שהתוצאה ידועה, ביומן בלי פונקציית עריכה. הציון שאחרי העסקה מדרג את ההחלטה ואת התוצאה בנפרד, כך שהחלטה גרועה שהצליחה במזל והחלטה טובה שנכשלה בגלל חוסר מזל מסווגות בנפרד, במקום ששתיהן נחשבות סתם ניצחון או הפסד. דוח כיול בודק אם הפעמים שבהן המערכת אמרה שהיא בטוחה ב-70% אכן ניצחו בערך ב-70% מהמקרים.
- פרומפטים והגדרות שיכולים להציע שינויים לעצמם. הפרומפטים של Strategist ו-Critic, ושבעה עשר פרמטרים רכים, יכולים להיות מוצעים לשינוי על ידי המערכת עצמה, מול חוזה כתוב שמפרט בדיוק מה אפשר לשנות ומה לעולם לא: ה-Reviewer, ה-Trader, כל מגבלה קשיחה. גרסת מועמד נבדקת מול מקרים היסטוריים אמיתיים בבדיקה מקבילה שלא משפיעה על מסחר אמיתי, בלי כסף ובלי השפעה על החלטה בזמן אמת. אדם עדיין צריך לאשר בלחיצה, ויש חזרה לגרסה קודמת בפקודה אחת.
האוטומציה החדשה יותר נבדקת עם עסקאות מדומות. המתג הראשי ומתג הכניסה האוטומטית כבויים כברירת מחדל. בתהליך עם האישור שתיארתי למעלה, רק יציאות שמפחיתות סיכון יכולות לפעול בלי לחיצה של אדם.
עדיין לא הוכח
לולאת האוטופיילוט רצה עם עסקאות מדומות. כניסה אוטומטית תשנה את כלל האישור שתיארתי למעלה. כדי להפעיל אותה בכסף אמיתי, אני צריך להחליט על כך ולפעול לפי תוכנית ההפעלה המדורגת, שמתחילה בתוצאות סימולציה ובפוזיציות קטנות.
מערכת הזיכרון כנה בנוגע לגילה הצעיר. היא לא תכתוב לקח עד שראתה את אותו דפוס שלוש פעמים, ושום דבר לא נשאר אחרי 45 יום אלא אם זה קורה שוב. כרגע כמעט אין לה דעה על שום דבר, וזה בדיוק איך שמערכת שעוד לא צברה לקחים אמורה להיראות.
פרומפטים שמתפתחים בעצמם קיימים בקוד, אבל עדיין לא בשימוש יומיומי. פרומפט שהשתנה צריך לרוץ בבדיקה מקבילה מול החלטות ישנות ולנצח את הגרסה הנוכחית לפני שאדם בכלל רואה כפתור לחזרה לגרסה קודמת. לא הרצנו את המחזור הזה מספיק פעמים כדי שיהיו לנו תוצאות אמיתיות שאפשר להשוות.
התחשבות בנתוני מאקרו וחדשות (FOMC, CPI, לוחות זמנים לדוחות, כותרות) בנויה ומחוברת, אבל כבויה עד שנאשר ספק נתונים ותקציב לזה. חיפוש חי באינטרנט למחקר של ה-Critic נמצא מאחורי אותו סוג של דגל.
תוכנית ההפעלה מתחילה במסחר מדומה, ואחריו בפוזיציה קטנה בכסף אמיתי. הגדלת הסכום תלויה בתוצאות.
עדיין אין בדיקה היסטורית (backtest) מול נתוני מחיר מהעבר. יש כבר מצב מסחר על הנייר, ברירת המחדל של האוטופיילוט, בתוספת מסגרת shadow-eval שמריצה פרומפט מועמד מול החלטות עבר לפני שהוא עולה. אף אחד מהם לא מראה איך המערכת הייתה מתפקדת לאורך כמה שנים של נתוני מחירים.
פעם בשבוע אחד מאיתנו צריך להתחבר מחדש. זה לוקח חצי דקה. זה עדיין מעצבן.
בוט הטלגרם רץ היום כתהליך רקע קבוע ב-Render, לא על ה-Mac mini. ה-Mac משמש רק לפיתוח מקומי; אם הוא כבוי, שום דבר לא נשבר.
הרצנו את זה רק בתנאי שוק פחות או יותר רגילים. מנגנוני העצירה קיימים ונבדקו בפיתוח. האם הם יתנהגו כך גם תחת קריסה אמיתית? אני לא יודע. מה שלא נבדק, לא נבדק.
ניגשתי לזה בלי לדעת איך בונים מערכת מסחר. ידעתי Python ועבדתי עם ממשקי API בעבר. החלק הקשה היה להחליט מה המערכת צריכה לסרב לעשות ולהגדיר את המגבלות האלה בקוד.
עוד לא פרסמתי את הקוד בקוד פתוח. לליבת המסחר אין תלויות חיצוניות והיא יכולה לרוץ על רוב המכונות, אבל זרימת ה-OAuth ותשתית Cloudflare מותאמות לאופן שבו בנינו את הדברים אצלנו. אם אתם רוצים את הקוד, שלחו לי אימייל ל[email protected]. אם יהיה מספיק עניין, אני אסדר אותו ואפרסם אותו כמו שצריך. אם בניתם משהו דומה, או העברתם חשבון מ-Robinhood ל-Schwab בשביל הגישה ל-API, אשמח לדבר ולהשוות רשמים.
פרויקטים קשורים
schwagent הוא הפרויקט הקרוב ביותר שמצאתי: אותה טכנולוגיה (Python + Schwab + Telegram + LLM), קוד פתוח. הוא הרבה יותר גדול: יותר מ-35 מדדים טכניים, אסטרטגיות אופציות (wheel, iron condors, covered calls), בדיקה היסטורית בשיטת מונטה קרלו, ולוח בקרה ויזואלי. מדובר במערכת רצינית.
שלנו קטנה בכוונה. אין מדדים, אין בדיקה היסטורית, אין אופציות. אפס תלויות pip בליבה. רצינו משהו שנוכל לפרוס תוך אחר הצהריים ולסמוך עליו כי קראנו כל שורה בו.
אם אתם מחפשים אוטונומיה מלאה, כדאי לקרוא את הפוסט על קרן מסחר שמנוהלת על ידי סוכן ב-HN. שם ה-AI מקבל כל החלטה, בלי אדם בלולאה. הכותב תיעד כל אסטרטגיה כושלת באותה קפדנות כמו הניצחונות. המשמעת הזו ראויה להערכה. אנחנו בנינו משהו אחר: כלי לשני אנשים לחשוב יחד, כשה-AI עוזר ואנחנו אלה שמחליטים.