English Русский 中文 Español Deutsch 日本語 Português Italiano
preview
William Gann yöntemleri (Bölüm III): Astroloji işe yarıyor mu?

William Gann yöntemleri (Bölüm III): Astroloji işe yarıyor mu?

MetaTrader 5Sınayıcı |
17 2
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Giriş

Finansal piyasa katılımcıları sürekli olarak yeni piyasa analizi ve tahmin yöntemleri aramaktadır. En sıra dışı konseptler bile dışarıda bırakılmamıştır. Standart olmayan ve tamamen benzersiz yaklaşımlardan biri, ünlü yatırımcı William Gann tarafından popüler hale getirilen astrolojinin alım-satımda kullanılmasıdır.

Gann'ın araçlarına daha önceki yazılarımızda değinmiştik. İşte birinci ve ikinci bölüm. Şimdi gezegen ve yıldız konumlarının dünya piyasaları üzerindeki etkisini incelemeye odaklanacağız.

En modern teknolojileri ve eski bilgileri birleştirmeye çalışalım. Astronomik olaylar ile EURUSD paritesinin hareketleri arasındaki bağlantıyı bulmak için Python programlama dili ve MetaTrader 5 platformunu kullanacağız. Finansta astrolojinin teorik kısmını ele alacağız ve kendimizi bir tahmin sistemi geliştirmenin pratik kısmında deneyeceğiz.

Ayrıca, astronomik ve finansal verileri toplamayı ve senkronize etmeyi, bir korelasyon matrisi oluşturmayı ve sonuçları görselleştirmeyi inceleyeceğiz. 


Finansta astrolojinin teorik temeli

Bu konuyla uzun zamandır ilgileniyorum ve bugün astrolojinin finansal piyasalar üzerindeki etkisi hakkındaki düşüncelerimi paylaşmak istiyorum. Oldukça tartışmalı olmasına rağmen bu gerçekten etkileyici bir alan.

Anladığım kadarıyla finansal astrolojinin temel fikri, gök cisimlerinin hareketlerinin bir şekilde piyasa döngüleriyle ilişkili olduğudur. Bu konseptin uzun ve köklü bir geçmişi vardır ve özellikle geçen yüzyılın ünlü yatırımcılarından William Gann tarafından popüler hale getirilmiştir.

Bu teorinin temel ilkeleri hakkında çok düşündüm. Örneğin, yıldızların ve gezegenlerin hareketlerinin de piyasa hareketleri gibi doğası gereği döngüsel olduğunu belirten döngüsellik fikri. Gezegen açıları bağlamında, bazı insanlar belirli gezegen konumlarının piyasalar üzerinde güçlü bir etkiye sahip olduğuna inanmaktadır. Peki ya burçlar? Gezegenlerin farklı burç takımyıldızlarından geçişinin de bir şekilde piyasayı etkilediğine inanılıyor.

Ay döngüleri ve güneş aktivitelerinden de bahsetmek gerekir. Ayın evrelerinin piyasadaki kısa vadeli dalgalanmalarla, güneş patlamalarının ise uzun vadeli trendlerle ilişkili olduğuna dair görüşler gördüm. İlginç hipotezler, değil mi?

William Gann bu alanda gerçek bir öncüydü. Astronomi, geometri ve sayı dizilerine dayanan ünlü 9'un Karesi gibi bir dizi araç geliştirdi. Eserleri hala hararetli tartışmalara neden olmaktadır.

Elbette bilim camiasının bir bütün olarak astrolojiye şüpheyle yaklaştığı da göz ardı edilemez. Birçok ülkede resmi olarak sözde bilim olarak kabul edilmektedir. Ve açık konuşmak gerekirse, astrolojik yöntemlerin finans alanındaki etkinliğine dair henüz kesin bir kanıt yok. Çoğu zaman, gözlemlenen bazı korelasyonların sadece bilişsel önyargıların sonucu olduğu ortaya çıkmaktadır.

Buna rağmen, finansal astroloji fikirlerini hararetle savunan birçok yatırımcı vardır.

Bu yüzden kendi araştırmamı yapmaya karar verdim. İstatistiksel yöntemler ve büyük verileri kullanarak astrolojinin finansal piyasalar üzerindeki etkisinin objektif bir değerlendirmesini yapmaya çalışmak istiyorum. Kim bilir, belki ilginç bir şey keşfederiz. Öyle ya da böyle, yıldızların ve hisse senedi grafiklerinin kesiştiği dünyaya büyüleyici bir yolculuk olacak.


Kullanılacak Python kütüphanelerine genel bakış

Birkaç Python kütüphanesine ihtiyacım olacak. 

Başlangıç olarak, astronomik veriler elde etmek için Skyfield paketini kullanmaya karar verdim. Doğru aracı seçmek için uzun zaman harcadım ve Skyfield hassasiyeti ile beni etkiledi. Onun yardımıyla, gök cisimlerinin konumları ve ayın evreleri hakkında ondalık basamaklarda çok yüksek doğrulukla bilgi toplayabileceğim - veri kümelerim için gereken her şey.

Piyasa verilerine gelince, seçimim Python için resmi MetaTrader 5 kütüphanesi oldu. Döviz paritelerinin geçmiş verilerini indirmeye ve hatta gerekirse işlem açmaya olanak tanıyacaktır.

Pandas, verilerle çalışırken sadık yol arkadaşımız olacak. Bu kütüphaneyi geçmişte çok kullandım ve zaman serileriyle çalışmak için tek kelimeyle vazgeçilmez. Toplanan tüm verilerin ön işlemesi ve senkronizasyonu için kullanacağım.

İstatistiksel analiz için SciPy kütüphanesinde karar kıldım. Geniş işlevselliği, özellikle korelasyon ve regresyon analizi araçları etkileyicidir. Umarım ilginç kalıplar bulmama yardımcı olurlar.

Sonuçları görselleştirmek için eski dostlarım Matplotlib ve Seaborn'u kullanmaya karar verdim. Bu kütüphaneleri grafik oluşturmadaki esneklikleri nedeniyle seviyorum. Tüm bulguları görselleştirmeye yardımcı olacaklarından eminim.

Tüm set bir araya geldi. Bu, mükemmel bileşenlerden güçlü bir bilgisayar oluşturmak gibidir. Artık astrolojik faktörlerin finansal piyasalar üzerindeki etkisine dair kapsamlı bir çalışma yürütmek için ihtiyacımız olan her şeye sahibiz. Verilerin içine dalmak ve hipotezlerimi test etmeye başlamak için sabırsızlanıyorum!


Astronomik verileri toplama

import pandas as pd
import numpy as np
from skyfield.api import load, wgs84, utc
from skyfield.data import mpc
from datetime import datetime, timedelta
import requests

# Loading planet ephemerides
planets = load('de421.bsp')
earth = planets['earth']
ts = load.timescale()

def get_planet_positions(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    planet_positions = {}
    planet_ids = {
        'mercury': 'MERCURY BARYCENTER',
        'venus': 'VENUS BARYCENTER',
        'mars': 'MARS BARYCENTER',
        'jupiter': 'JUPITER BARYCENTER',
        'saturn': 'SATURN BARYCENTER',
        'uranus': 'URANUS BARYCENTER',
        'neptune': 'NEPTUNE BARYCENTER'
    }
    for planet, planet_id in planet_ids.items():
        planet_obj = planets[planet_id]
        astrometric = earth.at(t).observe(planet_obj)
        ra, dec, _ = astrometric.radec()
        planet_positions[planet] = {'ra': ra.hours, 'dec': dec.degrees}
    return planet_positions

def get_moon_phase(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    eph = load('de421.bsp')
    moon, sun, earth = eph['moon'], eph['sun'], eph['earth']
    
    e = earth.at(t)
    _, m, _ = e.observe(moon).apparent().ecliptic_latlon()
    _, s, _ = e.observe(sun).apparent().ecliptic_latlon()
    
    phase = (m.degrees - s.degrees) % 360
    return phase

def get_solar_activity(date):
    # Get solar activity data from NOAA API
    url = f"https://services.swpc.noaa.gov/json/solar-cycle/observed-solar-cycle-indices.json"
    response = requests.get(url)
    data = response.json()
    
    # Convert date to 'YYYY-MM' format
    target_date = date.strftime("%Y-%m")
    
    # Find the closest date in the data
    closest_data = min(data, key=lambda x: abs(datetime.strptime(x['time-tag'], "%Y-%m") - datetime.strptime(target_date, "%Y-%m")))
    
    return {
        'sunspot_number': closest_data.get('ssn', None),
        'f10.7_flux': closest_data.get('f10.7', None)
    }

def calculate_aspects(positions):
    aspects = {}
    planets = list(positions.keys())
    for i in range(len(planets)):
        for j in range(i+1, len(planets)):
            planet1 = planets[i]
            planet2 = planets[j]
            ra1 = positions[planet1]['ra']
            ra2 = positions[planet2]['ra']
            angle = abs(ra1 - ra2) % 24
            angle = min(angle, 24 - angle) * 15  # Convert to degrees
            
            if abs(angle - 0) <= 10 or abs(angle - 180) <= 10:
                aspects[f"{planet1}_{planet2}"] = "conjunction" if abs(angle - 0) <= 10 else "opposition"
            elif abs(angle - 90) <= 10:
                aspects[f"{planet1}_{planet2}"] = "square"
            elif abs(angle - 120) <= 10:
                aspects[f"{planet1}_{planet2}"] = "trine"
    
    return aspects

start_date = datetime(2024, 4, 1, tzinfo=utc)
end_date = datetime(2024, 5, 31, tzinfo=utc)
current_date = start_date
astronomical_data = []

while current_date <= end_date:
    planet_positions = get_planet_positions(current_date)
    moon_phase = get_moon_phase(current_date)
    try:
        solar_activity = get_solar_activity(current_date)
    except Exception as e:
        print(f"Error getting solar activity for {current_date}: {e}")
        solar_activity = {'sunspot_number': None, 'f10.7_flux': None}
    aspects = calculate_aspects(planet_positions)
    
    data = {
        'date': current_date,
        'moon_phase': moon_phase,
        'sunspot_number': solar_activity.get('sunspot_number'),
        'f10.7_flux': solar_activity.get('f10.7_flux'),
        **planet_positions,
        **aspects
    }
    astronomical_data.append(data)
    
    current_date += timedelta(days=1)
    print(f"Processed: {current_date}")

# Convert data to DataFrame
df = pd.DataFrame(astronomical_data)

# Save data to CSV file
df.to_csv('astronomical_data_2018_2024.csv', index=False)
print("Data saved to astronomical_data_2018_2024.csv")

Bu Python kodu, gelecekte piyasa analizi için kullanacağımız astronomik verileri toplar.

Kod, 1 Ocak 2018'den 31 Mayıs 2024'e kadar olan dönemi kullanmakta ve aşağıdaki gibi bir dizi veri toplamaktadır:

  • Gezegenlerin konumları - Venüs, Merkür, Mars, Jüpiter, Satürn, Uranüs ve Neptün
  • Ay evreleri
  • Güneş aktivitesi
  • Gezegen açıları (gezegenlerin birbirlerine göre nasıl hizalandıkları)

Komut dosyası, kütüphane içe aktarımlarını, ana döngüyü ve verileri Excel formatında kaydetmeyi içerir. Kod, gezegen konumlarını hesaplamak için daha önce bahsedilen Skyfield kütüphanesini, veriler için Pandas'ı ve güneş aktivitesi verilerini elde etmek için Requests’i kullanır.

Dikkate değer fonksiyonlar: get_planet_positions() gezegenlerin konumlarını (sağ açıklık ve dik açıklık) almak için, get_moon_phase() mevcut ay evresini bulmak için, get_solar_activity() NOAA API'sinden güneş aktivitesi verilerini doğrudan almak için ve calculate_aspects() açıları (gezegenlerin birbirlerine göre konumları) hesaplamak için.

Döngünün bir parçası olarak her günü gözden geçiriyor ve tüm verileri topluyoruz. Sonuç olarak, ileride kullanmak üzere her şeyi tek bir Excel dosyasına kaydediyoruz. 


MetaTrader 5 aracılığıyla finansal verileri alma

Finansal verileri almak üzere Python için MetaTrader 5 kütüphanesini kullanacağız. Kütüphane, finansal verileri doğrudan aracı kurumdan indirmemize ve herhangi bir enstrüman için fiyat zaman serilerini almamıza olanak tanıyacaktır. İşte geçmiş verileri yüklemek için kodumuz: 

import MetaTrader5 as mt5
import pandas as pd
from datetime import datetime

# Connect to MetaTrader5
if not mt5.initialize():
    print("initialize() failed")
    mt5.shutdown()

# Set query parameters
symbol = "EURUSD"
timeframe = mt5.TIMEFRAME_D1
start_date = datetime(2018, 1, 1)
end_date = datetime(2024, 12, 31)

# Request historical data
rates = mt5.copy_rates_range(symbol, timeframe, start_date, end_date)

# Convert data to DataFrame
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')

# Save data to CSV file
df.to_csv(f'{symbol}_data.csv', index=False)

# Terminate the connection to MetaTrader5
mt5.shutdown()

Komut dosyası işlem terminaline bağlanır, EURUSD D1'deki verileri alır, ardından bir veri çerçevesi oluşturur ve bunu tek bir CSV dosyasına kaydeder. 


Astronomik ve finansal verilerin senkronize edilmesi

Astronomi ile ilgili verilerimiz var, EURUSD ile ilgili verilerimiz de var. Şimdi onları senkronize etmeliyiz. Verileri tarihlere göre birleştirelim, böylece tek bir veri kümesi hem finansal hem de astronomik tüm gerekli bilgileri içerir.

import pandas as pd

# Load data
astro_data = pd.read_csv('astronomical_data_2018_2024.csv')
financial_data = pd.read_csv('EURUSD_data.csv')

# Convert date columns to datetime
astro_data['date'] = pd.to_datetime(astro_data['date'])
financial_data['time'] = pd.to_datetime(financial_data['time'])

# Merge data
merged_data = pd.merge(financial_data, astro_data, left_on='time', right_on='date', how='inner')

# Save merged data
merged_data.to_csv('merged_astro_financial_data.csv', index=False)

Komut dosyası, kaydedilen tüm verileri yükler, tarih sütunlarını datetime biçimine dönüştürür ve veri kümelerini tarihe göre birleştirir. Sonuç olarak, gelecekteki analizler için ihtiyaç duyduğumuz tüm verileri içeren bir CSV dosyası elde ediyoruz.


Korelasyonların istatistiksel analizi

Devam edelim. Elimizde ortak bir veri kümesi var ve şimdi verilerde astronomi ile piyasa hareketleri arasında herhangi bir ilişki olup olmadığını bulma zamanı. Pandas kütüphanesindeki corr() fonksiyonunu kullanacağız. Ayrıca, her iki kodumuzu tek bir kodda birleştireceğiz.

İşte nihai komut dosyası:

import pandas as pd
import numpy as np
from skyfield.api import load, wgs84, utc
from skyfield.data import mpc
from datetime import datetime, timedelta
import requests
import MetaTrader5 as mt5
import seaborn as sns
import matplotlib.pyplot as plt

# Part 1: Collecting astronomical data

# Loading planetary ephemerides
planets = load('de421.bsp')
earth = planets['earth']
ts = load.timescale()

def get_planet_positions(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    planet_positions = {}
    planet_ids = {
        'mercury': 'MERCURY BARYCENTER',
        'venus': 'VENUS BARYCENTER',
        'mars': 'MARS BARYCENTER',
        'jupiter': 'JUPITER BARYCENTER',
        'saturn': 'SATURN BARYCENTER',
        'uranus': 'URANUS BARYCENTER',
        'neptune': 'NEPTUNE BARYCENTER'
    }
    for planet, planet_id in planet_ids.items():
        planet_obj = planets[planet_id]
        astrometric = earth.at(t).observe(planet_obj)
        ra, dec, _ = astrometric.radec()
        planet_positions[planet] = {'ra': ra.hours, 'dec': dec.degrees}
    return planet_positions

def get_moon_phase(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    eph = load('de421.bsp')
    moon, sun, earth = eph['moon'], eph['sun'], eph['earth']

    e = earth.at(t)
    _, m, _ = e.observe(moon).apparent().ecliptic_latlon()
    _, s, _ = e.observe(sun).apparent().ecliptic_latlon()

    phase = (m.degrees - s.degrees) % 360
    return phase

def get_solar_activity(date):
    url = f"https://services.swpc.noaa.gov/json/solar-cycle/observed-solar-cycle-indices.json"
    response = requests.get(url)
    data = response.json()

    target_date = date.strftime("%Y-%m")

    closest_data = min(data, key=lambda x: abs(datetime.strptime(x['time-tag'], "%Y-%m") - datetime.strptime(target_date, "%Y-%m")))

    return {
        'sunspot_number': closest_data.get('ssn', None),
        'f10.7_flux': closest_data.get('f10.7', None)
    }

def calculate_aspects(positions):
    aspects = {}
    planets = list(positions.keys())
    for i in range(len(planets)):
        for j in range(i+1, len(planets)):
            planet1 = planets[i]
            planet2 = planets[j]
            ra1 = positions[planet1]['ra']
            ra2 = positions[planet2]['ra']
            angle = abs(ra1 - ra2) % 24
            angle = min(angle, 24 - angle) * 15  # Convert to degrees

            if abs(angle - 0) <= 10 or abs(angle - 180) <= 10:
                aspects[f"{planet1}_{planet2}"] = "conjunction" if abs(angle - 0) <= 10 else "opposition"
            elif abs(angle - 90) <= 10:
                aspects[f"{planet1}_{planet2}"] = "square"
            elif abs(angle - 120) <= 10:
                aspects[f"{planet1}_{planet2}"] = "trine"

    return aspects

# Collecting astronomical data
start_date = datetime(2024, 3, 1, tzinfo=utc)
end_date = datetime(2024, 7, 30, tzinfo=utc)
current_date = start_date
astronomical_data = []

while current_date <= end_date:
    planet_positions = get_planet_positions(current_date)
    moon_phase = get_moon_phase(current_date)
    try:
        solar_activity = get_solar_activity(current_date)
    except Exception as e:
        print(f"Error getting solar activity for {current_date}: {e}")
        solar_activity = {'sunspot_number': None, 'f10.7_flux': None}
    aspects = calculate_aspects(planet_positions)

    data = {
        'date': current_date,
        'moon_phase': moon_phase,
        'sunspot_number': solar_activity.get('sunspot_number'),
        'f10.7_flux': solar_activity.get('f10.7_flux'),
        **planet_positions,
        **aspects
    }
    astronomical_data.append(data)

    current_date += timedelta(days=1)
    print(f"Processed: {current_date}")

# Convert data to DataFrame and save
astro_df = pd.DataFrame(astronomical_data)
astro_df.to_csv('astronomical_data_2018_2024.csv', index=False)
print("Astronomical data saved to astronomical_data_2018_2024.csv")

# Part 2: Retrieving financial data via MetaTrader5

# Initialize connection to MetaTrader5
if not mt5.initialize():
    print("initialize() failed")
    mt5.shutdown()

# Set request parameters
symbol = "EURUSD"
timeframe = mt5.TIMEFRAME_D1
start_date = datetime(2024, 3, 1)
end_date = datetime(2024, 7, 30)

# Request historical data
rates = mt5.copy_rates_range(symbol, timeframe, start_date, end_date)

# Convert data to DataFrame
financial_df = pd.DataFrame(rates)
financial_df['time'] = pd.to_datetime(financial_df['time'], unit='s')

# Save financial data
financial_df.to_csv(f'{symbol}_data.csv', index=False)
print(f"Financial data saved to {symbol}_data.csv")

# Shutdown MetaTrader5 connection
mt5.shutdown()

# Part 3: Synchronizing astronomical and financial data

# Load data
astro_df = pd.read_csv('astronomical_data_2018_2024.csv')
financial_df = pd.read_csv('EURUSD_data.csv')

# Convert date columns to datetime
astro_df['date'] = pd.to_datetime(astro_df['date']).dt.tz_localize(None)
financial_df['time'] = pd.to_datetime(financial_df['time'])

# Merge data
merged_data = pd.merge(financial_df, astro_df, left_on='time', right_on='date', how='inner')

# Save merged data
merged_data.to_csv('merged_astro_financial_data.csv', index=False)
print("Merged data saved to merged_astro_financial_data.csv")

# Part 4: Statistical analysis of correlations

# Select numeric columns for correlation analysis
numeric_columns = merged_data.select_dtypes(include=[np.number]).columns

# Create lags for astronomical data
for col in numeric_columns:
    if col not in ['open', 'high', 'low', 'close', 'tick_volume', 'spread', 'real_volume']:
        for lag in range(1, 6):  # Create lags from 1 to 5
            merged_data[f'{col}_lag{lag}'] = merged_data[col].shift(lag)

# Update list of numeric columns
numeric_columns = merged_data.select_dtypes(include=[np.number]).columns

# Calculate correlation matrix
correlation_matrix = merged_data[numeric_columns].corr()

# Create heatmap of correlations
plt.figure(figsize=(20, 16))
sns.heatmap(correlation_matrix, annot=False, cmap='coolwarm', vmin=-1, vmax=1, center=0)
plt.title('Correlation Matrix of Astronomical Factors (with Lags) and EURUSD Prices')
plt.tight_layout()
plt.savefig('correlation_heatmap_with_lags.png')
plt.close()

# Output the most significant correlations with the closing price
significant_correlations = correlation_matrix['close'].sort_values(key=abs, ascending=False)
print("Most significant correlations with the closing price:")
print(significant_correlations)

# Create a separate correlation matrix for astronomical data with lags and the current price
astro_columns = [col for col in numeric_columns if col not in ['open', 'high', 'low', 'tick_volume', 'spread', 'real_volume']]
astro_columns.append('close')  # Add the current closing price
astro_correlation_matrix = merged_data[astro_columns].corr()

# Create heatmap of correlations for astronomical data with lags and the current price
import seaborn as sns
import matplotlib.pyplot as plt

# Increase the header and axis label font
plt.figure(figsize=(18, 14))
sns.heatmap(astro_correlation_matrix, annot=False, cmap='coolwarm', vmin=-1, vmax=1, center=0, cbar_kws={'label': 'Correlation'})
plt.title('Correlation matrix of astronomical factors (with lags) and current EURUSD price', fontsize=24)
plt.xlabel('X-axis Label', fontsize=30)
plt.ylabel('Y-axis Label', fontsize=30)
plt.xticks(fontsize=30)
plt.yticks(fontsize=30)
plt.tight_layout()
plt.savefig('astro_correlation_heatmap_with_lags.png')
plt.close()

print("Analysis completed. Results saved in CSV and PNG files.")

Bu komut dosyası, veri kümesindeki tüm sayılar arasındaki korelasyonların bir haritasını ve ayrıca ısı haritası biçiminde tüm korelasyonların bir matrisini görüntüler ve kapanış fiyatlarıyla en önemli korelasyonların bir listesini oluşturur.

Bir korelasyonun varlığı ya da yokluğu, nedensel bir ilişkinin varlığı ya da yokluğu anlamına gelmez. Astronomik veriler ve fiyat hareketleri arasında güçlü korelasyonlar bulsak bile, bu bir faktörün diğerini belirlediği ya da tam tersi anlamına gelmez. Korelasyon haritası sadece en temel şey olduğu için yeni araştırmalara ihtiyaç vardır.


Konuya biraz daha yaklaştığımızda ise verilerde kayda değer bir korelasyon bulamıyoruz. Geçmiş astronomi verileri ile piyasa göstergeleri arasında net bir korelasyon bulunmamaktadır.


Makine öğrenimi yardıma geliyor

Bundan sonra ne yapacağımı düşündüm ve bir makine öğrenimi modeli uygulamaya karar verdim. CatBoost kütüphanesini kullanarak, veri kümesindeki verileri özellikler olarak kullanarak gelecekteki fiyatları tahmin etmeye çalışan iki komut dosyası oluşturdum. İşte modellerden ilki - bir regresyon modeli: 

import pandas as pd
import numpy as np
from catboost import CatBoostRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder

# Loading data
data = pd.read_csv('merged_astro_financial_data.csv')

# Converting date to datetime
data['date'] = pd.to_datetime(data['date'])

# Creating lags for financial data
for col in ['open', 'high', 'low', 'close']:
    for lag in range(1, 6):  # Creating lags from 1 to 5
        data[f'{col}_lag{lag}'] = data[col].shift(lag)

# Creating lags for astronomical data
astro_cols = ['mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']
for col in astro_cols:
    data[f'{col}_ra'] = data[col].apply(lambda x: eval(x)['ra'] if pd.notna(x) else np.nan)
    data[f'{col}_dec'] = data[col].apply(lambda x: eval(x)['dec'] if pd.notna(x) else np.nan)
    for lag in range(1, 6):  # Lags from 1 to 5
        data[f'{col}_ra_lag{lag}'] = data[f'{col}_ra'].shift(lag)
        data[f'{col}_dec_lag{lag}'] = data[f'{col}_dec'].shift(lag)
    data.drop(columns=[col, f'{col}_ra', f'{col}_dec'], inplace=True)

# Converting aspects to numerical features
aspect_cols = ['mercury_saturn', 'venus_mars', 'venus_jupiter', 'venus_uranus', 
               'mars_jupiter', 'mars_uranus', 'jupiter_uranus', 'mercury_neptune', 
               'venus_saturn', 'venus_neptune', 'mars_saturn', 'mercury_venus', 
               'mars_neptune', 'mercury_uranus', 'saturn_neptune', 'mercury_jupiter', 
               'mercury_mars', 'jupiter_saturn']

# Using LabelEncoder for encoding aspects
label_encoders = {}
for col in aspect_cols:
    label_encoders[col] = LabelEncoder()
    data[col] = label_encoders[col].fit_transform(data[col].astype(str))

# Filling missing values with mean values for numeric columns
numeric_cols = data.select_dtypes(include=[np.number]).columns
data[numeric_cols] = data[numeric_cols].fillna(data[numeric_cols].mean())

# Removing rows with missing values
data = data.dropna()

# Preparing features and target variable
features = [col for col in data.columns if col not in ['date', 'time', 'close']]
X = data[features]
y = data['close']

# Splitting data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)

# Creating and training the CatBoost model
model = CatBoostRegressor(iterations=500, learning_rate=0.1, depth=9, random_state=1)
model.fit(X_train, y_train, eval_set=(X_test, y_test), early_stopping_rounds=200, verbose=100)

# Evaluating the model
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Mean Absolute Error: {mae}")
print(f"R-squared Score: {r2}")

# Visualizing feature importance
feature_importance = model.feature_importances_
feature_names = X.columns
sorted_idx = np.argsort(feature_importance)
pos = np.arange(sorted_idx.shape[0]) + 0.5
plt.figure(figsize=(12, 6))
plt.barh(pos, feature_importance[sorted_idx], align='center')
plt.yticks(pos, np.array(feature_names)[sorted_idx])
plt.xlabel('Feature Importance')
plt.title('Feature Importance')
plt.show()

# Predicting the next value
def predict_next():
    # Selecting the last row of data
    last_data = data.iloc[-1]
    input_features = last_data[features].values.reshape(1, -1)
    # Prediction
    prediction = model.predict(input_features)
    print(f"Prediction for the next closing price: {prediction[0]}")

# Example of using the function to predict the next value
predict_next()


İkinci model ise sınıflandırmadır:

import pandas as pd
import numpy as np
from skyfield.api import load, utc
from datetime import datetime, timedelta
import requests
import MetaTrader5 as mt5
import seaborn as sns
import matplotlib.pyplot as plt
from catboost import CatBoostClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.preprocessing import LabelEncoder

# Part 1: Collecting astronomical data

planets = load('de421.bsp')
earth = planets['earth']
ts = load.timescale()

def get_planet_positions(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    planet_positions = {}
    planet_ids = {
        'mercury': 'MERCURY BARYCENTER',
        'venus': 'VENUS BARYCENTER',
        'mars': 'MARS BARYCENTER',
        'jupiter': 'JUPITER BARYCENTER',
        'saturn': 'SATURN BARYCENTER',
        'uranus': 'URANUS BARYCENTER',
        'neptune': 'NEPTUNE BARYCENTER'
    }
    for planet, planet_id in planet_ids.items():
        planet_obj = planets[planet_id]
        astrometric = earth.at(t).observe(planet_obj)
        ra, dec, _ = astrometric.radec()
        planet_positions[planet] = {'ra': ra.hours, 'dec': dec.degrees}
    return planet_positions

def get_moon_phase(date):
    t = ts.from_datetime(date.replace(tzinfo=utc))
    eph = load('de421.bsp')
    moon, sun, earth = eph['moon'], eph['sun'], eph['earth']
    
    e = earth.at(t)
    _, m, _ = e.observe(moon).apparent().ecliptic_latlon()
    _, s, _ = e.observe(sun).apparent().ecliptic_latlon()
    
    phase = (m.degrees - s.degrees) % 360
    return phase

def get_solar_activity(date):
    url = f"https://services.swpc.noaa.gov/json/solar-cycle/observed-solar-cycle-indices.json"
    response = requests.get(url)
    data = response.json()
    
    target_date = date.strftime("%Y-%m")
    
    closest_data = min(data, key=lambda x: abs(datetime.strptime(x['time-tag'], "%Y-%m") - datetime.strptime(target_date, "%Y-%m")))
    
    return {
        'sunspot_number': closest_data.get('ssn', None),
        'f10.7_flux': closest_data.get('f10.7', None)
    }

def calculate_aspects(positions):
    aspects = {}
    planets = list(positions.keys())
    for i in range(len(planets)):
        for j in range(i+1, len(planets)):
            planet1 = planets[i]
            planet2 = planets[j]
            ra1 = positions[planet1]['ra']
            ra2 = positions[planet2]['ra']
            angle = abs(ra1 - ra2) % 24
            angle = min(angle, 24 - angle) * 15  # Convert to degrees
            
            if abs(angle - 0) <= 10 or abs(angle - 180) <= 10:
                aspects[f"{planet1}_{planet2}"] = "conjunction" if abs(angle - 0) <= 10 else "opposition"
            elif abs(angle - 90) <= 10:
                aspects[f"{planet1}_{planet2}"] = "square"
            elif abs(angle - 120) <= 10:
                aspects[f"{planet1}_{planet2}"] = "trine"
    
    return aspects

# Part 2: Obtaining financial data through MetaTrader5

def get_financial_data(symbol, start_date, end_date):
    if not mt5.initialize():
        print("initialize() failed")
        mt5.shutdown()
        return None

    timeframe = mt5.TIMEFRAME_D1

    rates = mt5.copy_rates_range(symbol, timeframe, start_date, end_date)
    mt5.shutdown()

    financial_df = pd.DataFrame(rates)
    financial_df['time'] = pd.to_datetime(financial_df['time'], unit='s')
    return financial_df

# Part 3: Synchronizing astronomical and financial data

def sync_data(astro_df, financial_df):
    astro_df['date'] = pd.to_datetime(astro_df['date']).dt.tz_localize(None)
    financial_df['time'] = pd.to_datetime(financial_df['time'])
    merged_data = pd.merge(financial_df, astro_df, left_on='time', right_on='date', how='inner')
    return merged_data

# Part 4: Training the model and making predictions

def train_and_predict(merged_data):
    # Converting aspects to numerical features
    aspect_cols = [col for col in merged_data.columns if '_' in col and col not in ['date', 'time']]
    label_encoders = {}
    for col in aspect_cols:
        label_encoders[col] = LabelEncoder()
        merged_data[col] = label_encoders[col].fit_transform(merged_data[col].astype(str))
    
    # Creating lags for financial data
    for col in ['open', 'high', 'low', 'close']:
        for lag in range(1, 6):
            merged_data[f'{col}_lag{lag}'] = merged_data[col].shift(lag)
    
    # Creating lags for astronomical data
    astro_cols = ['mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']
    for col in astro_cols:
        merged_data[f'{col}_ra'] = merged_data[col].apply(lambda x: eval(x)['ra'] if pd.notna(x) else np.nan)
        merged_data[f'{col}_dec'] = merged_data[col].apply(lambda x: eval(x)['dec'] if pd.notna(x) else np.nan)
        for lag in range(1, 6):
            merged_data[f'{col}_ra_lag{lag}'] = merged_data[f'{col}_ra'].shift(lag)
            merged_data[f'{col}_dec_lag{lag}'] = merged_data[f'{col}_dec'].shift(lag)
        merged_data.drop(columns=[col, f'{col}_ra', f'{col}_dec'], inplace=True)

    # Filling missing values with mean values for numeric columns
    numeric_cols = merged_data.select_dtypes(include=[np.number]).columns
    merged_data[numeric_cols] = merged_data[numeric_cols].fillna(merged_data[numeric_cols].mean())

    merged_data = merged_data.dropna()

    # Creating binary target variable
    merged_data['price_change'] = (merged_data['close'].shift(-1) > merged_data['close']).astype(int)

    # Removing rows with missing values in the target variable
    merged_data = merged_data.dropna(subset=['price_change'])

    features = [col for col in merged_data.columns if col not in ['date', 'time', 'close', 'price_change']]
    X = merged_data[features]
    y = merged_data['price_change']

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)

    model = CatBoostClassifier(iterations=500, learning_rate=0.1, depth=9, random_state=1)
    model.fit(X_train, y_train, eval_set=(X_test, y_test), early_stopping_rounds=200, verbose=100)

    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    clf_report = classification_report(y_test, y_pred)
    conf_matrix = confusion_matrix(y_test, y_pred)

    print(f"Accuracy: {accuracy}")
    print("Classification Report:")
    print(clf_report)
    print("Confusion Matrix:")
    print(conf_matrix)

    # Visualizing feature importance
    feature_importance = model.feature_importances_
    feature_names = X.columns
    sorted_idx = np.argsort(feature_importance)
    pos = np.arange(sorted_idx.shape[0]) + 0.5

    plt.figure(figsize=(12, 6))
    plt.barh(pos, feature_importance[sorted_idx], align='center')
    plt.yticks(pos, np.array(feature_names)[sorted_idx])
    plt.xlabel('Feature Importance')
    plt.title('Feature Importance')
    plt.show()

    # Predicting the next value
    def predict_next():
        last_data = merged_data.iloc[-1]
        input_features = last_data[features].values.reshape(1, -1)
        prediction = model.predict(input_features)
        print(f"Price change prediction (0: will decrease, 1: will increase): {prediction[0]}")

    predict_next()

# Main program
start_date = datetime(2023, 3, 1)
end_date = datetime(2024, 7, 30)

astro_data = []
current_date = start_date

while current_date <= end_date:
    planet_positions = get_planet_positions(current_date)
    moon_phase = get_moon_phase(current_date)
    try:
        solar_activity = get_solar_activity(current_date)
    except Exception as e:
        print(f"Error getting solar activity for {current_date}: {e}")
        solar_activity = {'sunspot_number': None, 'f10.7_flux': None}
    aspects = calculate_aspects(planet_positions)
    
    astro_data.append({
        'date': current_date,
        'mercury': str(planet_positions['mercury']),
        'venus': str(planet_positions['venus']),
        'mars': str(planet_positions['mars']),
        'jupiter': str(planet_positions['jupiter']),
        'saturn': str(planet_positions['saturn']),
        'uranus': str(planet_positions['uranus']),
        'neptune': str(planet_positions['neptune']),
        'moon_phase': moon_phase,
        **solar_activity,
        **aspects
    })
    
    current_date += timedelta(days=1)

astro_df = pd.DataFrame(astro_data)

symbol = "EURUSD"
financial_data = get_financial_data(symbol, start_date, end_date)

if financial_data is not None:
    merged_data = sync_data(astro_df, financial_data)
    train_and_predict(merged_data)

Ne yazık ki, her iki model de büyük bir doğruluk sağlamamaktadır. Sınıflandırma doğruluğu %50'den biraz daha yüksektir, bu da yazı tura atarak da kolayca tahmin yapabileceğimiz anlamına gelir.


Regresyon modeline çok az dikkat verildiği için sonuç iyileştirilebilir. Belki gezegen konumları ile Ay ve Güneş'in faaliyetlerini kullanarak fiyatları tahmin etmek mümkün olabilir. Eğer müsait olursam bu konu hakkında başka bir makale daha yazacağım.


Sonuçlar

Şimdi sonuçları özetleme zamanı. Basit bir analiz yaptıktan ve iki tahmin modeli yazdıktan sonra, astrolojinin piyasa üzerindeki potansiyel etkisine ilişkin çalışmanın sonuçlarına bakıyoruz. 

Korelasyon analizi. Elde ettiğimiz korelasyon haritası, gezegen konumları ile EURUSD kapanış fiyatı arasında güçlü bir korelasyon ortaya koymadı. Tüm korelasyonlarımız 0.3'ten daha zayıftır, bu da bize yıldızların veya gezegenlerin konumunun finansal piyasalarla hiçbir bağlantısı olmadığını belirtiyor.

CatBoost regresyon modeli. Regresyon modelinin nihai sonuçları, astronomik verilere dayalı olarak gelecekteki kapanış fiyatlarını doğru tahmin etme becerisinin çok zayıf olduğunu gösterdi.

Ortaya çıkan MSE, MAE ve R kare gibi model performans ölçütleri çok zayıftır ve verileri çok yetersiz bir şekilde açıklıyor. Aynı zamanda model, en önemli özelliklerin gezegen pozisyonlarından ziyade gecikmeler ve önceki fiyat değerleri olduğunu göstermektedir. Peki bu, fiyatın güneş sistemimizdeki herhangi bir gezegenin konumundan daha iyi bir gösterge olduğu anlamına mı geliyor?

CatBoost sınıflandırma modeli. Sınıflandırma modeli, gelecekteki fiyat artışlarını veya düşüşlerini tahmin etmede son derece zayıftır. Doğruluk oranı %50'yi ancak aşıyor ki bu da astronominin gerçek piyasada işe yaramadığını teyit ediyor.


Sonuç

Çalışmanın sonuçları oldukça açıktır - astroloji yöntemleri ve astronomik verilere dayanarak gerçek piyasadaki fiyatları tahmin etme girişimleri tamamen yararsızdır. Belki bu konuya tekrar döneceğim ama şimdilik William Gann'ın öğretileri, sadece kitap ve alım-satım kursu satmak için yaratılmış, işe yaramayan çözümleri gizleme girişimleri gibi görünüyor.

Gann açı değerlerini, 9’un karesi değerlerini ve Gann ızgara değerlerini bir arada kullanan geliştirilmiş bir model daha iyi performans gösterebilir mi? Bunu henüz bilmiyoruz. Çalışmanın sonuçları beni biraz hayal kırıklığına uğrattı.

Ancak yine de Gann açılarının bir şekilde çalışan fiyat tahminleri elde etmek için kullanılabileceğini düşünüyorum. Fiyat açılarla bir şekilde etkileşime girmekte, onlara tepki vermektedir ki bu, önceki çalışmanın sonuçlarından anlaşılmaktadır. Açıların eğitim modelleri için özellikler olarak kullanılması da mümkündür. Böyle bir veri seti oluşturmaya çalışacağım ve sonuç olarak ne elde edeceğimi göreceğim. 

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

Ekli dosyalar |
GannAstroClass.py (9.39 KB)
AstroCorr.py (7.59 KB)
Son yorumlar | Tartışmaya git (2)
Maxim Kuznetsov
Maxim Kuznetsov | 29 Ağu 2024 saat 11:51

Gana'nın ayak izlerini takip ederek, deneyimin saflığı adına, EURUSD değil, örneğin pamuk vadeli işlemlerini almalıydınız. Ve enstrüman yaklaşık olarak aynıdır ve astronomik döngüler içinde olabilir, sonuçta tarım.

spalsule
spalsule | 10 Mar 2025 saat 07:19
Görünüşe göre Gann zaman döngülerini incelememişsiniz. Bu nedenle işe yaramadığını düşünüyorsunuz. Tüm hisse senetleri ve emtialar üzerinde çalışır.
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.
William Gann yöntemleri (Bölüm II): Gann Karesi göstergesi oluşturma William Gann yöntemleri (Bölüm II): Gann Karesi göstergesi oluşturma
Zaman ve fiyatın karesi alınarak oluşturulan Gann'ın 9’un Karesine dayalı bir gösterge oluşturacağız. Kodu hazırlayacağız ve göstergeyi platformda farklı zaman aralıklarında test edeceğiz.
İş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.
William Gann yöntemleri (Bölüm I): Gann Açıları göstergesi oluşturma William Gann yöntemleri (Bölüm I): Gann Açıları göstergesi oluşturma
Gann Teorisinin ana fikri nedir? Gann açıları nasıl çizilir? MetaTrader 5 için Gann Açıları göstergesi oluşturacağız.