Skip to content
All library documents

Four-Price Intraday Breakout Strategy with Reversal and Time-Based Exits

Code TqSdk

Summary

This example implements an intraday breakout strategy around the prior session’s high and low. It opens a long position when the latest price rises above the prior high and a short when it falls below the prior low, targeting a fixed position size in either direction. The strategy refreshes those boundaries when a new daily bar begins and uses a target-position task to manage orders.

For risk control, it exits if price has crossed either boundary and then returns through the current session’s opening price. It also closes positions at a configured time near the session close. The example is illustrative code, not a tested trading recommendation: it supplies no backtest, transaction-cost analysis, or evidence that the triggers are profitable. Its contract, position size, session timing, and reversal logic are fixed example choices that would need assessment for the intended instrument and trading hours.

Key ideas

  • The strategy uses the previous session’s high and low as breakout thresholds.
  • It opens a fixed-size long above the upper threshold or short below the lower threshold.
  • It exits after a breakout reverses through the current session’s opening price.
  • A time-based rule closes positions near the end of the trading session.
  • The example provides no backtest or transaction-cost analysis to support its profitability.

Tags

Full text
# fairy_four_price.py


```py
#!/usr/bin/env python
#  -*- coding: utf-8 -*-
__author__ = 'limin'

'''
菲阿里四价 策略(日内突破策略, 在每日收盘前对所持合约进行平仓)
参考: https://www.shinnytech.com/blog/fairy-four-price/
注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改
'''

from tqsdk import TqApi, TqAuth, TargetPosTask
from datetime import datetime
import time

symbol = "SHFE.ni2012"  # 合约代码
close_hour, close_minute = 14, 50  # 平仓时间

api = TqApi(auth=TqAuth("快期账户", "账户密码"))  # 使用模拟帐号直连行情和交易服务器
quote = api.get_quote(symbol)  # 获取指定合约的盘口行情
klines = api.get_kline_serial(symbol, 24 * 60 * 60)  # 获取日线
position = api.get_position(symbol)  # 持仓信息
target_pos = TargetPosTask(api, symbol)  # 目标持仓

top_rail = klines.high.iloc[-2]  # 上轨: 昨日高点
bottom_rail = klines.low.iloc[-2]  # 下轨: 昨日低点
print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1])

while True:
    api.wait_update()
    if api.is_changing(klines.iloc[-1], "datetime"):  # 如果产生一根新日线 (即到达下一个交易日): 重新获取上下轨
        top_rail = klines.high.iloc[-2]
        bottom_rail = klines.low.iloc[-2]
        print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1])

    if api.is_changing(quote, "last_price"):  # 如果行情最新价发生变化
        print("当前最新价", quote.last_price)
        # 开仓突破
        if quote.last_price > top_rail and position.pos_long == 0:  # 如果价格突破上轨: 买入开仓
            print("最新价:", quote.last_price, ", 价格突破上轨,买入开仓")
            target_pos.set_target_volume(3)  # 设置目标持仓手数,将指定合约调整到目标头寸
        elif quote.last_price < bottom_rail and position.pos_short == 0:  # 如果价格跌破下轨: 卖出开仓
            print("最新价:", quote.last_price, ", 价格跌破下轨, 卖出开仓")
            target_pos.set_target_volume(-3)

        # 平仓止损: 当价格 向上突破上轨 或 向下突破下轨 后, 再次回破当日开盘价
        if (quote.highest > top_rail and quote.last_price <= quote.open) or (
                quote.lowest < bottom_rail and quote.last_price >= quote.open):
            print("平仓止损")
            target_pos.set_target_volume(0)

    if api.is_changing(quote, "datetime"):
        now_time = datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f")  # 获取当前的行情时间
        if now_time.hour == close_hour and now_time.minute >= close_minute:  # 到达平仓时间: 平仓
            print("临近本交易日收盘: 平仓")
            target_pos.set_target_volume(0)
            deadline = time.time() + 60  # 设置截止时间为当前时间的60秒以后
            while api.wait_update(deadline=deadline):  # 等待60秒
                pass
            api.close()  # 关闭api
            break  # 退出while循环

```

Shown in full with attribution under the source's licence. Licence: Apache-2.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.