摘要: 用python实现股票自动下单并不神秘,核心是打通券商接口、生成买卖信号、管理订单状态。本文拆解自动下单的完整流程,对比股票与期货自动交易的差异,并给出可运行的最小代码框架,帮助普通人迈出自动化交易第一步。

为什么有人想用python自动下单

手动炒股最痛苦的不是选不到好股票,而是明明设好了止损位,盘中一忙就忘了挂单,收盘一看多亏了五个点。自动下单就是把「看到信号→点击卖出」这个动作交给程序去执行,人只负责写规则。python能干这事,是因为它有丰富的网络请求库和数据处理库,能连券商、算指标、发订单,一条龙跑完。

自动下单到底在自动什么

很多人以为自动下单是程序自己判断该买该卖,其实那是策略层的事。自动下单只负责一件事:把策略层生成的「买1000股某股票,限价10.5元」这条指令,准确地送到券商服务器,并且跟踪它成交没成交。拆开看是三个环节:

python股票自动下单怎么实现?散户也能看懂的自动化交易入门

  • 信号生成:你的策略算出今天该买还是该卖,产出目标持仓。

  • 订单执行:把目标持仓换算成具体的委托单,包括方向、数量、价格类型。

  • 状态管理:盯着订单是已报、部成、全成还是废单,处理撤单和重试。

python在这三个环节都能插手,但最核心的门槛在第二个环节——你得有一条能发单的通道。

券商接口是绕不开的关卡

普通散户拿不到交易所直连,只能用券商提供的通道。目前市面上有三类路子:

第一类,券商官方API。部分券商对机构或高净值客户开放量化交易接口,python通过HTTP或WebSocket调用,下单、撤单、查持仓都有标准文档。这类接口最稳,但有资金门槛,通常要求资产五十万以上。

第二类,第三方量化平台。像聚宽、米筐这类平台封装了券商通道,你在平台上写python策略,平台帮你把单子送出去。优点是省心,缺点是策略跑在别人服务器上,灵活性受限制。

第三类,模拟点击。用pyautogui或selenium操控券商客户端的下单界面,本质是让程序模仿人点鼠标。这条路门槛最低,任何券商都能用,但极不稳定——客户端一更新按钮位置变了,程序就瞎了。只适合练手,别拿真钱跑。

期货这边略有不同。国内期货公司普遍提供CTP接口,python有现成的封装库,开户后申请接口权限就能连,比股票券商接口透明得多。很多做自动交易的人是从期货入门的,因为通道更规范。

一个最小可跑的下单代码框架

下面这段代码不依赖任何真实券商接口,用模拟对象演示订单从生成到发送的完整逻辑。你看懂结构后,把MockBroker换成真实接口就能用。


import time

from dataclasses import dataclass

from enum import Enum

class OrderSide(Enum):

    BUY = "buy"

    SELL = "sell"

class OrderStatus(Enum):

    PENDING = "pending"

    FILLED = "filled"

    CANCELLED = "cancelled"

@dataclass

class Order:

    symbol: str

    side: OrderSide

    quantity: int

    price: float

    status: OrderStatus = OrderStatus.PENDING

    order_id: str = ""

class MockBroker:

    """模拟券商接口,真实场景替换成券商SDK调用"""

    def __init__(self):

        self.orders = {}

        self.counter = 0

    def send_order(self, order: Order) -> str:

        self.counter += 1

        order_id = f"MOCK{self.counter:06d}"

        order.order_id = order_id

        self.orders[order_id] = order

        print(f"已发送订单 {order_id}: {order.side.value} {order.symbol} "

              f"{order.quantity}股 @ {order.price}")

        return order_id

    def query_order(self, order_id: str) -> Order:

        order = self.orders.get(order_id)

        if order and order.status == OrderStatus.PENDING:

            order.status = OrderStatus.FILLED  # 模拟立即成交

        return order

def generate_signal(price_series):

    """简单双均线策略:短期均线上穿长期均线买入,下穿卖出"""

    if len(price_series) < 20:

        return None

    short_ma = sum(price_series[-5:]) / 5

    long_ma = sum(price_series[-20:]) / 20

    if short_ma > long_ma:

        return OrderSide.BUY

    elif short_ma < long_ma:

        return OrderSide.SELL

    return None

def run_trading_loop():

    broker = MockBroker()

    prices = [10.0] * 20  # 假装有20天历史价格

    position = 0

    for tick in range(5):

        # 模拟新价格进来

        prices.append(10.0 + tick * 0.1)

        prices = prices[-20:]

        signal = generate_signal(prices)

        if signal == OrderSide.BUY and position == 0:

            order = Order(prices[-1], OrderSide.BUY, 1000, prices[-1])

            oid = broker.send_order(order)

            time.sleep(0.1)

            result = broker.query_order(oid)

            if result.status == OrderStatus.FILLED:

                position += result.quantity

                print(f"买入成交,当前持仓 {position} 股\n")

        elif signal == OrderSide.SELL and position > 0:

            order = Order(prices[-1], OrderSide.SELL, position, prices[-1])

            oid = broker.send_order(order)

            time.sleep(0.1)

            result = broker.query_order(oid)

            if result.status == OrderStatus.FILLED:

                position -= result.quantity

                print(f"卖出成交,当前持仓 {position} 股\n")

if __name__ == "__main__":

    run_trading_loop()

跑一遍这段代码,你能看到订单怎么生成、怎么发送、怎么查询状态。真实环境里把MockBroker换成券商封装,把print换成日志,基本骨架不用大改。

股票自动下单和期货自动下单的关键差别

股票是T+1,今天买的明天才能卖。程序里如果没做持仓锁定,策略连续发买入信号,可能一天买三次,第二天才能卖一次,仓位直接超配。期货是T+0,当天可以反复开平,但带杠杆,一笔单子亏起来速度是股票的十倍。

股票委托有「废单」机制,价格超出涨跌停范围、数量不是100股整数倍,交易所直接拒单。期货按手数下单,一手对应不同吨数,程序里数量单位搞错,一手螺纹钢可能变成十手。

股票接口的行情推送通常有延迟,免费接口三秒一次,自动下单策略如果依赖秒级信号,滑点会吃掉利润。期货CTP接口的行情是逐笔推送,延迟低得多。这也是为什么高频自动交易团队更倾向期货通道。

自动下单必须加的几道保险

程序最容易在输错代码时闯祸。买100股输成10000股,一秒钟就能把账户打穿。下单前必须做数量校验:不超过总资产的百分之二十,不超过该股票近期日均成交量的百分之一。

价格也要校验。限价单的价格偏离最新成交价超过百分之三,直接拦截。市价单在流动性差的股票上能滑出天际,能用限价就别用市价。

订单状态要有超时机制。委托发出去五秒还在「已报」没成交,检查一下是不是价格挂偏了,该撤就撤。python里用time.time()记录发送时间,循环里查一次状态,超时就调撤单接口。

最重要的一道保险是断线重连和状态同步。网络闪断后程序不知道之前发的单子成交没有,重新连上第一件事是拉取当日全部委托和成交记录,把本地状态对齐,再继续跑。

普通人从哪一步开始练

别一上来就接真钱。先用模拟接口跑两周,每天开盘前启动程序,收盘后检查订单日志,看看有没有重复下单、数量算错、状态卡死的问题。模拟盘跑顺了,用最小资金实盘跑,单笔不超过100股,跑一个月。

python自动下单的门槛不在编程,在于对交易规则的理解。把委托类型、成交规则、涨跌停机制搞明白,代码只是把理解翻译成机器能执行的动作。翻译错了,代码写得再漂亮也亏钱。

期货自动交易同理,杠杆放大了所有错误的代价。先用模拟盘把开平仓、保证金、强平规则摸透,再碰真账户。程序不会让你变聪明,它只会让你的错误执行得更快。