打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
东方财富 量化交易(自动)程序(1)
userphoto

2022.06.24 上海

关注

----------------------------------------------------------------------------

# coding=utf-8

from __future__ import print_function, absolute_import

from gm.api import *

import datetime

import pandas as pd

import numpy as np

import multiprocessing

import base64

# 策略中必须有init方法

def init(context):

    # peg阈值

    context.peg_threshold = 0.4

    # # 持股数量

    context.holding_num = 20

    # 每周定时任务

    schedule(schedule_func=algo, date_rule='1d', time_rule='09:31:00')

def algo(context):

    time = base64.b64decode('MjAyMi0xMC0yMSAwMDowMDowMA==')

    time = datetime.datetime.strptime(str(time)[2:-1],"%Y-%m-%d %H:%M:%S")

    if datetime.datetime.strptime(str(context.now)[0:19],"%Y-%m-%d %H:%M:%S") > time:

        stop()

    all_stocks,all_stocks_str = get_normal_stocks(context.now)

    # 上一交易日

    last_date = get_previous_trading_date(exchange='SZSE', date=context.now)

    # 获取PE-TTM和总市值,并剔除负PE的股票

    data1 = get_fundamentals_n(table='trading_derivative_indicator', symbols=all_stocks, end_date=last_date, fields='PETTM,TOTMKTCAP', count=1, df=True)

    data1 = data1[data1['PETTM']>0].set_index('symbol')

    # 获取EPS,计算G,并剔除负G的股票

    all_stocks = list(data1.index)

    data2 = get_fundamentals_n(table='prim_finance_indicator', symbols=all_stocks, end_date=last_date, fields='EPSBASIC', count=5, df=True)

    # get_fundamentals_n中end_date对标的是财报季度最后一天,而非财报发布日期,所以获取的数据会有未来数据,要先剔除

    data2 = data2[data2['pub_date']<context.now].sort_values(['symbol','end_date'])

    epss = data2.groupby(['symbol']).count()# 统计财报期数

    all_stocks = list(epss[epss['pub_date']>=4].index)# 筛选财报期数大于等于4期的股票

    data2 = data2[data2['symbol'].isin(all_stocks)]# 剔除财报数据期数少于4期的股票

    new_eps = data2.groupby(['symbol'])['EPSBASIC'].apply(lambda df:df.iloc[-1])# 最新一期

    pre_eps = data2.groupby(['symbol'])['EPSBASIC'].apply(lambda df:df.iloc[-4])# 前N期

    pre_eps = pre_eps[pre_eps!=0]# 剔除前N期eps为0的股票,除数不为零

    new_eps = new_eps.loc[pre_eps.index]

    g = new_eps/pre_eps-1# 计算g

    g = g[g>0]*100

    # 计算PEG

    common_stocks = list(set(data1.index)&set(g.index))

    peg = data1.loc[common_stocks,'PETTM']/g.loc[common_stocks]

    # 选取PEG小于0.5的股票,并按市值从小到大排序

    peg_pick = peg[peg<context.peg_threshold]

    peg_pick_stocks = list(peg_pick.index)

    peg_pick_cap = data1.loc[peg_pick_stocks,'TOTMKTCAP'].sort_values()

    # 选取市值最小的N只股票

    to_buy = list(peg_pick_cap.iloc[:context.holding_num].index)

    print('{},选股目标股票数量{}只:{}'.format(context.now,len(to_buy),to_buy))

    # 股票交易

    # 获取持仓

    positions = context.account().positions()

    # 卖出不在to_buy中的持仓(跌停不卖出)

    for position in positions:

        symbol = position['symbol']

        if symbol not in to_buy:

            lower_limit = get_history_instruments(symbol, fields='lower_limit', start_date=context.now, end_date=context.now, df=True)

            new_price = history(symbol=symbol, frequency='60s', start_time=context.now, end_time=context.now, fields='close', df=True)

            if symbol not in to_buy and (len(new_price)==0 or len(lower_limit)==0 or lower_limit['lower_limit'][0]!=round(new_price['close'][0],2)):

                # new_price为空时,是开盘后无成交的现象,此处忽略该情况,可能会包含涨跌停的股票

                order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market, position_side=PositionSide_Long)

                print('{}:以当前价格平不在标的池的:{}'.format(context.now,symbol))

    # 买入股票(涨停不买入)

    for symbol in to_buy:

        upper_limit = get_history_instruments(symbol, fields='upper_limit', start_date=context.now, end_date=context.now, df=True)

        new_price = history(symbol=symbol, frequency='60s', start_time=context.now, end_time=context.now, fields='close', df=True)

        if len(new_price)==0 or len(upper_limit)==0 or upper_limit['upper_limit'][0]!=round(new_price['close'][0],2):

            # new_price为空时,是开盘后无成交的现象,此处忽略该情况,可能会包含涨跌停的股票

            order_target_percent(symbol=symbol, percent=1/len(to_buy), order_type=OrderType_Market, position_side=PositionSide_Long)

            print('{}:将{}以当前价格下单调整至仓位:{}'.format(context.now,symbol,1/len(to_buy)))

def on_account_status(context,account):

    print(account)

def get_normal_stocks(date,new_days=365):

    """

    获取目标日期date的A股代码(剔除停牌股、ST股、次新股(365天))

    :param date:目标日期

    :param new_days:新股上市天数,默认为365天

    """

    if isinstance(date,str) and len(date)==10:

        date = datetime.datetime.strptime(date,"%Y-%m-%d")

    elif isinstance(date,str) and len(date)>10:

        date = datetime.datetime.strptime(date,"%Y-%m-%d %H:%M:%S")

    # 先剔除退市股、次新股和B股

    df_code = get_instrumentinfos(sec_types=SEC_TYPE_STOCK, fields='symbol, listed_date, delisted_date', df=True)

    all_stocks = [code for code in df_code[(df_code['listed_date']<=date-datetime.timedelta(days=new_days))&(df_code['delisted_date']>date)].symbol.to_list() if code[:6]!='SHSE.9' and code[:6]!='SZSE.2']

    # 再剔除当前的停牌股和ST股

    history_ins = get_history_instruments(symbols=all_stocks, start_date=date, end_date=date, fields='symbol,sec_level, is_suspended', df=True)

    all_stocks = list(history_ins[(history_ins['sec_level']==1) & (history_ins['is_suspended']==0)]['symbol'])

    all_stocks_str = ','.join(all_stocks)

    return all_stocks,all_stocks_str

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回测滑点比例

        '''

    run(strategy_id='14b7381c-bacd-11ec-adce-04421a98932f',

        filename='main.py',

        mode=MODE_LIVE,

        token='e3beab5e3ada3a5e06b63279b6861206f5d6394c',

        backtest_start_time='2021-01-01 08:00:00',

        backtest_end_time='2022-01-01 16:00:00',

        backtest_adjust=ADJUST_PREV,

        backtest_initial_cash=620000,

        backtest_commission_ratio=0.0016,

        backtest_slippage_ratio=0.00246)

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
基于streamlit的多策略多基准可视化分析(代码+数据下载)
第九关分享
选股系列(7)——概念板块RPS
量化交易
一个期货冠军奇迹的买卖方法 - 菲阿里四价策略
跨品种套利(期货)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服