states尝试

This commit is contained in:
gyz 2025-05-23 21:12:13 +08:00
parent 43a419a56f
commit d0b92aa1ef
2 changed files with 159 additions and 15 deletions

View File

@ -5,12 +5,11 @@ import os
from datetime import datetime, timedelta, date from datetime import datetime, timedelta, date
import pandas as pd import pandas as pd
import mplfinance as mpf import mplfinance as mpf
import sqlite3
import stock_database
import mysql_database import mysql_database
from EmailTest import send_email, parse_return_email from EmailTest import send_email, parse_return_email
from dataclasses import dataclass from dataclasses import dataclass
import time import time
import threading
''' '''
todo todo
@ -346,9 +345,10 @@ class TurtleTrading_OnTime(object):
3实时监测主流程 3实时监测主流程
''' '''
def __init__(self, turtle: TurtleTrading, user_email): def __init__(self, turtles: list[TurtleTrading], user_email):
self.turtle = turtle self.turtles = turtles # List of TurtleTrading instances
self.user_email = user_email self.user_email = user_email
self.email_events = {} # Track email response events for each turtle
def get_stocks_data(self): def get_stocks_data(self):
"""获取实时股票、基金数据,不保存 """获取实时股票、基金数据,不保存
@ -717,18 +717,22 @@ class TurtleTrading_OnTime(object):
# ------------------准备阶段-------------------- # ------------------准备阶段--------------------
# 获取数据或读取数据 -- 计算ATR Donchian 20 50 up, 20 down # 获取数据或读取数据 -- 计算ATR Donchian 20 50 up, 20 down
self.turtle.get_ready(100) # 初始化所有turtle
self.turtle.N = float(self.turtle.CurrentData['ATR'].iloc[-1]) for turtle in self.turtles:
self.turtle.prev_heigh = float(self.turtle.CurrentData['最高价'].iloc[-1]) # 准备数据
self.turtle.Donchian_20_up = float(self.turtle.CurrentData['Donchian_20_upper'].iloc[-1]) turtle.get_ready(100)
self.turtle.Donchian_50_up = float(self.turtle.CurrentData['Donchian_50_upper'].iloc[-1]) turtle.N = float(turtle.CurrentData['ATR'].iloc[-1])
self.turtle.Donchian_10_down = float(self.turtle.CurrentData['Donchian_10_lower'].iloc[-1]) turtle.prev_heigh = float(turtle.CurrentData['最高价'].iloc[-1])
self.turtle.CalPositionSize() 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])
turtle.CalPositionSize()
# ------------------实时监测阶段-------------------- # ------------------实时监测阶段--------------------
# 9:00 1、判断是否是新的一周是则重新计算Position Size # 9:00 1、判断是否是新的一周是则重新计算Position Size
# 判断是否是新的一周 # 判断是否是新的一周
if datetime.now().weekday() == 0: if datetime.now().weekday() == 0:
self.turtle.CalPositionSize() for turtle in self.turtles:
turtle.CalPositionSize()
# 每分钟获取一次数据,判断是否触发条件 9:30-11:30 13:00-15:00 # 每分钟获取一次数据,判断是否触发条件 9:30-11:30 13:00-15:00
while True: while True:
@ -757,8 +761,9 @@ class TurtleTrading_OnTime(object):
break break
# 获取股票和ETF数据 # 获取股票和ETF数据
stock_data, etf_data = self.get_stocks_data() self.monitor_all_turtles()
self.run_short_trading_loop(stock_data, etf_data) # 等待一段时间后再次检查
time.sleep(60) # 每分钟检查一次
# ------------------结束阶段-------------------- # ------------------结束阶段--------------------
# 数据库更新当天数据增加ATR、donchian数据 # 数据库更新当天数据增加ATR、donchian数据
# 直接做个新表 # 直接做个新表
@ -766,6 +771,110 @@ class TurtleTrading_OnTime(object):
self.turtle.get_ready(100) self.turtle.get_ready(100)
time.sleep(16.5*600) time.sleep(16.5*600)
def monitor_all_turtles(self):
"""主监控循环"""
# 获取实时数据
stock_data, etf_data = self.get_stocks_data()
# 遍历所有turtle进行监控
for turtle in self.turtles:
self.monitor_single_turtle(turtle, stock_data, etf_data)
def monitor_single_turtle(self, turtle: TurtleTrading, stock_data, etf_data):
"""监控单个turtle的交易条件"""
now = datetime.now().time()
if turtle.type == "stock":
turtle.PriceNow = float(stock_data.loc[etf_data['代码'] == self.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])
if now.hour == 9 and now.minute == 30 and self.turtle.PriceNow > self.turtle.prev_heigh:
turtle.is_gap_up = True
# 判断当前仓位状态并执行相应操作
if turtle.TrigerTime == 0:
if turtle.system1EnterNormal(
turtle.PriceNow,
turtle.Donchian_20_up,
turtle.BreakOutLog
):
self.start_email_thread(turtle, "买入", turtle.PriceNow)
# 突破 记录self.turtle.breakoutlog
today = datetime.now().strftime("%Y-%m-%d")
breakout_this_time = BreakOutLog(today,
turtle.Donchian_20_up,
turtle.Donchian_20_up - 2 * turtle.N,
'valid',
None)
turtle.BreakOutLog.append(breakout_this_time)
elif turtle.system1EnterSafe(
turtle.PriceNow,
turtle.Donchian_50_up
):
self.start_email_thread(turtle, "买入", turtle.PriceNow)
elif 1 <= turtle.TrigerTime <= 3:
# 加仓状态
if turtle.add(turtle.PriceNow):
self.start_email_thread(turtle, "加仓", turtle.PriceNow)
# 止损状态
elif turtle.system_1_stop(turtle.PriceNow):
self.start_email_thread(turtle, "止损", turtle.PriceNow)
# 止盈
elif turtle.system_1_Out(
turtle.PriceNow,
turtle.Donchian_10_down
):
self.start_email_thread(turtle, "止盈", turtle.PriceNow)
elif turtle.TrigerTime == 4:
# 满仓 止损 止盈
if turtle.system_1_stop(turtle.PriceNow):
self.start_email_thread(turtle, "止损", turtle.PriceNow)
elif turtle.system_1_Out(
turtle.PriceNow,
turtle.Donchian_10_down
):
self.start_email_thread(turtle, "止盈", turtle.PriceNow)
def start_email_thread(self, turtle, 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()
def handle_email_response(self, turtle, action, price_now, event):
"""处理邮件响应的线程"""
# 发送邮件
if action == "买入":
self.Buy_stock(price_now)
elif action == "加仓":
self.add_stock(price_now)
elif action == "止损":
self.stop_sale_stock(price_now)
elif action == "止盈":
self.out_sale_stock(price_now)
# 等待邮件响应
event.wait()
if __name__ == '__main__': if __name__ == '__main__':
user_email = "guoyize2209@163.com" user_email = "guoyize2209@163.com"

View File

@ -10,6 +10,7 @@ from EmailTest import send_email, parse_return_email
from dataclasses import dataclass from dataclasses import dataclass
import time import time
import threading import threading
import yaml # 添加YAML支持
''' '''
todo todo
@ -90,6 +91,7 @@ class TurtleTrading(object):
self.cash = cash self.cash = cash
self.TrigerTime = 0 self.TrigerTime = 0
self.BuyStates = list[BuyState] self.BuyStates = list[BuyState]
self.state_file = f"state_{self.TradeCode}.yaml" # 状态文件名
self.tradeslog = list[TradeLog] self.tradeslog = list[TradeLog]
self.BreakOutLog = list[BreakOutLog] self.BreakOutLog = list[BreakOutLog]
@ -335,7 +337,40 @@ class TurtleTrading(object):
return False return False
def day_end(self): def day_end(self):
pass self.save_state() # 每日结束保存状态
def save_state(self):
"""保存当前状态到YAML文件"""
state_data = {
'TrigerTime': self.TrigerTime,
'BuyStates': [vars(bs) for bs in self.BuyStates],
'tradeslog': [vars(tl) for tl in self.tradeslog],
'BreakOutLog': [vars(bol) for bol in self.BreakOutLog],
'PriceNow': self.PriceNow,
'Donchian_20_up': self.Donchian_20_up,
'Donchian_10_down': self.Donchian_10_down,
'Donchian_50_up': self.Donchian_50_up,
'is_gap_up': self.is_gap_up,
'prev_heigh': self.prev_heigh
}
with open(self.state_file, 'w') as file:
yaml.dump(state_data, file)
def load_state(self):
"""从YAML文件加载状态"""
if os.path.exists(self.state_file):
with open(self.state_file, 'r') as file:
state_data = yaml.safe_load(file)
self.TrigerTime = state_data['TrigerTime']
self.BuyStates = [BuyState(**bs) for bs in state_data['BuyStates']]
self.tradeslog = [TradeLog(**tl) for tl in state_data['tradeslog']]
self.BreakOutLog = [BreakOutLog(**bol) for bol in state_data['BreakOutLog']]
self.PriceNow = state_data['PriceNow']
self.Donchian_20_up = state_data['Donchian_20_up']
self.Donchian_10_down = state_data['Donchian_10_down']
self.Donchian_50_up = state_data['Donchian_50_up']
self.is_gap_up = state_data['is_gap_up']
self.prev_heigh = state_data['prev_heigh']
class TurtleTrading_OnTime(object): class TurtleTrading_OnTime(object):
''' 实时监测主程序可以处理多个turtle ''' 实时监测主程序可以处理多个turtle