zoukankan      html  css  js  c++  java
  • 波动率与价格价格配合策略

    本策略为波动率与价格想结合的策略,策略想法较为复杂,交易次数较少。

    代码如下:

    import pandas as pd
    import pyodbc
    from sqlalchemy import create_engine
    import numpy as np
    from statistics import median
    import crash_on_ipy
    import pdb
    import matplotlib.pyplot as plt
    # import matplotlib_finance as mpf
    # from matplotlib.finance import candlestick
    from numpy import nan
    #SERVER服务器地址,DATABASE数据库名,UID用户名,PWD登录密码
    con = pyodbc.connect('DRIVER={SQL Server};SERVER=192.168.60.5;DATABASE=data_history;UID=gx;PWD=01')
    # querystring="select * from [data_history].[dbo].[ag1612]"
    querystring="select top (20000000) [time],[price] from [data_history].[dbo].[ag1612]"
    engine = create_engine('mssql+pyodbc://scott:tiger@mydsn')
    data=pd.read_sql(querystring, con, index_col='time')
    # data=pd.read_csv('data.csv',index_col='ID')
    print(data.head())
    print(data.tail())


    # data=data.iloc[:,0:3]
    # data['date_time']=data['date']+data['time']
    # del data['date'],data['time']
    data=data.sort_index()
    # data=data.set_index('date_time')
    data.rename(index=lambda x:str(x)[:16],inplace=True)
    # #得到每小时K线数据的开盘价、最高价、最低价、收盘价

    new_data=data.groupby(data.index).last()
    new_data['open_price']=data.groupby(data.index).first()
    new_data['high_price']=data.groupby(data.index).max()
    new_data['low_price']=data.groupby(data.index).min()
    new_data.columns=['close_price','open_price', 'high_price', 'low_price']
    print('new_date.head():{}'.format(new_data.head()))
    new_data.drop(new_data.index[152:181],inplace=True)
    # new_data.to_csv('new_data1.csv')


    # 得到周期为10的标准差
    # 得到所有数据的行数
    # 策略判断标准前面需要至少(3*24+10)h,即82h,当天需要6根k线,即6h,总共88h,取前88h,i从87开始。
    T=len(new_data.index)
    print('T:{}'.format(T))
    std=[]
    std_mean=[]
    #记录开平仓位置
    position_locat=[0]*T
    profit=[]
    #定义前三日第二大方差差值、区间最大值、区间最小值、开仓价
    second_diff=0
    x=0;y=0;z=0;z1=0;z2=0;m=0;m1=0;m2=0
    interval_data_max=0
    interval_data_min=0
    open_price=0


    #std数据为T-10个
    for i in range(10,T):
    data_close=new_data['close_price'].iloc[i-10:i].values
    std.append(data_close.std())
    # print(std)
    #得到std的均值,为T-10-24个,即T-34个
    for i in range(24,len(std)):
    std_mean.append(np.mean(std[i-24:i]))
    # print(std_mean)
    print(len(new_data),len(std),len(std_mean))
    #new_data比std数据多10个,std数据比mean多24个,把所有数据量统一,去掉前面多于的数据
    new_data=new_data.iloc[34:,:]
    std=std[24:]
    print(len(new_data),len(std),len(std_mean))

    T=len(new_data)
    mark_enter=[0]*(T)
    mark_leave=[0]*(T)

    def vol(i):
    vol_open_condition = False
    second_diff = median([np.max(std[i - 77:i - 53]) - np.mean(std[i - 77:i - 53]),
    np.max(std[i - 53:i - 29]) - np.mean(std[i - 53:i - 29]),
    np.max(std[i - 29:i - 5]) - np.mean(std[i - 77:i - 53])])
    interval_data=0;std_high=0;std_low=0;interval_data_max=0;interval_data_min=0;interval_begin_time=0;interval_close_time=0
    if std[i - 4] > 0.8 * second_diff and std[i - 4] >= std[i - 5] and std[i - 4] > std[i - 3] > std[i - 2] > std[
    i - 1]:
    # 记录区间的开始位置,(i-4)为高点,(i-5)是高点前一根K线
    x = i - 5
    b = True
    while b:
    if std[i - 1] >= std[i]:
    i += 1
    else:
    b = False
    break
    # 记录区间的结束位置,i-1为低点位置
    y = i - 1
    interval_data = new_data.iloc[x:y+1, :]
    std_high = std[x - 4]
    std_low = std[y]
    second_diff_satisfy_std = second_diff
    interval_data_max = interval_data['high_price'].max()
    interval_data_min = interval_data['low_price'].min()
    interval_begin_time=interval_data.index[0]
    interval_close_time=interval_data.index[-1]
    # interval_std_high=std[i-4]
    print(x, y, std_high,std_low,interval_data_max, interval_data_min,interval_begin_time,interval_close_time)
    vol_open_condition = True
    return second_diff,interval_data,std_high,std_low,interval_data_max,interval_data_min,vol_open_condition
    return second_diff,interval_data,std_high,std_low,interval_data_max,interval_data_min,vol_open_condition
    # interval_data,std_high,std_low,interval_data_max,interval_data_min=vol(22)

    #得到所有最高点和最低点,即对应价格区间(x:y)
    open_long=False
    open_long_number=False
    open_short_number=False
    open_condition=False
    second_diff_satisfy_std=0
    interval_data_satisfy_std=0
    std_high_satisfy_std=0
    std_low_satisfy_std=0
    interval_data_max_satisfy_std=0
    interval_data_min_satisfy_std=0
    # pdb.set_trace()
    #79开始
    for i in range(91, T - 10):
    if not open_condition and vol(i)[6]:
    # vol_condition = vol(i)
    # vol_condition[6]
    open_condition = True
    second_diff_satisfy_std=vol(i)[0]
    interval_data_satisfy_std=vol(i)[1]
    std_high_satisfy_std=vol(i)[2]
    std_low_satisfy_std=vol(i)[3]
    interval_data_max_satisfy_std=vol(i)[4]
    interval_data_min_satisfy_std=vol(i)[5]

    #向上突破后回调情况
    if open_condition and not open_long_number and not open_short_number and
    interval_data_min_satisfy_std<new_data.iloc[i,0]<interval_data_max_satisfy_std and new_data.iloc[i-1,3]>interval_data_max_satisfy_std:
    open_price=new_data.iloc[i,0]
    # 开多,记录开仓价格,i+2期收盘价
    print('买入开仓,开仓价为:{},开仓位为:{}'.format(open_price,i))
    mark_enter[i]=1
    open_condition=False
    open_long_number=True

    # 得到向下突破后回调情况
    if open_condition and not open_long_number and not open_short_number and
    interval_data_min_satisfy_std<new_data.iloc[i, 0]<interval_data_max_satisfy_std and new_data.iloc[i-1,2]<interval_data_min_satisfy_std:
    #开空,记录开仓价格,i+2期收盘价
    open_price=new_data.iloc[i,0]
    print('卖出开仓,开仓价为:{},开仓位为:{}'.format(open_price,i))
    print('i:{}'.format(i))
    # position_locat[i+3]=2
    open_condition=False
    open_short_number =True
    mark_enter[i] = 1

    #得到波动率大于前高的位置z3
    if open_condition and std[i-1] > std_high_satisfy_std:
    open_condition=False
    std_high_satisfy_std=std[i-1]
    print('波动率大于前高位置,重置区间,重置点为:{}'.format(i))


    #出场
    #出场分四种情况,分别是多头(正常出场和止损出场)和空头(正常出场和止损出场)
    #多头正常出场
    if open_long_number and std[i-3]>0.3*second_diff_satisfy_std and std[i-1]>std[i-2] and std[i-1]>std[i]:
    # 平多,记录平仓位置
    # m1=i+4
    profit_yield = (new_data.iloc[i, 0] - open_price) / open_price
    print('正常卖出平仓,平仓价为:{},平仓位为:{}'.format(new_data.iloc[i, 0],i))
    profit.append(profit_yield)
    open_long_number=False
    mark_leave[i] = 1

    #多头止损出场
    if open_long_number and (new_data.iloc[i,3]>interval_data_max_satisfy_std or new_data.iloc[i,2]<interval_data_min_satisfy_std):
    #平多,记录平仓位置
    # m2=i
    profit_yield = (new_data.iloc[i, 0] - open_price) / open_price
    print('止损卖出平仓,平仓价为:{},平仓位为:{}'.format(new_data.iloc[i, 0],i))
    profit.append(profit_yield)
    open_long_number=False
    mark_leave[i] = 1

    #空头正常出场
    if open_short_number and std[i]>0.3*second_diff_satisfy_std and std[i-1]>std[i-2] and std[i-1]>std[i]:
    #平空,记录平仓位置
    # m1=i+4
    profit_yield = (open_price - new_data.iloc[i, 0]) / open_price
    print('正常买入平仓,平仓价为:{},平仓位为:{}'.format(new_data.iloc[i, 0],i))
    profit.append(profit_yield)
    open_short_number=False
    mark_leave[i] = 1

    #空头止损出场
    if open_short_number and (new_data.iloc[i,3]>interval_data_max_satisfy_std or new_data.iloc[i,2]<interval_data_min_satisfy_std):
    #平空,记录平仓位置
    # m2=i
    profit_yield = (open_price - new_data.iloc[i, 0]) / open_price
    print('止损买入平仓,平仓价为:{},平仓位为:{}'.format(new_data.iloc[i, 0],i))
    profit.append(profit_yield)
    open_short_number=False
    mark_leave[i] = 1

    #计算sharpe
    #计算总回报
    total_return=np.expm1(np.log1p(profit).sum())
    #计算年化回报
    annual_return=(1+total_return)**(365/30)-1
    risk_free_rate=0.015
    profit_std=np.array(profit).std()
    volatility=profit_std*(len(profit)**0.5)
    annual_factor=12
    annual_volatility=volatility*((annual_factor)**0.5)
    sharpe=(annual_return-risk_free_rate)/annual_volatility
    # print(total_return,annual_return,std,volatility,annual_volatility,sharpe)
    print('夏普比率:{}'.format(sharpe))

    #计算最大回撤
    #计算
    df_cum=np.exp(np.log1p(profit).cumsum())
    max_return=np.maximum.accumulate(df_cum)
    max_drawdown=((max_return-df_cum)/max_return).max()
    print('-----------------')
    print('最大回撤: {}'.format(max_drawdown))

    #计算盈亏比plr
    from collections import Counter
    # win_times=Counter(x>0 for x in minute_return)
    # loss_times=Counter(x<0 for x in minute_return)
    win_times=sum(x>0 for x in profit)
    loss_times=sum(x<0 for x in profit)
    plr=win_times/loss_times
    print('----------------------------')
    print('盈利次数:{}'.format(win_times))
    print('亏损次数:{}'.format(loss_times))
    print('盈亏比:{}'.format(plr))

    # #画出净值走势图
    fig=plt.figure()
    ax1=fig.add_subplot(3,1,1)
    ag_close_price,=plt.plot(new_data['close_price'].values,label='close_price')
    ag_open_price,=plt.plot(new_data['open_price'].values,label='open_price')
    ag_high_price,=plt.plot(new_data['high_price'].values,label='high_price')
    ag_low_price,=plt.plot(new_data['low_price'].values,label='low_price')
    plt.legend([ag_close_price,ag_open_price,ag_high_price,ag_low_price],['close_price','open_price','high_price','low_price'])
    ag_close_price_mark_enter=new_data.iloc[:,0].values.tolist()
    ag_close_price_mark_leave=new_data.iloc[:,0].values.tolist()
    # print(type(spread),type(spread_mark))
    for i in range(0,T):
    if mark_enter[i]==0:
    ag_close_price_mark_enter[i]=nan
    plt.plot(ag_close_price_mark_enter,'*')
    for i in range(0,T):
    if mark_leave[i]==0:
    ag_close_price_mark_leave[i]=nan
    plt.plot(ag_close_price_mark_leave,'+')

    ax2=fig.add_subplot(3,1,2)
    ag_std,=plt.plot(std,label='std')
    ag_std_mean,=plt.plot(std_mean,label='std_mean')
    plt.legend([ag_std,ag_std_mean],['std','std_mean'])
    ax3=fig.add_subplot(3,1,3)
    cum_net_worth,=plt.plot(df_cum,label='cum_net_worth')
    plt.legend([cum_net_worth],['cum_net_worth'])


    plt.show()
    pdb.set_trace()

    下面为运行结果图:











































  • 相关阅读:
    团队开发冲刺第二阶段(三)
    团队开发冲刺第二阶段(二)
    团队开发冲刺第二阶段(一)
    第十四周总结
    第十三周总结
    第十二周总结
    第十一周总结
    《人月神话》阅读笔记(三)
    《人月神话》阅读笔记(二)
    《人月神话》阅读笔记(一)
  • 原文地址:https://www.cnblogs.com/bawu/p/6789430.html
Copyright © 2011-2022 走看看