3.0平台的历史数据问题,运行代码就发现history只能看2个记录,不能看11个记录
由csowen创建,最终由csowen 被浏览 3 用户
from bigmodule import M
# <aistudiograph>
# @param(id="m9", name="run")
def m9_run_bigquant_run(input_1, input_2, input_3):
# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
# 示例代码如下。在这里编写您的代码
import dai
df = input_1.read()
drop_cols =['st_status', 'low', 'low_1', 'price_limit_status']
df = df.drop(columns=drop_cols)
ds = dai.DataSource.write_bdb(df)
return dict(data_1=ds, data_2={"hello": "world"}, data_3=None)
# @param(id="m14", name="initialize")
# 交易引擎:初始化函数, 只执行一次
def m14_initialize_bigquant_run(context):
import math
import numpy as np
from bigtrader.finance.commission import PerOrder
#系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0003, min_cost=5))#Owen set
#预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
#设置买入的股票数量,这里买入预测股票列表排名靠前的5只
context.stock_count=3
context.filter_flag=[0,0] ##disable filter3,filter2
#每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
##context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, context.stock_count)])#disabe
#设置每只股票占用的最大资金比例
context.max_cash_per_instrument = 1.0 ##disable limit
context.options['hold_days'] = 1
context.track_stock = {}
print ("owen-view", context.portfolio.positions.items())
print ("owen-view-cash","portfolio_value", context.portfolio.portfolio_value,"cash ", context.portfolio.cash)
# @param(id="m14", name="before_trading_start")
# 交易引擎:每个单位时间开盘前调用一次。
def m14_before_trading_start_bigquant_run(context, data):
# 盘前处理,订阅行情等
pass
def price_cut(context, data):
today = data.current_dt.strftime('%Y-%m-%d')
#------------------------------------------止损模块START------------------------------------------------
equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}
#新建当日止损股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
stoploss_stock = []
if len(equities) > 0:
##price_cut
for i in equities.keys():
stock_market_price = data.current(context.symbol(i), 'price') # 最新市场价格
last_sale_date = equities[i].last_sale_date # 上次交易日期
price_open = data.history(context.symbol(i), 'open',bar_count=2,frequency='1d')
price_close = data.history(context.symbol(i), 'close',bar_count=2,frequency='1d')
##1.09 2019.1.1~2024.2.5 331%-HUI 19.1%.
##1.095 2019.1.1 ~ 2024.2.5 359.72%-HUI 19.71%
## 2023.2.7~2024.2.7 -1.54% ~HUI 19.61%
##2016.6.5~2024.2.7 846.63%-HUI 19.8% 年化35.4%
##disable 2019.1.1 ~ 2024.2.5 383.84%-HUI 18.22%
#enable 2015.1.1~2024.2.9 911%,disable 1460%
if False:#price_close[-1] > price_close[-2] * 1.095:
continue
context.order_target_percent(context.symbol(i), 0)##高频卖出
stoploss_stock.append(i)
if len(stoploss_stock)>0:
print('日期:', today, '股票:', stoploss_stock, ' sell ',(stock_market_price - equities[i].cost_basis)/(equities[i].cost_basis))
return stoploss_stock
#-------------------------------------------止损模块END---------------------------------------------
return stoploss_stock
# @param(id="m14", name="handle_data")
# 回测引擎:每日数据处理函数, 每天执行一次
def m14_handle_data_bigquant_run(context, data):
print ('start ')
stoploss_stock = price_cut(context,data)#止损模块检查
#stoploss_stock += big_change(context, data) ##止损检查
today = data.current_dt.strftime('%Y-%m-%d')
print ('ranker data')
# 按日期过滤得到今日的预测数据
ranker_prediction = context.data[context.data.date == data.current_dt.strftime("%Y-%m-%d")]
#ranker_prediction = ranker_prediction.sort_values('score', ascending=False)
cash_for_buy = context.portfolio.cash#owen set
if cash_for_buy>1000*100*100:
print (today,'cash ',cash_for_buy,' more than 1000w')
##print (context.portfolio.cash, cash_avg, cash_for_buy,"owen-debug")
positions = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
###sell_stock = generate_sell(context,data,ranker_prediction,stoploss_stock) ##disable
sell_stock=[]
equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}
stock_hold = len(equities)
print ('current stock hold',stock_hold)
# 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
##buy_cash_weights = context.stock_weights #disable
buy_list = list(ranker_prediction.instrument)
buy_stock_num = context.stock_count - stock_hold ##owen-debug
if buy_stock_num == 0:
return ## has stock in track
##不再买入已经轮仓卖出和移动止损的股票,以防止出现空头持仓
buy_instruments = [i for i in buy_list if i not in sell_stock + stoploss_stock]
print ('buy_instruments',len(buy_instruments))
buy_stock = []
for i in buy_instruments[0:16]:##best 16
print (i, context.symbol(i),'debug ')
vol_h = data.history(context.symbol(i), 'volume', bar_count=11, frequency='1d')
print (type(vol_h),' lsit ',len(vol_h))
price_open = data.history(context.symbol(i), 'open',bar_count=11,frequency='1d')
price_close = data.history(context.symbol(i), 'close',bar_count=11,frequency='1d')
avg5=sum(price_close[-5:])/5
avg10=sum(price_close[-10:])/10
_avg5 = (price_close[-11] + sum(price_close[-4:]))/5
_avg10 = (price_close[-11] + sum(price_close[-9:]))/10
print ('start filer ')
if vol_h[-1] > vol_h[-2]*3 and vol_h[-1] < vol_h[2]*7 and (price_close[-1] > price_open[-1]*0.93 or price_close[-2] < price_open[-2]*0.93):
buy_stock.append(i)
continue
if avg5 *0.95 > avg10:
buy_stock.append(i)
continue
max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
count = 0
for i in buy_stock[0:3]:##top-3
if count +1 > buy_stock_num:
return
count = count +1
cash = cash_for_buy/buy_stock_num #only buy one
price = data.current(context.symbol(i), 'price')
stock_num = np.floor(cash/price/100)*100 # 向下取整
print (today, ' buy ',i, stock_num,' using ',(price*stock_num)/100/100,'w')
context.order_value(context.symbol(i), stock_num)
return ##dsiable
# 1. 资金分配
# 平均持仓时间是hold_days, 每日都将买入股票, 每日预期使用 1/hold_days 的资金
# 实际操作中, 会存在一定的买入误差, 所以在前hold_days天, 等量使用资金;之后, 尽量使用剩余资金(这里设置最多用等量的1.5倍)
is_staging = (
context.trading_day_index < context.options["hold_days"]
) # 是否在建仓期间(前 hold_days 天)
cash_avg = context.portfolio.portfolio_value / context.options["hold_days"]
cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
positions = {
e: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()
}
# 2. 生成卖出订单:hold_days天之后才开始卖出;对持仓的股票, 按机器学习算法预测的排序末位淘汰
if not is_staging and cash_for_sell > 0:
equities = {e: e for e, p in context.portfolio.positions.items()}
instruments = list(
reversed(
list(
ranker_prediction.instrument[
ranker_prediction.instrument.apply(lambda x: x in equities)
]
)
)
)
for instrument in instruments:
context.order_target(instrument, 0)
cash_for_sell -= positions[instrument]
if cash_for_sell <= 0:
break
# 3. 生成买入订单:按机器学习算法预测的排序, 买入前面的stock_count只股票
buy_cash_weights = context.stock_weights
buy_instruments = list(ranker_prediction.instrument[: len(buy_cash_weights)])
max_cash_per_instrument = (
context.portfolio.portfolio_value * context.max_cash_per_instrument
)
for i, instrument in enumerate(buy_instruments):
cash = cash_for_buy * buy_cash_weights[i]
if cash > max_cash_per_instrument - positions.get(instrument, 0):
# 确保股票持仓量不会超过每次股票最大的占用资金量
cash = max_cash_per_instrument - positions.get(instrument, 0)
if cash > 0:
context.order_value(instrument, cash)
# @param(id="m14", name="handle_trade")
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m14_handle_trade_bigquant_run(context, trade):
pass
# @param(id="m14", name="handle_order")
# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m14_handle_order_bigquant_run(context, order):
pass
# @module(position="-845,-1266", comment="""训练集""")
m1 = M.instruments_dai.v3(
start_date="""2010-01-01""",
start_date_bound_to_trading_date=False,
end_date="""2015-01-01""",
end_date_bound_to_trading_date=False,
market="""中国A股""",
custom_market="""""",
m_name="""m1"""
)
# @module(position="-395,-1377", comment="""""", comment_collapsed=True)
m2 = M.input_features_expr.v1(
features="""
m_avg(turn,5)
m_avg(turn,10)
total_market_cap
mf_net_amount_5
mf_net_amount_10
m_avg(volume,5) as avg_volume_5
m_avg(volume,10) as avg_volume_10
#return_5
#return_20
#daily_return_0
#daily_return_1
#adjust_factor_0/adjust_factor_10#415%
#volatility_5_0
#amount_0/avg_amount_30#remove -27%
#avg_amount_0/avg_amount_5
#avg_amount_5/avg_amount_20
#rank_avg_amount_0/rank_avg_amount_5
#rank_avg_amount_5/rank_avg_amount_10
#rank_return_0
#rank_return_5
#rank_return_10
#rank_return_0/rank_return_5
#rank_return_5/rank_return_10
#过滤因子,这四个因子不参与模型学习
st_status
low
price_limit_status
m_lag(low,1) as low_1
""",
m_name="""m2"""
)
# @module(position="-514,-1040", comment="""""", comment_collapsed=True)
m3 = M.extract_data_expr.v1(
instruments=m1.data,
features=m2.data,
start_date="""""",
end_date="""""",
before_start_days=90,
m_name="""m3"""
)
# @module(position="-977,-1102", comment="""""", comment_collapsed=True)
m4 = M.input_features_expr.v1(
features="""m_lead(close,-2) / m_lead(open, -1) AS _future_return
all_quantile_cont(_future_return, 0.01) AS _future_return_1pct
all_quantile_cont(_future_return, 0.99) AS _future_return_99pct
clip(_future_return, _future_return_1pct, _future_return_99pct) AS _clipped_return
all_cbins(_clipped_return, 20) AS _binned_return
_binned_return AS _label
if( m_lead(high, 1) = m_lead(low, 1), NULL, _label) as label
""",
m_name="""m4"""
)
# @module(position="-979,-1037", comment="""""", comment_collapsed=True)
m5 = M.extract_data_expr.v1(
instruments=m1.data,
features=m4.data,
start_date="""""",
end_date="""""",
before_start_days=90,
m_name="""m5"""
)
# @module(position="-726,-916", comment="""""", comment_collapsed=True)
m8 = M.data_join.v4(
data1=m5.data,
data2=m3.data,
on="""date,instrument""",
how="""inner""",
sort=True,
m_name="""m8"""
)
# @module(position="-727,-839", comment="""""", comment_collapsed=True)
m6 = M.data_filter.v5(
input_data=m8.data,
expr="""st_status==0 & price_limit_status==2 | price_limit_status ==3 & low>low_1""",
output_left_data=False,
m_name="""m6"""
)
# @module(position="-730,-764", comment="""""", comment_collapsed=True)
m12 = M.data_dropnan.v6(
input_data=m6.data,
m_name="""m12"""
)
# @module(position="-726,-677", comment="""""", comment_collapsed=True)
m9 = M.python.v2(
input_1=m12.data,
run=m9_run_bigquant_run,
do_run=True,
m_name="""m9"""
)
# @module(position="-315,-563", comment="""""", comment_collapsed=True)
m7 = M.stock_ranker_dai_train.v9(
data=m9.data_1,
learning_algorithm="""排序""",
number_of_leaves=32,
min_docs_per_leaf=1000,
number_of_trees=20,
learning_rate=0.1,
max_bins=1072,
feature_fraction=1,
data_row_fraction=1,
plot_charts=True,
ndcg_discount_base=1,
m_name="""m7"""
)
# @module(position="70,-1263", comment="""测试集""")
m15 = M.instruments_dai.v3(
start_date="""2015-01-01""",
start_date_bound_to_trading_date=False,
end_date="""2016-01-01""",
end_date_bound_to_trading_date=True,
market="""中国A股""",
custom_market="""""",
m_cached=False,
m_name="""m15"""
)
# @module(position="76,-937", comment="""""", comment_collapsed=True)
m16 = M.extract_data_expr.v1(
instruments=m15.data,
features=m2.data,
start_date="""""",
end_date="""""",
before_start_days=90,
m_name="""m16"""
)
# @module(position="76,-861", comment="""""", comment_collapsed=True)
m10 = M.data_filter.v5(
input_data=m16.data,
expr="""st_status==0 & price_limit_status==2 | price_limit_status ==3 & low>low_1""",
output_left_data=False,
m_name="""m10"""
)
# @module(position="78,-778", comment="""""", comment_collapsed=True)
m17 = M.data_dropnan.v6(
input_data=m10.data,
m_name="""m17"""
)
# @module(position="-317,-490", comment="""""", comment_collapsed=True)
m13 = M.stock_ranker_dai_predict.v13(
model=m7.model,
data=m17.data,
m_name="""m13"""
)
# @module(position="-334,-396", comment="""""", comment_collapsed=True)
m14 = M.bigtrader.v34(
data=m13.predictions,
start_date="""""",
end_date="""""",
initialize=m14_initialize_bigquant_run,
before_trading_start=m14_before_trading_start_bigquant_run,
handle_data=m14_handle_data_bigquant_run,
handle_trade=m14_handle_trade_bigquant_run,
handle_order=m14_handle_order_bigquant_run,
capital_base=3000000.1,
frequency="""daily""",
product_type="""股票""",
rebalance_period_type="""交易日""",
rebalance_period_days="""5""",
rebalance_period_roll_forward=True,
backtest_engine_mode="""标准模式""",
before_start_days=0,
volume_limit=1,
order_price_field_buy="""open""",
order_price_field_sell="""close""",
benchmark="""沪深300指数""",
plot_charts=True,
debug=False,
backtest_only=False,
m_name="""m14"""
)
# </aistudiograph>
\