如何在网络连接丢失时重置Python程序

1 投票
2 回答
1838 浏览
提问于 2025-04-18 17:21

好的,我有一个用Python写的程序,运行在Python 2.7上,我用它来交易比特币。说实话,我对编程完全是个新手,但我知道怎么调整这个机器人和为它设置规则。程序运行得很好,直到我换网络连接,比如我开关我的VPN。我想知道在出现“无法获取响应”的情况下,我可以用什么代码来重启这个程序?谢谢你的帮助。下面是用来启动程序和主循环的代码。

def loop_body(self):  
        orders = self.update_portfolio()
        if orders is None:
            return

        if self.get_num_open_bids(orders) + self.get_num_open_asks(orders) >= MAX_OPEN_ORDERS and REMOVE_UNREALISTIC:
            self.update_portfolio

        if self.get_num_open_bids(orders) + self.get_num_open_asks(orders) >= MAX_OPEN_ORDERS:
            if DEBUG_MODE:
                print '---'
                print 'Too many open orders, sleep for', TOO_MANY_OPEN_SLEEP, 'seconds.'
                print " "
                print 'I have', self.get_num_portfolio_bids(), 'open bids,', self.get_num_portfolio_asks(), 'asks.'
                print 'API shows', self.get_num_open_bids(orders), 'open bids,', self.get_num_open_asks(orders), 'asks.'
                print "---"
                print 'Profit :', self.profit, 'CNY'

            sleep(TOO_MANY_OPEN_SLEEP)
            return

        a = None
        b = None
        d = None
        e = None

        market_depth = self.get_market_depth()
        if not market_depth:
            return
        market_lowest_ask = self.get_lowest_market_ask(market_depth)
        a = market_lowest_ask
        market_highest_bid = self.get_highest_market_bid(market_depth)
        d = market_highest_bid
        sleep(5)

        market_depth = self.get_market_depth()
        if not market_depth:
            return
        market_lowest_ask = self.get_lowest_market_ask(market_depth)
        b = market_lowest_ask
        market_highest_bid = self.get_highest_market_bid(market_depth)
        e = market_highest_bid

        if DEBUG_MODE:
            print '---'
            print 'I have', self.get_num_portfolio_bids(), 'open bids,', self.get_num_portfolio_asks(), 'asks.'
            print 'API shows', self.get_num_open_bids(orders), 'open bids,', self.get_num_open_asks(orders), 'asks.'
            print "---"
            print 'Profit :', self.profit, 'CNY'

        my_ask_price_2 = market_lowest_ask - CNY_STEP
        my_bid_price_2 = my_ask_price_2 - MIN_SURPLUS

        if a > b and d > e:
            for trial in xrange(MAX_TRIAL):
                response = self.trader.sell('{0:.2f}'.format(my_ask_price_2), BTC_AMOUNT)
                if response is True:
                    self.portfolio.append(
                        {'bid': my_bid_price_2, 'ask': my_ask_price_2, 'status': 'sell'})
                    if DEBUG_MODE:
                        print "---"
                        print 'I sold', BTC_AMOUNT, 'bitcoins at', my_ask_price_2
                    break
                else:
                    if DEBUG_MODE:
                        print "---"
                        print 'Sell failed:', response
                    break
                break

        my_bid_price = market_highest_bid + CNY_STEP
        my_ask_price = my_bid_price + MIN_SURPLUS 

        if a < b and d < e:
            for trial in xrange(MAX_TRIAL):
                if self.trader.buy('{0:.2f}'.format(my_bid_price), BTC_AMOUNT):
                    self.portfolio.append(
                        {'bid': my_bid_price, 'ask': my_ask_price, 'status': 'buy'})
                    if DEBUG_MODE:
                        print "---"
                        print 'I bought', BTC_AMOUNT, 'bitcoins at', my_bid_price
                    break
                else:
                    if DEBUG_MODE:
                        print "---"
                        print 'Buy failed:', response
                    break
                break

    def start(self):
        self.reset()
        while True:
            self.loop_body()

if __name__ == '__main__':
    bot = Bot()
    bot.start()

2 个回答

0

这里有两件事你需要做。

首先,你提到的“未能获取响应”的事件,可能是你用的那个 Bot 库抛出的一个异常。所以,你需要以某种方式处理这个异常。

其次,你需要在所有代码外面加一个永远循环的 while 循环,这样在处理完异常后,就可以回到最开始的地方再试一次。


如果你使用的是除了Windows以外的任何平台,并且不介意每次连接丢失时打印出一些难看的异常追踪信息,那么用一个外壳脚本来做可能会更简单:

#!/bin/sh

while true; do
    python ./myscript.py
done

无论程序是正常退出还是因为异常而退出,你的外壳脚本都会再次进入循环。


如果你想在Python中实现这个功能,可以把你的顶层代码改成:

if __name__ == '__main__':
    while True:
        try:
            bot = Bot()
            bot.start()
        except Exception as e:
            print('Failed with {!r}, retrying', e)

如果你知道你遇到的具体异常是什么——如果它没有出现在你最初的追踪信息中,它将是新循环中 e 的类型——你可能只想处理那个特定的异常。这样,如果你的程序还有其他问题,程序就不会一直循环,而是会告诉你哪里出了错。(没有什么比一个拼写错误导致无限循环的 Failed with NameError: 'slef' 消息更糟糕的了……)一旦你知道了这个异常,只需把 except 行改成:

except LostConnectionException as e:
0

最好还是自己管理一下网络交易,检查请求是否超时。然后根据情况来处理,比如可以让程序暂停一下,或者再试一次等等。

如果你想定期重启一个Python程序,可能需要写一个额外的脚本或者使用一个命令行脚本,但这样做其实不是处理这个问题的最佳方法。

撰写回答