From 835f3ddb4546c25b391ec7838a408bacccecb452 Mon Sep 17 00:00:00 2001 From: summer Date: Sat, 5 Jul 2025 17:31:46 +0800 Subject: [PATCH] init --- config/strategy_state.py | 5 +- kit/kit.py | 3 +- kit/logger.py | 3 + strategy.py | 2 +- task/base_task.py | 2 +- task/buy_stocks_func_task.py | 17 +++--- task/check_positions_stop_loss_task.py | 17 ++---- test.py | 83 ++++++++++++++++++++++---- 8 files changed, 99 insertions(+), 33 deletions(-) diff --git a/config/strategy_state.py b/config/strategy_state.py index ab771af..75707fb 100644 --- a/config/strategy_state.py +++ b/config/strategy_state.py @@ -138,4 +138,7 @@ class state: return self.data["high_stock_list"] def get_hold_list(self): - return self.data["position_list"] \ No newline at end of file + return self.data["position_list"] + + + diff --git a/kit/kit.py b/kit/kit.py index f973a1f..92b972e 100644 --- a/kit/kit.py +++ b/kit/kit.py @@ -289,4 +289,5 @@ class DataHelper: 返回: 未买入的股票代码列表 """ - return [stock for stock in stock_list if stock not in not_buy_again] \ No newline at end of file + return [stock for stock in stock_list if stock not in not_buy_again] + diff --git a/kit/logger.py b/kit/logger.py index afda4ad..8b59580 100644 --- a/kit/logger.py +++ b/kit/logger.py @@ -98,6 +98,9 @@ class Logger: network_config.insert_logs(strategy_id, "critical", message) except: pass + + + # # 使用示例 # if __name__ == "__main__": # # 示例1:创建新的logger实例 diff --git a/strategy.py b/strategy.py index 27d0ac0..6c8f0fc 100644 --- a/strategy.py +++ b/strategy.py @@ -91,4 +91,4 @@ class trade_strategy: 返回: 若下单成功(部分或全部成交)返回 True,否则返回 False """ - return self.channel.open_position(security, value) \ No newline at end of file + return self.channel.open_position(security, value) diff --git a/task/base_task.py b/task/base_task.py index 9141137..a81c4af 100644 --- a/task/base_task.py +++ b/task/base_task.py @@ -14,7 +14,7 @@ class base_task: self.strategy_config = self.strategy.get_strategy_config() self.configs = self.strategy.get_configs() - self.log = self.strategy.get_logger() + self.log = self.strategy.log def init(self, context: Any): pass diff --git a/task/buy_stocks_func_task.py b/task/buy_stocks_func_task.py index 7c6be47..8303401 100644 --- a/task/buy_stocks_func_task.py +++ b/task/buy_stocks_func_task.py @@ -31,6 +31,7 @@ class buy_stocks_func_task(base_task): self.today_trade_switch = self.get_config('today_trade_switch') self.temp_sells_list = {} self.temp_buys_list = {} + def run(self, context: Any): if not self.today_trade_switch: @@ -48,8 +49,8 @@ class buy_stocks_func_task(base_task): pos = context.portfolio.positions.get(stock) self.log.info(f"调仓决策:卖出股票 {stock}") # 通过持仓监控器注册卖出请求,而不是直接卖出 - self - #self.strategy.state.set_sell_request(stock, pos, 'rebalance') + self.sell_request(stock, pos, 'rebalance') + # self.strategy.state.set_sell_request(stock, pos, 'rebalance') self.sell_request(stock, pos, 'rebalance') else: self.log.info(f"调仓决策:继续持有股票 {stock}") @@ -59,8 +60,8 @@ class buy_stocks_func_task(base_task): if buy_targets: for stock in buy_targets: pos = context.portfolio.positions.get(stock) - #self.strategy.state.set_buy_request(stock, pos, 'buy') - self.buys_request(stock,pos,'buy') + # self.strategy.state.set_buy_request(stock, pos, 'buy') + self.buys_request(stock, pos, 'buy') self.log.info(f"调仓决策:将 {len(buy_targets)} 只股票加入待买入队列: {buy_targets}") def handle(self, context: Any): @@ -71,8 +72,8 @@ class buy_stocks_func_task(base_task): pass # 这里可以添加任何必要的清理或总结操作 - - def sell_request(self,stock,data,reason): + def sell_request(self, stock, data, reason): self.temp_sells_list[f"{stock}_{reason}"] = data - def buys_request(self,stock,data,reason): - self.temp_buys_list[f"{stock}_{reason}"] = data \ No newline at end of file + + def buys_request(self, stock, data, reason): + self.temp_buys_list[f"{stock}_{reason}"] = data diff --git a/task/check_positions_stop_loss_task.py b/task/check_positions_stop_loss_task.py index be9385e..869d47c 100644 --- a/task/check_positions_stop_loss_task.py +++ b/task/check_positions_stop_loss_task.py @@ -10,7 +10,6 @@ class check_positions_stop_loss_task(base_task): def __init__(self, strategy: trade_strategy): super().__init__(strategy) - def config(self, context: Any): self.stoploss_switch = self.get_config('stoploss_switch') # 是否启用止损策略 @@ -23,7 +22,6 @@ class check_positions_stop_loss_task(base_task): self.index_stocks = self.get_config('index_stocks') # 指数代码 self.temp_sells_list = {} - def run(self, context: Any): if len(self.hold_list) == 0: self.log.debug("当前无持仓,跳过止损检查。") @@ -37,14 +35,14 @@ class check_positions_stop_loss_task(base_task): if pos.price >= pos.avg_cost * 2: # 通过持仓监控器注册卖出请求,而不是直接卖出 # self.strategy.state.set_sell_request(stock, pos, 'take_profit') - self.sell_request(stock,pos,'take_profit') + self.sell_request(stock, pos, 'take_profit') self.log.debug(f"股票 {stock} 实现100%盈利,执行止盈卖出。") elif pos.price < pos.avg_cost * self.stoploss_stock_rate_data: # 通过持仓监控器注册卖出请求,而不是直接卖出 self.strategy.state.set_sell_request(stock, pos, 'stop_loss') - self.sell_request(stock,pos,'take_profit') + self.sell_request(stock, pos, 'take_profit') self.log.debug(f"股票 {stock} 触及止损阈值,执行卖出。") - #self.strategy.state.set_sell_reason("stoploss") + # self.strategy.state.set_sell_reason("stoploss") if self.stoploss_strategy == 2 or self.stoploss_strategy == 3: # 大盘止损判断,若整体市场跌幅过大则平仓所有股票 @@ -60,7 +58,7 @@ class check_positions_stop_loss_task(base_task): if df is not None and not df.empty: down_ratio = (df['close'] / df['open']).mean() if down_ratio <= self.stoploss_market_rate_data: - #self.strategy.state.set_sell_reason("stoploss") + # self.strategy.state.set_sell_reason("stoploss") self.log.debug(f"市场检测到跌幅(平均跌幅 {down_ratio:.2%}),卖出所有持仓。") for stock in list(context.portfolio.positions.keys()): pos = context.portfolio.positions[stock] @@ -79,8 +77,5 @@ class check_positions_stop_loss_task(base_task): self.log.info("当前卖出请求") pass - - - - def sell_request(self,stock,data,reason): - self.temp_sells_list[f"{stock}_{reason}"] = data \ No newline at end of file + def sell_request(self, stock, data, reason): + self.temp_sells_list[f"{stock}_{reason}"] = data diff --git a/test.py b/test.py index 5078d12..60e2eca 100644 --- a/test.py +++ b/test.py @@ -1,13 +1,13 @@ import logging import os from datetime import timedelta +from datetime import datetime import requests from typing import Any, Optional, List, Dict import pandas as pd -from strategy import trade_strategy class network_config: @@ -26,7 +26,8 @@ class network_config: "strategy_config": "mw1zi3dr5sy03em", # 查看项目URL获取 "strategy_base": "mtvgo6pbrlmbgjc", "strategy_config_template": "m4nty4o5t6sxzts", - "strategy_logs": "m8ebfypvbfpk38p" + "strategy_logs": "m8ebfypvbfpk38p", + "today_state": "mosii8hqry8xx9b" } pass @@ -143,6 +144,41 @@ class network_config: response = requests.post(url, headers=self.headers, data=data) response.raise_for_status() # 检查错误 + # def update_check(self, id: str, old_value: str, new_value: str): + # """ + # 更新网络配置参数 + # + # :return: + # """ + # PROJECT_ID = self.project_table['strategy_config'] + # url = f"{self.BASE_URL}/api/v2/tables/{PROJECT_ID}/records/" + # new_value = { + # "id": id, + # "old_value": old_value, + # "new_value": new_value, + # "create_date": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + # } + # update_response = requests.patch(url, headers=self.headers, json=new_value) + # update_response.raise_for_status() + # return update_response.json() + # + # def insert_check(self, strategy_id: str, key: str, value: str): + # """ + # 插入网络配置参数 + # """ + # PROJECT_ID = self.project_table['strategy_config'] + # url = f"{self.BASE_URL}/api/v2/tables/{PROJECT_ID}/records" + # data = { + # "strategy_id": strategy_id, + # "type": "check", + # "name": key, + # "new_value": value, + # "create_date": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), # 使用当前时间 + # + # } + # response = requests.post(url, headers=self.headers, data=data) + # response.raise_for_status() # 检查错误 + @staticmethod def insert_logs(strategy_id: str, log_type: str, log_content: str): """ @@ -167,6 +203,29 @@ class network_config: response = requests.post(url, headers=headers, data=data) response.raise_for_status() + @staticmethod + def insert_state(strategy_id: str,state_str:str,trade_date:str): + """ + + :param strategy_id: + :param state_str: + :param trade_date: + :return: + """ + PROJECT_ID = "mosii8hqry8xx9b" + url = f"http://101.34.79.70:8081/api/v2/tables/{PROJECT_ID}/records" + data = { + "strategy_id": strategy_id, + "trade_date": trade_date, # 使用当前时间 + "state": state_str + } + API_TOKEN = "mgIUTo_BATQnVPE3czsHLOLLgcQmnVv1qs7gJTIO" # 在用户设置中创建 + headers = { + "xc-token": API_TOKEN + } + response = requests.post(url, headers=headers, data=data) + response.raise_for_status() + class strategy_config: @@ -235,12 +294,12 @@ class strategy_config: id = self.configkey_id.get(key) self.connection.update_config(id, value) - -# if __name__ == "__main__": -# config_instance = strategy_config('aaa', '10000000', network_config(), None) + def get_config(self, key: str): + func = conf.config_type(key) + return func(key) + -from datetime import datetime class hold_data: @@ -377,6 +436,9 @@ class state: """ return self.data["high_stock_list"] + def get_hold_list(self): + return self.data["position_list"] + class conf: @@ -703,6 +765,7 @@ class DataHelper: return [stock for stock in stock_list if stock not in not_buy_again] + class Logger: """ 简单的日志操作类,支持控制台和文件输出 @@ -796,6 +859,8 @@ class Logger: network_config.insert_logs(strategy_id, "critical", message) except: pass + + class exchange: def close_positions(self, context: Any, position: Any): @@ -930,7 +995,8 @@ class trade_strategy: set_option('avoid_future_data', True) # 设置策略基准为上证指数 - set_benchmark(self.strategy_config.config["benchmark_stock"]) + # set_benchmark(self.strategy_config.config["benchmark_stock"]) + set_benchmark("000001.XSHG") # 使用真实市场价格,模拟实际交易 set_option('use_real_price', True) # 设置固定滑点,确保价格偏差不大 @@ -1034,9 +1100,6 @@ class base_task: return func(self.configs[key]['new_value'], data_params) -from kit.kit import DataHelper -from strategy import trade_strategy -from task.base_task import base_task class check_state_before_task(base_task):