This commit is contained in:
summer 2025-07-05 17:31:46 +08:00
parent c4ad8b9398
commit 835f3ddb45
8 changed files with 99 additions and 33 deletions

View File

@ -138,4 +138,7 @@ class state:
return self.data["high_stock_list"]
def get_hold_list(self):
return self.data["position_list"]
return self.data["position_list"]

View File

@ -289,4 +289,5 @@ class DataHelper:
返回:
未买入的股票代码列表
"""
return [stock for stock in stock_list if stock not in not_buy_again]
return [stock for stock in stock_list if stock not in not_buy_again]

View File

@ -98,6 +98,9 @@ class Logger:
network_config.insert_logs(strategy_id, "critical", message)
except:
pass
# # 使用示例
# if __name__ == "__main__":
# # 示例1创建新的logger实例

View File

@ -91,4 +91,4 @@ class trade_strategy:
返回:
若下单成功部分或全部成交返回 True否则返回 False
"""
return self.channel.open_position(security, value)
return self.channel.open_position(security, value)

View File

@ -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

View File

@ -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
def buys_request(self, stock, data, reason):
self.temp_buys_list[f"{stock}_{reason}"] = data

View File

@ -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
def sell_request(self, stock, data, reason):
self.temp_sells_list[f"{stock}_{reason}"] = data

83
test.py
View File

@ -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):