量化编程之低位锤子线选股python源码

早上醒得早,就想翻看涨停票,涨停之前有什么特点。发现大部分会有这样一个走势,就是之前的某个时候,K线出现了低位锤子线。然后就是连续小幅上涨,可能会伴有小幅下跌。而小幅下跌无疑是个很好的入场机会。

那用python原来来选股应该怎么实现呢。于是打开豆包,输入如下提示词:

15日内低位长下影线锤子型K线,昨日收阴的股票,用Python编写成函数

豆包生成如下代码:

import pandas as pd
import numpy as np

def find_specific_stock(df):
    """
    筛选满足条件的股票
    :param df: 包含股票历史行情数据的DataFrame,至少包含open、high、low、close字段
    :return: 是否满足条件的布尔值
    """
    # 检查数据是否满足基本要求
    required_cols = ['open', 'high', 'low', 'close']
    for col in required_cols:
        if col not in df.columns:
            raise ValueError(f"数据中缺少必要的列: {col}")

    # 计算下影线长度,下影线长度 = min(open, close) - low
    df['lower_shadow'] = df.apply(lambda row: min(row['open'], row['close']) - row['low'], axis=1)
    # 计算实体长度,实体长度 = abs(open - close)
    df['body_length'] = df.apply(lambda row: abs(row['open'] - row['close']), axis=1)
    # 计算上影线长度,上影线长度 = high - max(open, close)
    df['upper_shadow'] = df.apply(lambda row: row['high'] - max(row['open'], row['close']), axis=1)

    # 找出15日内有低位长下影线锤子型K线的情况
    # 锤子型K线条件:
    # 1. 下影线长度至少是实体长度的2倍
    # 2. 上影线很短(这里设置为不超过实体长度的0.5倍)
    # 3. 收盘价高于开盘价
    is_hammer = (df['lower_shadow'] >= 2 * df['body_length']) & \
                (df['upper_shadow'] <= 0.5 * df['body_length']) & \
                (df['close'] > df['open'])
    
    # 判断是否处于相对低位(这里定义为收盘价在20日最低价的5%范围内)
    df['low_20'] = df['low'].rolling(window=20).min()
    is_low_price = df['close'] <= df['low_20'] * 1.05
    
    # 综合锤子线和低位条件
    has_hammer_low_price = is_hammer & is_low_price
    has_hammer_last_15 = np.any(has_hammer_low_price[-15:])

    # 检查昨日是否收阴,即昨日收盘价低于昨日开盘价
    is_yesterday_down = df['close'].iloc[-1] < df['open'].iloc[-1]

    return has_hammer_last_15 and is_yesterday_down    

上述代码优化了锤子线的判断条件,新增了上影线的判断,并加入了相对低位的定义(收盘价在 20 日最低价的 5% 范围内)。函数逻辑保持不变,依然返回是否满足条件的布尔值。

把这个函数结合掘金量化平台,整理成完整的策略代码,如下所示:

# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *
from datetime import datetime
from datetime import timedelta
import talib
import numpy as np
import pandas as pd
from MyTT import *
import snowater.common_func_new as cf

"""
在沪深A股筛选多头排列刚形成n天的股票
"""

# 常用参量设置
DATE_STR = "%Y-%m-%d"
TIME_STR = "%Y-%m-%d %H:%M:%S"

HIST_WINDOW = 300
LONG_PERIOD = 3


def init(context):
    # 全局变量设置
    context.dict_stock_price = dict()
    # 获取上一个交易日的日期
    last_day = get_previous_trading_date(exchange='SHSE', date=datetime.now())
    context.stock_pool = cf.get_instruments_all_stocks(context)
    context.stock_pool = cf.filter_stocks_by_financial_indicators(context.stock_pool, last_day)
    # 日期设定,避免出现未来函数,将起始日往前取一日
    start_date = datetime.strptime(last_day, DATE_STR)
    context.start_date = datetime.strftime(start_date - timedelta(days=200), TIME_STR)
    context.end_date = start_date
    symbols_pool = []
    # 获取起始日之前行情,便于计算指标
    for stock in context.stock_pool:
        history_info = history(symbol=stock, frequency='1d', start_time=context.start_date,
                               end_time=context.end_date, fields='eob,open,close,high,low,amount,volume', df=True,
                               skip_suspended=True, adjust=ADJUST_PREV,
                               adjust_end_time=context.end_date)

        if find_specific_stock(history_info):
            symbols_pool.append(stock)
            print(stock)
    print(f'选股完毕{symbols_pool}')


if __name__ == '__main__':
    run(strategy_id='088933ef-0bbd-11ec-b3f7-f65b3feb9565',
        filename='find_chuizi_start.py',
        mode=MODE_BACKTEST,
        token='2a73fd387f79b2c096806a91a6b13f915f981007',
        backtest_start_time='2025-04-23 08:00:00',
        backtest_end_time='2025-04-24 16:00:00')

import numpy as np


def find_specific_stock(df):
    """
    筛选满足条件的股票
    :param df: 包含股票历史行情数据的DataFrame,至少包含open、high、low、close字段
    :return: 是否满足条件的布尔值
    条件苛刻,经常选不出来
    """
    # 检查数据是否满足基本要求
    required_cols = ['open', 'high', 'low', 'close']
    for col in required_cols:
        if col not in df.columns:
            raise ValueError(f"数据中缺少必要的列: {col}")

    # 计算下影线长度,下影线长度 = min(open, close) - low
    df['lower_shadow'] = df.apply(lambda row: min(row['open'], row['close']) - row['low'], axis=1)
    # 计算实体长度,实体长度 = abs(open - close)
    df['body_length'] = df.apply(lambda row: abs(row['open'] - row['close']), axis=1)
    # 计算上影线长度,上影线长度 = high - max(open, close)
    df['upper_shadow'] = df.apply(lambda row: row['high'] - max(row['open'], row['close']), axis=1)

    # 找出15日内有低位长下影线锤子型K线的情况
    # 锤子型K线条件:
    # 1. 下影线长度至少是实体长度的2倍
    # 2. 上影线很短(这里设置为不超过实体长度的0.5倍)
    # 3. 收盘价高于开盘价
    is_hammer = (df['lower_shadow'] >= 2 * df['body_length']) & \
                (df['upper_shadow'] <= 0.5 * df['body_length']) & \
                (df['close'] > df['open'])

    # 判断是否处于相对低位(这里定义为收盘价在20日最低价的5%范围内)
    df['low_20'] = df['low'].rolling(window=20).min()
    is_low_price = df['close'] <= df['low_20'] * 1.05

    # 综合锤子线和低位条件
    # has_hammer_low_price = is_hammer# & is_low_price
    has_hammer_low_price = is_low_price
    has_hammer_last_15 = np.any(has_hammer_low_price[-30:])

    # 检查昨日是否收阴,即昨日收盘价低于昨日开盘价
    is_yesterday_down = df['close'].iloc[-1] < df['open'].iloc[-1]

    return has_hammer_last_15 #and is_yesterday_down

经测试,条件有些苛刻了,不过可以通过修改代码,实现只选低位股,或是只选有锤子线的股票。上面的选股函数:

#获取所有A股主板股票    
context.stock_pool = cf.get_instruments_all_stocks(context)
#根据技术指标筛选股票
 context.stock_pool = cf.filter_stocks_by_financial_indicators(context.stock_pool, last_day)

可以自行根据自己的平台去实现。也可以在量化专题中找相关代码。

创作不易,有兴趣的朋友请点赞、收藏、关注、转发,谢谢。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/1227571
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 1分钟前
下一篇 2024 年 8 月 6 日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注