אסטרטגיה מייצרת תוצאות טובות באופן לא מציאותי על ידי הצצה אל העתיד

אחת המטרות העיקריות שלנו בפיתוח שפת הפיין היא לספק למשתמשים כמה שיותר כלים שימושיים.  כלים אלה עשויים להיות מגוונים לשימושים שונים, ועם מניפולציות מסוימות,  כמה אינדיקטורים וסוגי גרף מאפשרים לך לחלץ נתונים מהברים או העסקאות העתידיות (ביחס לבר המעובד כעת). 

מכיוון שסוחר אינו יכול לקבל נתונים אלה במסחר אמיתי, אסטרטגיות הבנויות סביבן יכולות לייצר תוצאות רווחיות באופן לא מציאותי בעת בדיקה חוזרת, בעוד שבמסחר בזמן אמת עסקאות אלו יהיו מופסדות. הטעות בשימוש במידע מן העתיד באסטרטגיות נקראת גם הטיה למבט קדימה.

חלק ממשתמשי TradingView, מתוך בורות או מתוך כוונה זדונית, נוטים ליצור רעיונות ופרסומי סקריפט המנצלים תכונה זו. TradingView אינו יכול להסיר את התכונה עצמה מכיוון שהיא עשויה להיות שימושית במקרים מסוימים, אך יחד עם זאת, אנו מחויבים להזהיר משתמשים מפני התנהגות זו.

אסטרטגיות באמצעות נרות בסגנון יפני

סיבה נפוצה מאוד להתנהגות זו היא בדיקת אסטרטגיה חוזרת בגרפים בסגנון יפני (רנקו, קאגי וכו '). הבעיה נובעת מהעובדה שמנוע האסטרטגיה לבדיקה חוזרת מחשיב כל בר כ -4 עסקאות, במחירי הפתיחה, הגבוה, הנמוך והסגירה (כפי שקורה בגרף נר יפני רגיל). מסיבה זו, בגרף של רנקו, מנוע האסטרטגיה לבדיקה חוזרת יכול להיכנס / לצאת מפוזיציה במחיר שלא היה קיים במציאות.  בנוסף, אם אתה מגדיר ערך Box Size  קטן מ- mintick, ניתן לבדוק אם המחיר הבא יהיה גבוה או נמוך מזה הנוכחי ולהיכנס / לצאת מהפוזיציה מראש, לפני שמנוע ה- Back Testing יעבד את המחיר האמיתי.

//@version=4
strategy("My Strategy", overlay=true)
if close < close[1]    strategy.entry("ShortEntryId", strategy.short)
strategy.close("ShortEntryId", when = close > close[1])if close > close[1]    strategy.entry("LongEntryId", strategy.long)
strategy.close("LongEntryId", when = close < close[1])
JavaScript

כפי שניתן לראות בצילום המסך, אסטרטגיה פשוטה זו יכולה לבצע עסקאות במחירים שקרובים מאוד למקסימום / מינימום.

אסטרטגיות המשתמשות בפרמטר calc_on_order_fills = true

כאשר הפרמטר calc_on_order_fills = true מוגדר בפונקציית האסטרטגיה, מנוע הבק טסטינג מבצע חישוב נוסף בתוך הבר, לאחר ביצוע ההוראה (בניגוד למצב הרגיל כאשר האסטרטגיה מחושבת רק בסיום הבר).  יחד עם זאת, במהלך החישוב, האסטרטגיה מקבלת גישה לפרמטרים רבים נוספים של בר, למשל, ערכים גבוהים ונמוכים. זה מאפשר לך לכתוב אסטרטגיה שתראה ביצועים מצוינים בזמן בק טסטינג.

//@version=4
strategy("CalcOnOrderFillsStrategy", overlay=true, calc_on_order_fills=true)// a variable is used to prevent double entry on the same bar
var lastTimeEntry = 0
 longCondition = close > sma(close, 14)  and lastTimeEntry != time
if longCondition    strategy.entry("LongEntryId", strategy.long)
 strategy.exit("exitId", "LongEntryId", limit=high)
lastTimeEntry := time
JavaScript

בצילום המסך תוכלו לראות שהערך הוא במחיר פתיחה של הבר, והיציאה מתרחשת בגובהו של אותו בר.  כלומר, במהלך החישוב, לאחר ביצוע ההוראה,  הגדרנו את מחיר הגבול של האסטרטגיה. יציאה השווה לרמה הגבוהה של הבר הנוכחי, מה שלא נוכל לעשות במסחר אמיתי.

בפרמטר lookahead = barmerge.lookahead  in security and any security before Pine v3

פונקציית האבטחה ב- Pine מאפשרת לך לבקש נתונים מסימולים ו / או לוחות זמנים אחרים. בהתאם ליישום,  הדבר עשוי לאפשר לאסטרטגיה לקבל נתונים מהעתיד: אם למשל, מבקשים סגירה או שיא של בר יומי, בעוד שבדיקה חוזרת של האסטרטגיה יכולה לדעת את הערכים הללו ממש בפתיחת היום.

לפני גרסה 3, פונקציית הsecurity  החזירה את הערך ממסגרת הזמן הגבוהה עוד לפני שהיה צריך להיות נגיש.  בגרסה 3 התנהגות זו תוקנה, אך לצורך תאימות, פרמטר lookahead נוסף לפונקציית הsecurity . זה  false  כברירת מחדל (כלומר, הראייה העתידית כבויה), אך באפשרותך לאפשר זאת על ידי הגדרת הערך של הפרמטר lookahead ל- barmerge.lookahead_on).

דוגמה לאסטרטגיה רווחית שנבנתה באמצעות תכונה זו:

//@version=4
strategy("My Strategy", overlay=true)
dayStart = security(syminfo.tickerid, "1D", time, lookahead=barmerge.lookahead_on)
dayHigh = security(syminfo.tickerid, "1D", high, lookahead=barmerge.lookahead_on)
dayLow = security(syminfo.tickerid, "1D", low, lookahead=barmerge.lookahead_on)// entry at first bar of a day
if time == dayStart    // distance to daily high is further, so we can earn moreif abs(open - dayHigh) > abs(open - dayLow)        strategy.entry("LongEntryId", strategy.long)        strategy.exit("exitLongId", "LongEntryId", limit=dayHigh)else        strategy.entry("ShortEntryId", strategy.short)        strategy.exit("exitShortId", "ShortEntryId", limit=dayLow)plot(dayHigh)
plot(dayLow)
JavaScript

בבר הראשון אנו מנתחים האם המחיר יעלה למעלה או למטה יחסית למחיר הפתיחה ועל סמך זה אנו נכנסים למצב לונג או שורט ואז יוצאים במחיר המקסימום או המינימום של היום בהתאמה.

שים לב שלא בכל המקרים שבהם security() כוללת את הארגומנט barmerge.lookahead_on מכוונים לעתיד: למשל, אם היינו משנים את הקוד לעיל על ידי החלפת זמן / גבוה / נמוך בתוך security() לזמן [1] / גבוה [ 1] / low [1] בהתאמה, נקבל ערכים עבור הברים שכבר נסגרו. זה משמש לעתים קרובות קודנים מנוסים לקבל נתונים מsecurity() ללא כל סיכון של lookahead 

כרגע, כל אלה דרכים ידועות לאסטרטגיה של התבוננות בעתיד. אנו מקווים שתיאור זה יאפשר לך ליצור אסטרטגיות שאין בהן חסרונות אלה, וכן להימנע מאסטרטגיות שפורסמו אשר מחבריהם מנצלים את התכונות הללו ברעיונותיהם.