Explorar el Código

kappa实现的第一版。

skyffire hace 1 año
padre
commit
4e0a961e4c
Se han modificado 5 ficheros con 120 adiciones y 60 borrados
  1. 48 0
      as_study/03_04.py
  2. 27 0
      as_study/St_S0.py
  3. 40 58
      kappa/data_processing.py
  4. 1 1
      kappa/logger_config.py
  5. 4 1
      kappa/ws_client.py

+ 48 - 0
as_study/03_04.py

@@ -0,0 +1,48 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+# 设置参数
+T = 1.0      # 终止时间
+N = 1000     # 时间步数
+dt = T / N   # 每一步的时间间隔
+sigma = 0.2  # 波动率
+S0 = 100     # 初始价格
+A = 1.0      # 基准强度
+k = 0.5      # 衰减系数
+delta = 1.0  # 价格距离
+
+# 生成布朗运动路径
+t = np.linspace(0, T, N+1)  # 时间点
+W = np.random.randn(N)      # 生成N个标准正态分布的随机数
+W = np.insert(W, 0, 0)      # 将初始值0插入到W的开头
+W = np.cumsum(W) * np.sqrt(dt)  # 计算布朗运动的累加和并乘以sqrt(dt)
+
+# 计算参考价格路径
+S = S0 + sigma * W
+
+# 计算捕获流强度
+Lambda_plus = A * np.exp(-k * delta + k * (S - S[0]))
+Lambda_minus = A * np.exp(-k * delta - k * (S - S[0]))
+
+# 绘制参考价格和捕获流强度
+fig, ax1 = plt.subplots(figsize=(10, 6))
+
+# 绘制参考价格
+ax1.set_xlabel('Time')
+ax1.set_ylabel('Reference Price', color='tab:blue')
+ax1.plot(t, S, label='Reference Price', color='tab:blue')
+ax1.tick_params(axis='y', labelcolor='tab:blue')
+
+# 创建第二个y轴
+ax2 = ax1.twinx()
+ax2.set_ylabel('Intensity', color='tab:red')
+ax2.plot(t, Lambda_plus, label=r'$\Lambda^+(\delta, t, t + \Delta T)$', color='tab:red')
+ax2.plot(t, Lambda_minus, label=r'$\Lambda^-(\delta, t, t + \Delta T)$', color='tab:green')
+ax2.tick_params(axis='y', labelcolor='tab:red')
+
+# 设置图例
+fig.tight_layout()
+plt.title('Reference Price and Captured Flow Intensities')
+fig.legend(loc='upper left', bbox_to_anchor=(0.1,0.9))
+plt.grid(True)
+plt.show()

+ 27 - 0
as_study/St_S0.py

@@ -0,0 +1,27 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+# 设置参数
+T = 1.0      # 终止时间
+N = 1000     # 时间步数
+dt = T / N   # 每一步的时间间隔
+sigma = 0.2  # 波动率
+S0 = 100     # 初始价格
+
+# 生成布朗运动路径
+t = np.linspace(0, T, N+1)  # 时间点
+W = np.random.randn(N)      # 生成N个标准正态分布的随机数
+W = np.insert(W, 0, 0)      # 将初始值0插入到W的开头
+W = np.cumsum(W) * np.sqrt(dt)  # 计算布朗运动的累加和并乘以sqrt(dt)
+
+# 计算参考价格路径
+S = S0 + sigma * W
+
+# 绘制参考价格变化
+plt.figure(figsize=(10, 6))
+plt.plot(t, S)
+plt.title('Reference Price Path')
+plt.xlabel('Time')
+plt.ylabel('Price')
+plt.grid(True)
+plt.show()

+ 40 - 58
kappa/data_processing.py

@@ -1,11 +1,11 @@
 import json
-import scipy.stats as stats
-import numpy as np
 import pandas as pd
 import queue
 import threading
 from collections import deque
+from scipy.optimize import minimize
 from logger_config import logger
+import numpy as np
 
 # 假设我们有一个数据流,订单簿和成交数据
 order_book_snapshots = deque(maxlen=1000)  # 存储过去10000个订单簿快照
@@ -16,12 +16,20 @@ messages = queue.Queue()  # 创建一个线程安全队列
 
 stop_event = threading.Event()
 
+# 初始参数
+k_initial = 0.5
+A_initial = 1.0
+
+# 假设S0是初始的参考价格
+S0 = -1
+sigma = 0.2  # 假设一个波动率
+
 
 def on_message_depth(_ws, message):
     global order_book_snapshots
     json_message = json.loads(message)
-    bids = json_message['data']['b'][:10]  # Top 10 bids
-    asks = json_message['data']['a'][:10]  # Top 10 asks
+    bids = [[float(price), float(quantity)] for price, quantity in json_message['data']['b'][:10]]
+    asks = [[float(price), float(quantity)] for price, quantity in json_message['data']['a'][:10]]
     timestamp = pd.to_datetime(json_message['data']['E'], unit='ms')
     order_book_snapshots.append({
         'bids': bids,
@@ -33,58 +41,32 @@ def on_message_depth(_ws, message):
         process_depth_data(order_book_snapshots)
 
 
+def phi(k, S, S0):
+    return np.exp(k * (S - S0))
+
+
+def target_function(params, S_values):
+    A, k = params
+    r = 0
+    for S in S_values:
+        term1 = np.log(phi(k, S, S0))
+        r += (term1 - np.log(A)) ** 2
+    return r
+
+
 def process_depth_data(order_book_snapshots):
-    # 提取订单大小数据
-    order_sizes = []
-    for snapshot in order_book_snapshots:
-        for bid in snapshot['bids']:
-            order_sizes.append(float(bid[1]))
-        for ask in snapshot['asks']:
-            order_sizes.append(float(ask[1]))
-
-    if len(order_sizes) < 2:  # 确保有足够的数据进行计算
-        logger.warning("Not enough data to calculate kappa.")
-        return
-
-    # 使用 MLE 估计幂律指数 β
-    Q_min = np.min(order_sizes)
-    n = len(order_sizes)
-    try:
-        beta_hat = 1 + n / np.sum(np.log(order_sizes / Q_min))
-    except ZeroDivisionError:
-        logger.error("ZeroDivisionError encountered in MLE calculation.")
-        return
-
-    # 使用最小二乘法拟合幂律分布
-    log_order_sizes = np.log(order_sizes)
-    hist, bin_edges = np.histogram(log_order_sizes, bins=50, density=True)
-    bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2
-
-    # 过滤掉频率为零的bin
-    non_zero_indices = hist > 0
-    hist = hist[non_zero_indices]
-    bin_centers = bin_centers[non_zero_indices]
-
-    if len(hist) == 0 or len(bin_centers) == 0:
-        logger.warning("No non-zero bins available for linear regression.")
-        return
-
-    try:
-        slope, intercept, r_value, p_value, std_err = stats.linregress(bin_centers, np.log(hist))
-        beta_lsm = -slope
-    except ValueError as e:
-        logger.error(f"ValueError encountered in linear regression: {e}")
-        return
-
-    # 计算kappa值
-    gamma = 0.1  # 库存风险厌恶参数
-    sigma = 0.02  # 市场波动率
-    T_minus_t = 1  # 交易会话的剩余时间
-
-    # 结合不同方法估算的β值,计算kappa
-    kappa_mle = (2 / (gamma * sigma ** 2 * T_minus_t)) * np.log(1 + (gamma / beta_hat))
-    kappa_lsm = (2 / (gamma * sigma ** 2 * T_minus_t)) * np.log(1 + (gamma / beta_lsm))
-
-    # 输出结果
-    logger.info(f"Estimated beta_hat (MLE): {beta_hat}, kappa (MLE): {kappa_mle}")
-    logger.info(f"Estimated beta_lsm (LSM): {beta_lsm}, kappa (LSM): {kappa_lsm}")
+    global k_initial, A_initial, S0
+    S_values = [((snapshot['bids'][0][0] + snapshot['asks'][0][0]) / 2) for snapshot in order_book_snapshots]  # 使用买价计算
+
+    if S0 == 0:
+        S0 = S_values[0]
+
+    # 使用优化算法最小化目标函数,找到最优的A和k
+    params = np.array([A_initial, k_initial])
+    result = minimize(target_function, params, args=(S_values,))
+    A_opt, k_opt = result.x
+    logger.info("最优参数 A:" + str(A_opt) + " k:" + str(k_opt))
+
+    # 更新初始参数
+    A_initial = A_opt
+    k_initial = k_opt

+ 1 - 1
kappa/logger_config.py

@@ -4,7 +4,7 @@ import colorlog
 # 配置日志
 handler = colorlog.StreamHandler()
 handler.setFormatter(colorlog.ColoredFormatter(
-    fmt="%(log_color)s%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d \n %(message)s",
+    fmt="%(log_color)s%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d %(message)s",
     datefmt=None,
     reset=True,
     log_colors={

+ 4 - 1
kappa/ws_client.py

@@ -1,3 +1,5 @@
+import traceback
+
 import websocket
 import threading
 
@@ -10,7 +12,8 @@ SOCKET_DEPTH = "wss://fstream.binance.com/stream?streams=" + SYMBOL + "@depth20@
 
 
 def on_error(_ws, error):
-    logger.error(error)
+    traceback.print_exc()       # 打印完整的错误堆栈信息
+    # raise error                 # 重新抛出错误
 
 
 def on_open(_ws):