Понимание количественной торговли

C1.1 Fractal Dimension Index

В последней главе мы рассмотрели тест ADF и запустили тест на стационарность, чтобы оценить гипотезу эффективного рынка. В этом разделе мы рассмотрим индекс фрактальной размерности для проверки на ЭМГ.

В приведенном ниже коде предполагается, что у вас есть временной ряд биржевых данных, хранящихся в переменной stock_data. Функция fdi вычисляет FDI, вычисляя мгновенную фазу временного ряда с использованием преобразования Гильберта, а затем подгоняя линейную регрессию к логарифмическому графику автокорреляционной функции мгновенной фазы.

Важно отметить, что ПИИ являются лишь одним из многих статистических тестов, которые можно использовать для проверки стационарного поведения в биржевых данных. Результаты этого теста следует интерпретировать с осторожностью, поскольку на цены акций часто влияет широкий спектр факторов, и они не обязательно могут следовать стационарному процессу.

import numpy as np
from scipy.signal import hilbert

def fdi(data):
"""Calculate the Fractal Dimension Index of a time series"""
# Calculate the instantaneous phase of the time series using the Hilbert transform
phase = np.angle(hilbert(data))

# Calculate the FDI by fitting a linear regression to the log-log plot of the
# autocorrelation function of the instantaneous phase
n = len(phase)
r = np.correlate(phase, phase, mode="full")[-n:]
r = r/r[0]
result = np.polyfit(np.log(range(1,n+1)), np.log(r), 1)
return result[0]

# Load the stock data
stock_data = [your stock data]

# Calculate the FDI of the stock data
fdi_result = fdi(stock_data)

# Print the FDI
print(fdi_result)

# If the FDI is close to 1, the time series is considered stationary
if abs(fdi_result - 1) < 0.1:
print("The stock data is stationary.")
else:
print("The stock data is not stationary.")

Я предполагаю, что вы скопируете этот код и запустите его самостоятельно и проверите тест на стационарность, чтобы проверить EMH для биржевых данных.

Давайте разберемся с теорией, лежащей в основе того, почему логарифмическая доходность цены закрытия акций более предпочтительна в определенном сценарии, чем цена закрытия.

При построении статистических моделей цен на акции, как правило, рекомендуется использовать логарифмические доходы, а не необработанные цены закрытия. На это есть несколько причин:

  1. Нестационарность: Цены на акции часто не стационарны, что означает, что они имеют тенденцию к росту или падению с течением времени. Это может затруднить построение статистических моделей, которые точно фиксируют основные закономерности в данных. Использование логарифмических возвратов может помочь устранить тенденцию и сделать данные более стационарными, что может повысить производительность статистических моделей.
  2. Масштабирование: Цены на акции могут значительно различаться по величине, в зависимости от размера и финансового состояния компании. Использование отчетов журналов позволяет масштабировать данные таким образом, чтобы они были более сопоставимы по различным акциям и рыночным условиям.
  3. Нормализация: Логарифмические доходы, как правило, распределяются более нормально, чем цены на сырье, что может облегчить построение статистических моделей, использующих предположения о нормальности.

Конечно, есть и некоторые недостатки использования возвратов журналов. Например, их может быть сложнее интерпретировать и доносить до нетехнической аудитории. Кроме того, некоторые статистические модели могут работать лучше с необработанными ценами закрытия, а не с логарифмическими доходами, в зависимости от конкретных характеристик данных и целей анализа.

Как правило, при построении статистических моделей цен на акции рекомендуется попробовать как логарифмическую доходность, так и необработанные цены закрытия и посмотреть, какой подход лучше всего подходит для ваших конкретных целей данных и анализа.

C2.0:Фрактальная геометрия

В предыдущей главе мы узнали о 2 статистических тестах для проверки гипотезы «Гипотеза эффективного рынка», В этой главе давайте перейдем к геометрии и применению фрактальной геометрии к данным о ценах на акции

FРактальная геометрия — это математическая дисциплина, изучающая автомодельные закономерности в природе и других сложных системах. Он был применен к широкому кругу областей, включая финансы, в попытке понять и предсказать поведение рынка.

Одним из способов применения фрактальной геометрии к ценам на акции является использование индекса фрактальной размерности (FDI), который является мерой сложности временного ряда. ПИИ может быть рассчитан путем подгонки линейной регрессии к логарифмическому графику автокорреляционной функции мгновенной фазы временного ряда, рассчитанной с использованием преобразования Гильберта. Временные ряды с высокими ПИИ считаются более сложными и потенциально более предсказуемыми, чем временные ряды с низкими ПИИ.

Существуют также другие методы, которые были разработаны для применения фрактальной геометрии к ценам на акции, такие как показатель Херста и мультифрактальный анализ колебаний без тренда (MF-DFA). Эти методы могут быть использованы для выявления закономерностей и тенденций в ценах на акции и потенциально улучшить эффективность торговых стратегий.

Важно отметить, что обоснованность и полезность фрактальной геометрии в финансах является предметом постоянных дебатов. В то время как некоторые исследования показали, что фрактальные методы могут дать ценную информацию о поведении рынка, другие обнаружили, что они не значительно улучшают точность прогнозирования. Как и в случае с любым статистическим или математическим методом, важно тщательно оценить результаты и ограничения фрактальных методов применительно к ценам на акции или любым другим финансовым данным.

Ниже приведен код Python, демонстрирующий, как применять показатель Херста и мультифрактальный анализ колебаний без тренда (MF-DFA) к данным о ценах на акции:

import numpy as np
import pandas as pd

def hurst_exponent(data):
"""Calculate the Hurst exponent of a time series"""
# Calculate the range of scales to analyze
scales = range(2, int(np.floor(len(data)/2)))

# Initialize arrays to store the variance at each scale
tau = np.empty(len(scales))
variance = np.empty(len(scales))

# Loop over each scale and calculate the variance
for i, scale in enumerate(scales):
tau[i], variance[i] = compute_variance(data, scale)

# Fit a linear regression to the log-log plot of the variance
# and calculate the Hurst exponent
m, b = np.polyfit(np.log(scales), np.log(variance), 1)
hurst = m/2
return hurst

def compute_variance(data, scale):
"""Compute the variance of the data at a given scale"""
# Calculate the average at each scale
averages = np.empty(len(data) - scale + 1)
for i in range(len(averages)):
averages[i] = np.mean(data[i:i+scale])

# Calculate the variance at each scale
variance = np.var(averages)
tau = scale / len(data)
return tau, variance

def mf_dfa(data):
"""Calculate the multifractal detrended fluctuation analysis (MF-DFA) of a time series"""
# Calculate the range of scales to analyze
scales = range(2, int(np.floor(len(data)/2)))

# Initialize arrays to store the variance at each scale
tau = np.empty(len(scales))
variance = np.empty(len(scales))

# Loop over each scale and calculate the variance
for i, scale in enumerate(scales):
tau[i], variance[i] = compute_variance_mf_dfa(data, scale)

# Fit a linear regression to the log-log plot of the variance
# and calculate the Hurst exponent
m, b = np.polyfit(np.log(scales), np.log(variance), 1)
hurst = m/2
return hurst

def compute_variance_mf_dfa(data, scale):
"""Compute the variance of the detrended data at a given scale using MF-DFA"""
# Detrend the data by subtracting the trend at each scale
detrended = detrend(data, scale)

# Calculate the variance at each scale
variance = np.var(detrended)
tau = scale / len(data)
return tau, variance

def detrend(data, scale):
"""Detrend the data by subtracting the trend at each scale"""
# Initialize an array to store the detrended data
detrended = np

Вот пример того, как вы можете построить окончательный результат показателя Херста и мультифрактального анализа колебаний без тренда (MF-DFA) в Python:

import matplotlib.pyplot as plt

# Load the stock data
stock_data = pd.read_csv("stock_data.csv")

# Extract the stock price series
stock_price = stock_data["Close"]

# Calculate the Hurst exponent
hurst_result = hurst_exponent(stock_price)
print(f"Hurst exponent: {hurst_result:.2f}")

# Calculate the MF-DFA
mf_dfa_result = mf_dfa(stock_price)
print(f"MF-DFA: {mf_dfa_result:.2f}")

# Plot the results
plt.plot(hurst_result, label="Hurst exponent")
plt.plot(mf_dfa_result, label="MF-DFA")
plt.legend()
plt.show()

В этом коде предполагается, что у вас есть CSV-файл с именем «stock_data.csv», содержащий данные об акциях, со столбцом «Закрытие», который содержит цену закрытия акции на каждую дату. Предполагается, что вы определили hurst_exponent и mf_dfa, как показано в предыдущем ответе.

Полученный график покажет показатель Херста и MF-DFA по оси y и масштаб (т. е. период времени) по оси x. Более высокий показатель Херста или значение MF-DFA указывает на более устойчивый паттерн в данных о ценах на акции, в то время как более низкое значение указывает на менее устойчивый паттерн.

Важно отметить, что интерпретация показателя Херста и MF-DFA в финансах является предметом постоянных дебатов, и результаты этих тестов следует интерпретировать с осторожностью. Они могут дать некоторое представление о закономерностях и тенденциях цен на акции, но на них не следует полагаться как на окончательные индикаторы будущего поведения рынка.

C3.0:Вейвлет-преобразование

Во второй главе мы оценили основное свойство биржевых данных, называемое гипотезой эффективного рынка, Во второй главе мы заглянули в мир геометрии и применили некоторые тесты для выявления паттернов фрактальной геометрии на биржевых данных, В этой главе мы сосредоточимся на мире спектрального анализа, в частности на вейвлет-преобразовании.

Да, можно использовать вейвлет-преобразование данных о ценах на акции, чтобы разложить временные ряды на разные частотные диапазоны и потенциально извлечь полезную информацию о базовых паттернах и тенденциях.

Вот пример того, как вы можете использовать вейвлет-преобразование для декомпозиции данных о ценах на акции Apple и построения разложенных выходных данных в Python:

import pywt
import matplotlib.pyplot as plt
import pandas as pd

# Load the stock data
stock_data = pd.read_csv("AAPL.csv")

# Extract the stock price series
stock_price = stock_data["Close"]

# Decompose the stock price series using the Haar wavelet
coefficients = pywt.wavedec(stock_price, 'haar', level=5)

# Extract the detail coefficients at each level
cA5, cD5, cD4, cD3, cD2, cD1 = coefficients

# Plot the decomposed output
fig, ax = plt.subplots(nrows=6, ncols=1, figsize=(10, 6))
ax[0].plot(cA5, label="cA5")
ax[1].plot(cD5, label="cD5")
ax[2].plot(cD4, label="cD4")
ax[3].plot(cD3, label="cD3")
ax[4].plot(cD2, label="cD2")
ax[5].plot(cD1, label="cD1")
plt.tight_layout()
plt.show()

В этом коде предполагается, что у вас есть CSV-файл с именем «AAPL.csv», содержащий данные об акциях Apple, со столбцом «Закрытие», который содержит цену закрытия акций на каждую дату. Также предполагается, что у вас установлена библиотека pywt, которая предоставляет функции для вейвлет-преобразования в Python.

Полученный график покажет разложенный вывод данных о цене акций на каждом уровне вейвлет-преобразования. Коэффициенты cA представляют собой низкочастотные компоненты временного ряда, а коэффициенты cD представляют собой высокочастотные компоненты. Анализируя коэффициенты cA и cD на разных уровнях, вы потенциально можете выявить закономерности и тенденции в данных о ценах на акции в разных масштабах и частотах.

В этом конкретном примере предполагается, что мы разлагаем биржевые данные на различные частотные компоненты, вейвлеты очень хорошо работают для сглаживания данных по сравнению с методом скользящей средней или скользящей средней. В будущем мы будем использовать вейвлет-сглаживание при построении нашей модели.

Как рассчитать волатильность данных о цене акций?

Существует несколько способов расчета волатильности внутридневной цены акций. Одним из распространенных подходов является использование стандартного отклонения логарифмической доходности цены акций за определенный период времени. Это можно рассчитать с помощью следующего кода Python:

import numpy as np

def calculate_volatility(stock_price, time_period):
"""Calculate the volatility of an intraday stock price"""
# Calculate the log returns of the stock price
log_returns = np.log(stock_price) - np.log(stock_price.shift(1))

# Calculate the standard deviation of the log returns over the given time period
volatility = log_returns.rolling(time_period).std()
return volatility

# Load the stock data
stock_data = [your stock data]

# Extract the stock price series
stock_price = stock_data["Close"]

# Calculate the volatility of the stock price over a time period of 20 minutes
volatility = calculate_volatility(stock_price, 20)

# Print the volatility
print(volatility)

Этот код предполагает, что у вас есть временной ряд данных об акциях, хранящийся в переменной stock_data, со столбцом «Закрытие», который содержит цену закрытия акции на каждую дату. Он также предполагает, что вы указали период времени, за который следует рассчитать волатильность, в данном случае 20 минут.

C4.0: стратегия Мартингейла

Что такое стратегия Мартингейла

Алгоритм Мартингейла — это стратегия ставок, которая включает в себя удвоение размера ставки после каждого проигрыша в попытке возместить убытки и в конечном итоге получить прибыль. Он применялся в различных контекстах, включая финансы, в попытке повысить эффективность торговых стратегий.

Вот пример того, как вы можете протестировать алгоритм Мартингейла на данных о ценах на акции Apple в Python:

import pandas as pd

# Load the stock data
stock_data = pd.read_csv("AAPL.csv")

# Extract the stock price series
stock_price = stock_data["Close"]

# Set the starting bet size and the maximum number of bets
bet_size = 100
max_bets = 10

# Initialize the total profit and the number of bets
total_profit = 0
num_bets = 0

# Loop through the stock price data and apply the Martingale algorithm
for i in range(1, len(stock_price)):
# Check if the stock price increased or decreased from the previous day
if stock_price[i] > stock_price[i-1]:
# If the stock price increased, place a bet and double the bet size
total_profit -= bet_size
bet_size *= 2
num_bets += 1
else:
# If the stock price decreased, collect the winnings
total_profit += bet_size
bet_size = 100

# Stop betting after the maximum number of bets
if num_bets >= max_bets:
break

# Print the total profit
print(f"Total profit: ${total_profit:.2f}")

В этом коде предполагается, что у вас есть CSV-файл с именем «AAPL.csv», содержащий данные об акциях Apple, со столбцом «Закрытие», который содержит цену закрытия акций на каждую дату. Он также предполагает, что вы установили стартовый размер ставки и максимальное количество ставок по желанию.

Полученный результат покажет общую прибыль или убыток от применения алгоритма Мартингейла к данным о цене акций. Важно отметить, что алгоритм Мартингейла может быть очень рискованным и не обязательно может улучшить эффективность торговых стратегий на практике. Как правило, не рекомендуется использовать этот алгоритм или любую другую чисто механическую торговую стратегию, так как он не учитывает различные факторы, которые могут повлиять

C5.0: Декомпозиция сезонности

Методы декомпозиции сезонности и их применение к торговой стратегии

Предполагая, что цена акций представляет собой данные временных рядов, существует несколько способов разложить цены фондового рынка на сезонность и тренд.

Здесь показаны два популярных метода: 1) с использованием статистических методов 2) с использованием метода скользящей средней.

Статистическая модель, такая как метод сезонной декомпозиции временных рядов (STL), разлагает временной ряд на сезонные, трендовые и остаточные компоненты.

Другим способом декомпозиции цен на фондовом рынке является использование метода, называемого «декомпозиция с использованием скользящих средних». Это включает в себя использование скользящих средних для определения компонента тренда данных временных рядов и вычитание компонента тренда из исходных данных для получения сезонного компонента.

Независимо от используемого метода, цель декомпозиции цен на фондовом рынке состоит в том, чтобы определить основной тренд и сезонные закономерности в данных, что может помочь инвесторам принимать более обоснованные решения о покупке и продаже акций.

  1. Статистическая декомпозиция сезонности
import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose

import matplotlib.pyplot as plt

# Load the Apple stock price data into a pandas DataFrame
df = pd.read_csv('apple_stock_prices.csv', index_col='Date', parse_dates=True)

# Decompose the stock price data using a statistical method (such as decomposition using moving averages)
result = seasonal_decompose(df['Close'], model='additive')

# Extract the trend, seasonal, and residual components from the result
trend = result.trend
seasonal = result.seasonal
residual = result.resid


# Alternatively, you can use the STL method to decompose the stock price data
result = seasonal_decompose(df['Close'], model='multiplicative', period=30)

# Extract the trend, seasonal, and residual components from the result
trend = result.trend
seasonal = result.seasonal
residual = result.resid

# Create a new figure and plot the trend component
plt.figure()
plt.plot(trend)
plt.title('Trend Component')

# Create a new figure and plot the seasonal component
plt.figure()
plt.plot(seasonal)
plt.title('Seasonal Component')

# Create a new figure and plot the residual component
plt.figure()
plt.plot(residual)
plt.title('Residual Component')

Этот код использует функцию seasonal_decompose() из библиотеки statsmodels для декомпозиции данных о ценах на акции. Параметр model указывает тип используемой декомпозиции («аддитивная» или «мультипликативная»). Параметр period указывает количество периодов, которые будут использоваться для сезонного компонента (например, если период равен 30, сезонный компонент будет основан на ежемесячных данных).

2. Метод скользящей средней для разложения сезонности

import pandas as pd
import matplotlib.pyplot as plt

# Load the Apple stock price data into a pandas DataFrame
df = pd.read_csv('apple_stock_prices.csv', index_col='Date', parse_dates=True)

# Calculate the rolling mean of the stock price data with a window size of 30
rolling_mean = df['Close'].rolling(window=30).mean()

# Subtract the rolling mean from the original stock price data to obtain the trend component
trend = df['Close'] - rolling_mean

# Add the rolling mean back to the trend component to obtain the seasonal component
seasonal = trend + rolling_mean

# Create a new figure and plot the trend component
plt.figure()
plt.plot(trend)
plt.title('Trend Component')

# Create a new figure and plot the seasonal component
plt.figure()
plt.plot(seasonal)
plt.title('Seasonal Component')

# Create a new figure and plot the residual component
plt.figure()
plt.plot(residual)
plt.title('Residual Component')

Этот код использует функцию rolling() от pandas для вычисления скользящего среднего данных о цене акций с размером окна 30. Затем он вычитает скользящее среднее из исходных данных, чтобы получить компонент тренда, и добавляет скользящее среднее обратно к компоненту тренда, чтобы получить сезонный компонент. Наконец, он создает отдельные рисунки для каждого компонента и отображает данные с помощью функции plot() из библиотеки matplotlib.

LET строит торговый старт на аспекте сезонности цены акций Apple.Inc.

Обычно методы декомпозиции сезонности применяются для сглаживания временных рядов и удаления компонента сезонности. Сигнал тренда Smoothend используется для прогнозирования будущего. Однако в данных о ценах на акции тенденция циклична, и этот подход не сработает. Мы взяли альтернативный подход, взяв среднее значение за 365 периодов данных без тренда, и построили простую торговую стартовую схему.

import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose

# Load the Apple stock price data into a pandas DataFrame
df = pd.read_csv('apple_stock_prices.csv', index_col='Date', parse_dates=True)

# Decompose the stock price data using the STL method
result = seasonal_decompose(df['Close'], model='multiplicative', period=30)

# Extract the seasonal component from the result
seasonal = result.seasonal

# Calculate the average value of the seasonal component over the past year
avg_seasonal = seasonal.rolling(window=365).mean()

# Calculate the current value of the seasonal component
current_seasonal = seasonal.iloc[-1]

# If the current value of the seasonal component is above the average value, buy the stock
if current_seasonal > avg_seasonal:
print('Buy the stock!')

# If the current value of the seasonal component is below the average value, sell the stock
elif current_seasonal < avg_seasonal:
print('Sell the stock!')

# If the current value of the seasonal component is close to the average value, do nothing
else:
print('Hold the stock!')

Этот код использует функцию seasonal_decompose() из библиотеки statsmodels для декомпозиции данных о ценах акций на сезонную составляющую. Затем он вычисляет среднее значение сезонного компонента за прошедший год, используя функции rolling()() и mean() из pandas, и вычисляет текущее значение сезонного компонента с помощью индексатора iloc[]. Наконец, он использует оператор if-elif-else, чтобы определить, следует ли покупать, продавать или удерживать акции на основе текущей стоимости сезонного компонента по отношению к среднему значению.

C6: фильтр Калмана

Сглаживание Калмана и выгода от скользящей средней, применение к торговому стартегу

TФильтр Калмана — это математический алгоритм, который используется для оценки состояния системы на основе серии зашумленных измерений. Он часто используется в области техники управления для сглаживания данных и уменьшения влияния шума и ошибок измерений.

В контексте анализа цен на акции фильтр Калмана можно использовать для сглаживания зашумленных или волатильных ценовых данных и выявления тенденций или закономерностей, которые могут быть не сразу очевидны. Это может быть полезно для инвесторов, которые пытаются принимать обоснованные решения о покупке и продаже акций.

Чтобы применить фильтр Калмана к данным о ценах на акции, сначала необходимо определить математическую модель системы (в данном случае фондового рынка). Эта модель обычно включает переменные, такие как текущая цена акций, скорость изменения цены акций и любые другие соответствующие факторы, которые могут повлиять на цену акций. Затем вы должны использовать фильтр Калмана для оценки состояния системы (т. е. цены акций) на основе серии зашумленных измерений (т. е. исторических данных о ценах на акции).

Ниже приведен код Python, демонстрирующий, как сгладить данные о ценах на акции Apple с помощью фильтра Калмана и сравнить результат со сглаживанием на основе 50-периодной скользящей средней:

import pandas as pd
import matplotlib.pyplot as plt
from pykalman import KalmanFilter
import numpy as np

# Load the Apple stock price data into a pandas DataFrame
df = pd.read_csv('apple_stock_prices.csv', index_col='Date', parse_dates=True)

# Define the Kalman filter model
kf = KalmanFilter(transition_matrices=[1], observation_matrices=[1], initial_state_mean=df['Close'].iloc[0], initial_state_covariance=1, observation_covariance=1, transition_covariance=.01)

# Use the Kalman filter to smooth the stock price data
smoothed_kalman = df['Close'].apply(lambda x: kf.filter(x)[0]).to_frame()

# Calculate the 50-period moving average of the stock price data
smoothed_ma = df['Close'].rolling(window=50).mean()

# Calculate MAE
mae = np.mean(np.abs(smoothed_kalman - smoothed_ma))

# Calculate RMSE
rmse = np.sqrt(np.mean((smoothed_kalman - smoothed_ma)**2))

# Print MAE and RMSE
print('MAE:', mae)
print('RMSE:', rmse)

# Create a new figure
plt.figure()

# Plot the original, Kalman-smoothed, and moving average-smoothed data
plt.plot(df['Close'], label='Original')
plt.plot(smoothed_kalman, label='Kalman-smoothed')
plt.plot(smoothed_ma, label='Moving average-smoothed')

# Plot the error between the Kalman-smoothed and moving average-smoothed data
plt.plot(mae, label='MAE_Error')
plt.plot(rmse, label='RMSE_Error')

# Add a legend
plt.legend()

Этот код использует класс KalmanFilter из библиотеки pykalman для определения модели фильтра Калмана для данных о цене акций. Затем он использует методы apply()() и filter() для сглаживания данных с помощью фильтра Калмана. Он также вычисляет 50-периодную скользящую среднюю данных о цене акций с помощью функций rolling()() и mean() от pandas. Наконец, он строит исходные, сглаженные Калманом и скользящие сглаженные средние данные с помощью функции plot() из matplotlib и добавляет легенду с помощью функции legend()

WПреимущество использования фильтра Калмана по сравнению со скользящей средней

Фильтр Калмана и скользящая средняя — это методы, которые можно использовать для сглаживания зашумленных или изменчивых данных и выявления тенденций или закономерностей, которые могут быть не сразу очевидны. Тем не менее, между этими двумя методами есть некоторые ключевые различия, которые могут сделать один из них более подходящим для определенных применений, чем другой.

Одним из преимуществ использования фильтра Калмана по сравнению со скользящей средней является то, что он может более эффективно обрабатывать изменяющиеся во времени сигналы, такие как те, которые демонстрируют меняющиеся тренды или сезонные модели. Это связано с тем, что фильтр Калмана использует динамическую модель системы, которая со временем корректируется на основе новых измерений. В отличие от этого, метод скользящей средней просто вычисляет среднее значение фиксированного числа прошлых наблюдений и не учитывает никаких изменений в базовых данных.

Еще одним преимуществом фильтра Калмана является то, что он может включать дополнительную информацию о моделируемой системе, такую как оценки процесса и шума измерения.

При этом метод скользящей средней, как правило, проще в реализации и может быть достаточным для некоторых приложений. Он также менее ресурсоемкий, чем фильтр Калмана, что может быть важным фактором для приложений реального времени.

Торговый старт, который сочетает в себе фильтр Калмана и экспоненциальное перемещение с нулевым запаздыванием и принятие торгового решения

import numpy as np
import pandas as pd

def initialize(context):
# Set the asset to be traded
context.asset = symbol('AAPL')

# Set the number of days to hold the asset
context.hold_days = 5

# Set the window size for the Kalman filter and ZLEMA
context.kalman_window = 30
context.zlema_window = 10

# Set the weight for the Kalman filter in the combination
context.kalman_weight = 0.7

# Initialize the Kalman filter
context.kalman = KalmanFilter(dim_x=2, dim_z=1)
context.kalman.x = np.array([[0], [0]])
context.kalman.F = np.array([[1, 1], [0, 1]])
context.kalman.H = np.array([[1, 0]])
context.kalman.P *= 1000
context.kalman.R = 5
context.kalman.Q = Q_discrete_white_noise(2, 0.1, 1)

def handle_data(context, data):
# Get the price history for the asset
prices = data.history(context.asset, 'price', context.kalman_window, '1d')

# Update the Kalman filter
context.kalman.predict()
context.kalman.update(prices[-1])

# Calculate the ZLEMA
zlema = (context.zlema_window - 1) * context.portfolio.positions[context.asset].cost_basis
zlema += prices[-1]
zlema /= context.zlema_window

# Combine the Kalman filter and ZLEMA using the specified weight
combined = context.kalman_weight * context.kalman.x[0] + (1 - context.kalman_weight) * zlema

# If the price is above the combined value, buy the asset
if data.can_trade(context.asset) and data.current(context.asset, 'price') > combined:
order_target_percent(context.asset, 1.0)

# If it's time to sell, sell the asset
if context.hold_days > 0:
context.hold_days -= 1
else:
order_target_percent(context.asset, 0)
context.hold_days = 5

Эта стратегия сначала инициализирует фильтр Калмана некоторыми начальными значениями, а затем использует фильтр Калмана для прогнозирования и обновления цены актива на основе прошлой истории цен. Он также рассчитает ZLEMA, используя прошлую историю цен. Затем стратегия объединит выходные данные фильтра Калмана и ZLEMA с использованием указанного веса и будет использовать это комбинированное значение в качестве ориентира для принятия решений о покупке и продаже. Если текущая цена актива выше комбинированной.

C7: Одномерный анализ

Применение одномерного анализа на биржевых данных и определение их характеристик

Нивариатный анализ — это статистический метод, используемый для анализа и описания одной переменной. Он включает в себя изучение распределения, закономерностей и тенденций одной переменной без учета взаимосвязи с другими переменными.

Одномерный анализ может быть применен к данным о ценах на акции, чтобы понять характеристики движения цены акций за определенный период времени. Некоторые распространенные методы, используемые в одномерном анализе данных о ценах на акции, включают:

  1. Описательная статистика: Это включает в себя расчет таких показателей, как среднее значение, медиана, режим, диапазон и стандартное отклонение данных о ценах на акции. Эти меры могут помочь обобщить общие характеристики данных и выявить любые выбросы.
  2. Визуализация: Построение данных о ценах на акции с течением времени с использованием линейного графика или гистограммы может помочь определить тенденции, закономерности и взаимосвязи в данных.
  3. Распределения вероятностей: Подгонка распределения вероятностей (например, нормальное, логнормальное и т. д.) к данным о ценах на акции может помочь понять основные статистические свойства данных и сделать прогнозы о будущих движениях цен.
  4. Корреляционный анализ: Это включает в себя изучение взаимосвязи между данными о ценах на акции и другими переменными, такими как экономические показатели или другие цены на акции.

Чтобы применить одномерный анализ к данным о ценах на акции в Python, вы можете использовать такие инструменты, как NumPy, Pandas и Matplotlib. Вы также можете использовать статистические библиотеки, такие как SciPy или StatsModels, для согласования распределений вероятностей или выполнения корреляционного анализа.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Load the stock price data into a Pandas DataFrame
df = pd.read_csv('AAPL.csv')

# Calculate some descriptive statistics
mean = np.mean(df['Close'])
median = np.median(df['Close'])
mode = scipy.stats.mode(df['Close'])[0][0]
range = np.ptp(df['Close'])
std = np.std(df['Close'])

print(f"Mean: {mean}")
print(f"Median: {median}")
print(f"Mode: {mode}")
print(f"Range: {range}")
print(f"Standard deviation: {std}")

# Plot the stock price data over time
plt.plot(df['Date'], df['Close'])
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.title('Apple Stock Price over Time')
plt.show()

# Plot a histogram of the stock price data
plt.hist(df['Close'], bins=20)
plt.xlabel('Close Price')
plt.ylabel('Frequency')
plt.title('Histogram of Apple Stock Price')
plt.show()

Этот код сначала загружает данные о цене акций в кадр данных Pandas, а затем вычисляет некоторую описательную статистику (среднее значение, медиана, мода, диапазон и стандартное отклонение) с помощью функций NumPy. Затем он строит данные о ценах на акции с течением времени с помощью Matplotlib и строит гистограмму данных о ценах на акции.

import scipy.stats as stats

# Fit a lognormal distribution to the stock price data
param = stats.lognorm.fit(df['Close'])

# Generate a range of values for the x-axis
x = np.linspace(df['Close'].min(), df['Close'].max(), 100)

# Calculate the probability density function (PDF) of the fitted distribution
pdf = stats.lognorm.pdf(x, *param)

# Plot the stock price data and the fitted distribution
plt.hist(df['Close'], bins=20, density=True)
plt.plot(x, pdf, 'r', linewidth=2)
plt.xlabel('Close Price')
plt.ylabel('Probability Density')
plt.title('Lognormal Fit of Apple Stock Price')
plt.show()

Этот код подгоняет логнормальное распределение к данным о цене акций с помощью функции fit из библиотеки scipy.stats Затем он генерирует диапазон значений для оси x, вычисляет функцию плотности вероятности (PDF) подогнанного распределения и строит график данных о цене акций и подогнанном распределении с помощью Matplotlib.

AУтокорреляционный анализ — это статистический метод, используемый для изучения зависимости между переменной и самой собой в разных временных лагах. Это может быть полезно для выявления закономерностей и тенденций в данных временных рядов, таких как данные о ценах на акции.

Вот код Python, демонстрирующий, как применить автокорреляционный анализ к данным о ценах на акции Apple с помощью Pandas:

import pandas as pd
import pandas as pd
from statsmodels.graphics.tsaplots import plot_acf

# Load the stock price data into a Pandas DataFrame
df = pd.read_csv('AAPL.csv')

# Calculate the autocorrelation for different lags
autocorr = df['Close'].autocorr(lag=1)
print(f"Autocorrelation at lag 1: {autocorr}")

autocorr = df['Close'].autocorr(lag=5)
print(f"Autocorrelation at lag 5: {autocorr}")

autocorr = df['Close'].autocorr(lag=10)
print(f"Autocorrelation at lag 10: {autocorr}")

# Plot the autocorrelation function
pd.plotting.autocorrelation_plot(df['Close'])
plt.show()

# Plot the ACF
plot_acf(df['Close'])
plt.show()

его код сначала загружает данные о цене акций в кадр данных Pandas, а затем строит график ACF с помощью функции plot_acf. ACF строится вместе с доверительными интервалами, которые можно использовать для определения статистической значимости автокорреляции на каждом запаздывании.

C8: ACF, PCF, ARIMA

Общие сведения о ACF, PCF и ARIMA, Использование ACF, PCF для соответствия модели ARIMA

ARIMA (AutoRegressive Integrated Moving Average) — это статистическая модель, которую можно использовать для анализа и прогнозирования данных временных рядов, таких как цены на акции. Он основан на предположении, что прошлое поведение временного ряда может быть использовано для прогнозирования будущего поведения. Другие методы одномерного анализа, которые могут быть применены к данным о ценах на акции, включают экспоненциальное сглаживание, Бокса-Дженкинса и сезонную декомпозицию.

ACF (автокорреляционная функция) и PCF (частичная автокорреляционная функция) — это графики, которые можно использовать для определения соответствующих параметров для модели ARIMA (AutoRegressive Integrated Moving Average).

График ACF показывает корреляцию между данными временных рядов и запаздывающими версиями самого себя. Это может помочь определить, проявляют ли данные временных рядов автокорреляцию, то есть наличие закономерности в данных, которая коррелирует сама с собой через определенную задержку. График ACF также может помочь определить количество авторегрессионных (AR) терминов, которые должны быть включены в модель ARIMA.

График PCF показывает корреляцию между данными временных рядов и запаздывающими версиями самого себя после учета эффектов любых промежуточных запаздываний. График PCF также может помочь определить количество терминов скользящей средней (MA), которые должны быть включены в модель ARIMA.

Чтобы определить подходящие параметры для модели ARIMA с использованием графиков ACF и PCF, можно выполнить следующие действия:

  1. Постройте график ACF и PCF данных временных рядов.
  2. Определите запаздывания, при которых график ACF начинает обрываться, а график PCF начинает обрываться. Количество членов AR должно быть равно запаздыванию, с которым график ACF начинает обрываться, а количество членов MA должно быть равно запаздыванию, при котором график PCF начинает обрываться.
  3. Определите порядок разницы (d) данных временных рядов, посмотрев на тенденцию на графике временных рядов. Если график временных рядов демонстрирует положительную тенденцию, то d должен быть установлен равным 1 (т.е. данные временных рядов интегрируются порядка 1). Если график временных рядов демонстрирует отрицательную тенденцию, то d должен быть установлен на -1 (т.е. данные временных рядов интегрируются порядка -1). Если график временных рядов не показывает тренда, то d должен быть установлен равным 0 (т. е. данные временных рядов интегрируются порядка 0).
  4. Используйте значения, полученные на шагах 2 и 3, в качестве параметров для модели ARIMA.
  5. Например, если график ACF начинает обрываться с запаздыванием 2, а график PCF начинает обрываться с запаздыванием 3, а данные временных рядов демонстрируют положительную динамику, то модель ARIMA должна быть указана как ARIMA(2,1,3).
# Import necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# Load the stock price data
df = pd.read_csv('AAPL.csv')

# Convert the date column to datetime and set it as the index
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)

# Select the 'Close' column as the time series data
ts = df['Close']

# Plot the Tine series, ACF and PCF of the time series
plt.plot(ts)
plot_acf(ts)
plot_pacf(ts)
plt.show()

# Determine the difference order of the time series data
# based on the trend in the plot
if ts.trend == 'increasing':
d = 1
elif ts.trend == 'decreasing':
d = -1
else:
d = 0

# Determine the number of AR and MA terms based on the
# lags at which the ACF and PCF plots start to tail off
# or cut off, respectively
p = 2 # Number of AR terms
q = 3 # Number of MA terms

# Fit an ARIMA model to the time series data
model = ARIMA(ts, order=(p,d,q))
model_fit = model.fit()

# Print summary of the fit model
print(model_fit.summary())

# Forecast future stock prices
forecast = model_fit.forecast(steps=30)[0]

# Plot the forecasted stock prices
plt.plot(forecast)
plt.show()

Этот код предполагает, что данные о цене акций хранятся в CSV-файле с именем «AAPL.csv» со столбцами «Дата» и «Закрытие», а даты имеют формат «ГГГГ-ММ-ДД». Сначала код загружает данные в кадр данных Pandas, преобразует столбец «Дата» в дату и время и устанавливает его в качестве индекса, а столбец «Закрыть» выбирает в качестве данных временного ряда. Затем он строит данные временных рядов, а также ACF и PCF временных рядов.

Затем код определяет порядок различий данных временных рядов на основе тенденции на графике. Если тенденция усиливается, d устанавливается равным 1 (т.е. данные временных рядов интегрируются порядка 1); если тренд снижается, d устанавливается равным -1 (т.е. данные временных рядов интегрируются порядка -1); в противном случае d устанавливается равным 0 (т. е. данные временных рядов интегрируются порядка 0).

Затем количество членов AR и MA определяется на основе запаздываний, с которыми графики ACF и PCF начинают обрываться или обрываться соответственно. В этом примере количество членов AR установлено равным 2, а количество членов MA — 3. Эти значения могут быть скорректированы исходя из конкретных характеристик времени

C9: Ошибки измерения MAE, R2, MFE, RMSE

Мера точности статистической модели не является подходящим выбором для оценки производительности модели, поскольку она не учитывает величину ошибок, допущенных моделью.

Другие меры погрешности, такие как средняя абсолютная ошибка (MAE), средняя квадратичная ошибка (MSE) и среднеквадратичная ошибка (RMSE), учитывают величину ошибок, допущенных моделью, и поэтому больше подходят для оценки производительности статистической модели.

Средняя абсолютная погрешность (MAE): MAE измеряет среднюю величину ошибок в наборе прогнозов, не учитывая их направление. Он рассчитывается как сумма абсолютных ошибок, деленная на количество прогнозов.

Формула:

МАЭ = (1/n) * ∑|y_i — ŷ_i|

где n — количество наблюдений, y_i — фактическое значение i-го наблюдения, а ŷ_i — прогнозируемое значение i-го наблюдения.

Код Python:

import numpy as np

def mae(y_true, y_pred):
return np.mean(np.abs(y_true - y_pred))

R-квадрат (R2): R2 — это мера доли дисперсии в зависимой переменной, которая объясняется моделью. Он колеблется от 0 до 1, при этом более высокие значения указывают на лучшую посадку.

Формула для R2:

R2 = 1 — (∑(y_i — ŷ_i)² / ∑(y_i — ȳ)²)

где n — число наблюдений, y_i — действительная величина i-го наблюдения, ŷ_i — прогнозируемое значение i-го наблюдения, ȳ — среднее значение фактических значений.

Код Python:

import numpy as np

def r2(y_true, y_pred):
y_mean = np.mean(y_true)
numerator = np.sum((y_true - y_pred)**2)
denominator = np.sum((y_true - y_mean)**2)
return 1 - (numerator / denominator)

Средняя ошибка прогноза (MFE): MFE — это средняя ошибка набора прогнозов. Он рассчитывается как сумма ошибок, деленная на количество прогнозов.

Формула:

MFE = (1/n) * ∑(y_i — ŷ_i)

где n — количество наблюдений, y_i — фактическое значение i-го наблюдения, а ŷ_i — прогнозируемое значение i-го наблюдения.

Код Python:

import numpy as np

def mfe(y_true, y_pred):
return np.mean(y_true - y_pred)

Среднеквадратичная ошибка (RMSE): RMSE — это мера разницы между прогнозируемыми и фактическими значениями. Он вычисляется как квадратный корень из среднего квадрата ошибки.

Формула:

RMSE = √((1/n) * ∑(y_i — ŷ_i)²)

где n — количество наблюдений, y_i — фактическое значение i-го наблюдения, а ŷ_i — прогнозируемое значение i-го наблюдения.

Код Python:

import numpy as np

def rmse(y_true, y_pred):
return np.sqrt(np.mean((y_true - y_pred)**2))

Выбор меры зависит от конкретных целей и контекста моделирования.

  • MAE может быть хорошим выбором, если вы хотите узнать среднюю величину ошибок в ваших прогнозах, поскольку он измеряет среднюю абсолютную разницу между прогнозируемыми и фактическими значениями.
  • MFE может быть хорошим выбором, если вы хотите узнать среднюю погрешность ваших прогнозов, поскольку он измеряет среднюю разницу между прогнозируемыми и фактическими значениями.
  • RMSE может быть хорошим выбором, если вы хотите узнать типичный размер ошибок в ваших прогнозах, поскольку он измеряет среднеквадратичную разницу между прогнозируемыми и фактическими значениями. Как правило, он более чувствителен к большим ошибкам, чем MAE или MFE.

В конечном счете, наилучшая мера погрешности для анализа данных о ценах на акции будет зависеть от конкретных целей и контекста вашего анализа, а также от характеристик данных. Может быть полезно попробовать использовать несколько показателей и сравнить их результаты, чтобы увидеть, какой из них дает наиболее полезную информацию для вашего конкретного анализа.

C10: Двумерный анализ цены акций

Двумерный анализ цены акций и простая модель для прогнозирования будущего

BИвариативный анализ включает в себя изучение взаимосвязи между двумя переменными. В контексте данных о ценах на акции двумерный анализ может быть использован для изучения взаимосвязи между ценой акций и одной или несколькими другими переменными (такими как объем, волатильность, макроэкономические или технические показатели) с целью прогнозирования будущих цен на акции.

Шаги, которые вы можете выполнить, чтобы выполнить двумерный анализ данных о ценах на акции:

  • Сбор и очистка данных: сбор исторических данных о цене акций и других переменных для анализа. Обязательно очистите данные, обработав отсутствующие значения, выбросы и другие проблемы.
  • Изучите данные: используйте графические и статистические методы для изучения взаимосвязей между переменными. Например, вы можете создать диаграммы рассеяния, чтобы визуализировать взаимосвязь между ценой акции и другими переменными, или использовать коэффициенты корреляции для измерения силы и направления взаимосвязи.
  • Постройте статистическую модель: используйте аналитические сведения, полученные в результате исследования данных, для создания статистической модели, включающей взаимосвязи между переменными.
  • Оценка модели: используйте меру погрешности (например, MAE, MSE или RMSE) для оценки производительности модели. Вы также можете использовать методы перекрестной проверки, чтобы получить более надежную оценку производительности модели.

Используйте несколько моделей для прогнозирования цены акций Не забывайте учитывать неопределенность в своих прогнозах и рассмотрите возможность использования диапазона возможных результатов, а не одноточечной оценки. Оцените лучшую среди всех моделей.

Ниже приведен пример кода Python, демонстрирующий, как выполнять двумерный анализ данных об акциях Apple, используя объем, цену закрытия и VIX (меру волатильности рынка) в качестве переменных:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Load the data into a Pandas DataFrame
df = pd.read_csv('apple_stock_data.csv')

# Select the relevant columns
df = df[['volume', 'close', 'VIX']]

# Explore the data
sns.pairplot(df)
plt.show()

# Calculate the correlations between the variables
corr = df.corr()
print(corr)

# Build a linear regression model to predict stock price based on volume and VIX
from sklearn.linear_model import LinearRegression

X = df[['volume', 'VIX']]
y = df['close']

model = LinearRegression()
model.fit(X, y)

# Make predictions using the model
y_pred = model.predict(X)

# Evaluate the model using the mean squared error
from sklearn.metrics import mean_squared_error

mse = mean_squared_error(y, y_pred)
print('Mean Squared Error:', mse)

Этот код сначала загружает данные в кадр данных Pandas и выбирает соответствующие столбцы. Затем он использует парный график для визуализации взаимосвязей между переменными и вычисляет корреляции между переменными с помощью метода corr.

Затем код строит модель линейной регрессии для прогнозирования цены акций на основе переменных объема и VIX и использует модель для прогнозирования тех же данных, которые использовались для обучения модели. Наконец, он оценивает модель, используя среднюю квадратичную ошибку (MSE).

C11: корреляция VS коинтеграция

CОрреляция и коинтеграция — это два статистических показателя, которые можно использовать для выявления взаимосвязей между переменными. Однако они измеряют разные типы взаимосвязей и имеют разные последствия для прогнозирования и моделирования.

  • Корреляция измеряет силу и направление линейной зависимости между двумя переменными. Он может варьироваться от -1 (идеальная отрицательная корреляция) до 1 (идеальная положительная корреляция), при этом значения около 0 указывают на слабую связь или ее отсутствие. Корреляция полезна для понимания силы взаимосвязи между двумя переменными, но она не подразумевает какой-либо долгосрочной взаимосвязи или возврата к среднему значению между переменными.
  • Коинтеграция, с другой стороны, относится к долгосрочной взаимосвязи между двумя или более переменными временных рядов, так что их движения коррелируют в долгосрочной перспективе. Коинтеграция подразумевает, что переменные в конечном итоге вернутся к долгосрочным равновесным отношениям, даже если они могут расходиться в краткосрочной перспективе. Коинтеграция может быть использована для выявления возможностей для торговых стратегий возврата к среднему значению или для построения моделей, которые прогнозируют долгосрочное поведение переменных.

В контексте данных о ценах на акции корреляция может использоваться для выявления взаимосвязей между различными акциями или между акцией и внешним фактором (например, индексом или макроэкономическим показателем). Коинтеграция может быть использована для выявления взаимосвязей между двумя или более акциями или между акциями и внешним фактором, которые, вероятно, со временем вернутся к долгосрочным равновесным отношениям.

Пример кода Python по корреляции и коинтеграции

Корреляция

Вот пример того, как вы можете найти акции, которые больше всего коррелируют с ценой акций Apple от компаний NASDAQ 100:

  1. Во-первых, вам нужно получить цены на акции Apple и компаний NASDAQ 100. Вы можете сделать это с помощью финансового API или путем очистки данных с финансового веб-сайта.
  2. Далее вам нужно будет рассчитать корреляцию между ценами на акции Apple и каждой из компаний NASDAQ 100.
  3. После того, как у вас есть корреляции для всех компаний NASDAQ 100, вы можете найти компанию с наибольшей корреляцией, отсортировав корреляции в порядке убывания и взяв лучший результат.
import pandas as pd

# Get the stock prices for Apple and the NASDAQ 100 companies
apple_prices = get_stock_prices("AAPL")
nasdaq_prices = get_stock_prices(nasdaq_100_tickers)

# Calculate the correlations between the stock prices
correlations = nasdaq_prices.corrwith(apple_prices)

# Sort the correlations in descending order and print the company with the highest correlation
highest_correlation = correlations.sort_values(ascending=False).index[0]
print(f"The stock most correlated with Apple is {highest_correlation}")

Этот код предполагает, что у вас есть get_stock_prices, которая принимает тикерный символ и возвращает цены на акции этой компании в виде серии Pandas, и что у вас есть список тикеров для компаний NASDAQ 100 под названием nasdaq_100_tickers. Отсортируем корреляции в порядке убывания, чтобы найти лучшие акции, которые сильно коррелируют с Apple.

Коинтеграция

Вот пример того, как вы можете найти акции компаний NASDAQ 100, которые наиболее интегрированы с ценой акций Apple:

  1. Во-первых, вам нужно получить цены на акции Apple и компаний NASDAQ 100. Вы можете сделать это с помощью финансового API или путем очистки данных с финансового веб-сайта.
  2. Затем вам нужно будет проверить коинтеграцию между ценами на акции Apple и каждой из компаний NASDAQ 100. Один из способов сделать это — использовать функцию coint из библиотеки statsmodels в Python. Эта функция выполняет расширенный тест Дики-Фуллера, который проверяет стационарность в остатках линейной регрессии между двумя временными рядами. Если остатки неподвижны, это указывает на то, что два временных ряда интегрированы.
  3. Вы можете найти компанию с самой сильной коинтеграцией, отсортировав p-значения в порядке возрастания и взяв лучший результат. Меньшее значение p указывает на более сильную коинтеграцию.
  4. Есть и другие методы, которые вы также можете использовать, такие как тест Йохансена или тест Филлипса-Улиариса для коинтеграции

Ниже приведен пример кода, показывающий, как это можно сделать с помощью методов ADF, Йохансена и Филлипса-Улиариса

import pandas as pd
from statsmodels.tsa.stattools import coint
from statsmodels.tsa.vector_ar.vecm import coint_johansen
from statsmodels.tsa.stattools import ogs

# Get the stock prices for Apple and the NASDAQ 100 companies
apple_prices = get_stock_prices("AAPL")
nasdaq_prices = get_stock_prices(nasdaq_100_tickers)

# Test for cointegration between the stock prices using Augmented Dickey-Fuller test
coint_results_ADF = {}
for ticker in nasdaq_100_tickers:
_, pvalue, _ = coint(apple_prices, nasdaq_prices[ticker])
coint_results_ADF[ticker] = pvalue

# Sort the p-values in ascending order and print the company with the strongest cointegration
strongest_coint_ADF = sorted(coint_results_ADF, key=coint_results_ADF.get)[0]
print(f"The stock most cointegrated with Apple using ADF is {strongest_coint_ADF}")

# Test for cointegration between the stock prices using Johansen test
coint_results_J = {}
for ticker in nasdaq_100_tickers:
prices = pd.concat([apple_prices, nasdaq_prices[ticker]], axis=1)
_, _, eigvals, _ = coint_johansen(prices, det_order=0, k_ar_diff=1)
coint_results_J[ticker] = min(eigvals)

# Sort the eigenvalues in ascending order and print the company with the strongest cointegration
strongest_coint_J = sorted(coint_results_J, key=coint_results_J.get)[0]
print(f"The stock most cointegrated with Apple Using Johnsen is {strongest_coint_J}")

# Test for cointegration between the stock prices using Phillips-Ouliaris test
coint_results_PO = {}
for ticker in nasdaq_100_tickers:
prices = pd.concat([apple_prices, nasdaq_prices[ticker]], axis=1)
_, _, _, _, _, _, _, phillips_ouliaris_test = ogs(prices, trend='c',
var_type='c')
coint_results_PO[ticker] = phillips_ouliaris_test

# Sort the p-values in ascending order and print the company with the strongest cointegration
strongest_coint_PO = sorted(coint_results_PO, key=coint_results_PO.get)[0]
print(f"The stock most cointegrated with Apple Using Phillips_Ouliaris is {strongest_coint_PO}")

Тест Йохансена — это многомерная версия расширенного теста Дики-Фуллера, который проверяет коинтеграцию между несколькими временными рядами. Тест возвращает матрицу собственных значений, а минимальное собственное значение является мерой силы коинтеграции. Меньшее собственное значение указывает на более сильную коинтеграцию.

для Phillips_Ouliaris теста мы сортируем p-значения в порядке возрастания и печатаем компанию с самой сильной коинтеграцией

C12: Парная торговля и треугольный арбитраж

Парная торговля — это торговая стратегия, при которой инвестор покупает и продает две связанные ценные бумаги, обычно две акции, в ожидании, что разница в цене между двумя ценными бумагами сократится или увеличится. Стратегия основана на идее, что цена двух связанных ценных бумаг будет иметь тенденцию двигаться в тандеме друг с другом с течением времени, но могут быть периоды, когда разница в цене между двумя ценными бумагами становится необычно большой.

Арбитраж, с другой стороны, включает в себя использование разницы в ценах между двумя или более рынками или биржами. Например, если цена определенного актива на одной бирже выше, чем на другой, арбитражный трейдер может купить актив на более дешевой бирже и продать его на более дорогой бирже, прикарманив разницу в качестве прибыли.

КомуРеализуя парную торговлю, инвестор может купить одну ценную бумагу и продать другую, или наоборот, в ожидании, что разница в цене между двумя ценными бумагами в конечном итоге сократится или расширится до своего исторического среднего значения. Инвестор, как правило, удерживает парную сделку до тех пор, пока разница в цене между двумя ценными бумагами не вернется к своему историческому среднему значению, после чего сделка может быть закрыта с прибылью.

Существует несколько методов, которые можно использовать для реализации парной торговли с данными акций Apple. Вот несколько примеров:

  • Статистический арбитраж: Этот метод включает в себя анализ исторических данных о ценах на две связанные ценные бумаги, такие как Apple и конкурент, и определение периодов, когда разница в цене между двумя ценными бумагами становится необычно большой. Затем инвестор может купить одну ценную бумагу и продать другую, ожидая, что разница в цене в конечном итоге вернется к своему историческому среднему значению.
import pandas as pd
import numpy as np

# Load historical price data for Apple and a competitor
apple_data = pd.read_csv('apple_data.csv')
competitor_data = pd.read_csv('competitor_data.csv')

# Calculate the price differential between Apple and the competitor
price_differential = apple_data['Close'] - competitor_data['Close']

# Calculate the rolling mean and standard deviation of the price differential
mean = price_differential.rolling(window=20).mean()
std = price_differential.rolling(window=20).std()

# Calculate the z-score of the price differential
z_score = (price_differential - mean) / std

# Identify periods when the z-score is outside of a certain threshold (e.g. 2 standard deviations)
# This could indicate an unusually large price differential between Apple and the competitor
threshold = 2
buy_signal = z_score > threshold
sell_signal = z_score < -threshold

# Implement the trade by buying or selling Apple and the competitor based on the signals
if buy_signal:
# Buy Apple and sell the competitor
elif sell_signal:
# Sell Apple and buy the competitor
else:
# Do nothing
  • Корреляционная торговля: Этот метод включает в себя анализ исторической корреляции цен между двумя связанными ценными бумагами и определение периодов, когда корреляция нарушается. Затем инвестор может купить одну ценную бумагу и продать другую в ожидании, что ценовая корреляция в конечном итоге вернется к своему историческому среднему значению.
import pandas as pd
import numpy as np

# Load historical price data for Apple and a competitor
apple_data = pd.read_csv('apple_data.csv')
competitor_data = pd.read_csv('competitor_data.csv')

# Calculate the rolling correlation between Apple and the competitor
correlation = apple_data['Close'].rolling(window=20).corr(competitor_data['Close'])

# Identify periods when the correlation falls below a certain threshold (e.g. 0.5)
# This could indicate a breakdown in the historical price correlation between Apple and the competitor
threshold = 0.5
buy_signal = correlation < threshold
sell_signal = correlation > 1 - threshold

# Implement the trade by buying or selling Apple and the competitor based on the signals
if buy_signal:
# Buy Apple and sell the competitor
elif sell_signal:
# Sell Apple and buy the competitor
else:
# Do nothing
  • Возврат к среднему: Этот метод включает в себя анализ исторических данных о ценах на две связанные ценные бумаги и выявление периодов, когда цена одной ценной бумаги значительно отклоняется от ее долгосрочного среднего значения. Затем инвестор может купить ценную бумагу, которая недооценена по сравнению с ее долгосрочным средним значением, и продать ценную бумагу, которая переоценена по сравнению с ее долгосрочным средним значением, в ожидании, что цены в конечном итоге вернутся к своим долгосрочным средним значениям.

В приведенном ниже примере market_data.csv содержит ежедневные данные для четырех активов (asset1asset2asset3 и asset4) за определенный период времени и доходность 4 активов за тот же период (asset1_returns asset2_returns asset3_returns asset4_returns). Файл включает дату, цену каждого актива и доходность каждого актива. Доходность рассчитывается как разница между текущей ценой и предыдущей ценой, нормализованная предыдущей ценой.

import pandas as pd
from sklearn.ensemble import RandomForestRegressor

# Load the data for all assets in the market or sector
data = pd.read_csv('market_data.csv')

# Split the data into training and testing sets
train_data = data[data['date'] < '2020-01-01']
test_data = data[data['date'] >= '2020-01-01']

# Train a random forest regressor to predict the returns of each asset
model = RandomForestRegressor()
X_train = train_data.drop(columns=['returns'])
y_train = train_data['returns']
model.fit(X_train, y_train)

# Use the trained model to predict the returns of each asset in the testing set
predictions = model.predict(test_data.drop(columns=['returns']))

# Calculate the residuals (predicted returns - actual returns) for each asset
residuals = predictions - test_data['returns']

# Identify pairs of assets with high residual correlation
correlated_pairs = []
for i in range(len(residuals.columns)):
for j in range(i+1, len(residuals.columns)):
corr = residuals.iloc[:,i].corr(residuals.iloc[:,j])
if abs(corr) > 0.8:
correlated_pairs.append((residuals.columns[i], residuals.columns[j]))

# For each correlated pair, enter a long position in the asset with the higher residual and a short position in the asset with the lower residual
for pair in correlated_pairs:
asset1, asset2 = pair
if residuals[asset1].mean() > residuals[asset2].mean():
position1 = 'long'
position2 = 'short'
else:
position1 = 'short'
position2 = 'long'
# Enter the trades
if position1 == 'long':
buy_asset1()
sell_asset2()
elif position1 == 'short':
sell_asset1()
buy_asset2()

# Monitor the positions and exit the trades when the residual correlation falls below the threshold
while True:
current_correlations = []
for pair in correlated_pairs:
asset1, asset2 = pair
corr = residuals[asset1].corr(residuals[asset2])
current_correlations.append(corr)
if all(abs(corr) < 0.8 for corr in current_correlations):
break

# Close the positions and exit the trades
if position1 == 'long':
sell_asset1()
buy_asset2()
elif position1 == 'short':
buy_asset1()
sell_asset2()

Важно отметить, что парная торговля сопряжена с риском и не всегда может быть успешной. Важно тщательно анализировать исторические данные о ценах и использовать правильные методы управления рисками при реализации стратегии парной торговли.

Треугольный арбитраж: пример скрипта Python, который выполняет треугольный арбитраж криптоактива. Этот скрипт использует библиотеку ccxt для подключения к бирже Binance и получения книги заказов для торговой пары BTC/USDT. Затем он проверяет, есть ли возможность арбитража, сравнивая самую низкую цену предложения с самой высокой ценой предложения. Если цена предложения ниже цены предложения, это означает, что есть возможность купить BTC по более низкой цене и продать его по более высокой цене, и скрипт выполняет сделку. Если возможности арбитража нет, скрипт печатает сообщение.

import ccxt

# Set the exchange credentials
api_key = 'API_KEY'
secret = 'SECRET'

# Set the exchange and the trading pair
exchange_name = 'binance'
trading_pair = 'BTC/USDT'

# Initialize the exchange API client
client = getattr(ccxt, exchange_name)({
'apiKey': api_key,
'secret': secret
})

# Fetch the order book for the trading pair
order_book = client.fetch_order_book(trading_pair)

# Check if there are arbitrage opportunities
if order_book['asks'][0][0] < order_book['bids'][0][0]:
# Calculate the arbitrage profit
profit = order_book['bids'][0][0] - order_book['asks'][0][0]
# Calculate the amount of BTC to buy
btc_amount = order_book['asks'][0][1]
# Calculate the amount of USDT to sell
usdt_amount = btc_amount * order_book['asks'][0][0]

# Place a buy order for BTC
buy_order = client.create_order(trading_pair, 'limit', 'buy', btc_amount, order_book['asks'][0][0])
# Place a sell order for USDT
sell_order = client.create_order('USDT/BTC', 'limit', 'sell', usdt_amount, order_book['bids'][0][0])

# Print the profit
print(f'Arbitrage profit: {profit}')
else:
print('No arbitrage opportunities found')

C13: модель LSTM и модель Маркова

Как мы поняли, данные по акциям имеют долгосрочную зависимость от прошлых результатов, и эта зависимость носит временный характер. Поэтому нам нужно выбрать модель Neuralnet, которая охватывает оба этих аспекта

LSTM: Одним из алгоритмов нейронной сети, который может сохранять прошлые закономерности и временные параметры для прогнозирования временного ряда, является сеть Long Short-Term Memory (LSTM). LSTM — это тип рекуррентной нейронной сети (RNN), специально разработанной для захвата долгосрочных зависимостей в последовательных данных. Они делают это, вводя ячейку памяти, которая представляет собой устройство, способное сохранять информацию в течение длительных периодов времени и выборочно раскрывать ее остальной части сети по мере необходимости.

LSTM могут сделать это с помощью вентилей, которые представляют собой блоки, которые контролируют поток информации в ячейку памяти и из нее. Вентили позволяют сети выборочно сохранять или забывать информацию из прошлого, позволяя ей сосредоточиться на наиболее релевантных паттернах и временных параметрах для составления прогноза.

Чтобы использовать LSTM для прогнозирования временных рядов, вы обычно вводите последовательность прошлых наблюдений в сеть, и LSTM будет использовать эти наблюдения для прогнозирования следующего значения в последовательности.

Особенности алгоритма LSTM:

  • LSTM обрабатывают входные данные последовательно, шаг за шагом, используя выходные данные предыдущего шага времени в качестве входных данных для текущего шага времени.
  • LSTM имеют встроенную ячейку памяти, которая позволяет им сохранять информацию в течение длительных периодов времени.
  • LSTM обычно обучаются с использованием обратного распространения во времени (BPTT), которое включает в себя развертывание сети по входной последовательности и использование градиентного спуска для обновления весов сети.
  • LSTM делают прогнозы о следующем значении в последовательности на основе обработанной входной последовательности и текущего состояния ячейки памяти.

Базовая архитектура LSTM для прогнозирования логарифмической доходности цены закрытия Apple путем взятия лучших гиперпараметров из списка:

# First, we'll import the necessary libraries
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from keras.layers import Dense, LSTM
from keras.models import Sequential

# Next, we'll load the data into a pandas DataFrame
df = pd.read_csv('apple_stock_data.csv')

# We'll use the 'Close' column as the target variable
y = df['Close'].values

# We'll use the 'Open', 'High', 'Low', 'Close', and 'Volume' columns as the input variables
X = df[['Open', 'High', 'Low', 'Close', 'Volume']].values

# We'll scale the input variables to have zero mean and unit variance
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# We'll split the data into training and test sets
split_index = int(len(X) * 0.8)
X_train, X_test = X_scaled[:split_index], X_scaled[split_index:]
y_train, y_test = y[:split_index], y[split_index:]

# We'll reshape the input data to have the shape (num_samples, time_steps, num_features)
time_steps = 5
X_train = np.reshape(X_train, (X_train.shape[0], time_steps, X_train.shape[1]))
X_test = np.reshape(X_test, (X_test.shape[0], time_steps, X_test.shape[1]))

# Now, we'll define the LSTM model
model = Sequential()
model.add(LSTM(50, input_shape=(time_steps, X_train.shape[2]), return_sequences=True))
model.add(LSTM(50, return_sequences=True))
model.add(LSTM(50, return_sequences=True))
model.add(LSTM(50))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')

# We'll use the best hyperparameters determined by the loop to fit the model on the training data
model.fit(X_train, y_train, epochs=best_epoch, batch_size=best_batch_size, verbose=1)

# Now, we'll make predictions on the test data
y_pred = model.predict(X_test)

# We'll compute the log return of the predicted close prices
y_pred_log_return = np.log(y_pred / y_pred[:,0][:, None])

# We'll compute the log return of the actual close prices
y_test_log_return = np.log(y_test / y_test[:,0][:, None])

# Finally, we'll print the predicted and actual log returns
print(f'Predicted log return: {y_pred_log_return[-1,0]:.3f}')
print(f'test log return: {y_test_log_return})

Зачем возвращать журнал?

Как правило, лучше предсказать логарифмическую доходность цены акции, а не саму сырую цену, потому что логарифмическая доходность является относительной мерой, которая фиксирует процентное изменение цены с течением времени. Это может быть более информативно, чем сырая цена, на которую могут влиять такие факторы, как инфляция и изменения на фондовом рынке в целом.

Использование логарифмического возврата в качестве целевой переменной также может помочь стабилизировать дисперсию цели, что может облегчить модели LSTM изучение взаимосвязи между входными переменными и целевым объектом.

MПроцесс Маркова — это тип стохастического процесса (процесс со случайно изменяющимися результатами), который удовлетворяет свойству Маркова, которое гласит, что будущее состояние процесса не зависит от его прошлых состояний с учетом его текущего состояния. Это означает, что вероятность перехода из одного состояния в другое зависит только от текущего состояния, а не от последовательности предшествовавших ему состояний.

Свойство Маркова часто используется для моделирования систем, которые демонстрируют поведение без памяти, где текущее состояние системы не зависит от ее прошлых состояний. Это может быть полезно для моделирования цен на акции, поскольку позволяет включать краткосрочные зависимости, игнорируя долгосрочные зависимости.

Пример кода Python

# First, we'll import the necessary libraries
import numpy as np
import pandas as pd

# Next, we'll load the stock price data into a pandas DataFrame
df = pd.read_csv('apple_stock_data.csv')

# We'll define a function to compute the log return of the stock price
def log_return(x):
return np.log(x / x.shift(1))

# We'll compute the log return of the close price
df['log_return'] = log_return(df['Close'])

# We'll define a function to assign a state (bullish or bearish) based on the log return
def state(x):
if x > 0:
return 'bullish'
else:
return 'bearish'

# We'll apply the state function to the log return column to create a new 'State' column
df['State'] = df['log_return'].apply(state)

# Now, we'll use the 'State' column to create a transition matrix
transition_matrix = pd.crosstab(df['State'], df['State'].shift(1))

# We'll normalize the transition matrix so that the rows sum to 1
transition_matrix = transition_matrix.div(transition_matrix.sum(axis=1), axis=0)

# We'll print the transition matrix
print(transition_matrix)

# Now, we can use the transition matrix to forecast the likelihood of transitioning from one state to another
# For example, we can forecast the likelihood of transitioning from a bearish state to a bullish state
forecast = transition_matrix.loc['bearish', 'bullish']
print(f'Probability of transitioning from bearish to bullish: {forecast:.2f}')

Этот код вычисляет логарифмическую доходность цены акций, назначает состояние (бычье или медвежье) на основе логарифмической доходности и создает матрицу перехода, показывающую вероятность перехода из одного состояния в другое. Затем матрицу переходов можно использовать для прогнозирования вероятности перехода из одного состояния в другое.

C14: уравнение Беллмана и обучение с подкреплением

BУравнение Эллмана — это фундаментальная концепция в динамическом программировании, которая представляет собой метод решения задач оптимизации путем разбиения их на более мелкие, перекрывающиеся подзадачи. Уравнение названо в честь Ричарда Беллмана, который разработал концепцию в 1950-х годах.

Уравнение Беллмана выражает значение решения в данный момент времени (называемое «состоянием») в терминах ожидаемого значения решений, которые могут быть приняты на следующем временном шаге (называемых «состояниями-преемниками»). Другими словами, он определяет оптимальное значение решения в данном состоянии как максимальное ожидаемое значение решений, которые могут быть приняты из этого состояния.

Уравнение Беллмана может быть применено к широкому кругу задач оптимизации, в том числе связанных с ценами на акции. В контексте цен на акции уравнение Беллмана может быть использовано для оптимизации инвестиционных решений путем рассмотрения ожидаемой стоимости различных действий (таких как покупка или продажа конкретной акции) в разные моменты времени.

RПринудительное обучение — это тип машинного обучения, который включает в себя обучение агента (например, компьютерной программы) принятию решений в среде, чтобы максимизировать вознаграждение. Агент учится методом проб и ошибок, корректируя свои действия в зависимости от получаемых вознаграждений. Уравнение Беллмана часто используется в алгоритмах обучения с подкреплением, чтобы оценить ожидаемую ценность различных действий и выбрать то, которое максимизирует вознаграждение.

Одно из ключевых различий между уравнением Беллмана и алгоритмами обучения с подкреплением заключается в том, что первый используется для решения задач оптимизации с учетом ожидаемой ценности решений в разные моменты времени, а второй используется для обучения агента принятию решений в среде, чтобы максимизировать вознаграждение.

Python-код алгоритма обучения с подкреплением для обучения торгового агента и построения торговой стратегии для акций Apple.

Обратите внимание, что вам нужно будет установить необходимые библиотеки, такие как gym и tensorflow, и настроить среду.

!pip install gym tensorflow

import gym
import tensorflow as tf

# Set up the environment
env = gym.make('StockTrading-v0')

Далее необходимо определить модель обучения с подкреплением. Это можно сделать с помощью модели глубокого обучения, такой как сверточная нейронная сеть (CNN) или сеть долговременной кратковременной памяти (LSTM).

# Define the model
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(128, input_shape=(None, env.observation_space.shape[0])))
model.add(tf.keras.layers.Dense(env.action_space.n, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy')

После того, как модель определена, можно приступать к обучению агента с помощью fit() Вам нужно будет определить цикл обучения, который выполняется в течение определенного количества эпох и использует метод step() среды для продвижения состояния и получения награды.

# Train the model
for epoch in range(num_epochs):
state = env.reset()
while True:
action = model.predict(state)
next_state, reward, done, _ = env.step(action)
model.fit(state, reward, epochs=1, verbose=0)
state = next_state
if done:
break

Наконец, вы можете использовать обученную модель для построения торговой стратегии для акций Apple. Это можно сделать, используя метод predict() модели для выбора оптимального действия в каждый момент времени, исходя из текущего состояния рынка.

# Build the trading strategy
state = env.reset()
while True:
action = model.predict(state)
state, reward, done, _ = env.step(action)
if done:
break
import pandas as pd

# Download the data
data = pd.read_csv('https://finance.yahoo.com/quote/AAPL/history?p=AAPL')

# Select the relevant columns
data = data[['Date', 'Close']]

# Convert the date column to datetime
data['Date'] = pd.to_datetime(data['Date'])

# Set the date column as the index
data.set_index('Date', inplace=True)

# Plot the data
data.plot(figsize=(10, 6))

Затем вы можете использовать обученную модель обучения с подкреплением для создания серии торговых сигналов на основе исторических данных о ценах. Это можно сделать, запустив метод predict() модели для данных в каждый момент времени и используя выходные данные, чтобы определить, покупать или продавать акции.

# Generate the trading signals
signals = []
for i in range(len(data)):
state = data.iloc[i].values
action = model.predict(state)
signals.append(action)

# Convert the signals to a Pandas series
signals = pd.Series(signals, index=data.index)

Наконец, вы можете построить торговые сигналы поверх ценового графика с помощью Matplotlib.

import matplotlib.pyplot as plt

# Plot the price chart
plt.figure(figsize=(10, 6))
plt.plot(data)

# Plot the trading signals
plt.scatter(signals.index, data[signals == 1], color='green', marker='^')
plt.scatter(signals.index, data[signals == 2], color='red', marker='v')

Это создаст график, показывающий исторические данные о ценах на акции, с зелеными треугольниками, указывающими сигналы на покупку, и красными треугольниками, указывающими сигналы на продажу.

Как только вы определите наиболее подходящую модель, вы можете применить ее на рынке Lice для принятия торгового решения.

import pandas as pd

# Download the data
data = pd.read_json('https://finance.yahoo.com/quote/AAPL/')

# Select the relevant columns
data = data[['regularMarketPrice']]

# Convert the data to a NumPy array
data = data.values

Затем вы можете использовать обученную модель обучения с подкреплением для генерации торгового сигнала на основе текущих ценовых данных. Это можно сделать, запустив метод predict() модели для данных и используя выходные данные, чтобы определить, покупать или продавать акции.

# Generate the trading signal
signal = model.predict(data)

if signal == 1:
print('Buy')
elif signal == 2:
print('Sell')

C15: обучение с подкреплением на стабильном базовом уровне OpenAI Gym

Startegy для обучения с подкреплением на основе StableBaseline3

OpenAI Gym — это библиотека для разработки и сравнения алгоритмов обучения с подкреплением. Он предоставляет смоделированную среду для обучения агентов выполнению различных задач, таких как игры, управление роботами и торговля акциями.

В контексте биржевой торговли библиотека OpenAI Gym может быть использована для разработки и тестирования торговых стратегий с использованием алгоритмов обучения с подкреплением. Библиотека включает в себя смоделированную торговую среду под названием StockTrading-v0, которая позволяет обучить агента совершать сделки на смоделированном фондовом рынке.

SБиблиотека таблиц Baselines, построенная на основе OpenAI Gym и использующая различные алгоритмы обучения с подкреплением, лучше, чем другие алгоритмы обучения с подкреплением в целом.

Библиотека стабильных базовых показателей является широко используемой и уважаемой библиотекой для обучения с подкреплением, и алгоритмы, которые она предоставляет, показали свою эффективность в широком спектре приложений. Библиотека разработана так, чтобы быть простой в использовании и предоставляет ряд полезных функций, таких как предварительная обработка и нормализация входных данных, поддержка нескольких параллельных сред и возможность использовать TensorFlow в качестве базовой библиотеки машинного обучения.

Пример того, как OpenAI Gym использует модель Qlearning.

import gym
import numpy as np

# Create the trading environment
env = gym.make('StockTrading-v0')

# Set the ticker symbol for the stock we want to trade
ticker = 'AAPL'

# Set the initial balance for the trading account
initial_balance = 10000

# Set the number of shares to buy or sell in each trade
trade_size = 100

# Initialize the trading environment
obs = env.reset(ticker=ticker, initial_balance=initial_balance)

# Set the number of episodes to run the trading strategy
num_episodes = 1000

# Initialize a list to store the rewards for each episode
rewards = []

# Set the learning rate for the Q-learning algorithm
alpha = 0.1

# Set the discount factor for the Q-learning algorithm
gamma = 0.9

# Initialize the Q-table
Q = np.zeros((3, 3))

# Run the trading strategy for the specified number of episodes
for episode in range(num_episodes):
# Initialize the total reward for the episode
total_reward = 0

# Set the initial state for the episode
state = obs['state']

# Run the episode until it is completed
while True:
# Select an action using an epsilon-greedy policy
if np.random.uniform(0, 1) < 0.1:
action = env.action_space.sample()
else:
action = np.argmax(Q[state, :])

# Take the action and observe the new state and reward
obs, reward, done, _ = env.step(action)
new_state = obs['state']

# Update the Q-table using the Q-learning algorithm
Q[state, action] = (1 - alpha) * Q[state, action] + alpha * (reward + gamma * np.max(Q[new_state, :]))

# Update the total reward for the episode
total_reward += reward

# Update the state for the next iteration
state = new_state

# End the episode if it is completed
if done:
break

# Store the total reward for the episode
rewards.append(total_reward)

# Print the final Q-table
print(Q)

Чтобы совершить сделку с помощью Q-таблицы, вы можете просто найти Q-значение для каждого действия в текущем состоянии и выбрать действие с наибольшим Q-значением. Это даст вам действие, которое, как ожидается, приведет к наибольшей награде в соответствии с изученной Q-таблицей.

Важно отметить, что Q-таблица хороша настолько, насколько хороши данные, используемые для ее изучения, поэтому важно использовать разнообразный и репрезентативный набор данных при обучении Q-таблицы.

# Set the current state of the market
current_state = obs['state']

# Look up the Q-values for each action in the current state
q_values = Q[current_state, :]

# Choose the action with the highest Q-value
action = np.argmax(q_values)

# Take the action in the environment
obs, reward, done, _ = env.step(action)

# Check the outcome of the trade
if reward > 0:
print("Made a profitable trade!")
else:
print("Made a losing trade :(")

Пример библиотеки стабильных базовых показателей, построенной на основе OpenAI Gym, для обучения модели проксимальной оптимизации политики (PPO) и построения торговой стратегии для акций Apple.

Во-первых, вам нужно установить необходимые библиотеки, такие как stable-baselines и tensorflow. Библиотека Stable Baselines предоставляет ряд готовых сред для торговли, таких как StockTrading-v0, которые можно использовать из коробки. Библиотека стабильных базовых показателей предоставляет ряд готовых моделей, включая модель PPO, которую можно использовать для обучения агента. Затем модель можно обучить с помощью метода learn() Это запустит цикл обучения на указанное количество шагов и обновит параметры модели в зависимости от вознаграждения, полученного на каждом шаге.

!pip install stable-baselines tensorflow

import stable_baselines
import tensorflow as tf

# Set up the environment
env = stable_baselines.gail.envs.trading_env.StockTradingEnv(mode='train')

# Define the model
model = stable_baselines.PPO2(policy='MlpPolicy', env=env)

# Train the model
model.learn(total_timesteps=num_steps)

# Build the trading strategy
state = env.reset()
while True:
action, _ = model.predict(state)
state, reward, done, _ = env.step(action)
if done:
break

Этот код ищет Q-значения для каждого действия в текущем состоянии рынка и выбирает действие с наибольшим значением Q. Затем он предпринимает действия в среде и проверяет результат сделки.

Настройте среду OpenAI Gym и включите 2 дополнительные переменные функций, такие как Volume и MA50, вот необходимые изменения.

  • Чтобы настроить среду, потребуется создать подкласс класса StockTradingEnv и переопределить метод _observation, который отвечает за определение состояния среды в каждый момент времени.
class CustomStockTradingEnv(stable_baselines.gail.envs.trading_env.StockTradingEnv):
def _observation(self):
# Call the parent method to get the base observation
obs = super()._observation()

# Add the volume and MA50 as additional features
volume = self.df['Volume'].iloc[self.current_step]
ma50 = self.df['MA50'].iloc[self.current_step]
obs = np.concatenate([obs, [volume, ma50]])

return obs

# Set up the environment with the custom subclass
env = CustomStockTradingEnv(mode='train')

# Define the model
model = stable_baselines.PPO2(policy='MlpPolicy', env=env)

# Train the model
model.learn(total_timesteps=num_steps)

# Build the trading strategy
state = env.reset()
while True:
action, _ = model.predict(state)
state, reward, done, _ = env.step(action)
if done:
break
  • Чтобы настроить функцию вознаграждения в модельной среде, включите комиссию за торговлю в размере 0,5% за каждое действие. Во-первых, вам нужно будет установить необходимые библиотеки, такие как stable-baselines и tensorflow, и настроить среду, как и раньше. Чтобы изменить функцию вознаграждения, вам нужно будет создать подкласс класса StockTradingEnv и переопределить метод _get_reward, который отвечает за расчет вознаграждения в каждый момент времени.
import stable_baselines
import tensorflow as tf

# Set up the environment
env = stable_baselines.gail.envs.trading_env.StockTradingEnv(mode='train')

class CustomStockTradingEnv(stable_baselines.gail.envs.trading_env.StockTradingEnv):
def _get_reward(self, action):
# Call the parent method to get the base reward
reward = super()._get_reward(action)

# Add a 0.5% trading fee
reward -= 0.005 * self.portfolio_value

return reward

# Set up the environment with the custom subclass
env = CustomStockTradingEnv(mode='train')

# Define the model
model = stable_baselines.PPO2(policy='MlpPolicy', env=env)

# Train the model
model.learn(total_timesteps=num_steps)

# Build the trading strategy
state = env.reset()
while True:
action, _ = model.predict(state)
state, reward, done, _ = env.step(action)
if done:
break

C16: Применение обучения с подкреплением к стратегии парной торговли

В этой лекции мы хотели бы поэкспериментировать, можно ли применить автоматическую программу обучения с подкреплением к сценариям парной торговли.

Давайте разберемся, как можно использовать алгоритм обучения с подкреплением для построения торговой стратегии для парной торговли акциями Apple и Google.

Во-первых, вам нужно будет получить данные о ценах на обе акции в режиме реального времени. Для загрузки данных можно использовать API финансовых данных, например Yahoo Finance или Alpha Vantage.

import pandas as pd

# Download the data
data_apple = pd.read_json('https://finance.yahoo.com/quote/AAPL/')
data_google = pd.read_json('https://finance.yahoo.com/quote/GOOGL/')

# Select the relevant columns
data_apple = data_apple[['regularMarketPrice']]
data_google = data_google[['regularMarketPrice']]

# Convert the data to a NumPy array
data_apple = data_apple.values
data_google = data_google.values

import tensorflow as tf

# Define the model
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(128, input_shape=(None, 2)))
model.add(tf.keras.layers.Dense(3, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy')

# Train the model
for epoch in range(num_epochs):
# Loop over the data
for i in range(len(data_apple)):
# Get the current state
state = np.stack([data_apple[i], data_google[i]])

# Choose the action
action = model.predict(state)

# Calculate the reward
reward = 0
if action == 0: # Sell Apple, buy Google
reward = data_google[i] - data_apple[i]
elif action == 1: # Hold
pass
elif action == 2: # Sell Google, buy Apple
reward = data_apple[i] - data_google[i]

# Calculate the next state
next_state = np.stack([data_apple[i+1], data_google[i+1]])

# Store the experience in the replay buffer
replay_buffer.append((state, action, reward, next_state))

# Sample a batch of experiences from the replay buffer
states, actions, rewards, next_states = replay_buffer.sample(batch_size)

# Train the model on the batch
model.train_on_batch(states, actions, rewards, next_states)

Чтобы соответствовать модели и делать прогнозы на реальном рынке, вам нужно будет обновить цикл обучения, чтобы использовать данные о ценах в реальном времени вместо исторических данных, которые вы использовали для обучения.

import requests

# Define the API endpoint
endpoint = 'https://finance.yahoo.com/quote/{}/'

# Get the current prices
response_apple = requests.get(endpoint.format('AAPL'))
response_google = requests.get(endpoint.format('GOOGL'))

# Extract the prices from the responses
price_apple = response_apple.json()['regularMarketPrice']
price_google = response_google.json()['regularMarketPrice']

# Get the current state
state = np.stack([price_apple, price_google])

# Make a prediction using the trained model
action = model.predict(state)

# Act on the prediction
if action == 0: # Sell Apple, buy Google
pass
elif action == 1: # Hold
pass
elif action == 2: # Sell Google, buy Apple
pass

Затем вы можете повторять этот процесс через регулярные промежутки времени, чтобы обновлять состояние и делать новые прогнозы по мере изменения цен на реальном рынке.

C17: вейвлет-декомпозированная модель LSTM и TCN

как вы можете построить модель Python для прогнозирования будущих цен на акции Apple, используя вейвлет-преобразование и применяя алгоритм LSTM:

Шаги, которые необходимо выполнить:

  1. Собирает данные о ценах на акции Apple с помощью библиотеки yfinance.
  2. Предварительно обработает данные, удалив отсутствующие значения и нормализовав их.
  3. Декомпозирует данные с помощью вейвлет-преобразования.
  4. Сглаживает данные с помощью скользящей средней.
  5. Строит модель LSTM с использованием библиотеки keras.
  6. Разбивает данные на обучающий и тестовый наборы.
  7. Изменяет форму данных для ввода в модель LSTM.
  8. Обучает модель LSTM.
  9. Делает прогнозы на тестовом наборе.
  10. Оценивает модель, используя среднюю абсолютную погрешность.
import yfinance as yf
import numpy as np
import pandas as pd

from pywt import dwt
from sklearn.preprocessing import MinMaxScaler
from keras.layers import LSTM, Dense
from keras.models import Sequential
from sklearn.metrics import mean_absolute_error

# Collect Apple stock price data
apple = yf.Ticker("AAPL")
data = apple.history(period="max")

# Preprocess the data
data.dropna(inplace=True)
data = data[['Close']]
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data)

# Decompose the data using wavelet transformation
coeffs = dwt(data, 'db4')
cA, cD = coeffs

# Smooth the data using moving average
window_size = 10
cA_smooth = np.zeros_like(cA)
for i in range(window_size, len(cA)):
cA_smooth[i] = np.mean(cA[i-window_size:i])

# Build the LSTM model
model = Sequential()
model.add(LSTM(50, input_shape=(1, 1)))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')

# Split the data into train and test sets
train_size = int(len(cA_smooth) * 0.8)
train, test = cA_smooth[:train_size], cA_smooth[train_size:]

# Reshape the data for input into the LSTM model
train = train.reshape(train.shape[0], 1, 1)
test = test.reshape(test.shape[0], 1, 1)

# Train the LSTM model
model.fit(train, train, epochs=50, batch_size=1, verbose=2)

# Make predictions on the test set
predictions = model.predict(test)

# Evaluate the model using mean absolute error
mae = mean_absolute_error(test, predictions)
print("Mean Absolute Error:", mae)

как вы можете построить модель Python для прогнозирования будущих цен на акции Apple, используя вейвлет-преобразование и применяя алгоритм TCN:

TCN (временная сверточная сеть) — это тип модели глубокого обучения, специально разработанный для моделирования последовательностей данных. Он состоит из ряда сверточных слоев с расширенными свертками, что позволяет модели фиксировать дальнодействующие зависимости в данных.

Шаги, которые необходимо выполнить:

  1. Собирает данные о ценах на акции Apple с помощью библиотеки yfinance.
  2. Предварительно обработает данные, удалив отсутствующие значения и нормализовав их.
  3. Декомпозирует данные с помощью вейвлет-преобразования.
  4. Строит модель TCN с использованием библиотеки keras.
  5. Разбивает данные на обучающий и тестовый наборы.
  6. Изменяет форму данных для ввода в модель TCN.
  7. Обучает модель TCN на вейвлет-разложенных данных
  8. Делает прогнозы на тестовом наборе.
  9. Оценивает модель, используя среднюю абсолютную погрешность.
import yfinance as yf
import numpy as np
import pandas as pd

from pywt import dwt
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Conv1D, Dense, Dropout
from keras.models import Sequential
from sklearn.metrics import mean_absolute_error

# Collect Apple stock price data
apple = yf.Ticker("AAPL")
data = apple.history(period="max")

# Preprocess the data
data.dropna(inplace=True)
data = data[['Close']]
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data)

# Decompose the data using wavelet transformation
coeffs = dwt(data, 'db4')
cA, cD = coeffs

# Build the TCN model
model = Sequential()
model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(None, 1)))
model.add(Dropout(0.5))
model.add(Conv1D(filters=64, kernel_size=2, activation='relu', dilation_rate=2))
model.add(Dropout(0.5))
model.add(Conv1D(filters=64, kernel_size=2, activation='relu', dilation_rate=4))
model.add(Dropout(0.5))
model.add(Conv1D(filters=64, kernel_size=2, activation='relu', dilation_rate=8))
model.add(Dropout(0.5))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')

# Split the data into train and test sets
train_size = int(len(cA) * 0.8)
train, test = cA[:train_size], cA[train_size:]

# Reshape the data for input into the TCN model
train = train.reshape(train.shape[0], train.shape[1], 1)
test = test.reshape(test.shape[0], test.shape[1], 1)

# Train the TCN model
model.fit(train, train, epochs=50, batch_size=1, verbose=2)

# Make predictions on the test set
predictions = model.predict(test)

# Evaluate the model using mean absolute error
mae = mean_absolute_error(test, predictions)
print("Mean Absolute Error:", mae)

C18: Торговая стратегия на основе временного термоядерного трансформатора (TFT)

Tэмпиральный термоядерный трансформатор (TFT) — это тип модели глубокого обучения, предназначенный для моделирования длинных последовательностей данных. Это вариант архитектуры трансформатора, который представляет собой тип нейронной сети, которая использует механизмы самовнимания для обработки последовательностей данных.

Модель TFT имеет несколько ключевых особенностей, которые делают ее хорошо подходящей для моделирования длинных последовательностей данных:

  1. Многомасштабная обработка: TFT-модель использует несколько уровней самовнимания для обработки входных данных в разных масштабах, что позволяет ей фиксировать как краткосрочные, так и долгосрочные зависимости в данных.
  2. Механизм слияния: Модель TFT использует механизм слияния для объединения выходов с разных уровней самовнимания, что позволяет ей эффективно интегрировать информацию из разных масштабов.
  3. Временное кодирование: Модель TFT использует схему временного кодирования для представления входных данных, что позволяет эффективно моделировать длинные последовательности данных.

В целом, TFT-модель является мощным и гибким инструментом для моделирования длинных последовательностей данных, и было показано, что она позволяет достигать самых современных результатов по широкому кругу задач, включая обработку естественного языка, машинный перевод и прогнозирование временных рядов.

Приложение к биржевым данным: В одном исследовании, опубликованном в 2021 году, использовалась модель TFT для прогнозирования цен на акции большого количества компаний, котирующихся на фондовой бирже NASDAQ. Авторы обнаружили, что модель TFT смогла превзойти несколько базовых моделей, включая модель длинной кратковременной памяти (LSTM) и модель сверточной нейронной сети (CNN), в этой задаче.

В другом исследовании, опубликованном в 2020 году, использовалась модель TFT для прогнозирования цен на акции для одной компании, и было обнаружено, что модель смогла превзойти модель LSTM в этой задаче.

В целом, эти исследования показывают, что модель TFT может быть эффективным инструментом для прогнозирования цен на акции.

Шаги по написанию примера Python:

  1. Собирает данные о ценах на акции Apple с помощью библиотеки yfinance.
  2. Предварительно обработает данные, удалив отсутствующие значения и нормализовав их.
  3. Токенизирует данные с помощью TFTokenizer из библиотеки transformers.
  4. Строит TFT-модель с помощью TFFusionModel из библиотеки transformers.
  5. Разбивает данные на обучающий и тестовый наборы.
  6. Обучает TFT-модель.
  7. Делает прогнозы на тестовом наборе.
  8. Оценивает модель, используя среднюю абсолютную погрешность.
import yfinance as yf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from transformers import TFTokenizer, TFFusionModel
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_error

# Collect Apple stock price data
apple = yf.Ticker("AAPL")
data = apple.history(period="max")

# Preprocess the data
data.dropna(inplace=True)
data = data[['Close']]
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data)

# Tokenize the data using the TFTokenizer
tokenizer = TFTokenizer.from_pretrained('t5-small')
input_ids = tokenizer.encode(data.tolist(), max_length=1024)
input_ids = np.expand_dims(input_ids, axis=0)

# Build the TFT model
model = TFFusionModel.from_pretrained('t5-small')

# Split the data into train and test sets
train_size = int(len(input_ids) * 0.8)
train, test = input_ids[:train_size], input_ids[train_size:]

# Train the TFT model
model.train_model(train)

# Make predictions on the test set
predictions = model.predict(test)

# Inverse transform the predictions and the test data
predictions = scaler.inverse_transform(predictions[0])
test = scaler.inverse_transform(test[0])

# Plot the predictions and the test data
plt.plot(predictions, label='Predictions')
plt.plot(test, label='Test data')
plt.legend()
plt.show()

# Generate a trading signal based on the predictions
signal = np.zeros(len(predictions))
for i in range(1, len(predictions)):
if predictions[i] > test[i-1]:
signal[i] = 1
else:
signal[i] = -1

# Plot the trading signal
plt.plot(signal, label='Trading signal')
plt.legend()
plt.show()

C19: Q Spectrum и торговой стратегии LSTM

Q-спектр — это мера распределения дисперсии по разным частотам во временном ряду. Он часто используется для анализа спектральных характеристик временного ряда, таких как его периодические компоненты и общая спектральная форма.

Q-спектр может быть оценен с использованием различных методов, таких как периодограмма, автоковариационная функция и метод максимальной энтропии. После того, как Q-спектр был оценен, его можно построить как функцию частоты, чтобы визуализировать распределение дисперсии по разным частотам во временном ряду.

Q-спектр часто используется в сочетании с другими методами спектрального анализа, такими как периодограмма и автокорреляционная функция, чтобы лучше понять основную структуру временного ряда. Это может быть особенно полезно для выявления периодических компонентов и тенденций в данных, а также для обнаружения нестационарности и изменений в спектральной форме временных рядов с течением времени.

Q-спектр можно использовать для анализа спектральных характеристик временных рядов цен на акции, таких как их периодические компоненты и общая спектральная форма.

Шаги для эксперимента с ценой акций

  1. При необходимости выполните предварительную обработку данных. Это может включать удаление отсутствующих значений, нормализацию данных и/или фильтрацию любых нежелательных компонентов (например, использование фильтра нижних частот для удаления высокочастотного шума).
  2. Оцените Q-спектр данных о ценах на акции, используя один из методов, упомянутых ранее, таких как периодограмма, автоковариационная функция или метод максимальной энтропии.
  3. Постройте Q-спектр в зависимости от частоты, чтобы визуализировать распределение дисперсии по разным частотам во временном ряду.
  4. Используйте Q-спектр для анализа спектральных характеристик данных о ценах на акции, таких как определение периодических компонентов и тенденций, обнаружение нестационарности и выявление изменений спектральной формы данных с течением времени.

Код Python для генерации торгового сигнала

import yfinance as yf
from scipy.signal import periodogram
import matplotlib.pyplot as plt

# Collect Apple stock price data
apple = yf.Ticker("AAPL")
data = apple.history(period="max")

# Preprocess the data
data.dropna(inplace=True)
data = data['Close']

# Estimate the Q-spectrum of the stock price data using the periodogram
f, Pxx_den = periodogram(data, fs=1)

# Plot the Q-spectrum
plt.plot(f, Pxx_den)
plt.xlabel('Frequency [Hz]')
plt.ylabel('Power Spectral Density [V**2/Hz]')
plt.show()

# Analyze the Q-spectrum to identify patterns and trends
if Pxx_den[1] > Pxx_den[0]:
# The Q-spectrum indicates that the stock price is likely to increase
signal = 1
else:
# The Q-spectrum indicates that the stock price is likely to decrease
signal = -1

# Generate a trading signal based on the analysis of the Q-spectrum
if signal == 1:
print("BUY")
else:
print("SELL")

# Plot the Q-spectrum
plt.plot(f, Pxx_den)

Оцените Q-спектр данных о цене акций с помощью функции periodogram из библиотеки scipy.signal Вы также можете искать тенденции в Q-спектре, которые предполагают, что цена акций, вероятно, продолжит двигаться в определенном направлении. Затем вы можете использовать эту информацию для генерации торгового сигнала, покупая или продавая акции на основе анализа Q-спектра. Например, вы можете купить акции, если Q-спектр указывает, что цена акций, вероятно, вырастет, и продать акции, если Q-спектр указывает, что цена акции, вероятно, снизится.

Давайте поэкспериментируем с периодограммой Q-спектра цены акций Apple в качестве входных данных для модели LSTM и вычислим погрешность, оценив прогнозы модели по сравнению с фактической ценой закрытия акции:

import pandas as pd
import numpy as np

# Load the stock price data
df = pd.read_csv('stock_prices.csv')

# Convert the date column to a datetime object and set it as the index
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')

# Calculate the Q-spectrum periodogram of the close price data
from scipy.signal import qspectra

fs = 1 # sampling frequency
f, Pxx_den = qspectra(df['close'], fs)

# Select the Q-spectrum periodogram as the input variable
X = Pxx_den.reshape(-1, 1)

# Select the 'close' column as the target variable
y = df['close']

# Split the data into a training set and a test set
train_size = int(len(y) * 0.8)
test_size = len(y) - train_size
train_X, test_X, train_y, test_y = X[0:train_size], X[train_size:len(y)], y[0:train_size], y[train_size:len(y)]

# Scale the data using MinMaxScaler
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(-1, 1))
train_X = scaler.fit_transform(train_X)
test_X = scaler.transform(test_X)

# Build the LSTM model
from keras.models import Sequential
from keras.layers import Dense, LSTM

model = Sequential()
model.add(LSTM(32, input_shape=(1, 1)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')

# Train the model
model.fit(train_X, train_y, epochs=10, batch_size=1, verbose=2)

# Make predictions on the test set
predictions = model.predict(test_X)

# Invert the predictions and the test set back to their original scale
predictions = scaler.inverse_transform(predictions)
test_y = scaler.inverse_transform(test_y.values.reshape(-1, 1))

# Calculate the root mean squared error (RMSE)
from sklearn.metrics import mean_squared_error

rmse = np.sqrt(mean_squared_error(test_y, predictions))
print('RMSE:', rmse)

Этот код сначала вычисляет периодограмму Q-спектра данных о цене закрытия с помощью функции qspectra из модуля scipy.signal Затем он использует периодограмму Q-спектра в качестве входной переменной (X) и цену закрытия в качестве целевой переменной (y). Затем данные разбиваются на обучающий набор и тестовый набор, а также входные данные

C20: переход планеты Луна и регрессор XGBoost для прогнозирования воздействия

Существует давнее убеждение, что фазы Луны могут влиять на поведение и психологию человека. Некоторые люди считают, что Луна оказывает сильное влияние на эмоции и поведение человека, и что определенные фазы Луны могут быть связаны с определенными психологическими эффектами.

Тем не менее, существует мало научных доказательств, подтверждающих эти убеждения. Большинство исследований, в которых изучалась взаимосвязь между фазами Луны и поведением человека, не обнаружили существенных корреляций.

Давайте построим простую торговую стратегию, рассматривающую переход Муна и регистрацию почасовой позиции от наблюдателя, находящегося на Нью-Йоркской фондовой бирже, с учетом географического положения Нью-Йорка, а затем построим взаимосвязь между углом перемещения Муна и изменением цены акций Apple.

import matplotlib.pyplot as plt
import ephem
import pandas as pd

# Create an Observer object for the New York Stock Exchange (NYSE) in New York, USA
observer = ephem.Observer()
observer.lat = '40.706495' # latitude of the NYSE (in degrees)
observer.lon = '-74.009322' # longitude of the NYSE (in degrees)
observer.elevation = 6 # elevation of the NYSE (in meters)

# Create a Moon object
moon = ephem.Moon()

# Set the starting date and time for the time series
start_date = '2022-01-01'
start_time = '00:00:00'

# Set the ending date and time for the time series
end_date = '2022-01-02'
end_time = '00:00:00'

# Set the time interval (in hours) for the time series
interval = 1 # hourly intervals

# Create an empty dataframe to store the time series data
moon_df = pd.DataFrame(columns=['date', 'azimuth', 'altitude'])

# Loop through the time series and calculate the Moon's position at each interval
date = start_date + ' ' + start_time
while date < end_date + ' ' + end_time:
observer.date = date
moon.compute(observer)
moon_df = moon_df.append({'date': date, 'azimuth': moon.az, 'altitude': moon.alt}, ignore_index=True)
date = ephem.Date(date) + interval * ephem.hour

# Display the time series data
#print(moon_df)

# Load the time series data for the stock price for the same time range
stock_df = pd.read_csv('stock_data.csv')

# Convert the date columns to datetime objects and set them as the index
moon_df['date'] = pd.to_datetime(moon_df['date'])
moon_df = moon_df.set_index('date')
stock_df['date'] = pd.to_datetime(stock_df['date'])
stock_df = stock_df.set_index('date')

# Create a figure and subplots
fig, ax1 = plt.subplots()

# Plot the time series data for the Moon's position
ax1.plot(moon_df['altitude'], color='b', label='Moon Altitude')
ax1.plot(moon_df['azimuth'], color='r', label='Moon Azimuth')
ax1.set_xlabel('Date')
ax1.set_ylabel('Angle (degrees)')
ax1.legend()

# Plot the time series data for the stock price
ax2 = ax1.twinx()
ax2.plot(stock_df['close'], color='g', label='Stock Price')
ax2.set_ylabel('Price (USD)')
ax2.legend()

# Show the plot
plt.show()

Этот код использует широту, долготу и высоту NYSE в качестве местоположения наблюдателя. Затем он вычисляет положение Луны на небе с часовыми интервалами между указанными датами начала и окончания и сохраняет рассчитанные положения в кадре данных.

Теперь давайте разработаем статистическую модель, используя регрессор XGboost для прогнозирования цены акций Apple с учетом будущего перехода Муна.

import xgboost as xgb
import pandas as pd

# Load the time series data for the Moon's position and the stock price
moon_df = pd.read_csv('moon_data.csv')
stock_df = pd.read_csv('stock_data.csv')

# Merge the dataframes on the date column
df = pd.merge(moon_df, stock_df, on='date')

# Set the date column as the index
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')

# Split the data into training and testing sets
train = df.iloc[:int(0.8*len(df))]
test = df.iloc[int(0.8*len(df)):]

# Define the features and target variables for the model
X_train = train[['altitude', 'azimuth']]
y_train = train['close']
X_test = test[['altitude', 'azimuth']]
y_test = test['close']

# Convert the data to DMatrix format for XGBoost
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

# Define the XGBoost regressor model
model = xgb.XGBRegressor(objective='reg:squarederror')

# Fit the model to the training data
model.fit(X_train, y_train)

# Make predictions on the testing data
predictions = model.predict(X_test)

# Calculate the error metric
error = mean_squared_error(y_test, predictions)
print(f'Mean squared error: {error}')

# Plot the predicted and actual values
plt.plot(predictions, label='Predicted')
plt.plot(y_test.values, label='Actual')
plt.legend()
plt.show()

В этом примере мы определили характеристики (высоту и азимут Луны) и целевую переменную (цену акций) для модели, преобразовали данные в формат DMatrix для XGBoost и определили регрессорную модель XGBoost. Затем модель подгоняется под обучающие данные, и на основе тестовых данных делаются прогнозы. Наконец, вычисляется метрика ошибки (средняя квадратичная ошибка), и прогнозируемые и фактические значения наносятся на один и тот же график.

C21: Применение ценообразования Блэка-Шоулза для выявления арбитража в цепочке опционов

Арбитражные возможности в цепочках опционов могут возникнуть, когда существует неправильная оценка между колл-опционами и пут-опционами на один и тот же базовый актив. Эти возможности можно выявить, проанализировав цепочку опционов и сравнив цены колл-опционов с ценами пут-опционов с той же датой экспирации и ценой исполнения.

TМодель Блэка-Шоулза основана на предположении об эффективных рынках и предоставляет формулу для определения теоретической стоимости опциона на основе определенных предположений о цене базового актива, волатильности, времени до истечения срока действия и безрисковой процентной ставке.

Формула Блэка-Шоулза для оценки колл-опциона:C — цена колл-опциона

C = S * N(d1) — X * e^(-rT) * N(d2)

  • S — цена базового актива
  • X — цена исполнения
  • r — безрисковая процентная ставка
  • T — время до истечения срока действия
  • N(d1) и N(d2) являются кумулятивными стандартными функциями нормального распределения

Формула Блэка-Шоулза для оценки опциона пут:

P = X * e^(-rT) * N(-d2) — S * N(-d1)

где:

  • P — цена опциона пут
  • S — цена базового актива
  • X — цена исполнения
  • r — безрисковая процентная ставка
  • T — время до истечения срока действия
  • N(-d1) и N(-d2) являются кумулятивными стандартными функциями нормального распределения

Чтобы использовать модель Блэка-Шоулза для расчета подходящей цены опциона, необходимо ввести соответствующие значения для S, X, r и T, а затем использовать приведенные выше формулы для расчета теоретической стоимости опциона. Затем вы можете сравнить это теоретическое значение с фактической ценой опциона, чтобы определить, существует ли спред между двумя ценами, что может указывать на наличие возможности арбитража.

Обратите внимание, что модель Блэка-Шоулза является теоретической моделью и не всегда может точно отражать фактические цены опционов на рынке.

import pandas as pd
import math

# Load option data into a pandas DataFrame
option_data = pd.read_csv('options.csv')

# Select the options with the same expiration date
expiration_date = '2022-12-31'
options = option_data[option_data['Expiration'] == expiration_date]

# Define the Black-Scholes formula for valuing a call option
def black_scholes_call(S, X, r, T):
d1 = (math.log(S / X) + (r + 0.5 * (S ** 2)) * T) / (S * math.sqrt(T))
d2 = d1 - S * math.sqrt(T)
return S * math.norm.cdf(d1) - X * math.exp(-r * T) * math.norm.cdf(d2)

# Define the Black-Scholes formula for valuing a put option
def black_scholes_put(S, X, r, T):
d1 = (math.log(S / X) + (r + 0.5 * (S ** 2)) * T) / (S * math.sqrt(T))
d2 = d1 - S * math.sqrt(T)
return X * math.exp(-r * T) * math.norm.cdf(-d2) - S * math.norm.cdf(-d1)

# Set the threshold for the spread between the fitted price and the actual price
threshold = 0.50

# Iterate over the call and put options in the option chain
for option_type in ['Call', 'Put']:
for index, row in options[options['Type'] == option_type].iterrows():
# Calculate the fitted price using the Black-Scholes model
if option_type == 'Call':
fitted_price = black_scholes_call(row['Underlying Price'], row['Strike'], row['Risk-Free Interest Rate'], row['Time to Expiration'])
else:
fitted_price = black_scholes_put(row['Underlying Price'], row['Strike'], row['Risk-Free Interest Rate'], row['Time to Expiration'])

# Calculate the spread between the fitted price and the actual price
spread = fitted_price - row['Price']

# If the spread is above the threshold, take an action
if spread > threshold:
print(f'Spread of ${spread:.2f} found for {option_type} option with strike price {row["Strike"]}')

Совершите действие, исходя из порогового значения и величины спреда.

Отказ от ответственности: Содержание здесь предназначено только для образовательных целей. Я не поддерживаю и не рекомендую какой-либо конкретный инвестиционный или финансовый продукт, а также не делаю никаких заявлений. Читатель несет ответственность за проведение собственных исследований и должной осмотрительности, а также за консультации с квалифицированным финансовым консультантом, прежде чем принимать какие-либо инвестиционные или торговые решения.

Источник