【代码】获取高级行情数据,并通过 qmt 进行实际下单交易,自动实现止盈止损管理

1 本篇教程默认阅读者已经知晓 python 的基本语法,如变量类型,循环,条件判断

2.本篇教程编写的目的是为了帮助量化小白快速上手 xtquant,并搭建自己的量化交易系统

3.作者本人并不是程序员出身,如在内容上有错误/纰漏,也欢迎各位给我进行留言或者私信都可以

0.安装 python 与 xtquant 包

【代码】获取高级行情数据,并通过 qmt 进行实际下单交易,自动实现止盈止损管理

标的池选择:上证 50

买入条件:当股票 1h 周期出现 ma 金叉,且 1d 周期出现 macd 位于 0 轴之上的情况,触发买入条件

卖出条件:当持仓的股票盈利超过设定幅度,或亏损超过设定幅度时,触发卖出条件

# 股票池:50etf标的池
# 策略:双均线策略
# 止盈止损:比例止盈止损

import pandas as pd
import numpy as np
import time
import datetime
from xtquant import xtdata,xttrader,xtconstant
from xtquant.xttype import StockAccount


## 策略所用的指标
def ema(df:pd.DataFrame,N):   
    return df.ewm(span=N, adjust=False).mean()  

def MACD(close:pd.DataFrame, short = 12, long = 26, M = 9):
    DIF = ema(close,short) - ema(close,long)
    DEA = ema(DIF,M)
    return DIF.round(3), DEA.round(3)

def CROSSUP(a, b):
    """
    向上穿越: 表当a从下方向上穿过b, 成立返回1, 否则返回0
    Args:
        a (pandas.Series): 数据序列1

        b (pandas.Series): 数据序列2

    Returns:
        pandas.Series: 上穿标志序列
    """
    crossup_data = pd.Series(np.where((a > b) & (a.shift(1) <= b.shift(1)), 1, 0))
    return crossup_data

# 初始化部分
### 这块有很多可以自己优化的点,比如一些固定的东西可以直接写成配置文件,自己再把整个初始化的部分封装成一个函数,避免重复写

xtdata.connect(port=58601) # 连接主程序开放的数据端口,以获取历史数据和实时数据
account = StockAccount("55001435","STOCK") # 设置交易账户,这个账户必须在你界面的能看到,且能手动下单的
xt_trade = xttrader.XtQuantTrader(r"C:\Program Files\国金证券QMT交易端\userdata_mini",int(time.time())) # 连接miniqmt,如果是连接投研的话,目录是..\userdata

class Mycallback(xttrader.XtQuantTraderCallback): # 继承XtQuantTraderCallback类,覆盖定义自己的回调函数,这个类是开源的,不懂的可以点进去自己看
    # 这个策略其实用不上回调,这里只写一个演示用法
    def on_stock_order(self, order):
        """
        委托回报推送
        :param order: XtOrder对象
        :return:
        """
        print(datetime.datetime.now(), '委托回调', order.order_remark)

    def on_stock_trade(self, trade):
        """
        成交变动推送
        :param trade: XtTrade对象
        :return:
        """
        print(datetime.datetime.now(), '成交回调', trade.order_remark)
callback = Mycallback()
xt_trade.register_callback(callback) # 注册回调信息
xt_trade.start() # 启动交易线程
connect_result = xt_trade.connect() # 连接账户准备交易
subscribe_result = xt_trade.subscribe(account) # 订阅接受账户的回调信息,没这一步的话收不到

if connect_result != 0:
    raise KeyboardInterrupt("连接交易失败,请查看https://dict.thinktrader.net/nativeApi/question_function.html?id=7zqjlm按步骤进行排查")

# 设置参数
strategyName = "双均线_MACD_大小周期共振策略" # 设置策略名称
stock_list = xtdata.get_stock_list_in_sector("上证50") # 设置股票交易列表

period1 = "1d" # 大数据周期
period2 = "1h" # 小数据周期

line_1 = 10 # 短周期
line_2 = 20 # 长周期

macd_n1,macd_n2,macd_M = 12, 26, 9 # MACD指标参数

take_profit_ratio = 10 # 止盈比例,单位%
stop_loss_ratio = 5 # 止损比例,单位%

# 初始化持仓容器
holdings = {}

# 信号计算
def strategyFunc(data):
    # 获取行情数据
    kline_1d:pd.DataFrame = xtdata.get_market_data_ex([],stock_list,period=period1,count=40)
    kline_1h:pd.DataFrame = xtdata.get_market_data_ex([],stock_list,period=period2,count=300)

    # 获取账户持仓数据
    for obj in xt_trade.query_stock_positions(account):
        stock_code = obj.stock_code
        if stock_code not in stock_list:
            continue 
        holdings[stock_code] = {
            "volume":obj.volume, # 持仓量
            "can_use_volume":obj.volume, # 可用量
            "open_price":obj.open_price, # 持仓均价
            "market_value":obj.market_value # 市值
        }

    print(holdings)
    tick = xtdata.get_full_tick(list(holdings.keys()) + stock_list)
    # print(data)
    for stock in stock_list:
        data1 = kline_1h[stock] # 取这个标的的1h数据
        data2 = kline_1d[stock] # 取这个标的的1d数据

        ## 计算均线
        ma1 = data1["close"].rolling(line_1).mean() # 计算短周期均线
        ma2 = data1["close"].rolling(line_2).mean() # 计算长周期均线
        signal = CROSSUP(ma1,ma2) # 计算金叉信号序列

        ## 计算MACD
        dif,dea = MACD(data2["close"])
        diff = dif - dea

        # print(signal,diff)
        # 如果MACD是金叉状态,即DIFF在0轴之上,且1小时均线金叉,则触发买入信号
        # print(stock,signal.iloc[-1] , diff.iloc[-1])
        if signal.iloc[-1] and diff.iloc[-1] > 0:
            # 判断是否有持仓,已经有持仓就不开仓了
            if stock in holdings:
                continue
            else:
                # 按最新价买入标的1手,实际交易中还要考虑买入但未成交的情况下,怎么防止超单
                xt_trade.order_stock_async(account, stock, xtconstant.STOCK_BUY, 100, xtconstant.LATEST_PRICE, 0, strategyName, 'order_test')
    
    # 止盈止损部分
    for stock in holdings:
        _d = holdings[stock]
        cost = _d["open_price"] * _d["volume"] # 计算成本
        profit = _d["market_value"] - cost # 计算盈利金额
        # 如果亏损超过了设定的幅度
        if (cost / _d["market_value"] - 1) * 100 < - stop_loss_ratio and _d["volume"] > 0:
            # 卖出所有持仓
            xt_trade.order_stock_async(account, stock, xtconstant.STOCK_SELL, _d["volume"], xtconstant.LATEST_PRICE, 0, strategyName, 'stop_loss_ratio')
        # 如果盈利超过了指定的幅度
        if (cost / _d["market_value"] - 1) * 100 > take_profit_ratio and _d["volume"] > 0:
             # 卖出所有持仓
            xt_trade.order_stock_async(account, stock, xtconstant.STOCK_SELL, _d["volume"], xtconstant.LATEST_PRICE, 0, strategyName, 'take_profit_ratio')

# 行情数据订阅
for i in stock_list:
    xtdata.subscribe_quote(i,period=period1,count=-1)
    xtdata.subscribe_quote(i,period=period2,count=-1)

xtdata.subscribe_quote("000300.SH",period="tick",callback=strategyFunc) # 订阅主图tick,并用主图tick来驱动策略信号计算,来实现类似与内置python中handlebar的机制

xtdata.run()

以下是一个简单的带5%止损及20%止盈QMT实盘交易事件网格策略,它会在满足触发条件时自动买入或卖出,同时设置止损止盈: ``` import qmt # 连接QMT实盘交易API qmt.connect("your_api_key", "your_secret_key") # 定义止损止盈比例 stop_loss_ratio = 0.05 take_profit_ratio = 0.2 # 定义网格交易策略 def grid_strategy(kline): # 判断K线阳包阴的情况 if kline.close > kline.open and kline.close < kline.high: # 计算买入价格和止损/止盈价格 buy_price = kline.close stop_loss_price = buy_price * (1 - stop_loss_ratio) take_profit_price = buy_price * (1 + take_profit_ratio) # 下单买入 qmt.buy("symbol", "amount", buy_price) # 设置止损止盈 qmt.stop_loss("symbol", stop_loss_price) qmt.take_profit("symbol", take_profit_price) # 判断K线阴包阳的情况 elif kline.close < kline.open and kline.close > kline.low: # 计算卖出价格和止损/止盈价格 sell_price = kline.close stop_loss_price = sell_price * (1 + stop_loss_ratio) take_profit_price = sell_price * (1 - take_profit_ratio) # 下单卖出 qmt.sell("symbol", "amount", sell_price) # 设置止损止盈 qmt.stop_loss("symbol", stop_loss_price) qmt.take_profit("symbol", take_profit_price) # 订阅K线数据,并执行网格交易策略 qmt.subscribe_kline("symbol", "interval", grid_strategy) ``` 需要注意的是,这段代码仅提供一个简单的示例,实际应用中还需要考虑更多的因素,比如交易手续费、资金管理、市场风险等。同时,也需要根据实际情况调整止损止盈比例,以及其他参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值