Python 控制台不允许我编写新的代码行。 PyCharm

Python Console not allowing me to write a new line of code. PyCharm

我是 Python 的新手,我的大部分代码都是用 R 完成的。在这段代码中,我从 Interactive Brokers API 中提取数据。代码以 0 个错误结束,但是,控制台中的 3 个绿色箭头消失了,我无法在控制台中编写任何内容或在脚本中执行代码。最后,我点击了左下角的绿色调试图标,现在我得到了这个不会消失的 "connecting to console"。

我在这个项目 (python 3.7) 上有一个翻译 运行ning。

我想看的是 运行 的代码,完成后允许我在控制台中编写代码并像往常一样在脚本中执行新代码。我决定不放入我的 Interactive brokers 代码,因为我认为它是多余的。如果你想看它,我会上传它。谢谢你。

下面是交互式经纪人代码。代码直接来自他们的示例脚本之一。我已决定将第 30 行的 app.reqMktData 设置为 True,True 这样我就只收到一个快照。我仍然遇到同样的问题。

import numpy as np
import pandas as pd
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum

class TestApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
    def error(self, reqId, errorCode, errorString):
        print("Error: ", reqId, " ", errorCode, " ", errorString)

    def tickPrice(self, reqId, tickType, price, attrib):
        print("Tick Price. Ticker Id:", reqId, "tickType:", TickTypeEnum.to_str(tickType), "Price:", price, end=" ")

    def tickSize(self, reqId, tickType, size):
        print("Tick Size. Ticker Id:", reqId, "tickType:", TickTypeEnum.to_str(tickType), "Size:", size, end=" ")

def main():
    app = TestApp()
    app.connect("127.0.0.1", 4001, 0)

    contract = Contract()
    contract.symbol = "AAPL"
    contract.secType = "STK"
    contract.exchange = "SMART"
    contract.currency = "USD"
    app.reqMarketDataType(4)
    app.reqMktData(1, contract, "", True, True, [])

    app.run()

if __name__ == "__main__":
    main()

当我将 run.app 放在 reqmkt 数据上方时,它只会一直旋转而不会返回任何内容。谢谢

我建议重新启动 PyCharm 以摆脱那些 "Connecting to console" 任务。我的猜测是它失败了,因为控制台已经死了。

然后使用动作(Ctrl+Shift+A 或 Ctrl+3 查找动作)"Run file in Console".

我认为您在这里看到的是 IB 用于其 API 的双线程系统的代表。 (link)

由于该应用是 运行,这些线程 运行 在无限循环中收集和处理数据。

从我在你的图片中看到的,你在 'exiting with code 0.' 之前只从 reqmktdata() 返回了一个 tick 在我自己的 reqmktdata 实现中,尽管是 C#,我返回了一致的数据流。 (对于 AAPL,这将是每秒几个报价和几种报价类型。)

很有可能您看到的是由这两个线程故意但非终止的无限循环引起的一些锁定。

建议:

  • 尝试将 app.run() 放在 reqmktdata() 调用之前。 (这是一个远景,因为我不熟悉 IB 的 Python 实施)
  • 逐行检查您的代码以查看它决定退出的确切位置是值得的。根据我自己的经验,这段代码不应该退出,直到你决定停止它。 (即:应该打印多行输出)

正如 Daniel 所说,这是一个常见问题,是 API 的线程在您的程序 return 之后卡住打开的结果。您将无法 运行 您的程序,然后在控制台中继续调用 API 。要解决连接到控制台的问题,您需要在 return 之前调用 app.disconnect() 来断开与脚本中 API 的连接。

此外,考虑将这些行添加到您的 TestApp 对象中:

thread = Thread(target=self.run)
thread.start()

setattr(self, "_thread", thread)

这将为您启动线程,您不再需要调用 app.run()

您需要从线程模块导入线程 class - from Threading import Thread

此博客可以帮助您实施其他 classes 并使用队列接收来自 API 的回调。 https://qoppac.blogspot.com/2017/03/interactive-brokers-native-python-api.html