0、交易函数内含属性说明
# 5.4.1. account 资金账号对象
m_dMaxMarginRate: 保证金比率,股票的保证金率等于 1,股票不需要
m_dFrozenMargin: 冻结保证金,外源性,股票的保证金就是冻结资金,股票不需要
m_dFrozenCash: 冻结金额,内外源冻结保证金和手续费四个的和
m_dFrozenCommission: 冻结手续费,外源性冻结资金源
m_dRisk: 风险度,风险度,冻结资金 / 可用资金,股票不需要
m_dNav: 单位净值
m_dPreBalance: 期初权益,股票不需要,也叫静态权益
m_dBalance: 总资产,动态权益,即市值
m_dAvailable: 可用金额
m_dCommission: 手续费,已经用掉的手续费
m_dPositionProfit: 持仓盈亏
m_dCloseProfit: 平仓盈亏,股票不需要
m_dCashIn: 出入金净值
m_dCurrMargin: 当前使用的保证金,股票不需要
m_dInitBalance: 初始权益
m_strStatus: 状态
m_dInitCloseMoney: 期初平仓盈亏,初始平仓盈亏
m_dInstrumentValue: 总市值,合约价值,合约价值
m_dDeposit: 入金
m_dWithdraw: 出金
m_dPreCredit: 上次信用额度,股票不需要
m_dPreMortgage: 上次质押,股票不需要
m_dMortgage: 质押,股票不需要
m_dCredit: 信用额度,股票不需要
m_dAssetBalance: 证券初始资金,股票不需要
m_strOpenDate: 起始日期,股票不需要
m_dFetchBalance: 可取金额
m_strTradingDate: 交易日
m_dStockValue: 股票总市值,期货没有
m_dLoanValue: 债券总市值,期货没有
m_dFundValue: 基金总市值,包括ETF和封闭式基金,期货没有
m_dRepurchaseValue: 回购总市值,所有回购,期货没有
m_dLongValue: 多单总市值,现货没有
m_dShortValue: 单总市值,现货没有
m_dNetValue: 净持仓总市值,净持仓市值 = 多 - 空
m_dAssureAsset: 净资产
m_dTotalDebit: 总负债
m_dEntrustAsset: 可信资产,用于校对
m_dInstrumentValueRMB: 总市值(人民币),沪港通
m_dSubscribeFee: 申购费,申购费
m_dGoldValue: 库存市值,黄金现货库存市值
m_dGoldFrozen: 现货冻结,黄金现货冻结
m_dMargin: 占用保证金,维持保证金
m_strMoneyType: 币种
m_dPurchasingPower: 购买力,盈透购买力
m_dRawMargin : 原始保证金
m_dBuyWaitMoney: 买入待交收金额(元),买入待交收
m_dSellWaitMoney: 卖出待交收金额(元),卖出待交收
m_dReceiveInterestTotal: 本期间应计利息
m_dRoyalty: 权利金收支,期货期权用
m_dFrozenRoyalty: 冻结权利金,期货期权用
m_dRealUsedMargin: 实时占用保证金,用于股票期权
m_dRealRiskDegree: 实时风险度
# 5.4.2. order 委托对象
m_strExchangeID: 证券市场
m_strExchangeName: 交易市场
m_strProductID: 品种代码
m_strProductName: 品种名称
m_strInstrumentID: 证券代码
m_strInstrumentName: 证券名称,合约名称
m_nTaskId:任务号
m_strOrderRef: 内部委托号,下单引用等于股票的内部委托号
m_nOrderPriceType: EBrokerPriceType 类型,例如市价单、限价单
m_nDirection: EEntrustBS 类型,操作,多空,期货多空,股票买卖永远是 48,其他的 dir 同理
m_nOffsetFlag: EOffset_Flag_Type 类型,操作,期货开平,股票买卖其实就是开平
m_nHedgeFlag: EHedge_Flag_Type 类型,投保
m_dLimitPrice: 委托价格,限价单的限价,就是报价
m_nVolumeTotalOriginal: 委托量,最初委托量
m_nOrderSubmitStatus: EEntrustSubmitStatus 类型,报单状态,提交状态,股票中不需要报单状态
m_strOrderSysID: 合同编号,委托号
m_nOrderStatus: EEntrustStatus,委托状态
m_nVolumeTraded: 成交数量,已成交量
m_nVolumeTotal: 委托剩余量,当前总委托量,股票的含义是总委托量减去成交量
m_nErrorID: 状态信息
m_dFrozenMargin: 冻结金额,冻结保证金
m_dFrozenCommission: 冻结手续费
m_strInsertDate: 委托日期,报单日期
m_strInsertTime: 委托时间
m_dTradedPrice: 成交均价(股票)
m_dCancelAmount: 已撤数量
m_strOptName: 买卖标记,展示委托属性的中文
m_dTradeAmount: 成交金额,成交额,期货 = 均价 * 量 * 合约乘数
m_eEntrustType: EEntrustTypes,委托类别
m_strCancelInfo: 废单原因
m_strUnderCode: 标的证券代码
m_eCoveredFlag: ECoveredFlag,备兑标记 ‘0’ - 非备兑,’1’ - 备兑
m_strCompactNo: 合约编号
m_strRemark:投资备注
# 5.4.3. deal 成交对象
m_strExchangeID: 证券市场,交易所代码
m_strExchangeName: 交易市场,交易所名称
m_strProductID: 品种代码
m_strProductName: 品种名称
m_strInstrumentID: 证券代码
m_strInstrumentName: 证券名称
m_strTradeID: 成交编号
m_nTaskId:任务号
m_strOrderRef: 下单引用,等于股票的内部委托号
m_strOrderSysID: 合同编号,报单编号,委托号
m_nDirection: EEntrustBS,买卖方向
m_nOffsetFlag: EOffset_Flag_Type,开平,股票的买卖
m_nHedgeFlag: EHedge_Flag_Type,投保,股票不需要
m_dPrice: 成交均价
m_nVolume: 成交量,期货单位手,股票做到股
m_strTradeDate: 成交日期
m_strTradeTime: 成交时间
m_dComssion: 手续费
m_dTradeAmount: 成交额,期货 = 均价 * 量 * 合约乘数
m_nOrderPriceType: EBrokerPriceType 类型,例如市价单、限价单
m_strOptName:买卖标记,展示委托属性的中文
m_eEntrustType: EEntrustTypes 类型,委托类别
m_eFutureTradeType: EFutureTradeType 类型,成交类型
m_nRealOffsetFlag: EOffset_Flag_Type 类型,实际开平,主要是区分平今和平昨
m_eCoveredFlag: ECoveredFlag类型,备兑标记 ‘0’ - 非备兑,’1’ - 备兑
m_nCloseTodayVolume: 平今量,不显示
m_dOrderPriceRMB: 委托价格(人民币),目前用于港股通
m_dPriceRMB: 成交价格(人民币),目前用于港股通
m_dTradeAmountRMB:成交金额(人民币),目前用于港股通
m_dReferenceRate: 汇率,目前用于港股通
m_strXTTrade: 是否是本终端交易
m_strCompactNo: 合约编号
m_dCloseProfit: 平仓盈亏 ,目前用于外盘
m_strRemark:投资备注
# 5.4.4. position 持仓对象
m_strExchangeID: 证券市场
m_strExchangeName: 市场名称
m_strProductID: 品种代码
m_strProductName: 品种名称
m_strInstrumentID: 证券代码
m_strInstrumentName: 证券名称
m_nHedgeFlag: EHedge_Flag_Type 类型,投保 ,股票不需要
m_nDirection: EEntrustBS 类型,买卖 ; 股票不需要
m_strOpenDate: 成交日期
m_strTradeID: 成交号,最初开仓位的成交
m_nVolume: 当前拥股,持仓量
m_dOpenPrice: 持仓成本
m_strTradingDay: 在实盘运行中是当前交易日,在回测中是股票最后交易过的日期
m_dMargin: 使用的保证金,历史的直接用 ctp 的,新的自己用成本价 * 存量 * 系数算,股票不需要
m_dOpenCost: 开仓成本,等于股票的成本价 * 第一次建仓的量,后续减持不影响,不算手续费,股票不需要
m_dSettlementPrice: 最新价,结算价,对于股票的当前价
m_nCloseVolume: 平仓量,等于股票已经卖掉的 股票不需要
m_dCloseAmount: 平仓额,等于股票每次卖出的量 * 卖出价 * 合约乘数(股票为 1)的累加 股票不需要
m_dFloatProfit: 浮动盈亏,当前量 * (当前价 - 开仓价) * 合约乘数(股票为 1)
m_dCloseProfit: 平仓盈亏,平仓额 - 开仓价 * 平仓量 * 合约乘数(股票为 1) 股票不需要
m_dMarketValue: 市值,合约价值
m_dPositionCost: 持仓成本,股票不需要
m_dPositionProfit: 持仓盈亏,股票不需要
m_dLastSettlementPrice: 最新结算价,股票不需要
m_dInstrumentValue: 合约价值,股票不需要
m_bIsToday: 是否今仓
m_strStockHolder: 股东账号
m_nFrozenVolume: 冻结数量,冻结持仓,期货不用这个字段,冻结数量
m_nCanUseVolume: 可用余额,可用持仓,期货不用这个字段,股票的可用数量
m_nOnRoadVolume: 在途股份,在途持仓,期货不用这个字段,股票的在途数量
m_nYesterdayVolume: 昨夜拥股,期货不用这个字段,股票的股份余额
m_dLastPrice: 最新价,结算价,对于股票的当前价
m_dProfitRate: 盈亏比例,持仓盈亏比例
m_eFutureTradeType: EFutureTradeType,成交类型
m_strExpireDate: 到期日,逆回购用
m_strComTradeID: 组合成交号 ,套利成交 ID
m_nLegId: 组合序号 ,组合 ID
m_dTotalCost: 累计成本,自定义累计成本,股票信用用到
m_dSingleCost: 单股成本,自定义单股成本,股票信用用到
m_nCoveredVolume: 备兑数量,用于个股期权
m_eSideFlag: ESideFlag 持仓类型 ,用于个股期权,标记 ‘0’ - 权利,’1’ - 义务,’2’ - ‘备兑’
m_dReferenceRate: 汇率,目前用于港股通
m_dStructFundVol: 分级基金可用(可分拆或可合并)
m_dRedemptionVolume: 分级基金可赎回量
m_nPREnableVolume: 申赎可用量(记录当日申购赎回的股票或基金数量)
m_dRealUsedMargin: 实时占用保证金,用于期权
m_dRoyalty: 权利金
交易策略开发过程


单均线策略
```py
#encoding:gbk
#导入外部程序包
import numpy as np #主要用于科学计算的Python包
import pandas as pd #建立在numpy和其他众多第三方库基础上的python包
#-------------------------------------------------------------
#初始化模块
def init(ContextInfo):
#获取当前主图股票代码
ContextInfo.tradestock =ContextInfo.stockcode + "." + ContextInfo.market
#设定股票池,即要操作的股票
ContextInfo.set_universe([ContextInfo.tradestock])
#设定账号
ContextInfo.accountid= '410038203732'
ContextInfo.MA_period = 19
#-------------------------------------------------------------
#基本运行模块
def handlebar(ContextInfo):
#获取股票收盘价系列
close= ContextInfo.get_history_data(ContextInfo.MA_period+1,'1d','close')[ContextInfo.tradestock]
#计算移动均线
MA20 = pd.rolling_mean(pd.Series(close),ContextInfo.MA_period) #得到1个DataFrame
# print(MA20)
MA20 = MA20.values
# print(MA20)
#判断买入条件满足则买入
if close[-1]>MA20[-1] and close[-2] <= MA20[-2]:
#获取账户资金
totalvalue = get_totalvalue(ContextInfo.accountid,'STOCK') #(账号,商品类型)
#下单全仓买进
order_target_value(ContextInfo.tradestock,totalvalue,ContextInfo,ContextInfo.accountid)
#判断卖出条件满足则卖出
if close[-1]<np.array(MA20)[-1] and close[-2] >= np.array(MA20)[-2]:
#下单全部卖出
order_target_value(ContextInfo.tradestock,0,ContextInfo,ContextInfo.accountid)
#--------------------------------------------------------------
#调用模块:获取账户资金
def get_totalvalue(accountid,datatype): #(账号,商品类型)
result=0 #设初值为0
resultlist=get_trade_detail_data(accountid,datatype,"ACCOUNT")#(账号,商品类型,账户类型)
print(resultlist)
for obj in resultlist:
result=obj.m_dBalance #账户可用资金余额
print(obj,result)
return result
```
多股实盘MACD跟踪策略
```py
#encoding:gbk
'''
当快线DIF上穿慢线DEA(金叉)时买进,当快线DIF下穿慢线DEA(死叉)时卖出
'''
import pandas as pd
import numpy as np
import talib
def init(ContextInfo):
#hs300成分股中sh和sz市场各自流通市值最大的前3只股票
ContextInfo.trade_code_list=['000651.SZ','601857.SH','600519.SH','000333.SZ','002415.SZ','000002.SZ']
ContextInfo.set_universe(ContextInfo.trade_code_list)
ContextInfo.accID = '6000000058'
#设定买入印花税为0,卖出印花税为0.0001,开仓手续费和平仓(平昨)手续费均为万三,平今手续费为0,最小手续费为5
commissionList = [0,0.0001,0.0003,0.0003,0,5]
ContextInfo.set_commission(0,commissionList)
def handlebar(ContextInfo):
#当前K线索引号
d=ContextInfo.barpos
#获取当前K线日期
today=timetag_to_datetime(ContextInfo.get_bar_timetag(d),'%Y-%m-%d')
#获取股票池中所有个股的51天历史收盘价数据
h=ContextInfo.get_history_data(51,'1d','close')
#获取持仓信息
holdings=get_holdings(ContextInfo.accID,'STOCK')
#获取账户总权益
totalvalue=get_totalvalue(ContextInfo.accID,'STOCK')
#等资金权重下,每只股票的分配金额
cash_per_stock=totalvalue/len(ContextInfo.trade_code_list)
for stk in ContextInfo.trade_code_list:
#获取个股昨日收盘价
pc=h[stk][-1]
if stk in h.keys():
#长期移动平均线、短期移动平均线、慢速线
macd, macdsignal, macdhist = talib.MACD(np.array(h[stk]), fastperiod=period1, slowperiod=period2, signalperiod=period3)
#当快线DIF上穿慢线DEA(金叉)时买进
if macdhist[-1]>0 and macdhist[-2]<0 and stk not in holdings.keys():
order_shares(stk,cash_per_stock/pc,ContextInfo,ContextInfo.accID)
#当快线DIF下穿慢线DEA(死叉)时平仓
elif macdhist[-1]<0 and macdhist[-2]>0 and stk in holdings.keys():
order_shares(stk,-holdings[stk]*100,ContextInfo,ContextInfo.accID)
#获取账户总权益m_dBalance
def get_totalvalue(accountid,datatype):
#datatype:FUTURE-期货 STOCK-股票 CREDIT-信用 STOCK_OPTION-期权 HUGANGTONG-沪港通 SHENGANGTONG-深港通
result=0
resultlist=get_trade_detail_data(accountid,datatype,"ACCOUNT")
for obj in resultlist:
result=obj.m_dBalance
return result
#获取持仓信息{code.market:手数}
def get_holdings(accountid,datatype):
#datatype:FUTURE-期货 STOCK-股票 CREDIT-信用 STOCK_OPTION-期权 HUGANGTONG-沪港通
holdinglist={}
#OPTION:持仓 ORDER:委托 DEAL:成交 ACCOUNT:帐号 TASK:任务
resultlist=get_trade_detail_data(accountid,datatype,"POSITION")
for obj in resultlist:
holdinglist[obj.m_strInstrumentID+"."+obj.m_strExchangeID]=obj.m_nVolume/100
#返回{code.market:持仓手数}
return holdinglist
```
## DataFrame 新建,插入、遍历、删除行
```py
df_buy=pd.DataFrame(columns=['stock','price','hand'])
df_buy=df_buy.append([{'stock':'300056.SZ','price':8,'hand':200}],ignore_index=True)
df_buy=df_buy.append([{'stock':'000955.SZ','price':2.75,'hand':1000}],ignore_index=True)
df_buy=df_buy.append([{'stock':'300007.SZ','price':14.75,'hand':2000}],ignore_index=True)
print(df_buy)
print('len=',len(df_buy))
print('row=',df_buy.shape[0])
print('col=',df_buy.shape[1])
for index,row in df_buy.iterrows():
print(index,row['stock'])
df_buy.drop([1],inplace=True)
df_buy
```
```python
df_buy=pd.DataFrame(columns=['stock','price','hand'])
df_buy=df_buy.append([{'stock':'300007.SZ','price':8,'hand':200}])
df=df_buy.set_index('stock')
new = pd.DataFrame({'stock':'300056.SZ','price':8,'hand':200},index=[1])
new = new.set_index('stock')
df = df.append(new)
#df_buy=df_buy.append([{'stock':'000955.SZ','price':2.75,'hand':1000}],ignore_index=False)
#df=df['300007.SZ']=[15,1000]
print(df)
df=df.drop(['300007.SZ'])
print(df)
_row=df.loc['300056.SZ',:]
#print(_row)
print('行数据:',_row['hand'],_row['price'])
if '300057.SZ' in df.index:
print('存在')
else:
print('不存在')
#print('len=',len(df_buy))
#print('row=',df_buy.shape[0])
#print('col=',df_buy.shape[1])
#for index,row in df_buy.iterrows():
# print(index,row['stock'])
#df_buy.drop([1],inplace=True)
#df_buy
```
V型底策略-止损、止赢、固定天数出仓方式
```py
#encoding:gbk
import pandas as pd
import numpy as np
import time
import datetime
from datetime import timedelta
def init(ContextInfo):
ContextInfo.tradestock =ContextInfo.stockcode + "." + ContextInfo.market
ContextInfo.set_universe([ContextInfo.tradestock])
ContextInfo.accountid= 'test'
# 当前点需要比低点至少上涨幅度
ContextInfo.g_increasePercent = increasePercent #将优化参数代入模型
# 低点比第一个高点至少下跌幅度
ContextInfo.g_decreasePercent = decreasePercent
# 当前点和最低点之间最大间隔
ContextInfo.g_rangeRight = rangeRight
# 最低点和第一个高点之间最大间隔
ContextInfo.g_rangeLeft = rangeLeft
# 最低点和高点之间最小间隔
ContextInfo.g_minDays = minDays
# 两个V点之间最小距离
ContextInfo.g_minDistanceBtwVBot = minDistanceBtwVBot
# 出场条件
ContextInfo.g_exitDays = 5
# 前一个V底时间
ContextInfo.g_previousVDate = datetime.datetime.strptime("2000-01-01 00:00:00","%Y-%m-%d %H:%M:%S")
# 出场时间计算
ContextInfo.g_daysCounts = 0
# 是否持仓
ContextInfo.g_state = "empty"
# 买入卖出数量
ContextInfo.g_numOfShares = 100
ContextInfo.buy_price = 0
ContextInfo.max_price = 0
ContextInfo.exit_ways = 0 #出场方式,0为固定天数,1为静态止盈止损,2为动态止盈止损
ContextInfo.stop_loss = 0.05 #静态止损幅度、动态止盈止损幅度
ContextInfo.stop_proft = 0.10 #静态止盈幅度
ContextInfo.max_profit = 0.0001 #最大盈利初值
#基本运行模块====================================================================================
def handlebar(ContextInfo):
#获取基础数据计算相关指标---------------------------------------------------------------------------
Hold_volume=get_holding(ContextInfo.accountid,'STOCK') #获取持仓量
d = ContextInfo.barpos #当前K线索引号
p = ContextInfo.get_net_value(d) #该索引策略回测的净值,后面绘图使用
#V型结束日期
timetag = timetag_to_datetime(ContextInfo.get_bar_timetag(d),'%Y%m%d %H:%M:%S') #该索引的时间 如20200120 00:00:00
pre_endtime = datetime.datetime.strptime(timetag,'%Y%m%d %H:%M:%S') #格式化字符串为 datetime 对象便于比较计算2020-01-20 00:00:00
endtime= datetime.datetime.strftime(pre_endtime,'%Y%m%d %H:%M:%S')[:8] #只取年月日 20200120
#往前n根K线找V型的最低点
g = ContextInfo.g_rangeRight
days = datetime.timedelta(days=g) #n根K线的时间
pre_starttime = pre_endtime - days #开始时间
starttime= datetime.datetime.strftime(pre_starttime,'%Y%m%d %H:%M:%S')[:8]
dividend_type = ContextInfo.dividend_type #当前主图的行情复权方式
#获取右边区间价格
rightPrice = ContextInfo.get_market_data(['close'],[ContextInfo.tradestock],starttime,endtime,skip_paused=True,period='1d',
dividend_type=dividend_type,count= -1)['close']
#昨天收盘价
rightPriceNum = np.array(rightPrice)[-1]
#昨日日期
rightPriceDate= datetime.datetime.strptime(rightPrice.index[-1],'%Y%m%d')
#找到价格最低点
lowPriceNum = rightPrice.min()
#价格最低点日期
lowPriceDate= datetime.datetime.strptime(rightPrice.argmin(),'%Y%m%d')
#两点价格波动幅度
chgPerRight = (rightPriceNum - lowPriceNum)/lowPriceNum
#两点相差天数
rangeRight = (rightPriceDate - lowPriceDate).days
#入场=======================================================================================
# 判断右侧条件是否成立:两点价格波动>2% & 两点相差>3
if chgPerRight >= ContextInfo.g_increasePercent and rangeRight >= ContextInfo.g_minDays:
#寻找左侧价格高点
g = ContextInfo.g_rangeRight
days= datetime.timedelta(days=g)
pre_starttime = pre_endtime - days
endtime= datetime.datetime.strftime(pre_endtime,'%Y%m%d %H:%M:%S')[:8]
starttime= datetime.datetime.strftime(pre_starttime,'%Y%m%d %H:%M:%S')[:8]
leftPrice= ContextInfo.get_market_data(['close'],[ContextInfo.tradestock],starttime,endtime,skip_paused=True,period='1d',dividend_type=dividend_type,count= -1)['close'][:rightPrice.argmin()]
#左侧最高点
leftPriceNum = leftPrice.max()
#左侧高点日期
leftPriceDate= datetime.datetime.strptime(rightPrice.argmax(),'%Y%m%d')
#两点波动幅度
chgPerLeft = (leftPriceNum - lowPriceNum)/lowPriceNum
#两点相差天数
rangeLeft = (lowPriceDate - leftPriceDate).days
#print(rangeLeft,type(rangeLeft))
#----------------------------------------------------------------------------------
#判断左侧是否满足条件
if chgPerLeft >= ContextInfo.g_decreasePercent and rangeLeft >= ContextInfo.g_minDays:
# 判断距离上次V型底是否大于最小距离
if (lowPriceDate - ContextInfo.g_previousVDate).days >= ContextInfo.g_minDistanceBtwVBot :
totalvalue=get_totalvalue(ContextInfo.accountid,'STOCK') #获取账户资金
ContextInfo.draw_text(1>0,p+0.1*p,"B") #绘图买入信号
ContextInfo.g_previousVDate= lowPriceDate #记录最低日期
if Hold_volume==0: #如果无持仓
order_target_value(ContextInfo.tradestock,totalvalue,ContextInfo,ContextInfo.accountid) #买进
ContextInfo.buy_price = ContextInfo.get_history_data(1,'1d','close')[ContextInfo.tradestock][0] #记录买入价格
ContextInfo.max_price = ContextInfo.buy_price #买入价作为最高价初值
#出场===================================================================================
#固定天数出场----------------------------------------------------------------------------
if ContextInfo.exit_ways==0:
if Hold_volume > 0:
#print(Hold_volume,ContextInfo.g_dayCounts)
ContextInfo.g_dayCounts+=1 #有持仓则持仓天数加一天
elif Hold_volume== 0:
ContextInfo.g_dayCounts= 0 #无持仓则持仓天数归零
if ContextInfo.g_dayCounts >= ContextInfo.g_exitDays and Hold_volume>0:
#print('持仓第n天平仓')
order_target_value(ContextInfo.tradestock,0,ContextInfo,ContextInfo.accountid)
ContextInfo.g_dayCounts= 0 #卖出则持仓天数归零
#静态止盈止损出场-------------------------------------------------------------------------
if ContextInfo.exit_ways==1 :
now_price=ContextInfo.get_history_data(1,'1d','close')[ContextInfo.tradestock][0] #获取当前价格
if now_price < ContextInfo.buy_price*(1-ContextInfo.stop_loss) and Hold_volume>0: #价格小于止损价并持仓则
order_target_value(ContextInfo.tradestock,0,ContextInfo,ContextInfo.accountid) #止损卖出
ContextInfo.buy_price= 0
ContextInfo.max_price = 0
ContextInfo.draw_text(1>0,p+0.1*p,"zs")
if now_price > ContextInfo.buy_price*(1+ContextInfo.stop_proft) and Hold_volume>0: #价格大于止盈价并持仓则
order_target_value(ContextInfo.tradestock,0,ContextInfo,ContextInfo.accountid) #止盈卖出
ContextInfo.buy_price= 0
ContextInfo.max_price = 0
ContextInfo.draw_text(1>0,p-0.1*p,"zy")
#盈利回落止盈止损出场----------------------------------------------------------------------
if ContextInfo.exit_ways==2 and Hold_volume > 0 :
now_price=ContextInfo.get_history_data(1,'1d','close')[ContextInfo.tradestock][0] #获取当前价格
profit = now_price / ContextInfo.buy_price-1 #计算盈亏幅度
ContextInfo.max_profit = max(ContextInfo.max_profit,profit) #计算最大盈利
if ContextInfo.max_profit-profit>ContextInfo.stop_loss and Hold_volume>0:
order_target_value(ContextInfo.tradestock,0,ContextInfo,ContextInfo.accountid)
print('max_profit %%%.2f, profit %%%.2f, down %%%.2f' %( ContextInfo.max_profit*100,profit*100,(ContextInfo.max_profit-profit)*100))
ContextInfo.buy_price= 0
ContextInfo.max_price = 0
ContextInfo.max_profit = 0.0001
if profit<0:
ContextInfo.draw_text(1>0,p-0.1*p,"ds")
else:
ContextInfo.draw_text(1>0,p-0.1*p,"dy")
#================================================================
#获取账户现金m_dAvailable
def get_totalvalue(accountid,datatype):
result=0
resultlist=get_trade_detail_data(accountid,datatype,"ACCOUNT")
for obj in resultlist:
result=obj.m_dBalance #获取账户现金
return result
#获取账户持仓
def get_holding(accountid,datatype):
result=0
resultlist=get_trade_detail_data(accountid,datatype,"POSITION")
for obj in resultlist:
result=obj.m_nVolume #获取账户持仓
return result
```
4、网格交易策略
```py
#coding:gbk
'''
本策略首先根据移动均线发散策略开仓,将初始资金的70%用于建仓,以开仓价为基准价,
以0.3%为买卖步长,在价格下跌0.3%后,买入10%底仓股票,上涨0.3%后,卖出 10%底仓股票。
网格数目为10,网格交易的价格上限为基准价的110%,价格下线为基准价的5%。
'''
import numpy as np
import pandas as pd
def init(ContextInfo):
#设置主图股票代码为买卖标的
ContextInfo.tradestock = ContextInfo.stockcode+"."+ContextInfo.market
ContextInfo.set_universe([ContextInfo.tradestock])
# 设置建仓资金比例
ContextInfo.weight = 0.60
# 设置网格的步长,以基准价的百分比表示
ContextInfo.step = 0.003 #步长设置参数
# 设置网格线的价格,以基准价的百分比表示
ContextInfo.band = pd.Series([0.2,1,1,1,1,1,1,1,1,1,1,1,10])+pd.Series([-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6])*ContextInfo.step
ContextInfo.holdings= []
ContextInfo.accountid='test'
ContextInfo.short=5
ContextInfo.middle=20
ContextInfo.long=40
ContextInfo.price=0
ContextInfo.basic_holdings= []
ContextInfo.holdings_list=[]
#对应区间的目标仓位,买入和卖出在同一价格区间的目标仓位不一致,需分别列出,以相对底仓的变动表示
ContextInfo.Buy_Lable=pd.Series([5,4,3,2,1,0,-1,-2,-3,-4,-5,-5])
ContextInfo.Sell_Lable=pd.Series([5,5,4,3,2,1,0,-1,-2,-3,-4,-5])
ContextInfo.number_plus = 0
ContextInfo.number_down = 0
def handlebar(ContextInfo):
#=============建仓=======================
holdings=get_holdings(ContextInfo.accountid,'STOCK')
totalvalue=get_totalvalue(ContextInfo.accountid,'STOCK')
if not holdings:
h=ContextInfo.get_history_data(41,'3m','close')
ma5=np.mean(h[ContextInfo.tradestock][-ContextInfo.short-1:-1])
ma20=np.mean(h[ContextInfo.tradestock][-ContextInfo.middle-1:-1])
ma40=np.mean(h[ContextInfo.tradestock][-ContextInfo.long-1:-1])
if ma20>ma40 and ma5>ma20:
order_target_value(ContextInfo.tradestock,ContextInfo.weight*totalvalue,ContextInfo,ContextInfo.accountid)
ContextInfo.price=h[ContextInfo.tradestock][-1]
#=============网格交易====================
if holdings:
#print(111)
ContextInfo.holdings_list.append(holdings[ContextInfo.tradestock])
#底仓为仓位记录的首位
basic_holdings= ContextInfo.holdings_list[0]
#网格线的具体价格
Limit_price = np.array(ContextInfo.band)*ContextInfo.price
Con_close= ContextInfo.get_history_data(2,'3m','close')[ContextInfo.tradestock]
#获取当前价格对应的区间
lable=pd.cut(Con_close[-1],Limit_price,labels=False)
#固定的交易量
trade_volume = int(0.1*basic_holdings/100)*100
#对应区间的目标仓位,买入和卖出在同一价格区间的目标仓位不一致,需分别列出
Buy_aim_Position= basic_holdings + pd.Series(ContextInfo.Buy_Lable*trade_volume)
Sell_aim_Position= basic_holdings + pd.Series(ContextInfo.Sell_Lable*trade_volume)
#print(Limit_price)
d = ContextInfo.barpos #当前K线索引号
p = ContextInfo.get_net_value(d)
#价格上涨部分卖出
if Con_close[1]>Con_close[0]:
Sell_volume = holdings[ContextInfo.tradestock]-Sell_aim_Position[lable]
#print(Sell_volume)
#过滤掉无效的价格波动
if Sell_volume >0:
ContextInfo.draw_text(1>0,p+0.01*p,"S")
order_shares(ContextInfo.tradestock,-Sell_volume*100,'fix',Limit_price[lable],ContextInfo,ContextInfo.accountid)
ContextInfo.number_down+=1
print('down',ContextInfo.number_down)
#价格下跌部分买入
if Con_close[1]<Con_close[0]:
Buy_volume = Buy_aim_Position[lable]-holdings[ContextInfo.tradestock]
#过滤掉无效的价格波动
if Buy_volume>0:
ContextInfo.draw_text(1>0,p+0.01*p,"B")
order_shares(ContextInfo.tradestock,Buy_volume *100,'fix',Limit_price[lable+1],ContextInfo,ContextInfo.accountid)
ContextInfo.number_plus+=1
print('plus',ContextInfo.number_plus)
#获取持仓信息{code.market:手数}
def get_holdings(accountid,datatype):
holdinglist={}
resultlist=get_trade_detail_data(accountid,datatype,"POSITION")
for obj in resultlist:
holdinglist[obj.m_strInstrumentID+"."+obj.m_strExchangeID]=obj.m_nVolume/100
#返回{code.market:持仓手数}
return holdinglist
#获取账户总权益m_dBalance
def get_totalvalue(accountid,datatype):
result=0
resultlist=get_trade_detail_data(accountid,datatype,"ACCOUNT")
for obj in resultlist:
result=obj.m_dBalance
return result
```
ma5
df['ma5']=talib.SMA(df['close'],timeperiod=5)
10、zig形态识别
```py
ContextInfo.df_zig=ContextInfo.df_zig.drop(index=ContextInfo.df_zig.index)
xa=1+0.05
xd=1-0.05
size=len(df)
k=df['close']
hh=df['high']
ll=df['low']
peer_i=0
candidate_i=None
scan_i=0
z=np.zeros(len(k))
state=ContextInfo.ZIG_STATE_START
while True:
scan_i +=1
if scan_i==len(k)-1:
if candidate_i is None:
addPeer(state,peer_i,df,df_zig)
peer_i=candidate_i
else:
if state == ContextInfo.ZIG_STATE_RISE:
if hh[scan_i]>=hh[candidate_i]:
peer_i=scan_i
addPeer(state,peer_i,df,ContextInfo)
else:
peer_i=candidate_i
addPeer(state,peer_i,df,ContextInfo)
peer_i=scan_i
addPeer(2,peer_i,df,ContextInfo)
elif state ==ContextInfo.ZIG_STATE_FALL:
if ll[scan_i]<=ll[candidate_i]:
peer_i=scan_i
addPeer(state,peer_i,df,ContextInfo)
else:
peer_i=candidate_i
addPeer(state,peer_i,df,ContextInfo)
peer_i=scan_i
addPeer(1,peer_i,df,ContextInfo)
break
if state==ContextInfo.ZIG_STATE_START:
if hh[scan_i]>=hh[peer_i]*xa:
candidate_i=scan_i
state=ContextInfo.ZIG_STATE_RISE
elif ll[scan_i]<=ll[peer_i]*xd:
candidate_i=scan_i
state=ContextInfo.ZIG_STATE_FALL
elif state==ContextInfo.ZIG_STATE_RISE:
if hh[scan_i]>=hh[candidate_i]:
candidate_i=scan_i
elif ll[scan_i]<=ll[candidate_i]*xd:
peer_i=candidate_i
addPeer(state,peer_i,df,ContextInfo)
state=ContextInfo.ZIG_STATE_FALL
candidate_i=scan_i
elif state==ContextInfo.ZIG_STATE_FALL:
if ll[scan_i]<=ll[candidate_i]:
candidate_i=scan_i
elif hh[scan_i]>hh[candidate_i]*xa:
peer_i=candidate_i
addPeer(state,peer_i,df,ContextInfo)
state=ContextInfo.ZIG_STATE_RISE
candidate_i=scan_i
print(ContextInfo.df_zig)
```