CNN לניתוח גרפי קריפטו: פיתוח 1D TCN, 2D EfficientNet

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

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1481
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1336
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1034
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1293
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    738
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1032

פיתוח מודלי CNN לניתוח גרפי קריפטו

אינדיקטורים סטנדרטיים כמו RSI ו-MACD נותנים אותות שגויים בגרפי קריפטו רועשים. רשת נוירונים היא הדרך היחידה לחלץ דפוסים נסתרים מנתוני שוק. אנו מפתחים מודלי CNN מוכנים לסיווג דפוסי נרות: מקונבולוציות 1D על סדרות זמן ועד קונבולוציות 2D על צילומי מסך. בפרויקט אחד, הדיוק עלה מ-78% ל-94% לאחר מעבר לארכיטקטורה היברידית, ועלויות מחשוב הענן הופחתו ב-2000 דולר לחודש. בנוסף, הלקוח חסך 15,000 דולר בשנה על ידי אופטימיזציה של שימוש ב-GPU. Bai et al. (2018) הראו ש-TCN עולה על LSTM במשימות רצף ארוך. צרו קשר — נבחן את המשימה שלכם ונציע את הפתרון האופטימלי.

1D או 2D CNN: מה לבחור לגרפי קריפטו?

במסחר בקריפטו קיימות שתי גישות בסיסיות לניתוח גרפים: עיבוד סדרות OHLCV מספריות דרך CNN 1D או רינדור גרף נרות לתמונה והזנתו ל-CNN 2D. לכל אחת יש יתרונות משלה. בואו נפרק זאת עם דוגמה.

גישה 1: CNN 1D לסדרות זמן

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

import torch
import torch.nn as nn

class CryptoCNN1D(nn.Module):
    def __init__(self, input_channels, seq_len=60):
        super().__init__()
        # Multi-scale convolutions: разные размеры ядер для разных таймфреймов
        self.conv_short = nn.Sequential(
            nn.Conv1d(input_channels, 64, kernel_size=3, padding=1),
            nn.BatchNorm1d(64),
            nn.ReLU()
        )
        self.conv_medium = nn.Sequential(
            nn.Conv1d(input_channels, 64, kernel_size=9, padding=4),
            nn.BatchNorm1d(64),
            nn.ReLU()
        )
        self.conv_long = nn.Sequential(
            nn.Conv1d(input_channels, 64, kernel_size=21, padding=10),
            nn.BatchNorm1d(64),
            nn.ReLU()
        )
        # Объединяем все масштабы
        self.residual_blocks = nn.ModuleList([
            ResidualBlock1D(192, 128),
            ResidualBlock1D(128, 64),
        ])
        self.global_avg_pool = nn.AdaptiveAvgPool1d(1)
        self.global_max_pool = nn.AdaptiveMaxPool1d(1)
        self.classifier = nn.Sequential(
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Dropout(0.3),
            nn.Linear(64, 3)  # buy / hold / sell
        )

    def forward(self, x):
        # x: (batch, channels, seq_len) — нужна транспозиция!
        x_t = x.permute(0, 2, 1)
        short = self.conv_short(x_t)
        medium = self.conv_medium(x_t)
        long = self.conv_long(x_t)
        combined = torch.cat([short, medium, long], dim=1)
        for block in self.residual_blocks:
            combined = block(combined)
        avg = self.global_avg_pool(combined).squeeze(-1)
        max_ = self.global_max_pool(combined).squeeze(-1)
        pooled = torch.cat([avg, max_], dim=1)
        return self.classifier(pooled)

class ResidualBlock1D(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.conv1 = nn.Conv1d(in_channels, out_channels, 3, padding=1)
        self.bn1 = nn.BatchNorm1d(out_channels)
        self.conv2 = nn.Conv1d(out_channels, out_channels, 3, padding=1)
        self.bn2 = nn.BatchNorm1d(out_channels)
        self.shortcut = nn.Conv1d(in_channels, out_channels, 1) if in_channels != out_channels else nn.Identity()

    def forward(self, x):
        residual = self.shortcut(x)
        x = torch.relu(self.bn1(self.conv1(x)))
        x = self.bn2(self.conv2(x))
        return torch.relu(x + residual)

גישה 2: CNN על גרפים כתמונות

רנדרו את גרף הנרות כתמונה, העבירו אותו ל-ResNet/EfficientNet לסיווג אותות.

from PIL import Image, ImageDraw
import numpy as np
import torchvision.models as models

def render_candlestick_image(ohlcv_data, width=224, height=224):
    """Рендерим последние N свечей как PIL Image"""
    img = Image.new('RGB', (width, height), color='black')
    draw = ImageDraw.Draw(img)
    n_candles = len(ohlcv_data)
    candle_width = width / n_candles * 0.8
    price_min = ohlcv_data['low'].min()
    price_max = ohlcv_data['high'].max()
    price_range = price_max - price_min

    def price_to_y(price):
        return height - int((price - price_min) / price_range * height * 0.9) - int(height * 0.05)

    for i, (_, row) in enumerate(ohlcv_data.iterrows()):
        x = int(i * width / n_candles) + int(candle_width / 2)
        # Фитиль
        draw.line([(x, price_to_y(row['high'])), (x, price_to_y(row['low']))], fill='white', width=1)
        # Тело свечи
        open_y = price_to_y(row['open'])
        close_y = price_to_y(row['close'])
        color = (0, 200, 0) if row['close'] >= row['open'] else (200, 0, 0)
        x1 = x - int(candle_width / 2)
        x2 = x + int(candle_width / 2)
        draw.rectangle([x1, min(open_y, close_y), x2, max(open_y, close_y)], fill=color)
    return img

class CandlestickCNN(nn.Module):
    def __init__(self, n_classes=3, pretrained=True):
        super().__init__()
        # Используем pretrained EfficientNet как backbone
        self.backbone = models.efficientnet_b0(pretrained=pretrained)
        n_features = self.backbone.classifier[1].in_features
        self.backbone.classifier = nn.Sequential(
            nn.Dropout(0.3),
            nn.Linear(n_features, n_classes)
        )

    def forward(self, x):
        return self.backbone(x)

השוואה בין גישות 1D ו-2D

הבחירה תלויה בנתוני המקור ובסוג הדפוסים הרצוי. אם יש לכם סדרות OHLCV נקיות והמשימה היא לסווג תנועות קצרות טווח, CNN 1D ייתן ביצועים טובים יותר. אם הגרף עשיר ויזואלית ודפוסי ניתוח טכני (ראש וכתפיים, דגלים) חשובים, CNN 2D עם backbone מאומן מראש יראה דיוק גבוה יותר.

ארכיטקטורות מתקדמות: TCN והיבריד CNN+LSTM

מעבר ל-CNN 1D ו-2D הקלאסיים, אנו מיישמים גרסאות מתקדמות יותר בפרויקטים.

TCN (רשת קונבולוציונית זמנית)

אלטרנטיבה מודרנית יותר לארכיטקטורת CNN 1D המשתמשת בקונבולוציות סיבתיות מורחבות:

class TCNBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, dilation):
        super().__init__()
        padding = (kernel_size - 1) * dilation
        self.conv = nn.Conv1d(in_channels, out_channels, kernel_size, padding=padding, dilation=dilation)
        self.chomp = nn.Identity() # обрезаем будущее: x[:, :, :-padding]
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.1)

    def forward(self, x):
        out = self.conv(x)
        # Causal: оставляем только прошлое
        if self.conv.padding[0] > 0:
            out = out[:, :, :-self.conv.padding[0]]
        return self.dropout(self.relu(out))

קונבולוציות מורחבות מגדילות באופן אקספוננציאלי את שדה הקליטה ללא הגדלת פרמטרים: עם הרחבה 1, 2, 4, 8 ו-kernel=3 אנו מכסים 32 צעדי זמן. מידע נוסף על הארכיטקטורה ניתן למצוא במאמר על TCN.

היבריד CNN+LSTM

CNN מחלץ דפוסים מקומיים, LSTM לוכד תלות ארוכת טווח:

class CNN_LSTM(nn.Module):
    def __init__(self, input_size, cnn_channels=64, lstm_hidden=128):
        super().__init__()
        self.cnn = nn.Sequential(
            nn.Conv1d(input_size, cnn_channels, 3, padding=1),
            nn.ReLU(),
            nn.Conv1d(cnn_channels, cnn_channels, 3, padding=1),
            nn.ReLU()
        )
        self.lstm = nn.LSTM(cnn_channels, lstm_hidden, batch_first=True)
        self.fc = nn.Linear(lstm_hidden, 1)

    def forward(self, x):
        # CNN expects (batch, channels, seq)
        cnn_out = self.cnn(x.permute(0, 2, 1)).permute(0, 2, 1)
        lstm_out, _ = self.lstm(cnn_out)
        return self.fc(lstm_out[:, -1, :])

השוואת גישות: 1D לעומת 2D לעומת TCN לעומת היבריד

גישה סוג נתונים שדה קליטה מורכבות אימון הכי מתאים ל
CNN 1D סדרות OHLCV מוגבל לגודל kernel נמוכה (מעט פרמטרים) דפוסים קצרי טווח (עד 30-60 נרות)
CNN 2D (EfficientNet) תמונות גרף כל צילום המסך גבוהה (דורש אימון מקדים) דפוסים ויזואליים (ראש וכתפיים, משולשים)
TCN סדרות OHLCV גדול אקספוננציאלית (מורחב) בינונית תלות ארוכת טווח (מאות נרות)
CNN+LSTM סדרות OHLCV בלתי מוגבל תיאורטית (LSTM) גבוהה (LSTM נוטה ל-overfitting) סולמות זמן מעורבים

השוואת ביצועים על מערך נתונים אמיתי

ארכיטקטורה ציון F1 זמן inference (ms/batch) פרמטרים (M)
CNN 1D (מוצע) 0.82 2.1 1.2
EfficientNet 2D 0.88 15.3 5.3
TCN 0.86 3.4 2.1
CNN+LSTM 0.84 8.7 3.5

למה TCN עדיף לתלות ארוכת טווח?

TCN פותר את בעיית שדה הקליטה המוגבל של CNN 1D הקלאסי. בזכות קונבולוציות מורחבות, שכבת TCN אחת עם הרחבה=1,2,4,8 ו-kernel=3 מכסה 32 צעדי זמן, וערימת מספר בלוקים מכסה מאות נרות. זה מאפשר למודל לראות הקשר מספיק לזיהוי מגמות ודפוסי ניתוח טכני גדולים. בפרויקט אחד, החלפת CNN 1D ב-TCN שיפרה את ציון F1 ב-12%.

אימון מקדים על נתונים סינתטיים

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

מה כלול בעבודה

  • תכנון ארכיטקטוני (בחירת טופולוגיית CNN/TCN/היברידית) לנתונים שלכם
  • יישום ב-PyTorch 2.x עם דיוק מעורב ותמיכה ב-multi-GPU
  • אימון מקדים על נתונים סינתטיים וכוונון עדין על הנרות ההיסטוריים שלכם
  • פיתוח צינור inference ואינטגרציה דרך REST API (FastAPI)
  • תיעוד (ארכיטקטורה, תצורה, הוראות אימון מחדש)
  • הכשרת הצוות שלכם ותמיכה למשך חודש לאחר המסירה

שלבי פיתוח מודל CNN

תהליך הפיתוח כולל את השלבים הבאים:

  1. ניתוח נתונים והגדרת בעיה (1-2 שבועות): לימוד נרות היסטוריים, הגדרת דפוסי מטרה, הכנת benchmark.
  2. תכנון ארכיטקטורה (שבוע): בחירת 1D/2D/TCN/היבריד, תכנון צינור augmentation.
  3. יישום ואימון מקדים (2-4 שבועות): יישום ב-PyTorch, אימון מקדים על נתונים סינתטיים, כוונון עדין.
  4. בדיקות ואופטימיזציה (1-2 שבועות): ולידציה על קבוצה מופרדת, cross-validation, ensembling.
  5. אינטגרציה ותיעוד (1-2 שבועות): REST API, הוראות, הכשרת צוות.

למה לעבוד איתנו?

הניסיון שלנו כולל למעלה מ-30 פריסות של מודלי CNN במערכות מסחר, כולל פרוטוקולי DeFi ומסחר prop. אנו מבטיחים השגת יעדי מדדים לדיוק ו-recall. קבלו ייעוץ למשימה שלכם והערכת לוחות זמנים ראשונית — צרו קשר. הזמינו פיתוח מודל וקבלו ארכיטקטורה ראשונית והערכת עלות תוך 3 ימי עסקים.