English Русский 中文 Español Deutsch 日本語 Português
preview
Zaman, fiyat ve hacme göre 3D çubuklar oluşturma

Zaman, fiyat ve hacme göre 3D çubuklar oluşturma

MetaTrader 5Entegrasyon |
22 4
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Giriş

Bu projeye başlayalı altı ay oldu. Bu fikrin ortaya çıkmasının üzerinden yarım yıl geçti; bana aptalca gelmişti, bu yüzden pek üzerinde durmadım, sadece tanıdığım yatırımcılarla tartıştım. 

Her şey basit bir soruyla başladı - yatırımcılar neden 2D grafiklere bakarak 3D bir piyasayı analiz etmeye çalışmakta ısrar ediyorlar? Fiyat hareketinin değerlendirilmesi, teknik analiz, dalga teorisi - tüm bunlar piyasanın bir düzleme yansıtılmasıyla yapılıyor. Peki ya fiyat, hacim ve zamanın gerçek yapısını görmeye çalışırsak ne olur?

Algoritmik sistemler üzerine yaptığım çalışmalarda, geleneksel göstergelerin fiyat ve hacim arasındaki kritik ilişkileri gözden kaçırdığı gerçeğiyle sürekli olarak karşılaştım.

3D çubuklar fikri hemen ortaya çıkmadı. İlk olarak, piyasa derinliğinin 3D görselleştirilmesiyle ilgili denemeler yaptım. Ardından hacim-fiyat kümelerinin ilk taslakları belirdi. Zaman bileşenini eklediğimde ve ilk 3D çubuğu oluşturduğumda, bunun piyasayı görmenin temelde yeni bir yolu olduğunu açıkça fark ettim.

Bugün sizlerle bu çalışmanın sonuçlarını paylaşmak istiyorum. Size Python ve MetaTrader 5'in gerçek zamanlı olarak hacim çubukları oluşturmanıza nasıl olanak sağladığını göstereceğim. Hesaplamaların arkasındaki matematikten ve bu bilgilerin pratik alım-satımda nasıl kullanılacağından bahsedeceğim.


3D çubukta farklı olan nedir?

Piyasaya iki boyutlu grafiklerin merceğinden baktığımız sürece, en önemli şeyi, yani gerçek yapısını gözden kaçırırız. Geleneksel teknik analiz fiyat-zaman, hacim-zaman projeksiyonları ile çalışır, ancak bu bileşenlerin etkileşiminin tam resmini asla göstermez.

3D analiz, piyasayı bir bütün olarak görmemizi sağlaması bakımından temelde farklıdır. Bir hacim çubuğu oluşturduğumuzda, kelimenin tam anlamıyla, her bir boyutun kritik bilgiler taşıdığı piyasa durumunun bir "anlık görüntüsünü" oluşturmuş oluruz:

  • çubuğun yüksekliği fiyat hareketinin genliğini gösterir
  • genişliği zaman ölçeğini yansıtır
  • derinliği hacim dağılımını görselleştirir

Bu neden önemli? Bir grafik üzerinde iki özdeş fiyat hareketi hayal edin. İki boyutlu olarak aynı görünürler. Ancak hacim bileşenini eklediğimizde, resim dramatik bir şekilde değişir - bir hareket büyük hacimle desteklenerek derin ve istikrarlı bir çubuk oluştururken, diğeri gerçek işlemler bakımından minimum desteğe sahip yüzeysel bir dalgalanma olabilir.

3D çubukları kullanan entegre bir yaklaşım, teknik analizin klasik bir sorunu olan sinyal gecikmesini çözer. Çubuğun hacimsel yapısı ilk tiklerden itibaren oluşmaya başlar ve güçlü bir hareketin ortaya çıkışını normal bir grafikte görünmeden çok önce fark etmemizi sağlar. Özünde, geçmiş kalıplara değil, mevcut işlemlerin gerçek dinamiklerine dayanan bir tahmine dayalı analiz aracı elde ediyoruz.

Çok değişkenli veri analizi güzel bir görselleştirmeden daha fazlasıdır; piyasa mikro yapısını anlamanın temelde yeni bir yoludur. Her 3D çubuk şu bilgileri içerir:

  • hacmin fiyat aralığı içindeki dağılımı
  • pozisyon birikim hızı
  • alıcılar ve satıcılar arasındaki dengesizlikler
  • mikro düzeyde volatilite
  • hareket momentumu

Tüm bu bileşenler tek bir mekanizma olarak çalışarak fiyat hareketinin gerçek doğasını görmenizi sağlar. Klasik teknik analizin sadece bir mum veya çubuk gördüğü yerde, 3D analiz arz ve talep etkileşiminin karmaşık yapısını gösterir.


Ana ölçütlerin hesaplanması için denklemler. 7D çubukların oluşturulmasının temel ilkeleri. Farklı boyutları tek bir sistemde birleştirme mantığı

3D çubukların matematiksel modeli, gerçek piyasa mikro yapısının analizinden ortaya çıkmıştır. Sistemdeki her bir çubuk üç boyutlu bir şekil olarak temsil edilebilir:

class Bar3D:
    def __init__(self):
        self.price_range = None  # Price range
        self.time_period = None  # Time interval
        self.volume_profile = {} # Volume profile by prices
        self.direction = None    # Movement direction
        self.momentum = None     # Impulse
        self.volatility = None   # Volatility
        self.spread = None       # Average spread

Kilit nokta, çubuk içindeki hacimsel profilin hesaplanmasıdır. Klasik çubuklardan farklı olarak, hacmin fiyat seviyelerine göre dağılımını analiz ediyoruz.

def calculate_volume_profile(self, ticks_data):
    volume_by_price = defaultdict(float)
    
    for tick in ticks_data:
        price_level = round(tick.price, 5)
        volume_by_price[price_level] += tick.volume
        
    # Normalize the profile
    total_volume = sum(volume_by_price.values())
    for price in volume_by_price:
        volume_by_price[price] /= total_volume
        
    return volume_by_price

Momentum, fiyat ve hacim değişim oranının bir kombinasyonu olarak hesaplanır:

def calculate_momentum(self):
    price_velocity = (self.close - self.open) / self.time_period
    volume_intensity = self.total_volume / self.time_period
    self.momentum = price_velocity * volume_intensity * self.direction

Çubuk içi volatilitenin analizine özellikle dikkat edilir. Hareketin mikro yapısını dikkate alan değiştirilmiş bir ATR denklemi kullanıyoruz:

def calculate_volatility(self, tick_data):
    tick_changes = np.diff([tick.price for tick in tick_data])
    weighted_std = np.std(tick_changes * [tick.volume for tick in tick_data[1:]])
    time_factor = np.sqrt(self.time_period)
    self.volatility = weighted_std * time_factor

Klasik çubuklardan temel farkı, tüm ölçütlerin gerçek zamanlı olarak hesaplanması ve çubuk yapısının oluşumunu görmemize olanak sağlamasıdır:

def update_bar(self, new_tick):
    self.update_price_range(new_tick.price)
    self.update_volume_profile(new_tick)
    self.recalculate_momentum()
    self.update_volatility(new_tick)
    
    # Recalculate the volumetric center of gravity
    self.volume_poc = self.calculate_poc()

Tüm ölçümler, belirli bir enstrüman için ayarlanmış ağırlık faktörleri sistemi aracılığıyla birleştirilir:

def calculate_bar_strength(self):
    return (self.momentum_weight * self.normalized_momentum +
            self.volatility_weight * self.normalized_volatility +
            self.volume_weight * self.normalized_volume_concentration +
            self.spread_weight * self.normalized_spread_factor)

Gerçek alım-satımda bu matematiksel model, piyasanın şu yönlerini görmemizi sağlar:

  • hacim birikimindeki dengesizlikler
  • fiyat oluşum hızındaki anormallikler
  • konsolidasyon ve kırılma bölgeleri
  • hacim özellikleri aracılığıyla bir trendin gerçek gücü

Her 3D çubuk sadece grafikteki bir nokta değil, aynı zamanda zamanın belirli bir anındaki piyasanın durumunun tam teşekküllü bir göstergesidir.


3D çubuklar oluşturmaya yönelik algoritmanın detaylı bir analizi. MetaTrader 5 ile çalışmanın özellikleri. Veri işlemeyle ilgili ayrıntılar

Ana algoritmanın hata ayıklamasını tamamladıktan sonra, nihayet en ilginç kısma geldim - çok boyutlu çubukların gerçek zamanlı olarak uygulanması. Kabul ediyorum, ilk başta göz korkutucu bir görev gibi görünüyordu. MetaTrader 5, harici komut dosyalarına pek dost değildir ve dokümantasyon bazen uygun bir açıklama sağlamakta yetersiz kalır. Ama sonunda bunun üstesinden nasıl geldiğimi size anlatayım.

Verileri depolamak için temel bir yapı ile başladım. Birkaç deneme ve düzeltmeden sonra, aşağıdaki sınıf ortaya çıktı:

class Bar7D:
    def __init__(self):
        self.time = None
        self.open = None
        self.high = None
        self.low = None
        self.close = None
        self.tick_volume = 0
        self.volume_profile = {}
        self.direction = 0
        self.trend_count = 0
        self.volatility = 0
        self.momentum = 0

En zor kısım, blok büyüklüğünün nasıl doğru bir şekilde hesaplanacağını bulmaktı. Birçok denemeden sonra bu denklemde karar kıldım:

def calculate_brick_size(symbol_info, multiplier=45):
    spread = symbol_info.spread
    point = symbol_info.point
    min_price_brick = spread * multiplier * point
    
    # Adaptive adjustment for volatility
    atr = calculate_atr(symbol_info.name)
    if atr > min_price_brick * 2:
        min_price_brick = atr / 2
        
    return min_price_brick

Hacimlerle ilgili de çok sorun yaşadım. İlk başta, sabit büyüklükte bir volume_brick kullanmak istedim, ancak bunun işe yaramadığını hemen fark ettim. Çözüm, uyarlanabilir bir algoritma şeklinde geldi:

def adaptive_volume_threshold(tick_volume, history_volumes):
    median_volume = np.median(history_volumes)
    std_volume = np.std(history_volumes)
    
    if tick_volume > median_volume + 2 * std_volume:
        return median_volume + std_volume
    return max(tick_volume, median_volume / 2)

Ancak istatistiksel ölçütlerin hesaplanmasında biraz aşırıya kaçtığımı düşünüyorum:

def calculate_stats(df):
    df['ma_5'] = df['close'].rolling(5).mean()
    df['ma_20'] = df['close'].rolling(20).mean()
    df['volume_ma_5'] = df['tick_volume'].rolling(5).mean()
    df['price_volatility'] = df['price_change'].rolling(10).std()
    df['volume_volatility'] = df['tick_volume'].rolling(10).std()
    df['trend_strength'] = df['trend_count'] * df['direction']
    
    # This is probably too much
    df['zscore_price'] = stats.zscore(df['close'], nan_policy='omit')
    df['zscore_volume'] = stats.zscore(df['tick_volume'], nan_policy='omit')
    return df

Komik ama en zor kısmı kodu yazmak değil, gerçek koşullarda hata ayıklamaktı. 

İşte 3-9 aralığında normalleştirme içeren fonksiyonun nihai sonucu. Neden 3-9? Hem Gann hem de Tesla bu sayılarda gizli bir tür sihir olduğunu öne sürmüşlerdir. Ayrıca, iyi bilinen bir platformda, bu sayılara dayanarak başarılı bir geri dönüş komut dosyası oluşturduğu söylenen bir yatırımcıyı şahsen gördüm. Ancak komplo teorilerine ve gizemciliğe girmeyelim. Bunun yerine şunu deneyelim:

def create_true_3d_renko(symbol, timeframe, min_spread_multiplier=45, volume_brick=500, lookback=20000):
    """
    Creates 3D Renko bars with extended analytics
    """
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, lookback)
    if rates is None:
        print(f"Error getting data for {symbol}")
        return None, None
        
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    
    if df.isnull().any().any():
        print("Missing values detected, cleaning...")
        df = df.dropna()
        if len(df) == 0:
            print("No data for analysis after cleaning")
            return None, None
    
    symbol_info = mt5.symbol_info(symbol)
    if symbol_info is None:
        print(f"Failed to get symbol info for {symbol}")
        return None, None
    
    try:
        min_price_brick = symbol_info.spread * min_spread_multiplier * symbol_info.point
        if min_price_brick <= 0:
            print("Invalid block size")
            return None, None
    except AttributeError as e:
        print(f"Error getting symbol parameters: {e}")
        return None, None
    
    # Convert time to numeric and scale everything
    scaler = MinMaxScaler(feature_range=(3, 9))
    
    # Convert datetime to numeric (seconds from start)
    df['time_numeric'] = (df['time'] - df['time'].min()).dt.total_seconds()
    
    # Scale all numeric data together
    columns_to_scale = ['time_numeric', 'open', 'high', 'low', 'close', 'tick_volume']
    df[columns_to_scale] = scaler.fit_transform(df[columns_to_scale])
    
    renko_blocks = []
    current_price = float(df.iloc[0]['close'])
    current_tick_volume = 0
    current_time = df.iloc[0]['time']
    current_time_numeric = float(df.iloc[0]['time_numeric'])
    current_spread = float(symbol_info.spread)
    current_type = 0
    prev_direction = 0
    trend_count = 0
    
    try:
        for idx, row in df.iterrows():
            if pd.isna(row['tick_volume']) or pd.isna(row['close']):
                continue
                
            current_tick_volume += float(row['tick_volume'])
            volume_bricks = int(current_tick_volume / volume_brick)
            
            price_diff = float(row['close']) - current_price
            if pd.isna(price_diff) or pd.isna(min_price_brick):
                continue
                
            price_bricks = int(price_diff / min_price_brick)
            
            if volume_bricks > 0 or abs(price_bricks) > 0:
                direction = np.sign(price_bricks) if price_bricks != 0 else 1
                
                if direction == prev_direction:
                    trend_count += 1
                else:
                    trend_count = 1
                
                renko_block = {
                    'time': current_time,
                    'time_numeric': float(row['time_numeric']),
                    'open': float(row['open']),
                    'close': float(row['close']),
                    'high': float(row['high']),
                    'low': float(row['low']),
                    'tick_volume': float(row['tick_volume']),
                    'direction': float(direction),
                    'spread': float(current_spread),
                    'type': float(current_type),
                    'trend_count': trend_count,
                    'price_change': price_diff,
                    'volume_intensity': float(row['tick_volume']) / volume_brick,
                    'price_velocity': price_diff / (volume_bricks if volume_bricks > 0 else 1)
                }
                
                if volume_bricks > 0:
                    current_tick_volume = current_tick_volume % volume_brick
                if price_bricks != 0:
                    current_price += min_price_brick * price_bricks
                    
                prev_direction = direction
                renko_blocks.append(renko_block)
                
    except Exception as e:
        print(f"Error processing data: {e}")
        if len(renko_blocks) == 0:
            return None, None
    
    if len(renko_blocks) == 0:
        print("Failed to create any blocks")
        return None, None
        
    result_df = pd.DataFrame(renko_blocks)
    
    # Scale derived metrics to same range
    derived_metrics = ['price_change', 'volume_intensity', 'price_velocity', 'spread']
    result_df[derived_metrics] = scaler.fit_transform(result_df[derived_metrics])
    
    # Add analytical metrics using scaled data
    result_df['ma_5'] = result_df['close'].rolling(5).mean()
    result_df['ma_20'] = result_df['close'].rolling(20).mean()
    result_df['volume_ma_5'] = result_df['tick_volume'].rolling(5).mean()
    result_df['price_volatility'] = result_df['price_change'].rolling(10).std()
    result_df['volume_volatility'] = result_df['tick_volume'].rolling(10).std()
    result_df['trend_strength'] = result_df['trend_count'] * result_df['direction']
    
    # Scale moving averages and volatility
    ma_columns = ['ma_5', 'ma_20', 'volume_ma_5', 'price_volatility', 'volume_volatility', 'trend_strength']
    result_df[ma_columns] = scaler.fit_transform(result_df[ma_columns])
    
    # Add statistical metrics and scale them
    result_df['zscore_price'] = stats.zscore(result_df['close'], nan_policy='omit')
    result_df['zscore_volume'] = stats.zscore(result_df['tick_volume'], nan_policy='omit')
    zscore_columns = ['zscore_price', 'zscore_volume']
    result_df[zscore_columns] = scaler.fit_transform(result_df[zscore_columns])
    
    return result_df, min_price_brick
İşte tek bir ölçekte elde ettiğimiz çubuk serisi böyle görünüyor. Pek durağan değil, öyle değil mi?

İstatistiksel dağılımlar:

 

Doğal olarak böyle bir seriyle tatmin olmadım, çünkü amacım az çok durağan bir seri oluşturmaktı - durağan, zaman-hacim-fiyat serisi. Devamında şunu yaptım:


Volatilite ölçümünün uygulanması 

create_stationary_4d_features fonksiyonunu uygularken, temelde farklı bir yol izledim. Verileri basitçe 3-9 aralığına ölçeklediğimiz orijinal 3D çubukların aksine, burada gerçekten durağan seriler oluşturmaya odaklandım.

Fonksiyonun ana fikri, durağan özellikler aracılığıyla piyasanın dört boyutlu bir temsilini oluşturmaktır. Basitçe ölçeklendirmek yerine, durağanlığı sağlamak için her boyut özel bir şekilde dönüştürülür:

  1. Zaman boyutu: Burada trigonometrik dönüşümü uygulayarak saatleri sinüs ve kosinüs dalgalarına dönüştürdüm. sin(2π * saat/24) ve cos(2π * saat/24) denklemleri döngüsel özellikler yaratarak günlük mevsimsellik sorununu tamamen ortadan kaldırmaktadır.
  2. Fiyat ölçümü: Mutlak fiyat değerleri yerine, bunların göreceli değişimleri kullanılır. Kodda bu, tipik fiyatın (yüksek + düşük + kapanış)/3 hesaplanması ve ardından getirilerin ve ivmelerinin hesaplanmasıyla uygulanır. Bu yaklaşım, fiyat seviyesinden bağımsız olarak seriyi durağan hale getirmektedir.
  3. Hacimsel ölçüm: Burada ilginç bir nokta var - sadece hacimlerdeki değişimleri değil, bunların göreceli artışlarını da dikkate alıyoruz. Bu önemlidir çünkü hacimler genellikle çok dengesiz dağılır. Kodda bu, pct_change() ve diff() fonksiyonlarının art arda uygulanması yoluyla gerçekleştirilir.
  4. Volatilitenin ölçülmesi: Burada iki aşamalı bir dönüşüm uyguladım - önce getirilerin standart sapması yoluyla devam eden volatiliteyi hesaplıyoruz ve ardından bu volatilitedeki göreceli değişimleri elde ediyoruz. Aslında, "volatilitenin volatilitesini" elde ediyoruz.

Her veri bloğu 20 periyotluk bir kayan pencerede oluşturulur. Bu rastgele bir sayı değildir - verilerin yerel yapısını korumak ve hesaplamaların istatistiksel anlamlılığını sağlamak arasında bir denge kurmak amacıyla seçilmiştir.

Hesaplanan tüm özellikler sonuçta 3-9 aralığına ölçeklendirilir, ancak bu halihazırda durağan serilere uygulanan ikincil bir dönüşümdür. Bu, veri ön işleme için temelde farklı bir yaklaşım kullanırken 3D çubukların orijinal uygulanışıyla uyumluluğu sürdürmemizi sağlar.

Özellikle önemli bir nokta, orijinal fonksiyondaki tüm temel ölçütleri korumaktır - hareketli ortalamalar, volatilite, z-skorları. Bu, yeni uygulanışın orijinal fonksiyonun yerine doğrudan kullanılmasına ve daha yüksek kalitede durağan veriler elde edilmesine olanak tanır.

Sonuç olarak, istatistiksel anlamda durağan olmakla kalmayıp aynı zamanda piyasa yapısıyla ilgili tüm önemli bilgileri koruyan bir özellikler kümesi elde ediyoruz. Bu yaklaşım, verileri makine öğrenimi ve istatistiksel analiz yöntemlerini uygulamak için çok daha uygun hale getirirken, orijinal alım-satım bağlamıyla olan bağlantısını da sürdürür.

Fonksiyon aşağıda yer almaktadır: 

def create_true_3d_renko(symbol, timeframe, min_spread_multiplier=45, volume_brick=500, lookback=20000):
    """
    Creates 4D stationary features with same interface as 3D Renko
    """
    rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, lookback)
    if rates is None:
        print(f"Error getting data for {symbol}")
        return None, None
        
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    
    if df.isnull().any().any():
        print("Missing values detected, cleaning...")
        df = df.dropna()
        if len(df) == 0:
            print("No data for analysis after cleaning")
            return None, None
    
    symbol_info = mt5.symbol_info(symbol)
    if symbol_info is None:
        print(f"Failed to get symbol info for {symbol}")
        return None, None
    
    try:
        min_price_brick = symbol_info.spread * min_spread_multiplier * symbol_info.point
        if min_price_brick <= 0:
            print("Invalid block size")
            return None, None
    except AttributeError as e:
        print(f"Error getting symbol parameters: {e}")
        return None, None
    
    scaler = MinMaxScaler(feature_range=(3, 9))
    df_blocks = []
    
    try:
        # Time dimension
        df['time_sin'] = np.sin(2 * np.pi * df['time'].dt.hour / 24)
        df['time_cos'] = np.cos(2 * np.pi * df['time'].dt.hour / 24)
        df['time_numeric'] = (df['time'] - df['time'].min()).dt.total_seconds()
        
        # Price dimension
        df['typical_price'] = (df['high'] + df['low'] + df['close']) / 3
        df['price_return'] = df['typical_price'].pct_change()
        df['price_acceleration'] = df['price_return'].diff()
        
        # Volume dimension
        df['volume_change'] = df['tick_volume'].pct_change()
        df['volume_acceleration'] = df['volume_change'].diff()
        
        # Volatility dimension
        df['volatility'] = df['price_return'].rolling(20).std()
        df['volatility_change'] = df['volatility'].pct_change()
        
        for idx in range(20, len(df)):
            window = df.iloc[idx-20:idx+1]
            
            block = {
                'time': df.iloc[idx]['time'],
                'time_numeric': scaler.fit_transform([[float(df.iloc[idx]['time_numeric'])]]).item(),
                'open': float(window['price_return'].iloc[-1]),
                'high': float(window['price_acceleration'].iloc[-1]),
                'low': float(window['volume_change'].iloc[-1]),
                'close': float(window['volatility_change'].iloc[-1]),
                'tick_volume': float(window['volume_acceleration'].iloc[-1]),
                'direction': np.sign(window['price_return'].iloc[-1]),
                'spread': float(df.iloc[idx]['time_sin']),
                'type': float(df.iloc[idx]['time_cos']),
                'trend_count': len(window),
                'price_change': float(window['price_return'].mean()),
                'volume_intensity': float(window['volume_change'].mean()),
                'price_velocity': float(window['price_acceleration'].mean())
            }
            df_blocks.append(block)
                
    except Exception as e:
        print(f"Error processing data: {e}")
        if len(df_blocks) == 0:
            return None, None
    
    if len(df_blocks) == 0:
        print("Failed to create any blocks")
        return None, None
        
    result_df = pd.DataFrame(df_blocks)
    
    # Scale all features
    features_to_scale = [col for col in result_df.columns if col != 'time' and col != 'direction']
    result_df[features_to_scale] = scaler.fit_transform(result_df[features_to_scale])
    
    # Add same analytical metrics as in original function
    result_df['ma_5'] = result_df['close'].rolling(5).mean()
    result_df['ma_20'] = result_df['close'].rolling(20).mean()
    result_df['volume_ma_5'] = result_df['tick_volume'].rolling(5).mean()
    result_df['price_volatility'] = result_df['price_change'].rolling(10).std()
    result_df['volume_volatility'] = result_df['tick_volume'].rolling(10).std()
    result_df['trend_strength'] = result_df['trend_count'] * result_df['direction']
    
    # Scale moving averages and volatility
    ma_columns = ['ma_5', 'ma_20', 'volume_ma_5', 'price_volatility', 'volume_volatility', 'trend_strength']
    result_df[ma_columns] = scaler.fit_transform(result_df[ma_columns])
    
    # Add statistical metrics and scale them
    result_df['zscore_price'] = stats.zscore(result_df['close'], nan_policy='omit')
    result_df['zscore_volume'] = stats.zscore(result_df['tick_volume'], nan_policy='omit')
    zscore_columns = ['zscore_price', 'zscore_volume']
    result_df[zscore_columns] = scaler.fit_transform(result_df[zscore_columns])
    
    return result_df, min_price_brick

2D olarak şöyle görünüyor:

Şimdi, plotly kullanarak 3D fiyatlar için etkileşimli bir 3D model oluşturmayı deneyelim. Yan tarafında normal iki boyutlu bir grafikte görünmelidir. İşte kod:

import plotly.graph_objects as go
from plotly.subplots import make_subplots


def create_interactive_3d(df, symbol, save_dir):
    """
    Creates interactive 3D visualization with smoothed data and original price chart
    """
    try:
        save_dir = Path(save_dir)
        
        # Smooth all series with MA(100)
        df_smooth = df.copy()
        smooth_columns = ['close', 'tick_volume', 'price_volatility', 'volume_volatility']
        
        for col in smooth_columns:
            df_smooth[f'{col}_smooth'] = df_smooth[col].rolling(window=100, min_periods=1).mean()
        
        # Create subplots: 3D view and original chart side by side
        fig = make_subplots(
            rows=1, cols=2,
            specs=[[{'type': 'scene'}, {'type': 'xy'}]],
            subplot_titles=(f'{symbol} 3D View (MA100)', f'{symbol} Original Price'),
            horizontal_spacing=0.05
        )
        
        # Add 3D scatter plot
        fig.add_trace(
            go.Scatter3d(
                x=np.arange(len(df_smooth)),
                y=df_smooth['tick_volume_smooth'],
                z=df_smooth['close_smooth'],
                mode='markers',
                marker=dict(
                    size=5,
                    color=df_smooth['price_volatility_smooth'],
                    colorscale='Viridis',
                    opacity=0.8,
                    showscale=True,
                    colorbar=dict(x=0.45)
                ),
                hovertemplate=
                "Time: %{x}<br>" +
                "Volume: %{y:.2f}<br>" +
                "Price: %{z:.5f}<br>" +
                "Volatility: %{marker.color:.5f}",
                name='3D View'
            ),
            row=1, col=1
        )
        
        # Add original price chart
        fig.add_trace(
            go.Candlestick(
                x=np.arange(len(df)),
                open=df['open'],
                high=df['high'],
                low=df['low'],
                close=df['close'],
                name='OHLC'
            ),
            row=1, col=2
        )
        
        # Add smoothed price line
        fig.add_trace(
            go.Scatter(
                x=np.arange(len(df_smooth)),
                y=df_smooth['close_smooth'],
                line=dict(color='blue', width=1),
                name='MA100'
            ),
            row=1, col=2
        )
        
        # Update 3D layout
        fig.update_scenes(
            xaxis_title='Time',
            yaxis_title='Volume',
            zaxis_title='Price',
            camera=dict(
                up=dict(x=0, y=0, z=1),
                center=dict(x=0, y=0, z=0),
                eye=dict(x=1.5, y=1.5, z=1.5)
            )
        )
        
        # Update 2D layout
        fig.update_xaxes(title_text="Time", row=1, col=2)
        fig.update_yaxes(title_text="Price", row=1, col=2)
        
        # Update overall layout
        fig.update_layout(
            width=1500,  # Double width to accommodate both plots
            height=750,
            showlegend=True,
            title_text=f"{symbol} Combined Analysis"
        )
        
        # Save interactive HTML
        fig.write_html(save_dir / f'{symbol}_combined_view.html')
        
        # Create additional plots with smoothed data (unchanged)
        fig2 = make_subplots(rows=2, cols=2, 
                            subplot_titles=('Smoothed Price', 'Smoothed Volume',
                                          'Smoothed Price Volatility', 'Smoothed Volume Volatility'))
        
        fig2.add_trace(
            go.Scatter(x=np.arange(len(df_smooth)), y=df_smooth['close_smooth'],
                      name='Price MA100'),
            row=1, col=1
        )
        
        fig2.add_trace(
            go.Scatter(x=np.arange(len(df_smooth)), y=df_smooth['tick_volume_smooth'],
                      name='Volume MA100'),
            row=1, col=2
        )
        
        fig2.add_trace(
            go.Scatter(x=np.arange(len(df_smooth)), y=df_smooth['price_volatility_smooth'],
                      name='Price Vol MA100'),
            row=2, col=1
        )
        
        fig2.add_trace(
            go.Scatter(x=np.arange(len(df_smooth)), y=df_smooth['volume_volatility_smooth'],
                      name='Volume Vol MA100'),
            row=2, col=2
        )
        
        fig2.update_layout(
            height=750,
            width=750,
            showlegend=True,
            title_text=f"{symbol} Smoothed Data Analysis"
        )
        
        fig2.write_html(save_dir / f'{symbol}_smoothed_analysis.html')
        
        print(f"Interactive visualizations saved in {save_dir}")
        
    except Exception as e:
        print(f"Error creating interactive visualization: {e}")
        raise

Yeni fiyat aralığımız şu şekildedir:



Genel olarak, çok ilginç görünüyor. Zamana göre fiyat gruplamasında belirli sekanslar ve hacme göre fiyat gruplamasında aykırı değerler görüyoruz. Yani, piyasa huzursuz olduğunda, büyük hacimler meydana geldiğinde, volatilite hızla arttığında, istatistiklerin ötesine geçen tehlikeli bir patlamayla karşı karşıya olduğumuz hissi oluşur (ve önde gelen yatırımcıların deneyimleriyle doğrudan onaylanır) - kötü şöhretli kuyruk riskleri. Dolayısıyla burada, bu tür koordinatlarda "normalliğin sınırlarının ötesine" böyle bir fiyat çıkışını hemen tespit edebiliriz. Sadece bunun için bile çok değişkenli fiyat grafikleri fikrine minnettarım! 

Lütfen dikkat edin:

Hastanın muayenesi (3D grafikler)

Sonra, görselleştirmeyi öneriyorum. Ama palmiye ağacının altındaki parlak geleceğimizi değil, 3D fiyat grafiklerini. Durumları dört kümeye ayıralım: yükseliş trendi, düşüş trendi, yükseliş trendinden düşüş trendine dönüş ve düşüş trendinden yükseliş trendine dönüş. Bunu yapmak için kodu biraz değiştirmemiz gerekecek: artık çubuk indekslerine ihtiyacımız yok, belirli tarihlerdeki verileri yükleyeceğiz. Aslında, bunu yapmak için sadece mt5.copy_rates_range'e başvurmamız gerekiyor.

def create_true_3d_renko(symbol, timeframe, start_date, end_date, min_spread_multiplier=45, volume_brick=500):
    """
    Creates 4D stationary features with same interface as 3D Renko
    """
    rates = mt5.copy_rates_range(symbol, timeframe, start_date, end_date)
    if rates is None:
        print(f"Error getting data for {symbol}")
        return None, None
        
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    
    if df.isnull().any().any():
        print("Missing values detected, cleaning...")
        df = df.dropna()
        if len(df) == 0:
            print("No data for analysis after cleaning")
            return None, None
    
    symbol_info = mt5.symbol_info(symbol)
    if symbol_info is None:
        print(f"Failed to get symbol info for {symbol}")
        return None, None
    
    try:
        min_price_brick = symbol_info.spread * min_spread_multiplier * symbol_info.point
        if min_price_brick <= 0:
            print("Invalid block size")
            return None, None
    except AttributeError as e:
        print(f"Error getting symbol parameters: {e}")
        return None, None
    
    scaler = MinMaxScaler(feature_range=(3, 9))
    df_blocks = []
    
    try:
        # Time dimension
        df['time_sin'] = np.sin(2 * np.pi * df['time'].dt.hour / 24)
        df['time_cos'] = np.cos(2 * np.pi * df['time'].dt.hour / 24)
        df['time_numeric'] = (df['time'] - df['time'].min()).dt.total_seconds()
        
        # Price dimension
        df['typical_price'] = (df['high'] + df['low'] + df['close']) / 3
        df['price_return'] = df['typical_price'].pct_change()
        df['price_acceleration'] = df['price_return'].diff()
        
        # Volume dimension
        df['volume_change'] = df['tick_volume'].pct_change()
        df['volume_acceleration'] = df['volume_change'].diff()
        
        # Volatility dimension
        df['volatility'] = df['price_return'].rolling(20).std()
        df['volatility_change'] = df['volatility'].pct_change()
        
        for idx in range(20, len(df)):
            window = df.iloc[idx-20:idx+1]
            
            block = {
                'time': df.iloc[idx]['time'],
                'time_numeric': scaler.fit_transform([[float(df.iloc[idx]['time_numeric'])]]).item(),
                'open': float(window['price_return'].iloc[-1]),
                'high': float(window['price_acceleration'].iloc[-1]),
                'low': float(window['volume_change'].iloc[-1]),
                'close': float(window['volatility_change'].iloc[-1]),
                'tick_volume': float(window['volume_acceleration'].iloc[-1]),
                'direction': np.sign(window['price_return'].iloc[-1]),
                'spread': float(df.iloc[idx]['time_sin']),
                'type': float(df.iloc[idx]['time_cos']),
                'trend_count': len(window),
                'price_change': float(window['price_return'].mean()),
                'volume_intensity': float(window['volume_change'].mean()),
                'price_velocity': float(window['price_acceleration'].mean())
            }
            df_blocks.append(block)
                
    except Exception as e:
        print(f"Error processing data: {e}")
        if len(df_blocks) == 0:
            return None, None
    
    if len(df_blocks) == 0:
        print("Failed to create any blocks")
        return None, None
        
    result_df = pd.DataFrame(df_blocks)
    
    # Scale all features
    features_to_scale = [col for col in result_df.columns if col != 'time' and col != 'direction']
    result_df[features_to_scale] = scaler.fit_transform(result_df[features_to_scale])
    
    # Add same analytical metrics as in original function
    result_df['ma_5'] = result_df['close'].rolling(5).mean()
    result_df['ma_20'] = result_df['close'].rolling(20).mean()
    result_df['volume_ma_5'] = result_df['tick_volume'].rolling(5).mean()
    result_df['price_volatility'] = result_df['price_change'].rolling(10).std()
    result_df['volume_volatility'] = result_df['tick_volume'].rolling(10).std()
    result_df['trend_strength'] = result_df['trend_count'] * result_df['direction']
    
    # Scale moving averages and volatility
    ma_columns = ['ma_5', 'ma_20', 'volume_ma_5', 'price_volatility', 'volume_volatility', 'trend_strength']
    result_df[ma_columns] = scaler.fit_transform(result_df[ma_columns])
    
    # Add statistical metrics and scale them
    result_df['zscore_price'] = stats.zscore(result_df['close'], nan_policy='omit')
    result_df['zscore_volume'] = stats.zscore(result_df['tick_volume'], nan_policy='omit')
    zscore_columns = ['zscore_price', 'zscore_volume']
    result_df[zscore_columns] = scaler.fit_transform(result_df[zscore_columns])
    
    return result_df, min_price_brick

İşte değiştirilmiş kodumuz:

def main():
    try:
        # Initialize MT5
        if not mt5.initialize():
            print("MetaTrader5 initialization error")
            return

        # Analysis parameters
        symbols = ["EURUSD", "GBPUSD"]
        timeframes = {
            "M15": mt5.TIMEFRAME_M15
        }
        
        # 7D analysis parameters
        params = {
            "min_spread_multiplier": 45,
            "volume_brick": 500
        }

        # Date range for data fetching
        start_date = datetime(2017, 1, 1)
        end_date = datetime(2018, 2, 1)

        # Analysis for each symbol and timeframe
        for symbol in symbols:
            print(f"\nAnalyzing symbol {symbol}")
            
            # Create symbol directory
            symbol_dir = Path('charts') / symbol
            symbol_dir.mkdir(parents=True, exist_ok=True)
            
            # Get symbol info
            symbol_info = mt5.symbol_info(symbol)
            if symbol_info is None:
                print(f"Failed to get symbol info for {symbol}")
                continue

            print(f"Spread: {symbol_info.spread} points")
            print(f"Tick: {symbol_info.point}")
            
            # Analysis for each timeframe
            for tf_name, tf in timeframes.items():
                print(f"\nAnalyzing timeframe {tf_name}")
                
                # Create timeframe directory
                tf_dir = symbol_dir / tf_name
                tf_dir.mkdir(exist_ok=True)
                
                # Get and analyze data
                print("Getting data...")
                df, brick_size = create_true_3d_renko(
                    symbol=symbol,
                    timeframe=tf,
                    start_date=start_date,
                    end_date=end_date,
                    min_spread_multiplier=params["min_spread_multiplier"],
                    volume_brick=params["volume_brick"]
                )
                
                if df is not None and brick_size is not None:
                    print(f"Created {len(df)} 7D bars")
                    print(f"Block size: {brick_size}")
                    
                    # Basic statistics
                    print("\nBasic statistics:")
                    print(f"Average volume: {df['tick_volume'].mean():.2f}")
                    print(f"Average trend length: {df['trend_count'].mean():.2f}")
                    print(f"Max uptrend length: {df[df['direction'] > 0]['trend_count'].max()}")
                    print(f"Max downtrend length: {df[df['direction'] < 0]['trend_count'].max()}")
                    
                    # Create visualizations
                    print("\nCreating visualizations...")
                    create_visualizations(df, symbol, tf_dir)
                    
                    # Save data
                    csv_file = tf_dir / f"{symbol}_{tf_name}_7d_data.csv"
                    df.to_csv(csv_file)
                    print(f"Data saved to {csv_file}")
                    
                    # Results analysis
                    trend_ratio = len(df[df['direction'] > 0]) / len(df[df['direction'] < 0])
                    print(f"\nUp/Down bars ratio: {trend_ratio:.2f}")
                    
                    volume_corr = df['tick_volume'].corr(df['price_change'].abs())
                    print(f"Volume-Price change correlation: {volume_corr:.2f}")
                    
                    # Print warnings if anomalies detected
                    if df['price_volatility'].max() > df['price_volatility'].mean() * 3:
                        print("\nWARNING: High volatility periods detected!")
                        
                    if df['volume_volatility'].max() > df['volume_volatility'].mean() * 3:
                        print("WARNING: Abnormal volume spikes detected!")
                else:
                    print(f"Failed to create 3D bars for {symbol} on {tf_name}")
        
        print("\nAnalysis completed successfully!")
        
    except Exception as e:
        print(f"An error occurred: {e}")
        import traceback
        print(traceback.format_exc())
    finally:
        mt5.shutdown()

İlk veri bölümünü ele alalım - EURUSD, 1 Ocak 2017'den 1 Şubat 2018'e kadar. Aslında, çok güçlü bir yükseliş trendi. 3D çubuklarda nasıl göründüğünü görmeye hazır mısınız?

İşte başka bir görselleştirme:

Yükseliş trendinin başlangıcına dikkat edin:

Ve sonuna:

Şimdi de düşüş trendine bakalım. 1 Şubat 2018'den 20 Mart 2020'ye kadar:

Düşüş trendinin başlangıcı:

Ve sonu:

Dolayısıyla, 3D gösterimdeki her iki trendin de (hem düşüş hem de yükseliş) 3D nokta yoğunluğunun altında bir nokta alanı olarak başladığını görüyoruz. Her iki durumda da trendin sonu parlak sarı bir renk şeması ile işaretlendi. 

Bu olguyu ve EURUSD fiyatlarının yükseliş ve düşüş trendlerindeki davranışını açıklamak için aşağıdaki evrensel denklem kullanılabilir:

P(t) = P_0 + \int_{t_0}^{t} A \cdot e^{k(t-u)} \cdot V(u) \, du + N(t)

Tanımlamalar:

  •  P(t) - belirli bir zamandaki döviz fiyatı.
  •  P_0 - belirli bir zamandaki ilk fiyat.
  •  A - fiyat değişimlerinin ölçeğini karakterize eden trend genliği.
  •  k - değişim oranını belirleyen katsayı (k > 0 yükseliş trendi; k < 0 düşüş trendi anlamına gelir).
  •  V(u) - piyasa aktivitesini etkileyen ve fiyat değişimlerinin önemini artırabilen belirli bir zamandaki işlem hacmi.
  •  N(t) - öngörülemeyen piyasa dalgalanmalarını yansıtan rastgele gürültü.

Metin açıklaması

Bu denklem, bir dövizin fiyatının bir dizi faktöre bağlı olarak zaman içinde nasıl değiştiğini açıklar. İlk fiyat başlangıç noktasıdır, bundan sonra integral, trend genliğinin ve değişim oranının etkisini hesaba katarak, büyüklüğe bağlı olarak fiyatı üstel artışa veya düşüşe maruz bırakır. Fonksiyonun temsil ettiği işlem hacmi, piyasa aktivitesinin de fiyat değişimlerini etkilediğini gösteren başka bir boyut katar.

Bu model, farklı trendler altındaki fiyat hareketlerinin görselleştirilmesine ve zaman ekseni, fiyat ve hacmin piyasa aktivitesinin zengin bir resmini oluşturduğu 3D uzayda görüntülenmesine olanak tanır. Bu grafikteki renk şemasının parlaklığı trendin gücünü yansıtabilir; daha parlak renkler daha yüksek türev fiyat ve işlem hacmi değerlerine karşılık gelir ve piyasadaki güçlü hacim hareketlerine işaret eder.


Geri dönüşü görüntüleme

İşte 14 Kasım'dan 28 Kasım'a kadar olan dönem. Bu zaman aralığının yaklaşık olarak ortasında fiyatlarda bir geri dönüş yaşayacağız. Bu 3D koordinatlarda nasıl görünüyor? İşte burada:

Geri dönüş ve normalleştirilmiş fiyat koordinatında artış anında tanıdık olan sarı rengi görüyoruz. Şimdi, 13 Eylül 2024'ten aynı yılın 10 Ekim'ine kadar olan dönemde, trendin geri döndüğü başka bir fiyat bölümüne bakalım:

Aynı resmi tekrar görüyoruz, sadece sarı renk ve birikimi artık altta. İlginç görünüyor.  

19 Ağustos 2024 - 30 Ağustos 2024, bu tarih aralığının ortasında trendin geri döndüğü görülebilir. Koordinatlarımıza bakalım.

Yine, tamamen aynı resim. Şimdi 17 Temmuz 2024'ten 8 Ağustos 2024'e kadar olan dönemi ele alalım. Model yakında bir geri dönüş işaretleri gösterecek mi?

Son dönem 21 Nisan - 10 Ağustos 2023 tarihleri arasındadır. Yükseliş trendi burada sona erdi.

Tanıdık sarı rengi tekrar görüyoruz.


Sarı kümeler

3D çubukları geliştirirken çok ilginç bir özellikle karşılaştım - sarı renkli hacim-volatilite kümeler. Grafikteki davranışları beni büyüledi! Bir ton geçmiş veriyi inceledikten sonra (tam olarak 2022-2024 için 400,000'den fazla çubuk), şaşırtıcı bir şey fark ettim.

İlk başta gözlerime inanamadım - yaklaşık 100 bin sarı çubuğun neredeyse tamamı (%97!) fiyat dönüşlerine yakındı. Üstelik bu, artı veya eksi üç çubukluk bir aralıkta çalıştı. İlginç bir şekilde, geri dönüşlerin sadece %40'ı (toplamda yaklaşık 169 bin adet vardı) sarı çubuklar içeriyordu. Sarı çubukların geri dönüşleri neredeyse garanti ettiği ortaya çıktı, ancak geri dönüşler onlar olmadan da gerçekleşebilir.

Trendleri daha derinlemesine incelediğimde net bir kalıp fark ettim. Trendin başlangıcında ve esnasında neredeyse hiç sarı çubuk yoktur, sadece yoğun bir grup halinde normal 3D çubuklar vardır. Ancak geri dönüşten önce, sarı kümeler grafikte parlar.

Bu durum özellikle uzun trendlerde açıkça görülmektedir. Örneğin, EURUSD'nin 2017'nin başından Şubat 2018'e kadar olan artışını ve ardından Mart 2020'ye kadar olan düşüşünü ele alalım. Her iki durumda da, bu sarı kümeler geri dönüşten önce ortaya çıktı ve 3D yerleşimleri kelimenin tam anlamıyla fiyatın nereye gideceğini gösterdi!

Bunu kısa dönemler üzerinde de test ettim - 2024'te 2-3 haftalık birkaç bölüm seçtim. Saat gibi işledi! Geri dönüşlerden önce her seferinde, uyarı gibi sarı çubuklar belirdi: "Hey, dostum, trend geri dönmek üzere!"

Bu sadece bir gösterge değildir. Bence piyasa yapısının kendisinde gerçekten önemli bir şey bulduk - hacimlerin dağılma şekli ve bir trend değişikliğinden önce volatilitenin değişmesi. Artık 3D grafikte sarı kümeler gördüğümde, geri dönüşe hazırlanma zamanının geldiğini biliyorum!


Sonuç

3D çubukları keşfimizi sonlandırırken, bu araştırmanın piyasa mikro yapısına ilişkin anlayışımı ne kadar derinden değiştirdiğini belirtmeden edemeyeceğim. Görselleştirmede bir deney olarak başlayan şey, piyasayı görmenin ve anlamanın temelde yeni bir yoluna dönüştü.

Bu proje üzerinde çalışırken, fiyatların geleneksel iki boyutlu temsilinin bizi ne kadar kısıtladığını defalarca fark ettim. Üç boyutlu analize geçiş, fiyat, hacim ve zaman arasındaki ilişkileri anlamak için tamamen yeni ufuklar açtı. Özellikle önemli piyasa olaylarından önce gelen kalıpların üç boyutlu uzayda ne kadar net göründüğü beni çok etkiledi.

En önemli keşif, potansiyel trend dönüşlerini erken tespit etme becerisiydi. 3D gösterimde hacimlerin karakteristik birikimi ve renk şemasındaki değişiklik, yaklaşan trend değişikliklerinin şaşırtıcı derecede güvenilir göstergeleri olduğunu kanıtlandı. Bu sadece teorik bir gözlem değildir - bunu birçok geçmiş örnekle teyit ettik.

Geliştirdiğimiz matematiksel model, piyasa dinamiklerini sadece görselleştirmemize değil, aynı zamanda niceliksel olarak değerlendirmemize de olanak sağlar. Modern görselleştirme teknolojileri ve yazılım araçlarının entegrasyonu, bu yöntemin gerçek alım-satımda uygulanmasını mümkün kıldı. Bu araçları her gün kullanıyorum ve piyasa analizine yaklaşımımda büyük bir fark yarattılar.

Ancak, henüz yolculuğun başında olduğumuza inanıyorum. Bu proje, çok değişkenli piyasa mikro yapı analizi dünyasının kapısını açtı ve bu yönde yapılacak daha fazla araştırmanın çok daha ilginç keşifler sağlayacağından eminim. Belki de bir sonraki adım, 3D formasyonları otomatik olarak tanımak için makine öğreniminin entegrasyonu veya çok değişkenli analize dayalı yeni alım-satım stratejilerinin geliştirilmesi olacaktır.

Nihayetinde, bu araştırmanın gerçek değeri güzel grafiklerde veya karmaşık denklemlerde değil, sağladığı yeni piyasa içgörülerindedir. Bir araştırmacı olarak, teknik analizin geleceğinin piyasa verilerini analiz etmeye yönelik çok değişkenli bir yaklaşımda yattığına kuvvetle inanıyorum.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/16555

Ekli dosyalar |
3D_Bars_Visual.py (19.48 KB)
Son yorumlar | Tartışmaya git (4)
Bogard_11
Bogard_11 | 4 Ara 2024 saat 11:39
Akla hemen şu soru geliyor - neden? Düz bir grafik doğru analiz için yeterli değil mi? Normal lise geometrisi burada işe yarar.
Thibauld Charles Ghislain Robin
Thibauld Charles Ghislain Robin | 2 Şub 2025 saat 08:28
Bogard_11 #:
Akla hemen şu soru geliyor - neden? Düz bir grafik doğru analiz için yeterli değil mi? İşte bu noktada normal lise geometrisi işe yarar.

Herhangi bir algoritma esasen uzamsal boyutları araştırır. Algoritmalar yaratarak, çok boyutlu arama yoluyla temel kombinatoryal patlama sorununu çözmeye çalışıyoruz. Bu bizim sonsuz olasılıklar denizinde gezinme yöntemimizdir.

(Çeviri mükemmel değilse özür dilerim)


Bogard_11
Bogard_11 | 2 Şub 2025 saat 17:36
Thibauld Charles Ghislain Robin #:

Herhangi bir algoritma esasen uzamsal boyutları araştırır. Algoritmalar yaratarak, çok boyutlu arama yoluyla temel kombinatoryal patlama sorununu çözmeye çalışıyoruz. Bu bizim sonsuz olasılıklar denizinde gezinme yöntemimizdir.

(Çeviri mükemmel değilse özür dileriz)

Anlaşıldı. Trend tahminini basit okul geometrik formülleriyle çözemezsek, insanlar turbo süperşarjlı, akıllı telefon kontrollü, gülen yüzlü ve diğer cicili bicili bir Lysaped icat etmeye başlar! Ama tekerlekleri yok ve olması da beklenmiyor. Ve tekerlekler olmadan, tek şasiyle uzağa gidemezsiniz.

BeeXXI Corporation
Nikolai Semko | 2 Şub 2025 saat 18:21
Bogard_11 #:

Anlıyorum. Trend tahminini basit okul geometrik formülleriyle çözmek imkansızsa, insanlar turbo süperşarjlı, akıllı telefon kontrollü, gülen yüzlü ve diğer cicili bicili bir lisaped icat etmeye başlar! Ama tekerlekleri yok ve olması da beklenmiyor. Ve tekerlekler olmadan, tek bir çerçeveyle uzağa gidemezsiniz.

Bu saçmalık.
Sadece 4 boyutlu bir algı mekanizmasıyla doğan ama sadece iki boyutlu kavramlarla düşünen birine sempati duyabilirim.
Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler
Yeni terminalin ve dilin tüm yeni olanaklarını ve özelliklerini listelemeyeceğim. Bunlar sayısızdır ve bazı yenilikler ayrı bir makalede tartışılmaya değerdir. Ayrıca burada nesne yönelimli programlama ile yazılmış bir kod yoktur, geliştiriciler için ek avantajlar olarak bir bağlamda basitçe bahsedilemeyecek kadar ciddi bir konudur. Bu makalede, MQL4'e kıyasla göstergeleri, yapılarını, çizimlerini, türlerini ve programlama ayrıntılarını ele alacağız. Umarım bu makale hem yeni başlayanlar hem de deneyimli geliştiriciler için faydalı olacaktır, belki bazıları yeni bir şeyler bulacaktır.
Borsada doğrusal olmayan regresyon modelleri Borsada doğrusal olmayan regresyon modelleri
Borsada doğrusal olmayan regresyon modelleri: Finansal piyasaları tahmin etmek mümkün mü? EURUSD fiyatlarını tahmin etmek için bir model oluşturmayı ve buna dayalı iki robot geliştirmeyi inceleyelim - Python ve MQL5'te.
İşte Karışınızda Yeni MetaTrader 5 ve MQL5 İşte Karışınızda Yeni MetaTrader 5 ve MQL5
Bu MetaTrader 5 ile ilgili sadece kısa bir inceleme. Sistemin tüm yeni özelliklerini bu kadar kısa sürede açıklayamam, test süreci 09.09.2009’da başladı. Bu sembolik bir tarihtir ve şanslı sayı olacağına eminim. MetaTrader 5 terminalinin ve MQL5’in beta sürümünü beş gün önce aldım. Tüm özelliklerini deneme şansım olmadı ama şimdiden etkilendim.
Forex veri analizinde ilişkilendirme kurallarını kullanma Forex veri analizinde ilişkilendirme kurallarını kullanma
Süpermarket perakendeciliği analitiğinin tahmin edici kuralları gerçek Forex piyasasına nasıl uygulanır? Kurabiye, süt ve ekmek satın alımlarının borsa işlemleriyle nasıl bir bağlantısı var? Makale, ilişkilendirme kurallarının kullanımına dayanan algoritmik alım-satıma yönelik yenilikçi bir yaklaşımı tartışmaktadır.