美股市场是全球最大、流动性最强的金融市场之一,涵盖了科技、金融、医疗等多个行业的优质公司。对于量化交易者来说,美股行情数据是构建策略的基础。无论是高频交易、均值回归策略,还是基于机器学习的预测模型,都离不开准确、及时的行情数据。

然而,获取高质量的美股数据并不容易。许多数据源要么价格昂贵,要么接口复杂,难以满足量化交易的需求。因此,找到一个性价比高且易于使用的接口显得尤为重要。

接口的基本调用功能

最近使用的这款实时行情接口提供了丰富的功能,包括实时行情、历史K线、深度数据等。以下是一些基本调用功能的示例代码:

1. 获取实时行情

import json
import time
import schedule
import threading
import websocket
from loguru import logger

class WebsocketExample:
    def __init__(self):
        self.session = None
        self.ws_url = "wss://data.infoway.io/wsbusiness=crypto&apikey=yourApikey"
        self.reconnecting = False

    def connect_all(self):
        """建立WebSocket连接并启动自动重连机制"""
        try:
            self.connect(self.ws_url)
            self.start_reconnection(self.ws_url)
        except Exception as e:
            logger.error(f"Failed to connect to {self.ws_url}: {str(e)}")

    def start_reconnection(self, url):
        """启动定时重连检查"""
        def check_connection():
            if not self.is_connected():
                logger.debug("Reconnection attempt...")
                self.connect(url)
        
        # 使用线程定期检查连接状态
        threading.Thread(target=lambda: schedule.every(10).seconds.do(check_connection), daemon=True).start()

    def is_connected(self):
        """检查WebSocket连接状态"""
        return self.session and self.session.connected

    def connect(self, url):
        """建立WebSocket连接"""
        try:
            if self.is_connected():
                self.session.close()
            
            self.session = websocket.WebSocketApp(
                url,
                on_open=self.on_open,
                on_message=self.on_message,
                on_error=self.on_error,
                on_close=self.on_close
            )
            
            # 启动WebSocket连接(非阻塞模式)
            threading.Thread(target=self.session.run_forever, daemon=True).start()
        except Exception as e:
            logger.error(f"Failed to connect to the server: {str(e)}")

    def on_open(self, ws):
        """WebSocket连接建立成功后的回调"""
        logger.info(f"Connection opened")
        
        try:
            # 发送实时成交明细订阅请求
            trade_send_obj = {
                "code": 10000,
                "trace": "01213e9d-90a0-426e-a380-ebed633cba7a",
                "data": {"codes": "BTCUSDT"}
            }
            self.send_message(trade_send_obj)
            
            # 不同请求之间间隔一段时间
            time.sleep(5)
            
            # 发送实时盘口数据订阅请求
            depth_send_obj = {
                "code": 10003,
                "trace": "01213e9d-90a0-426e-a380-ebed633cba7a",
                "data": {"codes": "BTCUSDT"}
            }
            self.send_message(depth_send_obj)
            
            # 不同请求之间间隔一段时间
            time.sleep(5)
            
            # 发送实时K线数据订阅请求
            kline_data = {
                "arr": [
                    {
                        "type": 1,
                        "codes": "BTCUSDT"
                    }
                ]
            }
            kline_send_obj = {
                "code": 10006,
                "trace": "01213e9d-90a0-426e-a380-ebed633cba7a",
                "data": kline_data
            }
            self.send_message(kline_send_obj)
            
            # 启动定时心跳任务
            threading.Thread(target=lambda: schedule.every(30).seconds.do(self.ping), daemon=True).start()
            
        except Exception as e:
            logger.error(f"Error sending initial messages: {str(e)}")

    def on_message(self, ws, message):
        """接收消息的回调"""
        try:
            logger.info(f"Message received: {message}")
        except Exception as e:
            logger.error(f"Error processing message: {str(e)}")

    def on_close(self, ws, close_status_code, close_msg):
        """连接关闭的回调"""
        logger.info(f"Connection closed: {close_status_code} - {close_msg}")

    def on_error(self, ws, error):
        """错误处理的回调"""
        logger.error(f"WebSocket error: {str(error)}")

    def send_message(self, message_obj):
        """发送消息到WebSocket服务器"""
        if self.is_connected():
            try:
                self.session.send(json.dumps(message_obj))
            except Exception as e:
                logger.error(f"Error sending message: {str(e)}")
        else:
            logger.warning("Cannot send message: Not connected")

    def ping(self):
        """发送心跳包"""
        ping_obj = {
            "code": 10010,
            "trace": "01213e9d-90a0-426e-a380-ebed633cba7a"
        }
        self.send_message(ping_obj)

# 使用示例
if __name__ == "__main__":
    ws_client = WebsocketExample()
    ws_client.connect_all()
    
    # 保持主线程运行
    try:
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        logger.info("Exiting...")
        if ws_client.is_connected():
            ws_client.session.close()

高阶策略开发:基于波动率的动态仓位管理

基于获取的实时和历史数据,我们可以开发更复杂的量化策略。以下是一个基于波动率的动态仓位管理策略示例:

策略逻辑

计算波动率:使用历史数据计算股票的滚动波动率。

动态调整仓位:波动率较高时减少仓位,波动率较低时增加仓位。

生成交易信号:根据波动率和价格趋势生成买入或卖出信号。

代码实现

import numpy as np
 
# 计算滚动波动率
def calculate_volatility(data, window=20):
    data['returns'] = data['close'].pct_change()
    data['volatility'] = data['returns'].rolling(window=window).std() * np.sqrt(252)  # 年化波动率
    return data
 
# 动态仓位管理策略
def dynamic_position_management(data, volatility_threshold_high=0.3, volatility_threshold_low=0.1):
    data['position'] = 1.0  # 默认满仓
    data.loc[data['volatility'] > volatility_threshold_high, 'position'] = 0.5  # 高波动率时减仓
    data.loc[data['volatility'] < volatility_threshold_low, 'position'] = 1.5  # 低波动率时加仓
    
    # 生成交易信号
    data['signal'] = np.where(data['position'].shift(1) > data['position'], -1, 1)
    return data
 
# 获取AAPL的历史数据
aapl_data = get_historical_data("AAPL.US", query_kline_num=252)
aapl_data = calculate_volatility(aapl_data)
aapl_data = dynamic_position_management(aapl_data)
 
# 计算策略收益
aapl_data['strategy_return'] = aapl_data['position'].shift(1) * aapl_data['returns']
cumulative_return = (1 + aapl_data['strategy_return']).cumprod()
 
# 绘制策略净值曲线
import matplotlib.pyplot as plt
 
plt.figure(figsize=(10, 6))
plt.plot(cumulative_return)
plt.title('Dynamic Position Management Strategy - AAPL')
plt.xlabel('Date')
plt.ylabel('Cumulative Return')
plt.show()[]()

Pair Trading策略

import java.util.HashMap;
import java.util.Map;
 
public class PairsTradingStrategyDemo {
 
    public static void main(String[] args) {
        Map<String, Double> priceData = new HashMap<>(); // 存储资产价格数据
 
        // 获取资产价格数据
        priceData.put("Asset1", 100.0);
        priceData.put("Asset2", 120.0);
 
        // 执行配对交易策略
        pairsTradingStrategy(priceData);
    }
 
    // 配对交易策略实现
    private static void pairsTradingStrategy(Map<String, Double> priceData) {
        double asset1Price = priceData.get("Asset1");
        double asset2Price = priceData.get("Asset2");
 
        // 计算价差
        double spread = asset1Price - asset2Price;
 
        // 设定价差阈值
        double threshold = 10.0;
 
        if (spread > threshold) {
            // 价差超过阈值,执行卖出Asset1、买入Asset2的交易
            System.out.println("Sell Asset1, Buy Asset2");
            // 执行相应的交易操作
        } else if (spread < -threshold) {
            // 价差低于阈值的负值,执行卖出Asset2、买入Asset1的交易
            System.out.println("Sell Asset2, Buy Asset1");
            // 执行相应的交易操作
        } else {
            // 价差在阈值范围内,无交易信号
            System.out.println("No trading signal");
        }
    }
}

均值回归策略

import random
 
def generate_random_price():
    return random.uniform(0, 100)
 
def calculate_mean(prices):
    return sum(prices) / len(prices)
 
def mean_reversion_strategy(price_data):
    mean = calculate_mean(price_data)  # 计算价格的均值
 
    for price in price_data:
        if price > mean:
            # 价格高于均值,触发卖出信号
            print("Sell stocks. Price:", price)
            # 在这里可以执行相应的卖出操作
        elif price < mean:
            # 价格低于均值,触发买入信号
            print("Buy stocks. Price:", price)
            # 在这里可以执行相应的买入操作
 
def main():
    price_data = []  # 股票价格数据获取
 
    # 填充股票价格数据(示例中使用随机生成的数据)
    for _ in range(100):
        price = generate_random_price()
        price_data.append(price)
 
    # 执行均值回归策略
    mean_reversion_strategy(price_data)
 
if __name__ == "__main__":
    main()

TickTank
2 声望2 粉丝

高频tick数据行情接口