20250408修改

This commit is contained in:
2025-04-09 17:18:30 +08:00
parent f925dff46b
commit aaf2224484
146 changed files with 157794 additions and 5718 deletions

View File

@@ -6,6 +6,7 @@ import os
import ast
import time
from datetime import datetime
import requests
# 加入邮件通知
import smtplib
@@ -65,6 +66,332 @@ os.chdir(new_directory)
updated_directory = os.getcwd()
print("已更改为新的工作目录:", updated_directory)
# 获取当前文件夹中所有包含"ofdata"字符的CSV文件
def get_csv_files():
files = {}
for filename in os.listdir():
if "ofdata" in filename and filename.endswith(".csv"):
files[filename] = os.path.join(os.getcwd(), filename)
return files
def send_mail(text):
global last_sent_time, count
# 检查时间间隔
current_time = time.time()
print('count:',count)
if count == 1 and current_time - last_sent_time <1:
print("current_time:",current_time)
print("last_sent_time:",last_sent_time)
print("一分钟内已发送过邮件,本次跳过")
return
elif count ==1 and current_time - last_sent_time >1:
count = 0
if count == 0 and current_time - last_sent_time < 1:
msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = ";".join(receivers)
msg["Subject"] = subject
html_content = f"""
<html>
<body>
<p>以下是数据的最后一列:</p>
{text}
</body>
</html>
"""
msg.attach(MIMEText(html_content, 'html'))
smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
smtp.login(username, password)
smtp.sendmail(sender, receivers, msg.as_string())
count = 1
smtp.quit()
# 根据文件路径加载数据只读取前12列
def load_data(file_path):
df = pd.read_csv(file_path, usecols=range(12)).iloc[-1200:] # 只读取前12列
df = df.drop_duplicates(subset='datetime', keep='first').reset_index(drop=True)
# df = df[df['high'] != df['low']]
df["delta"] = df["delta"].astype(float)
df['datetime'] = pd.to_datetime(df['datetime'],format='ISO8601')#, dayfirst=True, format='mixed'
# df['delta累计'] = df.groupby(df['datetime'].dt.date)['delta'].cumsum()
# 自定义分组逻辑前一日21:00至当日15:00为一天
def get_trading_day(dt):
# 如果时间在21:00之后属于下一个交易日
if dt.hour >= 21:
return (dt + pd.Timedelta(days=1)).date()
# 如果时间在15:00之前属于当前交易日
elif dt.hour < 15:
return dt.date()
# 15:00-21:00之间的数据属于当前交易日
else:
return dt.date()
# 添加交易日列并转换为字符串
df['trading_day'] = df['datetime'].apply(get_trading_day)
df['trading_day'] = df['trading_day'].astype(str) # 将日期转换为字符串
# 按交易日计算delta累计
df['delta累计'] = df.groupby('trading_day')['delta'].cumsum()
df = df.fillna('缺值')
df['终极平滑值'],df['趋势方向'] = ultimate_smoother(df['close'],time_period)
df['datetime'] = df['datetime'].dt.strftime("%Y-%m-%d %H:%M:%S")
df['POC'] = add_poc_column(df)
df['最终趋势'] = finall_trend(df['delta累计'],df['趋势方向'])
# print(df.tail(1))
# print(type(df['delta累计'].iloc[-1]))
# if len(df) >=time_period and (df['最终趋势'].iloc[-1] != df['最终趋势'].iloc[-2]):
# table_text = df.iloc[:,3:].tail(1).to_html(index=False) #price,Ask,Bid,symbol,datetime,delta,close,open,high,low,volume,dj
# send_mail(table_text)
# else:
# pass
# if df['最终趋势'].iloc[-1] != df['最终趋势'].iloc[-2]:
def send_feishu_message(text):
headers = {
"Content-Type": "application/json"
}
data = {
"msg_type": "text",
"content": {
"text": text
}
}
response = requests.post(FEISHU_WEBHOOK, headers=headers, json=data)
if response.status_code != 200:
print(f"飞书消息发送失败,状态码: {response.status_code}, 响应内容: {response.text}")
if len(df) >= 4*time_period:
if df['趋势方向'].iloc[-1] == '多头趋势' :
if delta_sum_trends(df['delta累计']) == 1 or delta_trends(df['delta']) == 1 or dj_trends(df['dj']) == 1:
table_text = df.iloc[:,3:].tail(1).to_html(index=False)
send_feishu_message("多头信号\n" + table_text)
if df['趋势方向'].iloc[-1] == '空头趋势' :
if delta_sum_trends(df['delta累计']) == -1 or delta_trends(df['delta']) == -1 or dj_trends(df['dj']) == -1:
table_text = df.iloc[:,3:].tail(1).to_html(index=False)
send_feishu_message("空头信号\n" + table_text)
else:
pass
return df.to_dict(orient="records")#.iloc[-48:]
# return df.iloc[-60:].iloc[::-1].to_dict(orient="records")
def finall_trend(delta_sum,trend):
f_trend = [None]*(len(delta_sum))
# delta_sum = delta_sum.astype(float)
for i in range(len(delta_sum)):
if (delta_sum[i] == '缺值') or (trend[i] == '缺值'):
f_trend[i] = '方向不明'
# return f_trend
else:
if delta_sum[i] > 0 and (trend[i] == '多头趋势'):
f_trend[i] = '强多头'
elif delta_sum[i] < 0 and (trend[i] == '空头趋势'):
f_trend[i] = '强空头'
else:
f_trend[i] = '方向不明'
return f_trend
def delta_sum_trends(delta_sum):
global delta_sum_trend
if delta_sum.iloc[-1] > 0 and delta_sum.iloc[-2] < 0:
delta_sum_trend = 1
elif delta_sum.iloc[-1] < 0 and delta_sum.iloc[-2] > 0:
delta_sum_trend = -1
else:
delta_sum_trend = 0
return delta_sum_trend
def delta_trends(delta):
global delta_trend, delta_rate, time_period
if delta.iloc[-1] > delta_rate * max(delta.iloc[-4 * time_period:-1]):
delta_trend = 1
elif delta.iloc[-1] < delta_rate * min(delta.iloc[-4 * time_period:-1]):
delta_trend = -1
else:
delta_trend = 0
return delta_trend
def dj_trends(dj):
global dj_trend,dj_rate,time_period
if dj.iloc[-1] > dj_rate * max(dj.iloc[-4* time_period:-1]):
dj_trend = 1
elif dj.iloc[-1] < dj_rate* min(dj.iloc[-4* time_period:-1]):
dj_trend = -1
else:
dj_trend = 0
return dj_trend
def safe_literal_eval(x):
"""带异常处理的安全转换"""
try:
return ast.literal_eval(x)
except ValueError:
return [] # 返回空列表作为占位符
def add_poc_column(df):
# 安全转换列数据
df['price'] = df['price'].apply(safe_literal_eval)
df['Ask'] = df['Ask'].apply(lambda x: list(map(int, safe_literal_eval(x))))
df['Bid'] = df['Bid'].apply(lambda x: list(map(int, safe_literal_eval(x))))
# 定义处理函数(带数据验证)
def find_poc(row):
# 验证三个列表长度一致且非空
if not (len(row['price']) == len(row['Ask']) == len(row['Bid']) > 0):
return '缺值' # 返回空值标记异常数据
sums = [a + b for a, b in zip(row['Ask'], row['Bid'])]
try:
max_index = sums.index(max(sums))
return row['price'][max_index]
except ValueError:
return '缺值' # 处理空求和列表情况
# 应用处理函数
df['POC'] = df.apply(find_poc, axis=1)
# 可选:统计异常数据
error_count = df['POC'].isnull().sum()
if error_count > 0:
print(f"警告:发现 {error_count} 行异常数据已标记为NaN")
return df['POC']
def ultimate_smoother(price,period):
# 初始化变量(修正角度单位为弧度)
a1 = np.exp(-1.414 * np.pi / period)
b1 = 2 * a1 * np.cos(1.414 * np.pi / period) # 将180改为np.pi
c2 = b1
c3 = -a1 ** 2
c1 = (1 + c2 - c3) / 4
# 准备输出序列
us = np.zeros(len(price))
us_new = np.zeros(len(price))
trend = [None]*(len(price))
ma_close = np.zeros(len(price))
# 前4个点用原始价格初始化
for i in range(len(price)):
if i < 4:
us[i] = price.iloc[i]
else:
# 应用递归公式
us[i] = (1 - c1) * price.iloc[i] + (2 * c1 - c2) * price.iloc[i-1] \
- (c1 + c3) * price.iloc[i-2] + c2 * us[i-1] + c3 * us[i-2]
us_new = np.around(us, decimals=2)
ma_close = price.rolling(window=4*period).mean()#5*
# if us_new[i]>price[i] and ma_close[i]>price[i]:
# trend[i] = '空头趋势'
# elif us_new[i]<price[i] and ma_close[i]<price[i]:
# trend[i] = '多头趋势'
# else:
# trend[i] = '无趋势'
if us_new[i] < ma_close.iloc[i]:
trend[i] = '空头趋势'
elif us_new[i] > ma_close.iloc[i]:
trend[i] = '多头趋势'
else:
trend[i] = '无趋势'
return us_new,trend
@app.route("/")
def index():
return render_template("index.html")
@app.route("/kline")
def kline():
return render_template("kline.html")
@app.route("/api/data")
def get_data():
try:
files = get_csv_files()
data = {}
for symbol, filename in files.items():
loaded_data = load_data(filename)
if loaded_data:
data[symbol] = loaded_data
return jsonify(data)
except Exception as e:
return jsonify({"error": str(e)})
def should_update():
"""检查是否应该在当前时间更新数据"""
now = datetime.now()
# 检查是否是整点5分钟
if now.minute % 2 == 0:
# 检查是否在5秒内
if now.second < 2:
return True
return False
def background_thread():
"""后台线程在每整点5分钟的5秒内发送数据更新"""
while True:
if should_update():
files = get_csv_files()
data = {}
for file_name, file_path in files.items():
data[file_name] = load_data(file_path)
socketio.emit('data_update', data)
print(f"数据更新完成 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
time.sleep(1) # 每秒检查一次
@socketio.on('connect')
def handle_connect():
print('Client connected')
# 启动后台线程
socketio.start_background_task(background_thread)
@socketio.on('disconnect')
def handle_disconnect():
print('Client disconnected')
if __name__ == "__main__":
socketio.run(app, host='0.0.0.0', port=5000, debug=True) # 监听所有网络接口
# 删除原有的邮件发送函数和相关配置
# receivers = ["240884432@qq.com"]
# subject = "TD_Simnow_Signal"
# smtp_server = "smtp.qq.com"
# smtp_port = 465
# sender = "240884432@qq.com"
# username = "240884432@qq.com"
# password = "osjyjmbqrzxtbjbf"
# last_sent_time = 0
# count = 0
time_period = 30
delta_sum_trend,delta_trend,dj_trend = 0
delta_rate = 0.8
dj_rate = 0.8
# current_dir = os.path.dirname(os.path.abspath(__file__))
# os.chdir(current_dir)
# print("已更改为新的工作目录:", current_dir)
# 获取当前工作目录
current_directory = os.getcwd()
print("当前工作目录:", current_directory)
# 设置新的工作目录
new_directory = r"C:/simnow_trader/traderdata"
os.chdir(new_directory)
# 验证新的工作目录
updated_directory = os.getcwd()
print("已更改为新的工作目录:", updated_directory)
# 获取当前文件夹中所有包含"ofdata"字符的CSV文件
def get_csv_files():
files = {}