Python量化交易策略
策略详情
按照1分k线图;跳过9:30点1分k线图不计算
买入;监控市面的可转债;当某1分涨幅大于x涨幅,一直重复x次,选择买入,符合x设置的条件只选择成交额最大的可转债买入(x要自定义)
例如;9:36分涨幅大于等于0.1;一直重复了2次;这2次的每1分都大于等于0.1;那么应该9:38分01秒买入
卖出方法条件1;当买入价格盈亏x%,选择自动卖出;(x要自定义)
卖出方法条件2;当某1分跌幅大于x跌幅,一直重复x次,选择卖出(x要自定义)、
例如;9:36分跌幅大于等于-0.1;一直重复了2次;这2次的每1分都大于等于-0.1;那么应该9:38分01秒卖出
(卖出符合这个2个条件任意一条都可以自动卖出)
1;可以设置每天用多少x万元交易
2;能可以设置1天买卖x次,超过次数停止工作;
3;能设置账户最大涨幅或者最大跌幅,超过这个最大涨幅或者最大跌幅,如果有持仓可转债立即卖出,停止工作;
4;买卖有选项,可以选择 对方最优价格 和 本方最优价格
# encoding:gbk
# coding:gbk
'''
'''
# coding:gbk
import datetime
import pandas as pd
import numpy as np
import talib
import time
def init(ContextInfo):
ContextInfo.trade_code_list = ['113595.SH', '127098.SZ', '123224.SZ', '128041.SZ', '127097.SZ', '110044.SH', '123235.SZ', '123054.SZ', '128085.SZ', '123167.SZ', '113627.SH', '123118.SZ', '113044.SH', '127101.SZ', '123207.SZ', '110059.SH', '113052.SH', '127096.SZ', '110061.SH', '127081.SZ']
ContextInfo.set_universe(ContextInfo.trade_code_list)
ContextInfo.accID = '6000000058'#'620000155051'
ContextInfo.buy = True
ContextInfo.capital = 100000
ContextInfo.sell = False
# 自定义设置x秒、涨跌幅和重复次数
ContextInfo.minutes_gain=1#买入间隔分钟
ContextInfo.minutes_loss=1#卖出间隔分钟数
#ContextInfo.x_seconds_gain = 60#间隔秒数
#ContextInfo.x_seconds_loss = 60#间隔秒数
ContextInfo.increase_percent_gain = 1#条件涨幅 >=
ContextInfo.increase_percent_loss = -1#条件跌幅<=
ContextInfo.repeat_times_gain = 1#买入重复次数
ContextInfo.repeat_times_loss = 1#卖出重复次数
ContextInfo.df = []
ContextInfo.his_DF = []
# 最大交易次数、最大涨幅和最大跌幅
ContextInfo.trades_loss = 0 # 卖出次数
ContextInfo.trades_gain = 0 # 买入次数
ContextInfo.max_trades_loss = 10 # 卖出最大次数
ContextInfo.max_trades_gain = 10 # 买入最大次数
ContextInfo.max_daily_gain = 5 # 最大涨幅 到了最大涨幅,最大跌幅自动卖出
ContextInfo.max_daily_loss = -5 # 最大跌幅
ContextInfo.one_profit_limit=3 #单次盈利超过这里2是2%
ContextInfo.one_loss_limit=-1#单次亏损限制自动 则卖出持仓
ContextInfo.Today_profit_limit=10 #当日盈利限制超过停止交易
ContextInfo.Today_loss_limit=-10 #当日亏损限制超过 则卖出持仓,当日停止交易
ContextInfo.Date=''
ContextInfo.Date_Time={}#{'2024':ContextInfo.Today_profit_and_loss}
ContextInfo.Today_profit_and_loss=0 #当日盈亏
ContextInfo.status=0 #持仓状态0为空仓,1为满仓
ContextInfo.status_code=0 #持仓代码
ContextInfo.account_price=100000#可用资金 调整到x元持仓 卖出是调整到0元
ContextInfo.stop_status=0#初始化清空账户停止交易状态
ContextInfo.type_gain='MARKET'
ContextInfo.type_loss='MARKET'
#LATEST:最新 FIX:指定 HANG:挂单 COMPETE:对手 MARKET:市价 SALE5, SALE4, SALE3, ‘SALE2’, ‘SALE1’:卖5-1价‘BUY1’, ‘BUY2’, ‘BUY3’, ‘BUY4’, ‘BUY5’:买1-5价
def zhangfu(list1):
a=((list1[1] - list1[0])/list1[0])*100
return a
#bond(ContextInfo, ContextInfo.x_seconds_gain,ContextInfo.x_seconds_loss, ContextInfo.increase_percent_gain,ContextInfo.increase_percent_loss, ContextInfo.repeat_times_gain,ContextInfo.repeat_times_loss,time1)
def bond(ContextInfo, percentage_gain,percentage_loss, num_trades_gain,num_trades_loss,formatted_time):
if ContextInfo.status==0:#空仓
try:
num_trades=num_trades_gain
if ContextInfo.Today_profit_and_loss>ContextInfo.Today_profit_limit:
print('当日账户涨幅{}超过(大于)限制的最大涨幅{}今日停止交易'.format(ContextInfo.Today_profit_and_loss,ContextInfo.Today_profit_limit))
return [2, list(ContextInfo.df['trade_code'])[0]]
if list(ContextInfo.df['买入卖出条件'])[0]==1:
new_price = list(ContextInfo.df['close'])[0]
return [1, list(ContextInfo.df['trade_code'])[0],new_price]#买入
except Exception as e:
print('异常')
print(ContextInfo.df)
print(e)
else:
num_trades=num_trades_loss
#time_list=Transform_time_21(formatted_time, num_trades, seconds)
if ContextInfo.Today_profit_and_loss<ContextInfo.Today_loss_limit:
print('当日账户跌幅{}超过(小于)限制的最大跌幅{} 持仓立即卖出,且今日停止交易'.format(ContextInfo.Today_profit_and_loss,ContextInfo.Today_loss_limit))
new_price = list(ContextInfo.df['close'])[0]# get_current_price2(ContextInfo, list(ContextInfo.df['trade_code'])[0])
return [-2, list(ContextInfo.df['trade_code'])[0],new_price]#
loss_DF=status_df(ContextInfo,ContextInfo.minutes_loss)
df_loss=loss_DF[loss_DF['名称']==ContextInfo.status_code]
if ContextInfo.one_loss>=ContextInfo.one_profit_limit:
print("当前持仓盈利{}超过单笔限制{}卖出当前持仓".format(ContextInfo.one_loss,ContextInfo.one_profit_limit))
new_price = list(df_loss['close'])[0]
return [-1, list(ContextInfo.df['trade_code'])[0],new_price]#卖出
if ContextInfo.one_loss<=ContextInfo.one_loss_limit:
print("当前持仓亏损{}超过单笔限制{}卖出当前持仓".format(ContextInfo.one_loss,ContextInfo.one_loss_limit))
new_price = list(df_loss['close'])[0]
return [-1, list(ContextInfo.df['trade_code'])[0],new_price]#卖出
if list(df_loss['买入卖出条件'])[0]==-1:
new_price = list(df_loss['close'])[0]
return [-1, list(ContextInfo.df['trade_code'])[0],new_price]#卖出
else:
print('当前不符合卖出条件无法卖出')
return [0, list(ContextInfo.df['trade_code'])[0]]#持有
def execute_buy(ContextInfo, stockcode,price):
# 执行买入操作的逻辑
print("全仓买入{}".format(stockcode))
print(ContextInfo.df)
ContextInfo.buy = False
ContextInfo.sell = True
# 列表中股票分别下单买入10手order_target_percent 1.0 order_target_value ContextInfo.type_gain
order_value(stockcode,ContextInfo.account_price, 'fix', price, ContextInfo, ContextInfo.accID)
ContextInfo.trades_gain = ContextInfo.trades_gain + 1
ContextInfo.status=1
def execute_sell(ContextInfo, stockcode):#price
# 执行卖出操作的逻辑
print("全仓卖出{}".format(stockcode))
print(ContextInfo.df)
ContextInfo.buy = True
ContextInfo.sell = False
# 列表中股票分别下单 order_target_percent ContextInfo.account_price ContextInfo.type_loss,
#print('按照指定价{}卖出可转债{}'.format(price,stockcode))
print('按照市场价卖出可转债{}'.format(stockcode))
#order_target_value(stockcode, 0,'fix',price, ContextInfo, ContextInfo.accID) # 'MARKET':市单价 'COMPETE':对手
order_target_value(stockcode, 0,ContextInfo.type_loss, ContextInfo, ContextInfo.accID) # 'MARKET':市单价 'COMPETE':对手
ContextInfo.trades_loss = ContextInfo.trades_loss + 1
ContextInfo.status=0
import datetime
def Transform_time(timestamp):
# 将13位时间戳转换为datetime对象
dt = datetime.datetime.fromtimestamp(int(timestamp) / 1000) # 需要将13位时间戳除以1000得到以秒为单位的时间戳
# 将datetime对象格式化为可读时间格式
formatted_time = dt.strftime('%Y-%m-%d %H:%M:%S')
return formatted_time
def status_df(ContextInfo,x):
x=x+1
hisdict = ContextInfo.get_history_data(x, '1m', 'close')#,skip_paused=True)
data_dict=[]
for k, v in hisdict.items():
if len(v) > 1:
v_dict={'名称':k}
v_num=len(v)-1
signal_list=[]
for i in range(v_num):
zhangfu_value=zhangfu([v[i],v[i+1]])
v_dict['涨幅'+str(i)]=zhangfu_value
if zhangfu_value<=ContextInfo.increase_percent_loss:
signal_list.append(-1)
elif zhangfu_value>=ContextInfo.increase_percent_gain:
signal_list.append(1)
else:
signal_list.append(0)
if list(set(signal_list)) == [-1]:
v_dict['买入卖出条件']=-1
elif list(set(signal_list)) == [1]:
v_dict['买入卖出条件']=1
else:
v_dict['买入卖出条件']=0
data_dict.append(v_dict)
his_DF=pd.DataFrame(data_dict)
df = ContextInfo.get_market_data(['amount','close'], stock_code=ContextInfo.get_universe(), skip_paused=True, period='1m',
dividend_type='front', count=-1)
df=df.reset_index()#.index=list(range(len(df)))
his_DF['amount']=df['amount']
his_DF['close']=df['close']
#print(his_DF)
return his_DF
def handlebar(ContextInfo): # ['lastClose', 'close','amount']
index = ContextInfo.barpos
time0= ContextInfo.get_bar_timetag(index)
time1 = Transform_time(time0)
start_930=datetime.datetime.strptime('09:31:00', "%H:%M:%S")
delta=datetime.timedelta(seconds=ContextInfo.minutes_gain*60*ContextInfo.repeat_times_gain)
start_9x=start_930+delta
if datetime.datetime.strptime(time1.split(' ')[1], "%H:%M:%S")<=start_9x:
print('当前时间{}小于等于{}不进行交易'.format(time1.split(' ')[1],str(start_9x).split(' ')[1]))
return
else:
print('当前时间{}为正常交易时间'.format(time1))
if ContextInfo.Date!=time1.split(' ')[0]:
ContextInfo.Date=time1.split(' ')[0]
ContextInfo.trades_gain=0#新的日期买入次数归零
ContextInfo.trades_loss=0#新的日期买出次数归零
ContextInfo.Today_profit_and_loss=0#新的日期清空账户涨跌幅
ContextInfo.stop_status==0#新的日期清空账户停止交易状态
print("新的交易日!!{}".format(ContextInfo.Date))
else:
index = ContextInfo.barpos
list_1=[]#historysums
print('历史持仓为')
result_historysums_records=get_result_records('historysums', index, ContextInfo)
for i in result_historysums_records:
list_1.append({'交易代码':i.market+'.'+i.stockcode,
#'交易日期':Transform_time(i.trade_date),
'持仓盈亏':i.profit,
#'盈利占比权重':i.benefit_weight,
'交易次数':i.buy_sell_times,
'持仓成本':i.trade_price,
'最新价':i.current_price,
'仓位数量':i.position,
#'仓位金额':i.position*i.trade_price,
'最新价':i.current_price,
})#:number,最新价,持仓中用这个价
if ContextInfo.stop_status==1:
print('当日已经停止交易')
return
ContextInfo.Date_Time[ContextInfo.Date]=[list_1]
print("历史交易明细为")
print(ContextInfo.Date_Time)
ContextInfo.Today_profit_and_loss=sum([i['持仓盈亏'] for i in list_1])/ContextInfo.capital
ContextInfo.Date_Time[ContextInfo.Date]=ContextInfo.Today_profit_and_loss#{'2024':ContextInfo.Today_profit_and_loss}
print("账户今日涨跌幅为{}".format(ContextInfo.Today_profit_and_loss))
print("全部日期涨跌幅为")
print(ContextInfo.Date_Time)
print("账户当前时刻买入次数{}".format(ContextInfo.trades_gain))
print("账户当前时刻卖出次数{}".format(ContextInfo.trades_loss))
#ContextInfo.Today_profit_and_loss
#print("最大涨幅为{}".format(ContextInfo.max_daily_gain))
if ContextInfo.Today_profit_and_loss > ContextInfo.Today_profit_limit:
print('因为涨幅{}超出当日最大涨幅{}停止交易'.format(ContextInfo.Today_profit_and_loss,ContextInfo.Today_profit_limit))
return # 涨跌幅超过设定值, 止操作
elif ContextInfo.Today_profit_and_loss < ContextInfo.Today_loss_limit:
print('因为跌幅{}超出当日最大跌幅{}停止交易'.format(ContextInfo.Today_profit_and_loss,ContextInfo.Today_loss_limit))
return # 涨跌幅超过设定值,停止操作
his_DF=status_df(ContextInfo,ContextInfo.minutes_gain)
if ContextInfo.trades_gain <= ContextInfo.max_trades_gain and ContextInfo.trades_loss <= ContextInfo.max_trades_loss:
index = ContextInfo.barpos
result_holdings_records=get_result_records('holdings', index, ContextInfo)#当下持仓
if result_holdings_records==[]:
print("当前没有持仓")
ContextInfo.status=0
end_his_DF=his_DF[his_DF['买入卖出条件']==1]
if len(end_his_DF)==0:
print("当前时间分钟{}没有满足买入条件的可转债".format(time1))
ContextInfo.df=[]
return
else:
end_his_DF['trade_code']=end_his_DF['名称']
ContextInfo.df = end_his_DF.sort_values(by='amount', ascending=False
) # 必然是成交额最大的可转债
print('当前股票池状态:')
print(ContextInfo.df)
else:
result_records=result_holdings_records
i=result_records[0]
print('当前持仓为')
print({'交易代码':i.market+'.'+i.stockcode,
#'交易日期':Transform_time(i.trade_date),
'持仓盈亏':i.profit,
#'盈利占比权重':i.benefit_weight,
'交易次数':i.buy_sell_times,
'持仓成本':i.trade_price,
'最新价':i.current_price,
'仓位数量':i.position,
#'仓位金额':i.position*i.trade_price,
'最新价':i.current_price,
})
one_loss=((i.current_price-i.trade_price)/i.trade_price)*100
print("当前持仓盈亏{}".format(one_loss))
ContextInfo.one_loss=one_loss
if len(result_records)!=1:
print("策略超过持仓数量限制1,持有{}支可转债".format(len(result_records)))
status_code=result_records[0].stockcode+'.'+result_records[0].market
ContextInfo.status_code=status_code
if i.position*i.trade_price>ContextInfo.account_price:
print('持仓总额{}超过设定的限制{},停止策略'.format(i.position*i.trade_price,ContextInfo.account_price))
return
print("时间{}持仓可转债{}金额{}".format(time1,status_code,i.position*i.trade_price))
#enddict={i.trade_date:i.profit for i in result_historysums_records}
#print(enddict)
ContextInfo.status=1
# 交易策略
# 买入条件:假设一支可转债在9点30分20秒涨跌幅为8%,过了20秒也就是9点30分40秒,涨跌幅为9%,比之前20秒大于1%,一直重复x次都符合这设定,只考虑 成交额 是第一的 可转债 进行买入
# 卖出条件:假设一支可转债在9点30分20秒涨跌幅为8%,过了20秒也就是9点30分40秒,涨跌幅为7%,比之前20秒小于1%,一直重复x次都符合这设定,进行卖出
condition = bond(ContextInfo, ContextInfo.increase_percent_gain,ContextInfo.increase_percent_loss, ContextInfo.repeat_times_gain,ContextInfo.repeat_times_loss,time1)
# 增加模拟资金;能设置1天买卖操作次数,超过次数停止工作;能设置1天涨幅大于x%或者跌幅大于x%停止操作
#print(condition)
if condition[0] == 1:
if ContextInfo.status==0:
print("时间{}以{}价格买入可转债{}".format(time1,condition[2],condition[1]))
execute_buy(ContextInfo, condition[1], condition[2])
#ContextInfo.status==1
elif condition[0] == -1:
if ContextInfo.status==1:
#if ContextInfo.status_code!=0:
print("时间{}以{}价格卖出可转债{}".format(time1,condition[2],ContextInfo.status_code))
execute_sell(ContextInfo,ContextInfo.status_code)#condition[1]#
elif condition[0] == 2:
ContextInfo.stop_status=1
elif condition[0] == -2:
if ContextInfo.status==1:
#if ContextInfo.status_code!=0:
print("时间{}今日最后一次卖出可转债{}".format(time1,ContextInfo.status_code))
execute_sell(ContextInfo,ContextInfo.status_code, condition[2])#condition[1]#
ContextInfo.stop_status=1
else:
pass
#print('持有')
else:
print('因为超出当日最大交易次数停止交易')
return
原文地址:https://blog.csdn.net/weixin_45934622/article/details/135709073
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!