### Initialize Strategy with Stock List and Context Source: https://github.com/khscience/oskhquant/blob/main/README.md The `init` function is called once at the start of a backtest or trading task. Use it for global setup like parameter configuration or data loading. It receives the stock pool and initialization context. ```python def init(stock_list, context): pass ``` -------------------------------- ### Basic Strategy Framework Structure Source: https://github.com/khscience/oskhquant/blob/main/README.md This is a minimal template for a strategy file, including the essential callback functions: init, khHandlebar, khPreMarket, and khPostMarket. It serves as a starting point for developing new trading strategies. ```python from typing import Dict, List def init(stock_list, context): """ 策略初始化函数,在任务开始时仅执行一次。 用于定义全局变量、加载外部数据等。 """ pass def khHandlebar(context: Dict) -> List[Dict]: """ 策略核心逻辑,会被框架根据设定的频率反复调用。 负责行情判断和生成交易信号。 """ signals = [] return signals def khPreMarket(context: Dict) -> List[Dict]: """ 盘前处理函数(可选)。 在每日开盘前的指定时间点调用。 """ signals = [] return signals def khPostMarket(context: Dict) -> List[Dict]: """ 盘后处理函数(可选)。 在每日收盘后的指定时间点调用。 """ signals = [] return signals ``` -------------------------------- ### Create a Buy Trade Signal Source: https://github.com/khscience/oskhquant/blob/main/README.md Example of a standard trade signal dictionary for buying shares. It includes the stock code, action, price, volume, and a reason for the trade. ```python # 以10.5元的价格买入100股平安银行 signal_1 = { 'code': '000001.SZ', 'action': 'buy', 'price': 10.5, 'volume': 100, 'reason': 'MACD金叉买入' } ``` -------------------------------- ### Create a Sell Trade Signal Source: https://github.com/khscience/oskhquant/blob/main/README.md Example of a standard trade signal dictionary for selling shares. It specifies the stock code, action, price, volume, and a reason for the sale, such as reaching a profit target. ```python # 以18.5元的价格卖出200股贵州茅台 signal_2 = { 'code': '600519.SH', 'action': 'sell', 'price': 18.50, 'volume': 200, 'reason': '达到止盈位卖出' } ``` -------------------------------- ### Calculate Number of Trading Days Between Two Dates Source: https://github.com/khscience/oskhquant/blob/main/README.md Use the `get_trade_days_count()` method with start and end dates in 'YYYY-MM-DD' format to compute the total number of A-share trading days within that period. ```python # 计算2024年全年的交易日天数 days = tools.get_trade_days_count("2024-01-01", "2024-12-31") print(f"2024年共有 {days} 个交易日。") ``` -------------------------------- ### init(stock_list, context) Source: https://github.com/khscience/oskhquant/blob/main/README.md Initializes the strategy once at the beginning of a backtest or trading task. Used for setting up global parameters and loading data. ```APIDOC ## init(stock_list, context) ### Description Initializes the strategy once at the beginning of a backtest or trading task. Used for setting up global parameters and loading data. ### Parameters #### Path Parameters - **stock_list** (list) - Required - Framework-provided stock pool list. - **context** (dict) - Required - Dictionary containing initialization context information. - **__current_time__** (dict) - Current time information. - **timestamp** (int) - Standard Unix timestamp. - **datetime** (str) - 'YYYY-MM-DD HH:MM:SS' format. - **date** (str) - 'YYYY-MM-DD' format. - **time** (str) - 'HH:MM:SS' format. - **__account__** (dict) - Account funding information. - **account_type** (str) - Account type (e.g., 'STOCK'). - **account_id** (str) - Account ID. - **cash** (float) - Available cash. - **frozen_cash** (float) - Frozen cash. - **market_value** (float) - Position market value. - **total_asset** (float) - Total assets. - **benchmark** (str) - Benchmark index code. - **__positions__** (dict) - Position information (usually empty at initialization). - **__framework__** (object) - Instance of the framework's core class. ``` -------------------------------- ### Retrieve Framework Configuration in Strategy Source: https://github.com/khscience/oskhquant/blob/main/README.md Demonstrates how to access the framework's configuration object within a strategy to retrieve parameters like benchmark code and commission rates. ```python def init(stock_list, context): # 从框架对象中获取配置实例 config = context['__framework__'].config # 读取回测配置中的 'benchmark' 参数 benchmark_code = config.get_config('backtest.benchmark') print(f"当前配置的基准合约为: {benchmark_code}") # 读取交易成本中的佣金比例 commission_rate = config.get_config('backtest.trade_cost.commission_rate') print(f"当前配置的佣金比例为: {commission_rate}") ``` -------------------------------- ### khQTTools Module for Strategy Utilities Source: https://github.com/khscience/oskhquant/blob/main/README.md The khQTTools module provides a collection of utility functions to simplify strategy development, covering time checks, trading calculations, and data retrieval. ```APIDOC ## Strategy Utility Tools (`khQTTools`) ### Description The `khQTTools.py` module offers a suite of efficient utility functions to streamline strategy development. These tools assist with time-based conditions, trading calculations, data fetching, and more, helping developers implement complex logic efficiently. ### Importing Tools Import desired functions from `khQTTools` at the beginning of your strategy file: ```python from khQTTools import ( KhQuTools, calculate_max_buy_volume, generate_signal, get_stock_names, khHistory ) ``` ### 1. Time Utilities (`KhQuTools`) `KhQuTools` is a class encapsulating common time-checking functionalities. It needs to be instantiated before use. ```python # Instantiate in the init function or global scope of your strategy tools = KhQuTools() ``` #### `is_trade_time()` * **Function**: Checks if the current time falls within standard A-share trading hours (09:30-11:30, 13:00-15:00). * **Returns**: `bool` - `True` if within trading hours, `False` otherwise. * **Usage**: Ensures trading logic executes only during market open periods. **Example:** ```python def khHandlebar(context: Dict) -> List[Dict]: if not tools.is_trade_time(): return [] # Not a trading time, exit early # ... Trading logic for within market hours ... logging.info("Within trading hours, executing strategy.") return [] ``` #### `is_trade_day(date_str=None)` * **Function**: Determines if a given date is an A-share trading day, excluding weekends and public holidays. * **Parameters**: * `date_str` (str, Optional): Date string in `YYYY-MM-DD` format. If omitted, defaults to the current day. * **Returns**: `bool` - `True` if it's a trading day, `False` otherwise. **Example:** ```python # Check if October 1, 2024, is a trading day is_trading = tools.is_trade_day("2024-10-01") print(f"Is 2024-10-01 a trading day? {'Yes' if is_trading else 'No'}") # Check if today is a trading day is_today_trading = tools.is_trade_day() print(f"Is today a trading day? {'Yes' if is_today_trading else 'No'}") ``` #### `get_trade_days_count(start_date, end_date)` * **Function**: Calculates the number of A-share trading days between two specified dates. * **Parameters**: * `start_date` (str): Start date in `YYYY-MM-DD` format. * `end_date` (str): End date in `YYYY-MM-DD` format. * **Returns**: `int` - The total count of trading days. **Example:** ```python # Calculate the number of trading days in 2024 days = tools.get_trade_days_count("2024-01-01", "2024-12-31") print(f"There are {days} trading days in 2024.") ``` ### 2. Trading Auxiliary Functions #### `calculate_max_buy_volume(data, stock_code, price, cash_ratio=1.0)` * **Function**: Calculates the maximum theoretical volume of shares that can be bought, given available cash and stock price. Automatically rounds down to the nearest 100 shares. * **Parameters**: * `data` (dict): The `context` object passed to the strategy callback function. * `stock_code` (str): The code of the stock to be bought. * `price` (float): The intended purchase price. * `cash_ratio` (float, Optional): The proportion of available cash to use for the purchase. Defaults to `1.0` (all available cash). * **Returns**: `int` - The maximum number of shares that can be purchased. **Example:** ```python def khHandlebar(context: Dict) -> List[Dict]: # Plan to use 50% of available cash to buy Ping An Bank stock stock_to_buy = '000001.SZ' current_price = context.get(stock_to_buy)['close'] # Get current price # Calculate the maximum number of shares that can be bought max_volume = calculate_max_buy_volume(context, stock_to_buy, current_price, cash_ratio=0.5) if max_volume > 0: logging.info(f"Sufficient funds, planning to buy {max_volume} shares of {stock_to_buy} at {current_price}") # ... Subsequent logic to generate and return trading signals ... return [] ``` ``` -------------------------------- ### Instantiate KhQuTools for Time Utilities Source: https://github.com/khscience/oskhquant/blob/main/README.md Create an instance of the KhQuTools class, typically in the init function or global scope of your strategy, to access its time-related utility methods. ```python # 在init函数或策略的全局部分实例化 tools = KhQuTools() ``` -------------------------------- ### Import khQuant Strategy Utility Functions Source: https://github.com/khscience/oskhquant/blob/main/README.md Import essential utility functions from the khQTTools module at the beginning of your strategy file to streamline development. These tools cover time checks, calculations, and data retrieval. ```python # 在策略文件顶部导入工具函数 from khQTTools import ( KhQuTools, calculate_max_buy_volume, generate_signal, get_stock_names, khHistory ) ``` -------------------------------- ### Log Strategy Events with Python Logging Source: https://github.com/khscience/oskhquant/blob/main/README.md Import and use Python's standard logging module to output information, warnings, and errors from your strategy code. This helps in debugging and monitoring strategy execution within the khQuant system. ```python import logging from typing import Dict, List def khHandlebar(context: Dict) -> List[Dict]: # 检查账户现金 cash = context['__account__']['cash'] logging.info(f"当前可用资金: {cash}") if cash < 10000: logging.warning("可用资金不足1万元,跳过本次交易机会。") return [] # ...后续策略逻辑... try: # 可能会出错的代码 risky_value = 1 / 0 except Exception as e: logging.error(f"计算风险值时发生严重错误: {e}", exc_info=True) # exc_info=True会记录完整的错误堆栈 return [] ``` -------------------------------- ### khPostMarket(context) Source: https://github.com/khscience/oskhquant/blob/main/README.md Optional function called once at a specified post-market time each trading day. Useful for daily performance review, data saving, or preparing for the next trading day. ```APIDOC ## khPostMarket(context) ### Description Optional function called once at a specified post-market time each trading day. Useful for daily performance review, data saving, or preparing for the next trading day. ### Parameters #### Path Parameters - **context** (dict) - Required - The structure is identical to the `context` in `khHandlebar`. It contains information for the last market data point of the day, including account, positions, and market data for all stocks in the pool. ### Return Value - **List[Dict]**: A list of trading signals, similar to `khHandlebar`. ``` -------------------------------- ### Implement Take-Profit and Stop-Loss for Positions Source: https://github.com/khscience/oskhquant/blob/main/README.md Checks for specific stock positions and generates sell signals based on profit ratio. It implements a 10% take-profit and a 5% stop-loss logic. ```python def khHandlebar(context: Dict) -> List[Dict]: positions = context['__positions__'] signals = [] # 检查是否持有 '600519.SH' (贵州茅台) if '600519.SH' in positions: # 获取该持仓的详细信息 pos_info = positions['600519.SH'] volume = pos_info['volume'] profit_ratio = pos_info['profit_ratio'] # 获取持仓盈亏率 print(f"持有 {volume} 股 600519.SH,当前盈利 {profit_ratio*100:.2f}%") # 止盈逻辑:如果盈利超过10%,就全部卖出 if profit_ratio > 0.10: sell_signal = { 'action': 'sell', 'code': '600519.SH', 'volume': volume, # 卖出全部持仓 'remark': '盈利超过10%,止盈' } signals.append(sell_signal) # 止损逻辑:如果亏损超过5%,就全部卖出 elif profit_ratio < -0.05: sell_signal = { 'action': 'sell', 'code': '600519.SH', 'volume': volume, # 卖出全部持仓 'remark': '亏损超过5%,止损' } signals.append(sell_signal) return signals ``` -------------------------------- ### Strategy Logging with Python's logging Module Source: https://github.com/khscience/oskhquant/blob/main/README.md Utilize Python's built-in logging module to output information, warnings, and errors directly from your strategy code. These logs are integrated with the Kanhai Quant Trading System's logging infrastructure, appearing in the interface and files. ```APIDOC ## Logging in Strategies ### Description Integrate logging into your strategy code to facilitate debugging and monitoring of the strategy's internal state. The framework configures Python's standard `logging` module, allowing direct use of its functions. ### Usage 1. Import the `logging` module at the top of your strategy file: `import logging`. 2. Call standard logging functions like `logging.info()`, `logging.warning()`, `logging.error()`, and `logging.debug()`. ### Log Levels and Interface Colors * **INFO (White)**: For general flow information or variable states. Example: `logging.info("Entering long position condition")`. * **DEBUG (Light Purple)**: For detailed information useful during debugging. Example: `logging.debug(f"Current ATR value: {atr_value}")`. (May require configuration to display). * **WARNING (Orange)**: For non-fatal but noteworthy situations. Example: `logging.warning("Failed to fetch latest market data, using previous period data as fallback")`. * **ERROR (Red)**: For critical errors that may prevent further logic execution. Example: `logging.error("Division by zero error during indicator calculation")`. ### Example ```python import logging from typing import Dict, List def khHandlebar(context: Dict) -> List[Dict]: cash = context['__account__']['cash'] logging.info(f"Current available funds: {cash}") if cash < 10000: logging.warning("Available funds less than 10,000, skipping this trading opportunity.") return [] try: risky_value = 1 / 0 except Exception as e: logging.error(f"Critical error during risk value calculation: {e}", exc_info=True) return [] ``` ### Emphasizing Log Messages To make a log message particularly stand out in the interface, use `logging.warning()` or `logging.error()`. `ERROR` (red) is the most prominent and typically indicates a problem that must be addressed. `WARNING` (orange) is also noticeable and suitable for highlighting potential risks or states needing attention. Choose the level based on the message's importance and urgency. ``` -------------------------------- ### 输出不同级别日志信息 Source: https://github.com/khscience/oskhquant/blob/main/README.md 在策略代码中调用self.log()方法输出不同级别的日志,对应界面上的不同颜色显示。适用于调试、信息记录和错误报告。 ```python self.log("进入长仓条件判断", "INFO") ``` ```python self.log("当前ATR值", "DEBUG") ``` ```python self.log("无法获取最新行情,使用上一周期数据代替", "WARNING") ``` ```python self.log("计算指标时出现除零错误", "ERROR") ``` ```python self.log(f"信号触发,准备买入", "TRADE") ``` -------------------------------- ### Main Strategy Logic with Context Source: https://github.com/khscience/oskhquant/blob/main/README.md The `khHandlebar` function is the core of the trading strategy, executed repeatedly based on the 'run driver' settings. It processes the context, which includes current time, account, positions, and market data for each stock, and returns trading signals. ```python def khHandlebar(context): pass ``` -------------------------------- ### Calculate Maximum Buyable Volume Based on Cash and Price Source: https://github.com/khscience/oskhquant/blob/main/README.md Employ the `calculate_max_buy_volume()` function to determine the maximum number of shares you can purchase for a given stock at a specific price, considering available cash and an optional cash ratio. The result is automatically rounded down to the nearest 100 shares. ```python def khHandlebar(context: Dict) -> List[Dict]: # 计划用50%的资金买入平安银行 stock_to_buy = '000001.SZ' current_price = context.get(stock_to_buy)['close'] # 获取当前价 # 计算最多能买多少股 max_volume = calculate_max_buy_volume(context, stock_to_buy, current_price, cash_ratio=0.5) if max_volume > 0: logging.info(f"资金足够,计划以 {current_price} 的价格买入 {max_volume} 股 {stock_to_buy}") # ...后续可以生成并返回交易信号 return [] ``` -------------------------------- ### Calculate Buy Volume Based on Account Funds Source: https://github.com/khscience/oskhquant/blob/main/README.md Calculates the volume of stock to buy based on available cash, using 20% of available funds. It retrieves stock price and rounds down the buyable volume to the nearest 100 shares. ```python def khHandlebar(context: Dict) -> List[Dict]: account = context['__account__'] # 获取当前可用资金 available_cash = account['cash'] # 设定一个目标仓位:使用当前可用资金的20% cash_to_use = available_cash * 0.2 # 获取 '000001.SZ' 的当前价格 stock_data = context.get('000001.SZ') if stock_data is not None and not stock_data.empty: stock_price = stock_data['close'] # 计算理论上可以买入多少股,并向下取整到100的倍数 if stock_price > 0: volume_to_buy = int(cash_to_use / stock_price / 100) * 100 if volume_to_buy > 0: print(f"资金充足,计划以 {stock_price} 元的价格买入 {volume_to_buy} 股 000001.SZ") # 此处可以构建并返回一个买入信号 return [] ``` -------------------------------- ### khPreMarket(context) Source: https://github.com/khscience/oskhquant/blob/main/README.md Optional function called once at a specified pre-market time each trading day. Useful for daily stock selection, factor calculation, or resetting states. ```APIDOC ## khPreMarket(context) ### Description Optional function called once at a specified pre-market time each trading day. Useful for daily stock selection, factor calculation, or resetting states. ### Parameters #### Path Parameters - **context** (dict) - Required - The structure is identical to the `context` in `khHandlebar`. It contains information for the first market data point of the day, including account, positions, and market data for all stocks in the pool. ### Return Value - **List[Dict]**: A list of trading signals, similar to `khHandlebar`. ``` -------------------------------- ### Post-Market Processing Function Source: https://github.com/khscience/oskhquant/blob/main/README.md The `khPostMarket` function is optionally called once per trading day at a specified post-market time. It receives the same context as `khHandlebar` and is useful for daily performance analysis or saving strategy states. It returns trading signals. ```python def khPostMarket(context): pass ``` -------------------------------- ### khHandlebar(context) Source: https://github.com/khscience/oskhquant/blob/main/README.md The main strategy logic function, called repeatedly by the framework based on trigger settings. Implements trading logic like market analysis, signal generation, and order placement. ```APIDOC ## khHandlebar(context) ### Description The main strategy logic function, called repeatedly by the framework based on trigger settings. Implements trading logic like market analysis, signal generation, and order placement. ### Parameters #### Path Parameters - **context** (dict) - Required - Dictionary containing all available information at the current time point. - **__current_time__** (dict) - Current time information. - **timestamp** (int) - Standard Unix timestamp. - **datetime** (str) - 'YYYY-MM-DD HH:MM:SS' format. - **date** (str) - 'YYYY-MM-DD' format. - **time** (str) - 'HH:MM:SS' format. - **__account__** (dict) - Account funding information. - **account_type** (str) - Account type. - **account_id** (str) - Account ID. - **cash** (float) - Available cash. - **frozen_cash** (float) - Frozen cash. - **market_value** (float) - Position market value. - **total_asset** (float) - Total assets. - **benchmark** (str) - Benchmark index code. - **__positions__** (dict) - Current position information. Structure: `{stock_code: position_details}`. - **position_details** (dict) - Details of a stock's position. - **account_type** (int) - Account type. - **account_id** (str) - Account ID. - **stock_code** (str) - Stock code. - **volume** (int) - Position volume. - **can_use_volume** (int) - Usable volume (sellable). - **open_price** (float) - Opening price for the day. - **market_value** (float) - Position market value. - **frozen_volume** (int) - Frozen volume. - **on_road_volume** (int) - Volume on the way. - **yesterday_volume** (int) - Yesterday's position volume. - **avg_price** (float) - Average cost price. - **current_price** (float) - Current market price. - **direction** (int) - Position direction. - **profit** (float) - Floating profit/loss. - **profit_ratio** (float) - Profit/loss ratio. - **__framework__** (object) - Instance of the framework's core class. - **[stock_code]** (pandas.Series) - Market data for a specific stock code (e.g., '000001.SZ') including fields like open, high, low, close, volume. ### Return Value - **List[Dict]**: A list of trading signals. Each signal is a dictionary. - **code** (str) - Required - Stock code (e.g., '000001.SZ'). - **action** (str) - Required - Trading action ('buy' or 'sell'). - **price** (float) - Required - Trading price. - **volume** (int) - Required - Trading volume (must be a multiple of 100). - **reason** (str) - Optional - Reason or remark for the trade. - **timestamp** (int) - Optional - Timestamp when the signal was generated. ``` -------------------------------- ### Accessing Time Information from Context Source: https://github.com/khscience/oskhquant/blob/main/README.md Time-related data is available within the `context['__current_time__']` dictionary. Access Unix timestamps, formatted datetime strings, dates, or times as needed for your strategy logic. ```python def khHandlebar(context: Dict) -> List[Dict]: time_info = context['__current_time__'] # 获取当前时间字符串,如 '09:31:00' current_time = time_info['time'] # 简单的交易时间控制:只在上午10点后、下午2点半前进行交易判断 if "10:00:00" < current_time < "14:30:00": # 在这里编写主要的策略逻辑... print("处于交易时间段,执行策略。" ) else: # 非交易时间段,不执行任何操作 print("非交易时间段,跳过。" ) return [] ``` -------------------------------- ### Pre-Market Processing Function Source: https://github.com/khscience/oskhquant/blob/main/README.md The `khPreMarket` function is optionally called once per trading day at a specified pre-market time. It receives the same context as `khHandlebar` and can be used for daily stock selection or resetting states. It returns trading signals. ```python def khPreMarket(context): pass ``` -------------------------------- ### Check if Current Time is within A-Share Trading Hours Source: https://github.com/khscience/oskhquant/blob/main/README.md Use the `is_trade_time()` method from an instantiated `KhQuTools` object to determine if the current moment falls within the standard A-share trading hours (09:30-11:30 and 13:00-15:00). This is useful for ensuring trading logic only executes during active market periods. ```python def khHandlebar(context: Dict) -> List[Dict]: if not tools.is_trade_time(): return [] # 非交易时间,直接返回 # ... 在此编写交易时间内的策略逻辑 ... logging.info("交易时间内,执行策略。") return [] ``` -------------------------------- ### Determine if a Specific Date is an A-Share Trading Day Source: https://github.com/khscience/oskhquant/blob/main/README.md Utilize the `is_trade_day()` method, optionally providing a date string in 'YYYY-MM-DD' format, to check if a given day is a trading day, excluding weekends and holidays. If no date is provided, it defaults to checking the current day. ```python # 判断2024年10月1日是否是交易日 is_trading = tools.is_trade_day("2024-10-01") print(f"2024-10-01 是交易日吗? {'是' if is_trading else '否'}") # 判断今天是否是交易日 is_today_trading = tools.is_trade_day() print(f"今天是交易日吗? {'是' if is_today_trading else '否'}") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.