Python量化交易学习——Part9:基于放量技术因子的策略实战

news2024/10/6 0:28:09

话不多说,直接进入正题
股票池:沪深300
买入策略:选择过去收盘价标准差小于0.05,且量比大于3的股票,当第二天高开的时候进行买入;
卖出策略:卖出条件为收益30%或者亏损7%;
首先我们可以先新建一个文件用于保存放量因子这个技术函数,我这里命名为volume_strategy.py,函数代码如下:

import numpy as np
import pandas as pd
from gm.api import *
import datetime
import statsmodels.api as sm
from dateutil.relativedelta import relativedelta
from sklearn.preprocessing import MinMaxScaler

"""
放量策略:
股票池:以XXX股票池为基础,过去收盘价标准差小于0.05的股票列入关注股票
买入策略:当第N日的成交量相比与第N-1日的成交量大于5的时候买入;
卖出策略:卖出条件为收益30%或者亏损7%;
"""
# 输入值:index:指数代码 now:现在时间 threshold:标准差大小
#返回值:股票清单
def volume_strategy_stock_pool (index,now,threshold):
    # 建立股票池
    last_day = get_previous_trading_date("SHSE",now) # 获取前一交易日的时间
    symbol_array = stk_get_index_constituents(index).sort_values(["symbol"],ascending=False)   #获取成分股,按照股票代码从大到小排序
    symbol_list = symbol_array["symbol"].values # 提取股票代码
    symbol_list_final = []

    for symbol in symbol_list:
        data = history_n(symbol=symbol, frequency="1d", count=14, end_time=last_day, fields="close", adjust=ADJUST_PREV, df=True)
        if data.empty == True: #判断数据是否为空
            pass
            #print("数据无效",symbol)
        else:
            close = data["close"].values
            close_std = np.std(close)
            if close_std < threshold:
                symbol_list_final.append(symbol)

    return symbol_list_final  #返回股票清单

# 输入值 index:股票清单 now:目前时间 symbol_count:总持仓股票数
# 返回值 symbol_buy_price_list,买入股票清单,dataframe类型 (股票,价格)
def volume_strategy_buy (index,now,symbol_count):
    # 买入股票
    last_day = get_previous_trading_date("SHSE", now)  # 获取前一交易日的时间
    symbol_buy_price = {}
    symbol_buy_price_list = []
    for symbol in index:
        data = history_n(symbol=symbol, frequency="1d", count=2, end_time=last_day, fields="volume", adjust=ADJUST_PREV, df=True)
        if data.empty == True or len(data["volume"].values) != 2: #判断数据是否为空
            pass  # print("数据无效",symbol)
        else:
            volume = data["volume"].values
            if volume[1]/volume[0] >= 3:
                current_price = current(symbol)[0]["price"]
                last_price = history_n(symbol=symbol, frequency="1d", count=1, end_time=last_day, fields="close", adjust=ADJUST_PREV, df=True)["close"].values
                if np.log(current_price/last_price) > 0: # 目前价格高于昨日收盘价,高开
                    order_target_percent(symbol=symbol,percent=1/symbol_count,order_type=OrderType_Market,position_side=PositionSide_Long)
                    symbol_buy_price[symbol] = current_price
                    print("buy",symbol,current_price)

    symbol_buy_price_list = pd.DataFrame((list(symbol_buy_price.items())), columns=["symbol", "price"])
    return symbol_buy_price_list

# 输入值 symbol_buy_price,买入股票清单,dataframe类型 (股票,价格)
# 返回值 sell_symbol_list,卖出股票清单,list类型
def volume_strategy_sell(symbol_buy_price):
    #卖出股票
    sell_symbol_list = []
    buy_price_list = list(symbol_buy_price["price"].values)
    symbol_list = list(symbol_buy_price["symbol"].values)
    for num in range(0,len(symbol_list)-1):
        current_price = current(symbol_list[num])[0]["price"]
        buy_price = buy_price_list[num]
        if current_price > buy_price*1.3 or current_price < buy_price*0.93 :
            order_target_percent(symbol=symbol_list[num],percent=0,order_type=OrderType_Market,position_side=PositionSide_Long)
            print("sell",symbol_list[num],"卖出价:",current_price,"买入价:",buy_price,"收益:",(current_price-buy_price)/current_price)
            sell_symbol_list.append(symbol_list[num])
    return sell_symbol_list

该文件中一共包含3个函数:
第一个函数是volume_strategy_stock_pool (index,now,threshold),这个函数的作用从现有股票池中选择收盘价连续14天标准差小于threshold的股票,形成一个备选股清单。因为有些股票有过停牌,所以我们剔除了那些无效数据。否则做标准差的时候会报错。
第二个函数是volume_strategy_buy (index,now,symbol_count),是购买股票的函数,我们根据备选股清单进行逐个排查,选择量比大于3的股票,如果第二天开盘价格大于前一天的收盘价,则买入;
第三个函数是volume_strategy_sell(symbol_buy_price),是卖出股票的函数,如果盈利超过30%,或者亏损超过7%,则卖出,否则仍然持有。
之后我们通过主函数调用,新建py文件volume_strategy_test.py,代码如下:

# coding=utf-8
from __future__ import print_function, absolute_import

import pandas as pd
from gm.api import *
import volume_strategy as vs

def init(context):
    # 每天14:50 定时执行algo任务,
    # algo执行定时任务函数,只能传context参数
    # date_rule执行频率,目前暂时支持1d、1w、1m,其中1w、1m仅用于回测,实时模式1d以上的频率,需要在algo判断日期
    # time_rule执行时间, 注意多个定时任务设置同一个时间点,前面的定时任务会被后面的覆盖
    context.symbol = "SHSE.000922"  # 沪深300
    context.num = 5 # 持仓做多股票种类
    context.threshold = 0.05  #选股标准差
    context.symbol_list = pd.DataFrame() #买入股票清单(股票,买入价格)
    schedule(schedule_func=algo, date_rule='1d', time_rule='09:31:00')

def algo(context):
    # 以沪深300指数为基础,选择14天标准差小于0.05的股票建立股票池
    symbol_list_final = vs.volume_strategy_stock_pool(context.symbol,context.now,context.threshold)
    # 判断买入股票的数量是否大于能持仓的最大数量
    if len(context.symbol_list.index) <= context.num:
        symbol_price_list = vs.volume_strategy_buy(symbol_list_final,context.now,context.num)  # 从股票池中获取量比大于3的股票作为标的股票,进行买入
        if len(symbol_price_list) != 0: # 如果选择出新的标的股票,则把标的股票加入到买入股票清单中
            context.symbol_list = pd.concat([context.symbol_list,symbol_price_list],axis=0).drop_duplicates(subset=['symbol'],keep='first') # 删除symbol重复项,只保留第一项
            context.symbol_list = context.symbol_list.reset_index(drop=True) # 重置行索引,不保留原索引作为列
    if len(context.symbol_list.index) != 0:
        sell_symbol_list = vs.volume_strategy_sell(context.symbol_list) #卖出股票,获得卖出股票清单
        if len(sell_symbol_list) != 0:
            for symbol in sell_symbol_list:  # 从股票清单中删除已经卖出的股票
                rows_to_delete = context.symbol_list[context.symbol_list['symbol'] == symbol].index
                context.symbol_list = context.symbol_list.drop(rows_to_delete)
                print(context.symbol_list)



# 查看最终的回测结果
def on_backtest_finished(context, indicator):
    print(indicator)


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
        backtest_match_mode市价撮合模式,以下一tick/bar开盘价撮合:0,以当前tick/bar收盘价撮合:1
    '''
    run(strategy_id='自己的策略',
        filename='volume_strategy_test.py',
        mode=MODE_BACKTEST,
        token='自己的token码',
        backtest_start_time='2020-01-01 09:30:00',
        backtest_end_time='2024-6-20 15:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001,
        backtest_match_mode=1)

在主函数def algo(context)中,我们先调用了volume_strategy_stock_pool()函数,得到了备选股票的清单,之后我们通过volume_strategy_buy()函数对股票进行买入操作,但因为我们的资金是有效的,所以我们只能持仓一定数量的股票,在这里我假设是5只,所以当持仓数量超过5只的时候,我们便不用再买入股票了,只需要看是否需要卖出。当有新的股票进行买卖资源池中,我们需要进行增删操作。要不每次都需要判断已经卖出的股票是否还需要卖出,浪费时间。
回测结果如下:
在这里插入图片描述
从回测结果看,该策略的收益还是可以的,4年半收益为97.81%,但在个股的操作上,看起来并不是十分明智,以交通银行为例,买入和卖出的时机都不算好,我们可以适当调节买入策略或者卖出策略,比如量比大于5买入,或者收益大于40%卖出,或者其他卖出方式,看是否可以得到更好的结果。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1866662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python复数的加、减、乘、除运算

一、复数 复数由实部和虚部组成&#xff0c;形如abi(a,b均为实数)的数为复数&#xff0c;其中&#xff0c;a被称为实部&#xff0c;b被称为虚部&#xff0c;i为虚数单位&#xff0c;。复数通常用z表示&#xff0c;即zabi&#xff0c;当z的虚部b&#xff1d;0时&#xff0c;则z…

基于CNN卷积神经网络的MQAM调制识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 CNN模型结构 4.2 损失函数与优化 4.3 训练与测试 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff0…

Labview_映射表

1.创建映射表 创建映射表时&#xff0c;该映射表内的所有键为同一类型、键为同一类型。映射表键名可以为任意类型。 PS:生成映射表在使用时请保证唯一键名&#xff0c;如使用同一键名&#xff0c;则在最终输出时只能搜索到最新插入的键值对信息。 2.插入映射表 按照已创建的映…

《TopFormer: Token Pyramid Transformer for Mobile Semantic Segmentation》

期刊&#xff1a;CVPR 年份&#xff1a;2022 代码&#xff1a;https://github.com/hustvl/TopFormer 摘要 尽管视觉Transformer(ViTs)在计算机视觉领域取得了巨大的成功&#xff0c;但沉重的计算成本阻碍了它们在密集预测任务中的应用&#xff0c;如移动设备上的语义分割。…

JavaScript通用下载方法,但jpg图片下载打不开

通用下载方法&#xff0c;通过Blob的方式&#xff0c;访问Url地址&#xff0c;下载对应的图片&#xff0c;excel等文件。 axios({method: "get",url,responseType: "blob",}).then((res: any) > {const link document.createElement("a");co…

Java基础:常用类(四)

Java基础&#xff1a;常用类&#xff08;四&#xff09; 文章目录 Java基础&#xff1a;常用类&#xff08;四&#xff09;1. String字符串类1.1 简介1.2 创建方式1.3 构造方法1.4 连接操作符1.5 常用方法 2. StringBuffer和StringBuilder类2.1 StringBuffer类2.1.1 简介2.1.2 …

信息学奥赛初赛天天练-36-CSP-J2021阅读程序-ASCII、运算符优先级、二进制补码存储、模拟算法应用

PDF文档公众号回复关键字:20240626 2021 CSP-J 阅读程序2 1 阅读程序(判断题1.5分 选择题3分 共计40分 ) #include<stdio.h> #include<string.h>char base[64]; char table[256]; char str[256]; char ans[256];void init() {for(int i0;i<26;i) base[i]Ai;fo…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-23卷积神经网络LeNet

23卷积神经网络LeNet import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as plt# 定义一个卷积神经网络 net nn.Sequential(nn.Conv2d(1, 6, kernel_size5, padding2), # 卷积层1&#xff1a;输入通道数1&#xff0c;输出通道数6&#x…

方法的其他形式——方法使用时常见的问题

示例&#xff1a; public class MethodDemo02 {public static void main(String[] args) {//目标&#xff1a;掌握按照方法的实际业务需求不同&#xff0c;设计出合理的方法形式来解决问题//需求&#xff1a;打印三行Hello World.printfHelloWorld();System.out.println("…

CVPR2024|vivo提出使用对抗微调获得泛化性更强的SAM,分割性能直接登顶 SOTA!

在计算机视觉不断发展的领域中&#xff0c;基础模型已成为一种关键工具&#xff0c;显示出对多种任务的出色适应性。其中&#xff0c;由 Meta AI 开发的 Segment Anything Model&#xff08;SAM&#xff09;在图像分割任务中表现杰出。然而&#xff0c;和其他类似模型一样&…

Python自动化操作:简单、有趣、高效!解放你的工作流程!

今天跟大家分享一套自动化操作流程解决方案&#xff0c;基于Python语言&#xff0c;涉及pyautogui、pyperclip、pythoncom、win32com依赖包。安装命令为&#xff1a; pip install pyautoguipip install pyperclippip install pythoncompip install win32compyautogui 是一个自…

解决“Duplicate keys detected: ‘ ‘.This may cause an update error.”问题

问题原因 出现“Duplicate keys detected”的错误&#xff0c;通常表示在v-for指令中使的:key绑定值有重复。 如果前端是静态数据&#xff0c;一般能自我避免:key绑定值有重复。如果前端是绑定的动态数据&#xff0c;那么需要另外提供一个唯一的键。 在这个例子中&#xff0c…

Xcode安装Simulator失败问题解决方法

Xcode安装Simulator_Runtime失败&#xff0c;安装包离线安装保姆级教程 Xcode更新之后有时候会提示要安装模拟器运行时环境&#xff0c;但是用Xcode更新会因为网络原因&#xff0c;我觉得基本上就是因为苹果服务器的连接不稳定导致的&#xff0c;更可气的是不支持断点续…

链式队列算法库构建

学习贺利坚老师课程,构建链式队列算法库 数据结构之自建算法库——链队&#xff08;链式队列&#xff09;_数据结构函数链队列的算法框架有哪些-CSDN博客文章浏览阅读6.2k次&#xff0c;点赞3次&#xff0c;收藏9次。本文针对数据结构基础系列网络课程(3)&#xff1a;栈和队列…

【unity实战】制作unity数据保存和加载系统——小型游戏存储的最优解(包含数据安全处理方案的加密解密)

前言 如何在 Unity 中正确制作一个保存和加载系统&#xff0c;该系统使用JSON 文件来处理保存配置文件&#xff0c;可以保存和加载任何类型对象&#xff01;标题为什么叫小型游戏存储功能呢&#xff1f;因为该存储功能可能只适合存储数据比较单一的情况&#xff0c;它非常的方…

Leetcode 102.目标和

给定一个正整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 ‘’ &#xff0c;在 1 之前添加 ‘-’ &…

AIGC笔记--U-ViT的简单代码实现

1--前言 原论文&#xff1a;All are Worth Words: A ViT Backbone for Diffusion Models 完整可debug的代码&#xff1a;Simple_U-ViT 2--结构 3--简单代码 以视频作为输入&#xff0c;实现上图红色框的计算&#xff1a; import torch import torch.nn as nn from einops im…

6.2 通过构建情感分类器训练词向量

在上一节中&#xff0c;我们简要地了解了词向量&#xff0c;但并没有去实现它。在本节中&#xff0c;我们将下载一个名为IMDB的数据集(其中包含了评论)&#xff0c;然后构建一个用于计算评论的情感是正面、负面还是未知的情感分类器。在构建过程中&#xff0c;还将为 IMDB 数据…

分享一个 MySQL 简单快速进行自动备份和还原的脚本和方法

前言 数据备份和还原在信息技术领域中具有非常重要的作用&#xff0c;不论是人为误操作、硬件故障、病毒感染、自然灾害还是其他原因&#xff0c;数据丢失的风险都是存在的。如果没有备份&#xff0c;一旦数据丢失&#xff0c;可能对个人、企业甚至整个组织造成巨大的损失。 …

2-17 基于matlab的改进的遗传算法(IGA)对城市交通信号优化分析

基于matlab的改进的遗传算法&#xff08;IGA&#xff09;对城市交通信号优化分析。根据交通流量以及饱和流量&#xff0c;对城市道路交叉口交通信号灯实施合理优化控制&#xff0c;考虑到交通状况的动态变化&#xff0c;及每个交叉口的唯一性。通过实时监测交通流量&#xff0c…