You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于yfinance的股票自动交易代码重复触发相同订单求助

问题描述

我编写了一段基于yfinance的股票自动交易代码,意图根据支撑位和阻力位触发买卖订单,但运行时代码持续重复执行Buy(多单)订单,无法正常切换交易方向。现将代码及运行输出附上,请求协助排查问题原因:

代码

import yfinance as yf

# Set the ticker symbol and thresholds for support and resistance levels
ticker_symbol = "RELIANCE.NS"
support_threshold = 100
resistance_threshold = 200

# Fetch data for the ticker
ticker = yf.Ticker(ticker_symbol)

while True:
    # Get the real-time price data in 5-minute intervals
    data = ticker.history(interval="5m")

    # Calculate the recent highs and lows (support and resistance levels)
    recent_highs = data["High"][-10:].max()
    recent_lows = data["Low"][-10:].min()

    # Check if the current price is above or below the support and resistance levels
    support_level = "above" if data["Close"][-1] > recent_lows else "below"
    resistance_level = "above" if data["Close"][-1] > recent_highs else "below"

    # Take a long position if the current price is above the support level and below the resistance level
    if support_level == "above" and resistance_level == "below":
      alice.place_order(transaction_type = TransactionType.Buy,
                    instrument = alice.get_instrument_by_symbol('NSE', 'INFY'),
                    quantity = 1,
                    order_type = OrderType.Market,
                    product_type = ProductType.Delivery,
                    price = 0.0,
                    trigger_price = None,
                    stop_loss = None,
                    square_off = None,
                    trailing_sl = None,
                    is_amo = False,
                    order_tag='order1' )
      print("long")
    # Take a short position if the current price is below the support level or above the resistance level
    elif support_level == "below" or resistance_level == "above":
      alice.place_order(transaction_type = TransactionType.Sell,
                    instrument = alice.get_instrument_by_symbol('NSE', 'INFY'),
                    quantity = 1,
                    order_type = OrderType.Market,
                    product_type = ProductType.Delivery,
                    price = 0.0,
                    trigger_price = None,
                    stop_loss = None,
                    square_off = None,
                    trailing_sl = None,
                    is_amo = False,
                    order_tag='order1' )
      print("short")
    
    # Print current price, support level, and resistance level every 5 minutes
    print(f"Price: {data['Close'][-1]}, Support level: {recent_lows}, Resistance level: {recent_highs}")
    time.sleep(500)

运行输出

long
Price: 2530.699951171875, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.75, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.949951171875, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.699951171875, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.14990234375, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.14990234375, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.050048828125, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.75, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.64990234375, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.64990234375, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2530.300048828125, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2531.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2531.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
long
Price: 2531.0, Support level: 2525.050048828125, Resistance level: 2534.199951171875
问题原因及修复方案

核心问题1:无持仓状态跟踪

代码完全没有记录当前持仓状态,只要价格处于支撑位上方、阻力位下方,就会反复触发多单,完全不考虑已经持有多单的情况,自然无法切换交易方向。

核心问题2:支撑/阻力逻辑不合理

从输出可见,当前价格一直在2530左右波动,支撑位是2525,阻力位是2534,价格始终处于两者之间,永远满足多单触发条件,不会触发空单。同时原代码的支撑/阻力判断逻辑过于粗糙:仅用价格高于最近低点就判定为“支撑位上方”,没有突破/跌破的确认机制,而且代码中定义的support_threshold和resistance_threshold两个阈值完全未使用。

其他问题

  • 未导入time模块,运行会报错
  • 数据获取标的是RELIANCE.NS,但下单标的却是INFY,标的不一致

修复后的代码示例

import yfinance as yf
import time
# 假设已正确初始化alice、TransactionType、OrderType、ProductType

# 设置标的和突破阈值
ticker_symbol = "RELIANCE.NS"
# 价格突破支撑/阻力的阈值,避免震荡误触发
breakout_threshold = 1.0

# 获取标的数据
ticker = yf.Ticker(ticker_symbol)
# 跟踪当前持仓状态:None=无持仓,"long"=多单,"short"=空单
current_position = None

while True:
    # 获取5分钟K线数据
    data = ticker.history(interval="5m")
    if len(data) < 10:
        print("数据不足,等待更新")
        time.sleep(500)
        continue

    # 计算最近10根K线的高低点作为支撑/阻力
    recent_highs = data["High"][-10:].max()
    recent_lows = data["Low"][-10:].min()
    current_price = data["Close"][-1]

    # 判断突破情况
    is_break_resistance = current_price > (recent_highs + breakout_threshold)
    is_break_support = current_price < (recent_lows - breakout_threshold)
    is_in_range = not is_break_resistance and not is_break_support

    # 交易逻辑:结合持仓状态和突破信号操作
    if is_in_range:
        # 区间内:无持仓则开多单,有空单则平仓
        if current_position is None:
            alice.place_order(
                transaction_type = TransactionType.Buy,
                instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                quantity = 1,
                order_type = OrderType.Market,
                product_type = ProductType.Delivery,
                price = 0.0,
                trigger_price = None,
                stop_loss = None,
                square_off = None,
                trailing_sl = None,
                is_amo = False,
                order_tag='order1'
            )
            print("开多单")
            current_position = "long"
        elif current_position == "short":
            # 平空单
            alice.place_order(
                transaction_type = TransactionType.Buy,
                instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                quantity = 1,
                order_type = OrderType.Market,
                product_type = ProductType.Delivery,
                price = 0.0,
                trigger_price = None,
                stop_loss = None,
                square_off = None,
                trailing_sl = None,
                is_amo = False,
                order_tag='close_short'
            )
            print("平空单")
            current_position = None
    elif is_break_resistance:
        # 突破阻力:非多单状态则先平仓(如有)再开多单
        if current_position != "long":
            if current_position == "short":
                alice.place_order(
                    transaction_type = TransactionType.Buy,
                    instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                    quantity = 1,
                    order_type = OrderType.Market,
                    product_type = ProductType.Delivery,
                    price = 0.0,
                    trigger_price = None,
                    stop_loss = None,
                    square_off = None,
                    trailing_sl = None,
                    is_amo = False,
                    order_tag='close_short'
                )
                print("平空单")
            alice.place_order(
                transaction_type = TransactionType.Buy,
                instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                quantity = 1,
                order_type = OrderType.Market,
                product_type = ProductType.Delivery,
                price = 0.0,
                trigger_price = None,
                stop_loss = None,
                square_off = None,
                trailing_sl = None,
                is_amo = False,
                order_tag='open_long'
            )
            print("突破阻力,开多单")
            current_position = "long"
    elif is_break_support:
        # 跌破支撑:非空单状态则先平仓(如有)再开空单
        if current_position != "short":
            if current_position == "long":
                alice.place_order(
                    transaction_type = TransactionType.Sell,
                    instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                    quantity = 1,
                    order_type = OrderType.Market,
                    product_type = ProductType.Delivery,
                    price = 0.0,
                    trigger_price = None,
                    stop_loss = None,
                    square_off = None,
                    trailing_sl = None,
                    is_amo = False,
                    order_tag='close_long'
                )
                print("平多单")
            alice.place_order(
                transaction_type = TransactionType.Sell,
                instrument = alice.get_instrument_by_symbol('NSE', ticker_symbol),
                quantity = 1,
                order_type = OrderType.Market,
                product_type = ProductType.Delivery,
                price = 0.0,
                trigger_price = None,
                stop_loss = None,
                square_off = None,
                trailing_sl = None,
                is_amo = False,
                order_tag='open_short'
            )
            print("跌破支撑,开空单")
            current_position = "short"

    # 打印当前状态
    print(f"价格: {current_price}, 支撑位: {recent_lows}, 阻力位: {recent_highs}, 当前持仓: {current_position}")
    time.sleep(500)

关键修复点

  1. 添加持仓状态跟踪:用current_position变量记录当前持仓情况,避免重复下单
  2. 优化支撑/阻力逻辑:加入突破阈值,只有价格明显突破支撑/阻力才触发交易,避免区间震荡误操作
  3. 统一交易标的:下单标的与数据获取标的保持一致
  4. 补充必要模块导入:添加time模块导入
  5. 完善交易逻辑:区分开仓和平仓操作,避免反向持仓

内容的提问来源于stack exchange,提问作者D-S TELUGU TRADERS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:10:22