diff --git a/EmailTest.py b/EmailTest.py index f0239f4..3e579c9 100755 --- a/EmailTest.py +++ b/EmailTest.py @@ -101,7 +101,8 @@ def parse_return_email(to_email, send_email_time): encoded_email = to_email.encode('utf-8') # 构建搜索条件:HEADER FROM "<发件人邮箱>, 时间大于 " - search_criteria = f'FROM "{encoded_email.decode("utf-8")}" SINCE "{send_email_time}"' + search_criteria = ['FROM', encoded_email.decode('utf-8'), 'SINCE', send_email_time] + # search_criteria = f'FROM "{encoded_email.decode("utf-8")}"' # 执行搜索操作 @@ -148,9 +149,9 @@ def parse_return_email(to_email, send_email_time): # 根据“实际买入价格-买入份额-手续费”格式解析body中的内容 parse_states = True body.split("-") - price = body.split("-")[0] - share = body.split("-")[1] - fee = body.split("-")[2] + price = float(body.split("-")[0]) + share = float(body.split("-")[1]) + fee = float(body.split("-")[2]) return parse_states, price, share, fee def check_email(to_email, send_email_time): diff --git a/TurtleOnTime.py b/TurtleOnTime.py index b199517..fa602ba 100644 --- a/TurtleOnTime.py +++ b/TurtleOnTime.py @@ -11,6 +11,7 @@ from dataclasses import dataclass import time import threading import yaml # 添加YAML支持 +import logging ''' todo @@ -90,10 +91,10 @@ class TurtleTrading(object): self.Capital = Capital self.cash = cash self.TrigerTime = 0 - self.BuyStates = list[BuyState] + self.BuyStates = [] - self.tradeslog = list[TradeLog] - self.BreakOutLog = list[BreakOutLog] + self.tradeslog = [] + self.BreakOutLog = [] self.PriceNow = 0.0 self.Donchian_20_up = 0.0 self.Donchian_10_down = 0.0 @@ -295,7 +296,7 @@ class TurtleTrading(object): def system1EnterSafe(self, PriceNow, TempDonchian55Upper): - if PriceNow > TempDonchian55Upper[-1]: # 保底的55日突破 + if PriceNow > TempDonchian55Upper: # 保底的55日突破 return True else: return False @@ -419,7 +420,7 @@ class TurtleTrading_OnTime(object): self.turtles = turtles # List of TurtleTrading instances self.user_email = user_email self.email_events = {} # Track email response events for each turtle - + logging.basicConfig(level=logging.INFO) # Load previous state from YAML if exists self.load_previous_state() @@ -451,8 +452,8 @@ class TurtleTrading_OnTime(object): body = f"{turtle.TradeCode},价格{price_now},份额{turtle.IntPositionSize} \n " body += "回复:实际买入价格-买入份额-手续费" send_email(subject, body, self.user_email) - send_email_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - + # send_email_time = datetime.strftime(datetime.now(),"%Y%m%d %H:%M:%S").date() + send_email_time = datetime.now().date() #每隔1分钟检测回信,解析邮件。 parsed_email_flag = False @@ -517,7 +518,7 @@ class TurtleTrading_OnTime(object): body = f"{turtle.TradeCode},价格{price_now},份额{turtle.IntPositionSize} \n " body += "回复:实际买入价格-买入份额-手续费" send_email(subject, body, self.user_email) - send_email_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + send_email_time = datetime.now().date() #每隔1分钟检测回信,解析邮件。 @@ -617,7 +618,7 @@ class TurtleTrading_OnTime(object): body = f"{turtle.TradeCode},价格{price_now},份额{turtle.IntPositionSize * sale_shares} \n " body += "回复:实际卖出价格-卖出份额-手续费" send_email(subject, body, self.user_email) - send_email_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + send_email_time = datetime.now().date() # 每隔1分钟检测回信,解析邮件。 @@ -667,7 +668,7 @@ class TurtleTrading_OnTime(object): body = f"{turtle.TradeCode},价格{price_now},份额{turtle.IntPositionSize} \n " body += "回复:实际卖出价格-卖出份额-手续费" send_email(subject, body, self.user_email) - send_email_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + send_email_time = datetime.now().date() # 每隔1分钟检测回信,解析邮件。 @@ -795,7 +796,7 @@ class TurtleTrading_OnTime(object): # 准备数据 turtle.get_ready(100) turtle.N = float(turtle.CurrentData['ATR'].iloc[-1]) - turtle.prev_heigh = float(turtle.CurrentData['最高价'].iloc[-1]) + turtle.prev_heigh = float(turtle.CurrentData['最高'].iloc[-1]) turtle.Donchian_20_up = float(turtle.CurrentData['Donchian_20_upper'].iloc[-1]) turtle.Donchian_50_up = float(turtle.CurrentData['Donchian_50_upper'].iloc[-1]) turtle.Donchian_10_down = float(turtle.CurrentData['Donchian_10_lower'].iloc[-1]) @@ -821,7 +822,7 @@ class TurtleTrading_OnTime(object): (now.hour == 14 and 0 <= now.minute <= 59) or (now.hour == 15 and now.minute <= 0) ) - + is_trading_time = True if not is_trading_time: @@ -843,7 +844,7 @@ class TurtleTrading_OnTime(object): for turtle in self.turtles: mysql_database.delete_table(f"{turtle.TradeCode}") turtle.get_ready(100) - time.sleep(16.5*600) + time.sleep(16.5*600) def monitor_all_turtles(self): @@ -852,9 +853,19 @@ class TurtleTrading_OnTime(object): stock_data, etf_data = self.get_stocks_data() # 遍历所有turtle进行监控 + # 为每个 Turtle 启动一个线程 + threads = [] for turtle in self.turtles: - self.monitor_single_turtle(turtle, stock_data, etf_data) - + thread = threading.Thread( + target=self.monitor_single_turtle, + args=(turtle, stock_data, etf_data) + ) + thread.start() + threads.append(thread) + + # 可选:等待所有线程完成(如果需要) + for thread in threads: + thread.join() def monitor_single_turtle(self, turtle: TurtleTrading, stock_data, etf_data): @@ -862,15 +873,17 @@ class TurtleTrading_OnTime(object): now = datetime.now().time() if turtle.type == "stock": - turtle.PriceNow = float(stock_data.loc[etf_data['代码'] == self.turtle.TradeCode, '最新价'].values[0]) + turtle.PriceNow = float(stock_data.loc[stock_data['代码'] == turtle.TradeCode, '最新价'].values[0]) elif turtle.type == "etf": # self.turtle.PriceNow = float(etf_data.loc[etf_data['基金代码'] == self.turtle.TradeCode, '当前-单位净值'].values[0]) - turtle.PriceNow = float(etf_data.loc[etf_data['代码'] == self.turtle.TradeCode, '最新价'].values[0]) + turtle.PriceNow = float(etf_data.loc[etf_data['代码'] == turtle.TradeCode, '最新价'].values[0]) - if now.hour == 9 and now.minute == 30 and self.turtle.PriceNow > self.turtle.prev_heigh: + if now.hour == 9 and now.minute == 30 and turtle.PriceNow > turtle.prev_heigh: turtle.is_gap_up = True - + + # fake_price = 1.470 + # turtle.PriceNow = fake_price # 判断当前仓位状态并执行相应操作 if turtle.TrigerTime == 0: if turtle.system1EnterNormal( @@ -925,37 +938,39 @@ class TurtleTrading_OnTime(object): def start_email_thread(self, turtle:TurtleTrading, action, price_now): """启动邮件处理线程""" - event = threading.Event() - self.email_events[turtle.TradeCode] = event - - thread = threading.Thread( - target=self.handle_email_response, - args=(turtle, action, price_now, event) - ) - thread.start() + + self.handle_email_response(turtle, action, price_now) + - def handle_email_response(self, turtle:TurtleTrading, action, price_now, event): + def handle_email_response(self, turtle:TurtleTrading, action, price_now): """处理邮件响应的线程""" - # 发送邮件 - if action == "买入": - self.Buy_stock(turtle, price_now) - elif action == "加仓": - self.add_stock(turtle, price_now) - elif action == "止损": - self.stop_sale_stock(turtle, price_now) - elif action == "止盈": - self.out_sale_stock(turtle, price_now) - # 等待邮件响应 - event.wait() + try: + logging.info("handle_email_response is called with action: {}".format(action)) + # 发送邮件 + if action == "买入": + self.Buy_stock(turtle, price_now) + elif action == "加仓": + self.add_stock(turtle, price_now) + elif action == "止损": + self.stop_sale_stock(turtle, price_now) + elif action == "止盈": + self.out_sale_stock(turtle, price_now) + else: + logging.warning(f"Unknown action: {action} for TradeCode: {turtle.TradeCode}") + + + except Exception as e: + logging.error(f"Error in handle_email_response for TradeCode: {turtle.TradeCode}, Error: {e}") if __name__ == '__main__': user_email = "guoyize2209@163.com" - t = TurtleTrading('513870', "etf", 0.0025, 100000, 200000) + nsdk = TurtleTrading('513870', "etf", 0.0025, 100000, 200000) + cjdl = TurtleTrading('600900', "stock", 0.0025, 100000, 200000) # t.get_ready(100) - a = TurtleTrading_OnTime(t, user_email) + a = TurtleTrading_OnTime([nsdk, cjdl], user_email) a.Start_short_system() # # 全是股票 diff --git a/__pycache__/EmailTest.cpython-310.pyc b/__pycache__/EmailTest.cpython-310.pyc index de27ca6..cd720e4 100644 Binary files a/__pycache__/EmailTest.cpython-310.pyc and b/__pycache__/EmailTest.cpython-310.pyc differ