This commit is contained in:
guoyz 2025-05-29 14:26:10 +08:00
parent 9bca280232
commit 082935662f
3 changed files with 61 additions and 45 deletions

View File

@ -101,7 +101,8 @@ def parse_return_email(to_email, send_email_time):
encoded_email = to_email.encode('utf-8')
# 构建搜索条件HEADER FROM "<发件人邮箱>, 时间大于 <send_email_time>"
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):

View File

@ -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:
@ -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,17 +938,15 @@ 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):
"""处理邮件响应的线程"""
try:
logging.info("handle_email_response is called with action: {}".format(action))
# 发送邮件
if action == "买入":
self.Buy_stock(turtle, price_now)
@ -945,17 +956,21 @@ class TurtleTrading_OnTime(object):
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}")
# 等待邮件响应
event.wait()
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()
# # 全是股票