量化

股市开始交易:开盘;

建仓:进入市场;

平仓:退出市场

外汇(交易)市场:forex,市场中有2种头寸=开盘,分为商业净头寸(包括央行的外汇储备、企业的进出口贸易、个人留学旅游等进行的外汇交易)和非商业净头寸(投机和套利)

如果人民币值钱了,则能把人民币兑换更多的外币

如果一段时间中国没有印钱,而经济又发展了,那么人民币就值钱了

黄金:黄金多了,它就不值钱了;钱多了,金就值钱了

套现:指利用不同市场中同一种产品价格之间的差别获利

大多数股票的面值均为每股一元;发行价格就是买股票的价格

每股净资产 =(总资产-总负债)/ 总股数,它越高,表示股东拥有的每股资产价值越多

股票按照业绩分类:蓝筹股(资本雄厚、信誉优良的公司的股票,如中石油、中石化)、绩优股(业绩优良的公司股票,如茅台)、ST股(特别处理股票,连续2年亏损或者每股净资产低于股票面值)

股票按照上市地区分类:

涨跌幅10%:一天的价格变动不能超过10%

T+1:T是交割日,今天买了,明天才能卖

T+3:当天买入的股票,3天后才能卖,比如第一天买入股票100股,第二天又买入100股,虽然已经有200股股票,但到三天后只能卖出100股,第四天才能卖出所有股票.

证监会:决定公司能否上市,若上市了不符合规定,还能撤下来;

证券中介机构:只有在证券交易所里面有席位才能去买股票,证券中介机构是有席位的,买不了席位的股民只能通过证券中介机构的席位才能买到股票

交易所:每个板有对应的大盘,即指数,能反应该板块所有股票的综合表现,在上证则为沪指

 市值 = 发行股票的总价值 = 每股市场价格 * 总股数,小公司一般小市值

没人买了就跌,有人买就涨

竞价:买方和卖方进行对接

开盘集合竞价:系统以成交量最大为原则将一定数量的买方和卖方撮合,然后确定开盘价

连续竞价时间内很快就能完成交易

收盘集合竞价:.....确定收盘价

股票交易时间:

K线可以观察每日价格变动,每个柱子代表该日的价格,柱子分为阳线(涨了,即低开高走:开盘价<收盘价)和阴线:

 

 5日均线:取前5日的价格做平均值,所连成的线

 基本面分析和技术分析:

 回测:用历史的数据来测试策略

ipython

ipython中 ,查找含有pp的命令:a.*pp*?

查看a的信息:a?

快捷键:

 !后面表示是一条命令

运行文件:%run a.py

%paste:粘贴代码并执行它

random.randint(参数1,参数2):参数1<=函数返回参数1和参数2之间的任意整数<=参数2

range(10) :产生10个数, [0123456789]

range(111) : [12345678910]

列表解析第一个是函数表达式,它作用于后面的每个元素上:

例1:a=[x for x in range(101) if x%2==0]

等价于<=>

a=[] for i in range(101): if i%2==0: a.append(i)

例2:

L = [ i**2 for i in range(1,11)]
print L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

创建100个从1-10000的随机数: li=[random.randint(1,10000) for i in range(100)]

sort排序后会作用到自己,计算排序时间:%timeit li.sort();

开启调整,如果接下来的命令出错,就进入到调试模式,用exit退出:%pdb on

关闭调试:%pdb off

执行1+1后,执行_则输出上面计算的结果2

可以输入首字母再按上下键来获得历史命令

把结尾的目录赋值给a:%bookmark a ~

列出所有保存过的目录:%bookmark -l

删除保存下来的a:%bookmark -d a

删除所有保存的:%bookmark -r

numpy:

list a为每件商品的单价,list b为对应商品的件数,根据他俩求商品总价:

将两个list转成ndarray格式,然后对应元素相乘,最后求总和:( np.array(list a) * np.array(list b) ).sum()

.dtype:ndarray数据类型

数组总的元素个数:.size

数组维度:.shape

下面三维数组维度是2页2行3列(2,2,3)

转置:a.T

有多少维:a.ndim

[2]*3 = [2,2,2]

np.zeros(10):10个0,且数据类型为float64

np.zeros(10,dtype='int'):10个0,且数据类型为int

np.ones(10):10个1

创建有5个位置的空数组,里面的数是其他程序留给内存的:np.empty(5)

np.arange(10):产生10个数,从0到9

x=np.arange(2,9):2-8

x**2:是里面的每一个数做平方

np.arange(2,10,3):3是步长,[2,5,8],步长还能是小数

np.linspace(0,100,101):起始值是0,结束值是100,包括结束值的,给区间切割101份,这样就是0,1,2...,100,也是101个数

np.eye(10):10*10的单位矩阵

将1维数组转换成3*5矩阵:.reshape((3,5))

a[0,0]:取第0行第0列

a[:4]:取前4个元素,索引为0,1,2,3

a[4:]:索引从4开始(包括)到结尾

b=list(range(10)):b是list类型

数组的切片内容更改后,影响原数组,除非切片.copy(),但是列表的切片并不影响

把数组a里面>5的元素取出来:a[a>5]

取>5且是偶数,或用 | :a[ (a>5) & (a%2==0) ]

取出ndarray中第0和第2号索引位置的元素:a[[0,2]]

假定取 [6,8;16,18]:

则:

a[ [1,3],:] 是取出第一和第三行,再取出第一和第三列 [ :, [1,3] ]

每个元素取绝对值:np.abs(a)

每个取根号:np.sqrt(a)

向零取整:np.trunc(a)

四舍五入与正负无关:np.round(a)

向下取整:np.floor(a)

向上取整:np.ceil(a)

将每个元素的整数和小数分开,变成2个元素: np.modf(a)

不是数,如负数开根号: nan :float("nan")

无穷大:float("inf")

np.isnan(a):a中不是nan的都是false,否则是true;np.isinf 同理

将数组a和数组b的每一个元素对应相比较,保留大的:np.maximum(a,b),类似np.minimum(a,b)

数组每个元素加起来:a.sum()

平均:a.mean()

方差=每个数据与平均值差的平方的和再除以元素个数:a.var()

标准差=方差开根号:a.std()

若是服从正态分布的数据,则抽出一堆数据后,均值+标准差表示数据的68.27%大约都分布在在这个区间

a.argmax():最大值索引;a.argmin():最小值索引

random.random():返回 [ 0,1 )

random.choice( [1,2,3] ):从给定数组中随便取一个值出来

random.shuffle(a):随机打乱数组a

random.randint(0,10,(2,3)):生成2*3的矩阵,每个元素都是随机数;类似random.choice( [1,2,3] ,10)

np.random.uniform(0, 2,10):生成10个随机数,每个数在 [0,2] 内

 pandas:

Series对象:

 a=pd.Series([11,12,13],index=["a","b","c"])

访问:a[0] 或者 a["b"]

字典:

获得索引和值:

 

切片:

为防止歧义:loc 明确表明使用的是key,iloc表示索引: sr.loc[]

 

 按照标签对应相加:

 此处的NaN表示数据缺失值

使用add则缺失的值默认为0:

处理缺失值(识别NaN)isNull和notnull:

 

 

 dropna删掉所有缺失值:

sr.fillna(0):将所有nan替换成0,注意这些函数都不是修改自身,若改动自身则再赋值

DataFrame

一列是一个类型,它的切片是包含首尾的

DataFrame的创建、索引命名:

 

 返回dataframe索引和值:

describe()分别统计每一列的信息:

count:该列非NaN的个数

25%:排序好后,第25%的数

50%:中间的数

用loc获取某个位置的值:

取某一列df["one"],取2列df[["one","two"]],取出第a行:df.loc["a"],取出第0行:df.iloc[0], 取出第one列,再取出第0行df['one'][0],取出第one列的倒数2个数df['one'][-2:],如果不想要前面的索引,则最后.values

对齐相加,NaN相加还是NaN:

df.dropna():若有1行里有NaN,则整行删掉

df.dropna(how='all'):只有一行里面全是NaN才删掉该行

df.dropna(axis=1):删除含有NaN的列

df.mean()默认是按照列求平均数,除非指定axis;.sum()类似,只有此处DataFrame默认是按照列进行的,其他函数都是默认按行

 sort_values用by指定按照什么来排序,ascending是降序,不管升降,有NaN的行都排在最后面:

 按照行索引排序:

 按照列索引降序排序:

dateutil格式化时间:

 

 

 pd.to_datetime批量转换日期:

  pd.date_range生成指定时间范围内的时间,以及指定天数来生成时间:

若指定freq='H',按照小时列出;freq='W':按照周日输出;frep='W-MON':按照周一输出;freq='B':按照工作日周一-周五输出

还能:

dateTimeindex可以拿来做series和dataframe的索引:

仅仅选取3月的数据:sr['2017-03'];

取出一段时间的:sr['2017':'2018-03']

按每周列,把每周内的数据加起来 sr.resample['W'].sum(),左列的日期是一周开始的日子

按照每月:

取平均:sr.resample['W'].mean()

读csv文件:pd.read_csv('aaa.csv')

以第0列作为索引(把第0列放到开头一列):

以日期作为索引:

 parse_dates把日期列定为时间对象,这样索引就是DateTimeindex了:

 指定文件无列名:

 指定列名:

 

 把原数据中的所有none字符串替换为NaN:

 读取excel文件:pd.read_excel('a.xlsx')

 将dataFrame写入到文件中:to_csv

header=False:列名不写了

index=Flase:索引列不写了

na_rep='null':把df中的NaN替换为null

columns指定写入哪些列

 df.to_csv('a.csv',header=False,index=False,na_rep='ASD',columns=['tow'])

 转成html和json:

matplotlib

一般:import matplotlib.pyplot as plt

pl.plot:画折现图,第三个参数是描的点

o:是点

o-:线

 

 只要不调用show,就会累积的画图

 调用legend时,需要plot里面有label参数,才能分开显示

 

 画出csv来:

 

 

 画数学函数:

 

 

 画子图:

bar第一个参数是横坐标,第二个参数是高度,width控制柱子宽度

xticks:在哪些刻度上写标签

 

 

柄图:

%.2f%%:f是转为附点数,.2是小数点后保留2位,最后的%%加到后面,explode是分离扇形

axis是把扇形画正

 

先把日期转换为python时间:

 import matplotlib.finance as fin

 

ochl是open、close...的简称,按照顺序传进去

 

 fig.show()

 

 

为了加快速度。可以使用切片:

tushare 获取股票数据

 import tushare as ts

输入的是证券代码:ts.get_k_data('601318')

ktype能画出日k线、周k线(开盘价是一周第一天的开盘价,收盘价是一周最后一天的收盘价)、月k线

还制定起始时间:

ts.get_k_data('601318',start='1988-01-01')

df["close"].shift(1):将dataframe的close一列向下挪动一行,-1是向上挪动

量化:

 

 

 

作业1:

买卖股票按照开盘价计算

答案在:homework1

MA5:5日均线;MA10:10日均线,5日和10日的叫日均线,30和60日的叫季均线,120天和240天的叫年均线,时间短的叫短期均线,时间长的叫长期均线

双均线策略:金叉:短期均线上穿长期均线的那个交叉点,之后股票可能大涨,则买入股票;死叉:....下穿.....,之后股票可能跌,则卖了

作业2:

提示:

for i in range(a,len(l))   :索引从 a 到 l 的结尾(包括)

if不需要括号,且用and

.index得到的是时间戳,to_pydatetime()能将时间戳进行转换

Series的索引若是时间,则sort_index()升序排列

每100股100股的买,一手买100股

最后的钱要加上还没卖完的股票的价值

 

 

答案在:homework2

作业3:

提示: 

不持仓:表示没有该股票

在joinquant中

红线是基准线(第一天拿所有的钱平均买该大盘里面的300成分股,然后也不卖,之后的涨跌情况),蓝线是自己写的策略线,纵坐标是获益百分比,0表示没有获益没有亏损

策略收益和基准收益是到截止日期时,获益的情况 =(最后的钱-开始的钱)/ 开始的钱,年化收益就是一年的获益率,胜率是赚的交易次数 / 总的交易次数,盈亏比=赚的钱 / 亏损的钱,最大回撤:可能面临的最大亏损,从任一高点到其后续最低点的下跌幅度的最大值,对应的回撤区间就是最大亏损幅度区间

保存什么东西就放到g的属性中;.XSHG是该股票在上海上市

get_index_stocks('000002.XSHG')能获取旗下所有成分股的代号

set_option('use_real_price',True):使用真实价格成交

买股票要佣金(给券商,让他帮我买),卖股票交佣金和印花税(给国家的)

针对的是股票type='stock',买股票不需要印花税open_tax=0,只需要付佣金万分之三open_commission=0.0003,卖需要千分之一印花税close_tax=0.001+佣金万分之三,每笔交易如果佣金低于5块则按照5块钱算:

set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')

今日涨停价一般等于昨日收盘价*1.1,跌停价=昨日收盘*0.9

每个工作日(如果下拉框选择是每天)会自动调用handle_data

get_current_data()['601318.xshg']返回该股票数据,是一个字典:

get_current_data()['601318.xshg'].day_open:去当日的股票池里找到该股票601318.xshg,然后返回该股票当日开盘价

attribute_history('601318.XSHG',5):返回该股票当日前5天(不包括当日)的历史数据

order('601318.XSHG',100):当日买100份股

买股票必须以100股的倍数,卖没事

order_value('601318.XSHG',1000):当日用1000块买这个股票,能买多少买多少,但是100的倍数

order_target('601318.XSHG',200):买到200股,若第二个参数=0,则表示全部卖出

order_target_value(‘代码’,1000):买股票买到值1000块为止

position对象中的avg_cost表示买该股票1份平均花了多少钱,total_amount是总仓位,即买了该股票总共多少股,仓位就是多少股

点击回测会显示更多详细信息

答案:

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    g.security = get_index_stocks("000300.XSHG")
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')

def handle_data(context,data):
    buy=[]
    # 先卖股票
    for stock in g.security:
        p = get_current_data()[stock].day_open
        histp = context.portfolio.positions[stock].avg_cost 
        amount = context.portfolio.positions[stock].total_amount
        if p>=histp*1.25 and amount>0:
            order_target(stock,0)
        if p<=histp*0.9 and amount>0:
            order_target(stock,0)
        if p<10 and amount==0:
            buy.append(stock)
    dividemoney = context.portfolio.available_cash / len(buy)
    for stock in buy:
        order_value(stock,dividemoney)

双均线属于择时

双均线作业:

record能多画几个图

 

 

 

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    g.security = ["601318.XSHG"]
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.p1=5
    g.p2=10
def handle_data(context,data):
    df = attribute_history('000300.XSHG',g.p2)
    ma5 = df['close'][-5:].mean()
    ma10 = df['close'].mean()
    for stock in g.security:
        if ma5 < ma10 and stock in context.portfolio.positions:
            order_target(stock,0)
        if ma5 > ma10 and stock not in context.portfolio.positions:
            order_value(stock,context.portfolio.available_cash*0.8)
    record(ma5=ma5,ma10=ma10)

因子选股策略

因子:选股的标准、如增长率、市值、市盈率、ROE(净资产收益率)

调仓:调整一下股票的种类和数目

以小市值策略为例:每个月调仓,使得所持有的股票一直是市值最小的那几份

a = query(valuation).filter(valuation.code.in_(g.security):由于valuation里面有市值数据,就到valuation表中查询包含有g.security里面股票的sql,g.security保存了一堆股票代码

get_fundamentals(a):获取上面这些股票的财务数据,包括市值股票代码code、市值market_cap等

run_monthly(handle,1):每月的第一个工作日运行handle函数

:n  是前n个

为了不要索引,最后.values:

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000002.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000002.XSHG')
    g.sql = query(valuation).filter(valuation.code.in_(g.security))
    g.num = 20
    run_monthly(handle,1)
    
def handle(context):
    tobuy = get_fundamentals(g.sql)[["code","market_cap"]].sort("market_cap")["code"][:g.num].values
    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

标准化能去掉量纲:

 

假定选2个因子为:roe,市值,想要高的roe,低的市值,要将2者用min-max标准化,然后用roe-市值得到一个综合因子,用该综合因子筛选。

roe在indicator表中

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000002.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000002.XSHG')
    g.sql = query(valuation,indicator).filter(valuation.code.in_(g.security))
    g.num = 20
    run_monthly(handle,1)
    
def handle(context):
    l = get_fundamentals(g.sql)[["code","market_cap","roe"]]
    l["market_cap"] = (l["market_cap"]-l["market_cap"].min())/(l["market_cap"].max()-l["market_cap"].min())
    l["roe"] = (l["roe"]-l["roe"].min())/(l["roe"].max()-l["roe"].min())
    l["score"] = l["roe"]-l["market_cap"]
    tobuy =l.sort("score")["code"][-g.num:].values
    
    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

 

均值回归理论:

当价格下跌离开均线到一定程度(偏离程度)时,它可能就会上涨,此时买;当上涨超过均值一定程度时,他可能会跌,此时卖

可定义偏离程度= (MA-P) / MA,除法能去量纲

series对象.nlargest(3):按照第二列,选择里面最大的3行

此处用该理论来选股:

def initialize(context):
    set_benchmark('000002.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000002.XSHG')
    g.sql = query(valuation,indicator).filter(valuation.code.in_(g.security))
    g.num = 10
    g.ma = 30
    run_monthly(handle,1)
    
def handle(context):
    tobuy =  pd.Series(index=g.security)
    for stock in tobuy.index:
        p = get_current_data()[stock].day_open
        ma = attribute_history(stock,g.ma)['close'].mean()
        tobuy[stock] = (ma-p)/ma
    tobuy = tobuy.nlargest(g.num).index.values    
    
    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

或者:

def initialize(context):
    set_benchmark('000002.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000002.XSHG')
    g.sql = query(valuation,indicator).filter(valuation.code.in_(g.security))
    g.num = 10
    g.ma = 30
    run_monthly(handle,1)
    
def handle(context):
    tobuy = pd.Series()
    for stock in g.security:
        p = get_current_data()[stock].day_open
        ma = attribute_history(stock,g.ma)['close'].mean()
        tobuy[stock] = (ma-p)/ma
    tobuy = tobuy.nlargest(g.num).index.values

    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

 

 布林带策略可用于择时:

有3条线,上面是压力线,中间是均线,下面是支撑线,可定义:中间线=20日均线,上线=20日均线+N*SD,SD是标准差,下线= 20日均线-N*SD

当价格超过压力线,则清仓,当价格低于支撑线,则全仓买入

def initialize(context):
    set_benchmark('600036.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = '600036.XSHG'
    g.n = 2
    g.m = 30

def handle_data(context,data):
    p = get_current_data()[g.security].day_open
    sr = attribute_history(g.security,g.m)['close']
    ma = sr.mean()
    up = ma + g.n*sr.std()
    down = ma - g.n*sr.std()
    if p > up and g.security in context.portfolio.positions:
        order_target(g.security,0)
    if p < down and g.security not in context.portfolio.positions:
        order_value(g.security,context.portfolio.available_cash)

PEG策略选股:

若股票定价合理,则市盈率PE=收益增长率G

市盈率PE=股价P / 每股收益EPS

EPS=总利润 / 总股数

股价 =市值/总股数

所以 市盈率PE = 市值 / 总利润,越被低估,股价越可能涨,则买入

 

 peg越低则买入,且要求分子分母都是正的,负的不行,因为说明在赔钱

 

 

思路是:计算所有股票的PEG指标,买入最小的N支股票

市盈率PE在valuation表里面叫pe_ratio,G在indicator里面叫inc_net_profit_year_on_year

筛选df:df[ (条件1) & (条件2) ] 

 前3个   :3

后三个     -3:

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000300.XSHG')
    g.sql = query(valuation,indicator).filter(valuation.code.in_(g.security))
    g.num = 20
    run_monthly(handle,1)
    
def handle(context):
    l = get_fundamentals(g.sql)[["code","pe_ratio","inc_net_profit_year_on_year"]]
    l = l[ (l['pe_ratio'] > 0) & (l['inc_net_profit_year_on_year']>0) ]
    l['peg'] = l['pe_ratio'] / l['inc_net_profit_year_on_year'] / 100
    tobuy = l.sort('peg')['code'][:g.num].values

    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

动量策略和反转策略是相反的:

采用它选股

 

取出一堆股票的前30天的close列的数据,转置后索引是股票代码,列是时间:

 history(30,field = "close",security_list=list(stocks)).T

ascending=False是降序,选最大的收益率是动量策略,最小的反转,此时让ascending=True

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    g.security = get_index_stocks('000300.XSHG')
    g.sql = query(valuation,indicator).filter(valuation.code.in_(g.security))
    g.num = 10
    run_monthly(handle,1)
    
def handle(context):
    l = history(30,field='close',security_list = g.security).T
    l['ret'] = (l.iloc[:,-1]-l.iloc[:,0])/l.iloc[:,0]
    tobuy = l.sort('ret',ascending=False).index[:g.num]

    for stock in context.portfolio.positions:
        if stock not in tobuy:
            order_target(stock,0)
    newbuy = [stock for stock in tobuy if stock not in context.portfolio.positions]
    if len(newbuy)>0:
        divide = context.portfolio.available_cash / len(newbuy)
        for stock in newbuy:
            order_value(stock,divide)
    

 

posted @ 2021-03-12 09:37  Jary霸  阅读(340)  评论(0)    收藏  举报