list_call_mdt, list_put_mdt = optionset.get_options_list_by_moneyness_mthd1(moneyness_rank=moneyness, maturity=maturity) put = optionset.select_higher_volume(list_put_mdt) if put is None: put = optionset.select_higher_volume(optionset.get_deepest_otm_put_list(maturity)) return put def close_option_position(account): for option in account.dict_holding.values(): if not isinstance(option, BaseOption): continue order = account.create_close_order(option, cd_trade_price=cd_price) record = option.execute_order(order, slippage=slippage) account.add_record(record, option) return True pu = PlotUtil() start_date = datetime.date(2015, 2, 9) end_date = datetime.date(2019,1,7) dt_histvol = start_date - datetime.timedelta(days=90) min_holding = 1 cd_price = c.CdTradePrice.CLOSE slippage = 0 m = 0.9 moneyness_put = -2 nbr_maturity=1 """ Data """ # df_metrics=pd.read_excel('../../../data/df_metrics.xlsx') # df_index= pd.read_excel('../../../data/df_index.xlsx') # # df_metrics = df_metrics[df_metrics[c.Util.DT_DATE]>=start_date].reset_index(drop=True) # df_index = df_index[df_index[c.Util.DT_DATE]>=start_date].reset_index(drop=True)
core_mktdata = pd.merge(coreids_df, futuredata_df, on=['id_instrument', 'dt_date'], how='left') rb_data = core_mktdata[core_mktdata['name_code'] == 'rb'] i_data = core_mktdata[core_mktdata['name_code'] == 'i'] j_data = core_mktdata[core_mktdata['name_code'] == 'j'] a = pd.merge(rb_data, i_data, on='dt_date') earningsdata = pd.merge(a, j_data, on='dt_date') earningsdata[ 'amt_earning'] = earningsdata['amt_close_x'] - 1.65 * earningsdata[ 'amt_close_y'] - 0.5 * earningsdata['amt_close'] print(earningsdata) pu = PlotUtil() f, ax = plt.subplots() count = 0 pu.plot_line(ax, 0, earningsdata['dt_date'], earningsdata['amt_earning'], lgd='钢厂利润指数') pu.plot_line(ax, 1, earningsdata['dt_date'], earningsdata['amt_close_x'], lgd='螺纹钢') pu.plot_line(ax,
deltalist_2 = [] gammalist1 = [] gammalist2 = [] for spot in spotlist: delta = pricing_utl.get_blackcalculator(dt_date, spot, Option, rf, vol).Delta() # gamma = pricing_utl.get_blackcalculator(dt_date, spot, Option, rf, vol).Gamma() # gammalist1.append(gamma) deltalist_1.append(delta) delta2 = pricing_utl.get_blackcalculator(dt_date, spot, Option, 0.1, vol).Delta() # gamma2 = pricing_utl.get_blackcalculator(dt_date, spot, Option2, rf, vol).Gamma() deltalist_2.append(delta2) # gammalist2.append(gamma2) plot_utl = PlotUtil() plot_utl.plot_line_chart(spotlist, [deltalist_2, deltalist_1], ['Delta (rf=0.03)', 'Delta (rf=0.1)']) # plot_utl.plot_line_chart(spotlist, [gammalist2,gammalist1], ['Gamma(T=1M)','Gamma(T=3M)']) plt.show() df = pd.DataFrame() df['spot'] = spotlist df['delta'] = deltalist_1 df.to_excel('../delta.xlsx') # for spot in spotlist: # black1 = pricing_utl.get_blackcalculator(dt_date, spot, Option, rf, vol) # delta1 = black1.Delta() # gamma1 = black1.Gamma() # black2 = pricing_utl.get_blackcalculator(dt_date, spot, Option, rf, vol2) # delta2 = black2.Delta() # gamma2 = black2.Gamma()
from back_test.model.base_option_set import BaseOptionSet from back_test.model.base_account import BaseAccount from data_access import get_data import back_test.model.constant as c import datetime import numpy as np from OptionStrategyLib.OptionReplication.synthetic_option import SytheticOption from Utilities.PlotUtil import PlotUtil import matplotlib.pyplot as plt import pandas as pd from Utilities.timebase import LLKSR, KALMAN, LLT pu = PlotUtil() start_date = datetime.date(2015, 1, 1) end_date = datetime.date(2018, 8, 8) dt_histvol = start_date - datetime.timedelta(days=90) min_holding = 15 init_fund = c.Util.BILLION slippage = 0 m = 1 # 期权notional倍数 """ commodity option """ name_code = name_code_option = c.Util.STR_M df_metrics = get_data.get_comoption_mktdata(start_date, end_date, name_code) df_future_c1_daily = get_data.get_future_c1_by_option_daily( dt_histvol, end_date, name_code, min_holding) """ 50ETF option """ # name_code = c.Util.STR_IH # name_code_option = c.Util.STR_50ETF # df_metrics = get_data.get_50option_mktdata(start_date, end_date) # df_future_c1_daily = get_data.get_mktdata_cf_c1_daily(dt_histvol, end_date, name_code) """ 隐含波动率 """
def implied_vol_analysis(evalDate, w, nameCode, exchangeCode): pu = PlotUtil() engine1 = create_engine( 'mysql+pymysql://readonly:[email protected]/mktdata', echo=False) Session1 = sessionmaker(bind=engine1) sess1 = Session1() engine2 = create_engine( 'mysql+pymysql://readonly:[email protected]/metrics', echo=False) Session2 = sessionmaker(bind=engine2) sess2 = Session2() optionMetrics = dbt.OptionMetrics dt_1w = w.tdaysoffset(-1, evalDate, "Period=W").Data[0][0].strftime("%Y-%m-%d") dt_2w = w.tdaysoffset(-2, evalDate, "Period=W").Data[0][0].strftime("%Y-%m-%d") dt_3w = w.tdaysoffset(-3, evalDate, "Period=W").Data[0][0].strftime("%Y-%m-%d") dt_4w = w.tdaysoffset(-4, evalDate, "Period=W").Data[0][0].strftime("%Y-%m-%d") dt_5w = w.tdaysoffset(-5, evalDate, "Period=W").Data[0][0].strftime("%Y-%m-%d") plt.rcParams['font.sans-serif'] = ['STKaiti'] plt.rcParams.update({'font.size': 15}) """波动率期限结构""" dates = [evalDate, dt_1w, dt_2w, dt_3w, dt_4w, dt_5w] query_f = sess1.query(futureMkt.dt_date, futureMkt.id_instrument.label('id_underlying'), futureMkt.amt_settlement,futureMkt.flag_night,futureMkt.name_code) \ .filter(or_(futureMkt.dt_date==evalDate,futureMkt.dt_date==dt_1w,futureMkt.dt_date==dt_2w, futureMkt.dt_date==dt_3w,futureMkt.dt_date==dt_4w,futureMkt.dt_date==dt_5w))\ .filter(futureMkt.name_code == nameCode)\ .filter(futureMkt.flag_night != 1) query_metrics = sess2.query(optionMetrics.dt_date,optionMetrics.id_instrument,optionMetrics.cd_option_type, optionMetrics.pct_implied_vol,optionMetrics.amt_option_price) \ .filter(or_(optionMetrics.dt_date == evalDate, optionMetrics.dt_date == dt_1w, optionMetrics.dt_date == dt_2w, optionMetrics.dt_date == dt_3w, optionMetrics.dt_date == dt_4w, optionMetrics.dt_date == dt_5w)) \ .filter(optionMetrics.name_code == nameCode) df_future = pd.read_sql(query_f.statement, query_f.session.bind) df_metrics = pd.read_sql(query_metrics.statement, query_metrics.session.bind) for (idx, row) in df_metrics.iterrows(): id_option = row['id_instrument'] if id_option[0] == nameCode or id_option[0:2] == nameCode: dt_date = row['dt_date'] option_price = row['amt_option_price'] strike = float(id_option[-4:]) if nameCode == 'm': id_underlying = id_option[:6] elif nameCode == 'sr': id_underlying = id_option[:7] else: id_underlying = None contract_month = id_underlying[-4:] if int(contract_month[-2:]) in [1, 5, 9]: df_metrics.loc[idx, 'flag'] = 1 underlying_price = df_future[ (df_future['dt_date'] == dt_date) & (df_future['id_underlying'] == id_underlying )]['amt_settlement'].values[0] df_metrics.loc[idx, 'dt_date'] = dt_date.strftime("%Y-%m-%d") df_metrics.loc[idx, 'id_underlying'] = id_underlying df_metrics.loc[idx, 'underlying_price'] = underlying_price df_metrics.loc[idx, 'contract_month'] = id_underlying[-4:] df_metrics.loc[idx, 'diff'] = abs(strike - underlying_price) else: df_metrics.loc[idx, 'flag'] = 0 else: df_metrics.loc[idx, 'flag'] = 0 df_metrics = df_metrics[df_metrics['flag'] == 1].reset_index() idx = df_metrics.groupby(['dt_date', 'id_underlying', 'cd_option_type' ])['diff'].transform(min) == df_metrics['diff'] df_iv = df_metrics[idx] df_call_iv = df_iv[df_iv['cd_option_type'] == 'call'].sort_values( by=['dt_date', 'id_underlying'], ascending=False).reset_index() # 选取认购平值合约 df_put_iv = df_iv[df_iv['cd_option_type'] == 'put'].sort_values( by=['dt_date', 'id_underlying'], ascending=False).reset_index() # 选取认沽平值合约 df_call_iv = df_call_iv.drop_duplicates(['dt_date', 'id_underlying']) df_put_iv = df_put_iv.drop_duplicates(['dt_date', 'id_underlying']) optiondata_atm_df = df_put_iv[['dt_date', 'contract_month']] optiondata_atm_df.loc[:, 'implied_vol'] = 100 * ( df_call_iv.loc[:, 'pct_implied_vol'] + df_put_iv.loc[:, 'pct_implied_vol']) / 2.0 f1, ax1 = plt.subplots() cont = 0 contracts = [] for d in dates: df = optiondata_atm_df[optiondata_atm_df['dt_date'] == d] df = df.sort_values(by=['contract_month'], ascending=True) pu.plot_line(ax1, cont, range(len(df)), df['implied_vol'], d, '合约月份', '波动率(%)') if len(contracts) == 0: contracts = df['contract_month'].tolist() cont += 1 ax1.legend(bbox_to_anchor=(0., 1.02, 1., .202), loc=3, ncol=6, mode="expand", borderaxespad=0., frameon=False) ax1.set_xticks(range(len(contracts))) ax1.set_xticklabels(contracts) f1.set_size_inches((12, 6)) optiondata_atm_df.to_csv('../data/' + nameCode + '_implied_vol_term_structure.csv') f1.savefig('../data/' + nameCode + '_iv_term_structure_' + str(evalDate) + '.png', dpi=300, format='png')
from sqlalchemy.orm import sessionmaker from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from matplotlib import cm as plt_cm import datetime import pandas as pd import numpy as np from WindPy import w from data_access.db_tables import DataBaseTables as dbt import matplotlib.pyplot as plt from Utilities.PlotUtil import PlotUtil import QuantLib as ql ########################################################################################### w.start() pu = PlotUtil() plt.rcParams['font.sans-serif'] = ['STKaiti'] plt.rcParams.update({'font.size': 11}) engine = create_engine( 'mysql+pymysql://guest:[email protected]/mktdata', echo=False) conn = engine.connect() metadata = MetaData(engine) Session = sessionmaker(bind=engine) sess = Session() index_mkt = Table('indexes_mktdata', metadata, autoload=True) indexmkt_table = dbt.IndexMkt index_ids = ['index_300sh', 'index_50sh', 'index_500sh'] ############################################################################################ # Eval Settings eval_date = datetime.date(2017, 12, 28) evalDate = eval_date.strftime("%Y-%m-%d")
data['BETA_F'] = hv.arithmetic_yield(data['IF.CFE']) data['BETA_S'] = hv.arithmetic_yield(data['000300.SH']) data['SMB_F'] = hv.arithmetic_yield(data['IC.CFE']) - hv.arithmetic_yield(data['IH.CFE']) data['SMB_S'] = hv.arithmetic_yield(data['000905.SH']) - hv.arithmetic_yield(data['000016.SH']) # data['RB_F'] = hv.arithmetic_yield(data['RB.SHF']) # data['RB_S'] = hv.arithmetic_yield(data['RB']) data['HC_F'] = hv.arithmetic_yield(data['HC.SHF']) # data['HC_S'] = hv.arithmetic_yield(data['HC']) # data['I_F'] = hv.arithmetic_yield(data['I.DCE']) # data['J_F'] = hv.arithmetic_yield(data['J.DCE']) # data['LC_S'] = hv.arithmetic_yield(data['LC']) # data['GC_S'] = hv.arithmetic_yield(data['GC']) # data['RB_PROFIT_F'] = hv.arithmetic_yield(data['steel_profit']) # 期货 data = data.set_index('date') pu = PlotUtil() data_reg = data.copy() data_reg['y'] = hv.arithmetic_yield(data_reg['index_top5']) data_reg = data_reg[['y', 'BETA_S', 'SMB_S', 'HC_F']].dropna() x_s = data_reg[['BETA_S', 'SMB_S', 'HC_F']] y = data_reg['y'] reg = Statistics.linear_regression(x_s, y) print(reg.params) print(reg.pvalues) print(reg.rsquared) print(reg.rsquared_adj) rsd = reg.resid cum_rsd= (1+rsd).cumprod() pu.plot_line_chart(list(data_reg.index),[cum_rsd])
current_core_underlying = 'm_1809' namecode = 'm' exchange_code = 'dce' ############################################################################################ w.start() endDate = dt_date evalDate = dt_date.strftime("%Y-%m-%d") # Set as Friday # startDate = datetime.date(2017, 1, 1) # hist_date = w.tdaysoffset(-7, startDate, "Period=M").Data[0][0].date() bd_1m = 21 bd_2m = 2 * bd_1m bd_3m = 3 * bd_1m bd_6m = 6 * bd_1m calendar = ql.China() pu = PlotUtil() ########################################################################################### # engine2 = create_engine('mysql+pymysql://guest:[email protected]/mktdata', echo=False) # metadata2 = MetaData(engine2) # Session2 = sessionmaker(bind=engine2) # sess2 = Session2() futureMkt = dbt.FutureMkt optionMkt = dbt.OptionMkt futuremkt_table = dbt.FutureMkt options_table = dbt.Options query_pcr = admin.session_mktdata().query(optionMkt.dt_date, optionMkt.cd_option_type,optionMkt.id_underlying, func.sum(optionMkt.amt_holding_volume).label('total_holding_volume'), func.sum(optionMkt.amt_trading_volume).label('total_trading_volume') ) \
data['SMB_F'] = hv.arithmetic_yield(data['IC.CFE']) - hv.arithmetic_yield( data['IH.CFE']) data['SMB_S'] = hv.arithmetic_yield(data['000905.SH']) - hv.arithmetic_yield( data['000016.SH']) data['RB_F'] = hv.arithmetic_yield(data['RB.SHF']) data['RB_S'] = hv.arithmetic_yield(data['RB']) data['HC_F'] = hv.arithmetic_yield(data['HC.SHF']) data['HC_S'] = hv.arithmetic_yield(data['HC']) data['I_F'] = hv.arithmetic_yield(data['I.DCE']) data['J_F'] = hv.arithmetic_yield(data['J.DCE']) data['LC_S'] = hv.arithmetic_yield(data['LC']) data['GC_S'] = hv.arithmetic_yield(data['GC']) data['RB_PROFIT_F'] = hv.arithmetic_yield(data['steel_profit']) # 期货 data = data.set_index('date') pu = PlotUtil() data_reg = data.copy() data_reg['y'] = hv.arithmetic_yield(data_reg['steel_index_bysales']) # data_reg['y'] = hv.arithmetic_yield(data_reg['801041.SI']) data_reg = data_reg[['y', 'BETA_S', 'SMB_S', 'HC_S']].dropna() x_s = data_reg[['BETA_S', 'SMB_S', 'HC_S']] y = data_reg['y'] reg = Regression.linear_regression(x_s, y) print(reg.params) print(reg.pvalues) print(reg.rsquared) print(reg.rsquared_adj) rsd = reg.resid cum_rsd = (1 + rsd).cumprod()
from unittest import TestCase from PricingLibrary.BinomialModel import BinomialTree from PricingLibrary.BlackCalculator import BlackCalculator from back_test.model.constant import OptionType, OptionExerciseType, QuantlibUtil import datetime import QuantLib as ql import numpy as np from Utilities.PlotUtil import PlotUtil import matplotlib.pyplot as plt pu = PlotUtil() dt_eval = datetime.date(2017, 1, 1) dt_maturity = datetime.date(2017, 4, 1) spot_price = 120 strike_price = 120 volatility = 0.3 # the historical vols or implied vols dividend_rate = 0 risk_free_rate = 0.03 # steps = 800 maturity_date = QuantlibUtil.to_ql_date(dt_maturity) option_type = ql.Option.Put day_count = ql.ActualActual() calendar = ql.NullCalendar() calculation_date = QuantlibUtil.to_ql_date(dt_eval) # print(day_count.yearFraction(calculation_date, maturity_date)) ql.Settings.instance().evaluationDate = calculation_date payoff = ql.PlainVanillaPayoff(option_type, strike_price) settlement = calculation_date
# account.account.to_csv('../sythetic_account.csv') # account.trade_records.to_csv('../sythetic_records.csv') # print(account.analysis()) # print('-'*50) # print(account.account.iloc[-3,:]) # print('-'*50) # print(account.account.iloc[-2,:]) # print('-'*50) # print(account.account.iloc[-1,:]) # print('-'*50) df_res_d.to_csv('../data/df_res_close.csv') df_mdd_d.to_csv('../data/df_mdd_close.csv') df_yield_d.to_csv('../data/df_yield_close.csv') pu = PlotUtil() dates = list(account.account.index) npvs.append(list(account.account['benchmark'])) methods.append('benchmark') deltas = list(account.account['position_delta']) pu.plot_line_chart(dates, npvs, methods) # pu.plot_line_chart(dates, [deltas], ['仓位占比']) plt.show() ######### Delta Bounds ################### # npvs = [] # df_yield_d = pd.DataFrame() # df_mdd_d = pd.DataFrame() # df_res_d = pd.DataFrame() # for u in [0.9,0.95,0.99,1]:
""" 历史波动率 """ def hist_vol(dt_start, df_future_c1_daily): m = 100 df_future_c1_daily.loc[:, 'histvol_10'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=10) * m df_future_c1_daily.loc[:, 'histvol_20'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=20) * m df_future_c1_daily.loc[:, 'histvol_30'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=30) * m df_future_c1_daily.loc[:, 'histvol_60'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=60) * m df_future_c1_daily.loc[:, 'histvol_90'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=90) * m df_future_c1_daily.loc[:, 'histvol_120'] = Histvol.hist_vol(df_future_c1_daily[c.Util.AMT_CLOSE], n=120) * m return df_future_c1_daily pu = PlotUtil() end_date = datetime.date(2018,12,31) start_date = datetime.date(2010, 1, 1) writer = ExcelWriter('../data/histvol_data_python.xlsx') name_codes = [c.Util.STR_CF, c.Util.STR_C, c.Util.STR_RU, c.Util.STR_M,c.Util.STR_CU] for (idx, name_code) in enumerate(name_codes): print(name_code) # df_res = pd.DataFrame() df_future_c1_daily = get_data.get_gc_future_c1_daily(start_date, end_date, name_code) pu.plot_line_chart(list(df_future_c1_daily[c.Util.DT_DATE]),[list(df_future_c1_daily[c.Util.AMT_CLOSE])],['close_'+name_code]) df_future_c1_daily = hist_vol(start_date, df_future_c1_daily) df_future_c1_daily = df_future_c1_daily.sort_values(by=c.Util.DT_DATE, ascending=False) df_future_c1_daily.to_excel(writer, 'hv_'+name_code) # pu.plot_line_chart(list(df_future_c1_daily[c.Util.DT_DATE]),[list(df_future_c1_daily['histvol_30'])],['histvol_'+name_code]) # plt.show()
from sqlalchemy.orm import sessionmaker from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from matplotlib import cm as plt_cm import datetime import pandas as pd import numpy as np from WindPy import w from data_access.db_tables import DataBaseTables as dbt import matplotlib.pyplot as plt from Utilities.PlotUtil import PlotUtil import QuantLib as ql ########################################################################################### w.start() pu = PlotUtil() plt.rcParams['font.sans-serif'] = ['STKaiti'] plt.rcParams.update({'font.size': 13}) engine1 = create_engine('mysql+pymysql://guest:[email protected]/mktdata_intraday', echo=False) engine2 = create_engine('mysql+pymysql://guest:[email protected]/mktdata', echo=False) metadata1 = MetaData(engine1) Session1 = sessionmaker(bind=engine1) sess1 = Session1() metadata2 = MetaData(engine2) Session2 = sessionmaker(bind=engine2) sess2 = Session2() index_intraday = Table('equity_index_mktdata_intraday', metadata1, autoload=True) EquityIndexIntraday = dbt.EquityIndexIntraday IndexMkt = dbt.IndexMkt ############################################################################################ # Eval Settings
from data_access import get_data import back_test.model.constant as c import datetime from Utilities.PlotUtil import PlotUtil import matplotlib.pyplot as plt from OptionStrategyLib.VolatilityModel.historical_volatility import HistoricalVolatilityModels as Histvol from Utilities import timebase import numpy as np pu = PlotUtil() start_date = datetime.date(2015, 1, 1) end_date = datetime.date(2018, 8, 8) dt_histvol = start_date - datetime.timedelta(days=40) min_holding = 18 """ commodity option """ # name_code = name_code_option = c.Util.STR_M # df_metrics = get_data.get_comoption_mktdata(start_date, end_date,name_code) # df_future_c1_daily = get_data.get_future_c1_by_option_daily(dt_histvol, end_date, name_code, min_holding) """ 50ETF option """ name_code = c.Util.STR_IH name_code_option = c.Util.STR_50ETF df_metrics = get_data.get_50option_mktdata(start_date, end_date) df_future_c1_daily = get_data.get_dzqh_cf_c1_daily(dt_histvol, end_date, name_code) name_code_index = c.Util.STR_INDEX_50SH df_index = get_data.get_index_mktdata(dt_histvol,end_date,name_code_index) """ 历史波动率 """ # df_vol_1m = Histvol.hist_vol(df_index) # df_parkinson_1m = Histvol.parkinson_number(df_future_c1_daily) # df_garman_klass = Histvol.garman_klass(df_future_c1_daily)
df_account = account1.account.rename(columns={c.Util.DT_DATE: 'date'}) print('original') res = account1.analysis() res['nbr_timing'] = account1.nbr_timing print(res) # res_base = account1.get_netvalue_analysis(account1.account['base_npv']) # res_index = account1.get_netvalue_analysis(account1.account['index_npv']) # df_res['ih_hedged'] = res # df_res['ih'] = res_base # df_res['index'] = res_index # df_res.to_csv('../../accounts_data/res_ih_.csv') pu = PlotUtil() dates = list(account1.account.index) hedged_npv = list(account1.account[c.Util.PORTFOLIO_NPV]) base_npv = list(account1.account['base_npv']) index_npv = list(account1.account['index_npv']) pu.plot_line_chart(dates, [hedged_npv, base_npv], ['hedged_npv', 'base_npv']) # pu.plot_line_chart(dates, [index_npv, base_npv], ['index_npv', 'base_npv']) plt.show() # account1.account.to_csv('../../accounts_data/hedge_account_ih_' + cd_short_ma + '_' + cd_long_ma + '_' + cd_std + '.csv') # account1.trade_records.to_csv('../../accounts_data/hedge_records_ih_' + cd_short_ma + '_' + cd_long_ma + '_' + cd_std + '.csv') # for cd_std in ['std_5','std_10','std_15','std_20']: # # # for P_mdd in [-0.09,-0.08, -0.07, -0.06,-0.05,-0.04]: # for P_mdd in [-0.07]:
transaction_fee += abs(delta - delta0) * (spot * replication.fee + replication.slippage) delta0 = delta else: d_asset = 0.0 # delta变化在一定范围内则不选择对冲。 asset += d_asset replicate = asset replicate_pnl = delta * spot - replicate - transaction_fee + change_pnl option_pnl = option_price - option0 replicate_cost = -replicate_pnl + option_pnl replicate_error = -replicate_pnl + max(0, strike - spot) # Mark to option payoff at maturity margin = abs(delta) * spot * replication.margin_rate df_res = pd.DataFrame(res) return df_res plot_utl = PlotUtil() # name_code = 'IF' name_code = 'IH' # id_index = 'index_300sh' id_index = 'index_50sh' vol = 0.2 rf = 0.03 fee_rate = 5.0 / 10000.0 dt1 = datetime.date(2014, 1, 5) # dt1 = datetime.date(2018, 1, 5) # dt2 = datetime.date(2018, 6, 30) dt2 = datetime.date(2018, 5, 13) #####################################################################################
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from matplotlib import cm as plt_cm import datetime import pandas as pd import numpy as np from WindPy import w from data_access.db_tables import DataBaseTables as dbt import matplotlib.pyplot as plt from Utilities.PlotUtil import PlotUtil import QuantLib as ql w.start() pu = PlotUtil() engine = create_engine( 'mysql+pymysql://guest:[email protected]/mktdata', echo=False) conn = engine.connect() metadata = MetaData(engine) Session = sessionmaker(bind=engine) sess = Session() options_mkt = Table('options_mktdata', metadata, autoload=True) futures_mkt = Table('futures_mktdata', metadata, autoload=True) options = Table('option_contracts', metadata, autoload=True) futuremkt_table = dbt.FutureMkt optionmkt_table = dbt.OptionMkt options_table = dbt.Options # Eval Settings evalDate = datetime.date(2018, 1, 19).strftime("%Y-%m-%d") # Set as Friday
def trade_volume(dt_date, dt_last_week, w, nameCode, core_instrumentid): pu = PlotUtil() options_mkt = admin.table_options_mktdata() evalDate = dt_date.strftime("%Y-%m-%d") # Set as Friday plt.rcParams['font.sans-serif'] = ['STKaiti'] plt.rcParams.update({'font.size': 15}) """当日成交持仓量 """ query_volume = admin.session_mktdata().query(options_mkt.c.dt_date, options_mkt.c.cd_option_type, options_mkt.c.amt_strike, options_mkt.c.amt_holding_volume, options_mkt.c.amt_trading_volume, options_mkt.c.amt_close, options_mkt.c.pct_implied_vol ) \ .filter(or_(options_mkt.c.dt_date == evalDate,options_mkt.c.dt_date == dt_last_week)) \ .filter(options_mkt.c.id_underlying == core_instrumentid)\ .filter(options_mkt.c.flag_night != 1) df_2d = pd.read_sql(query_volume.statement, query_volume.session.bind) df = df_2d[df_2d['dt_date'] == dt_date].reset_index() df_lw = df_2d[df_2d['dt_date'] == dt_last_week].reset_index() df_call = df[df['cd_option_type'] == 'call'].reset_index() df_put = df[df['cd_option_type'] == 'put'].reset_index() dflw_call = df_lw[df_lw['cd_option_type'] == 'call'].reset_index() dflw_put = df_lw[df_lw['cd_option_type'] == 'put'].reset_index() call_deltas = [] put_deltas = [] for idx, row in df_call.iterrows(): row_put = df_put.loc[idx] strike = row['amt_strike'] rowlw_call = dflw_call[dflw_call['amt_strike'] == strike] rowlw_put = dflw_put[dflw_put['amt_strike'] == strike] last_holding_call = 0.0 last_holding_put = 0.0 try: last_holding_call = rowlw_call['amt_holding_volume'].values[0] except: pass try: last_holding_put = rowlw_put['amt_holding_volume'].values[0] except: pass call_delta = row['amt_holding_volume'] - last_holding_call put_delta = row_put['amt_holding_volume'] - last_holding_put call_deltas.append(call_delta) put_deltas.append(put_delta) if nameCode == 'sr': wt = 25 else: wt = 15 strikes = df_call['amt_strike'].tolist() strikes1 = df_call['amt_strike'] + wt holding_call = df_call['amt_holding_volume'].tolist() holding_put = df_put['amt_holding_volume'].tolist() trading_call = df_call['amt_trading_volume'].tolist() trading_put = df_put['amt_trading_volume'].tolist() df_results = pd.DataFrame({ '0 call iv': df_call['pct_implied_vol'].tolist(), '1 call delta_holding': call_deltas, '2 call holding': df_call['amt_holding_volume'].tolist(), '3 call trading': df_call['amt_trading_volume'].tolist(), '4 call price': df_call['amt_close'].tolist(), '5 strikes': df_put['amt_strike'].tolist(), '6 put price': df_put['amt_close'].tolist(), '7 put trading': df_put['amt_trading_volume'].tolist(), '8 put holding': df_put['amt_holding_volume'].tolist(), '9 put delta_holding': put_deltas, '91 put iv': df_put['pct_implied_vol'].tolist() }) df_results.to_csv('../data/' + nameCode + '_holdings_' + evalDate + '.csv') ldgs = ['持仓量(看涨)', '持仓量(看跌)', '成交量(看涨)', '成交量(看跌)'] f3, ax3 = plt.subplots() p1 = ax3.bar(strikes, holding_call, width=wt, color=pu.colors[0]) p2 = ax3.bar(strikes1, holding_put, width=wt, color=pu.colors[1]) p3, = ax3.plot(strikes, trading_call, color=pu.colors[2], linestyle=pu.lines[2], linewidth=2) p4, = ax3.plot(strikes, trading_put, color=pu.colors[3], linestyle=pu.lines[3], linewidth=2) ax3.legend([p1, p2, p3, p4], ldgs, bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=4, mode="expand", borderaxespad=0., frameon=False) ax3.spines['top'].set_visible(False) ax3.spines['right'].set_visible(False) ax3.yaxis.set_ticks_position('left') ax3.xaxis.set_ticks_position('bottom') f3.set_size_inches((12, 8)) f3.savefig('../data/' + nameCode + '_holdings_' + evalDate + '.png', dpi=300, format='png', bbox_inches='tight')
list_atm_call, list_atm_put = optionset.get_options_list_by_moneyness_mthd1( moneyness_rank=0, maturity=maturity) atm_call = optionset.select_higher_volume(list_atm_call) atm_put = optionset.select_higher_volume(list_atm_put) return atm_call, atm_put def get_atm_iv_average(optionset, maturity): atm_call, atm_put = get_atm_options(optionset, maturity) iv_call = atm_call.get_implied_vol() iv_put = atm_put.get_implied_vol() iv_avg = (iv_call + iv_put) / 2 return iv_avg pu = PlotUtil() start_date = datetime.date(2018, 9, 12) end_date = datetime.date(2018, 9, 13) nbr_maturity = 0 min_holding = 8 df_daily = get_data.get_comoption_mktdata(start_date, end_date, Util.STR_SR) optionset = BaseOptionSet(df_data=df_daily, rf=0.015) optionset.init() # optionset.go_to(end_date) maturity = optionset.select_maturity_date(nbr_maturity, min_holding=min_holding) iv_htr = optionset.get_atm_iv_by_htbr(maturity) iv_avg = get_atm_iv_average(optionset, maturity) htbr = optionset.get_htb_rate(maturity)
from back_test.model.base_option_set import BaseOptionSet from back_test.model.base_account import BaseAccount from data_access import get_data import back_test.model.constant as c import datetime import numpy as np from OptionStrategyLib.OptionReplication.synthetic_option import SytheticOption from Utilities.PlotUtil import PlotUtil import matplotlib.pyplot as plt import pandas as pd from Utilities.timebase import LLKSR, KALMAN, LLT pu = PlotUtil() start_date = datetime.date(2015, 1, 1) end_date = datetime.date(2018, 8, 8) dt_histvol = start_date - datetime.timedelta(days=90) min_holding = 15 init_fund = c.Util.BILLION slippage = 0 m = 1 # 期权notional倍数 """ commodity option """ # name_code = name_code_option = c.Util.STR_M # df_metrics = get_data.get_comoption_mktdata(start_date, end_date,name_code) # df_future_c1_daily = get_data.get_future_c1_by_option_daily(dt_histvol, end_date, name_code, min_holding) """ 50ETF option """ name_code = c.Util.STR_IH name_code_option = c.Util.STR_50ETF df_metrics = get_data.get_50option_mktdata(start_date, end_date) df_future_c1_daily = get_data.get_mktdata_cf_c1_daily(dt_histvol, end_date, name_code) """ 隐含波动率 """
def trade_volume(dt_date, dt_last_week, df_option_metrics, name_code, core_instrumentid): pu = PlotUtil() df = df_option_metrics[ (df_option_metrics['dt_date'] == dt_date) & (df_option_metrics[c.Util.ID_UNDERLYING] == core_instrumentid)] df_lw = df_option_metrics[ (df_option_metrics['dt_date'] == dt_last_week) & (df_option_metrics[c.Util.ID_UNDERLYING] == core_instrumentid)] df_call = df[df['cd_option_type'] == 'call'].reset_index(drop=True) df_put = df[df['cd_option_type'] == 'put'].reset_index(drop=True) dflw_call = df_lw[df_lw['cd_option_type'] == 'call'].reset_index(drop=True) dflw_put = df_lw[df_lw['cd_option_type'] == 'put'].reset_index(drop=True) call_deltas = [] put_deltas = [] for idx, row in df_call.iterrows(): row_put = df_put.loc[idx] strike = row['amt_strike'] rowlw_call = dflw_call[dflw_call['amt_strike'] == strike] rowlw_put = dflw_put[dflw_put['amt_strike'] == strike] last_holding_call = 0.0 last_holding_put = 0.0 try: last_holding_call = rowlw_call['amt_holding_volume'].values[0] except: pass try: last_holding_put = rowlw_put['amt_holding_volume'].values[0] except: pass call_delta = row['amt_holding_volume'] - last_holding_call put_delta = row_put['amt_holding_volume'] - last_holding_put call_deltas.append(call_delta) put_deltas.append(put_delta) if name_code == c.Util.STR_SR: wt = 25 else: wt = 15 strikes = df_call['amt_strike'].tolist() strikes1 = df_call['amt_strike'] + wt holding_call = df_call['amt_holding_volume'].tolist() holding_put = df_put['amt_holding_volume'].tolist() trading_call = df_call['amt_trading_volume'].tolist() trading_put = df_put['amt_trading_volume'].tolist() df_results = pd.DataFrame({ '0 call iv': df_call['pct_implied_vol'].tolist(), '1 call delta_holding': call_deltas, '2 call holding': df_call['amt_holding_volume'].tolist(), '3 call trading': df_call['amt_trading_volume'].tolist(), '4 call price': df_call['amt_close'].tolist(), '5 strikes': df_put['amt_strike'].tolist(), '6 put price': df_put['amt_close'].tolist(), '7 put trading': df_put['amt_trading_volume'].tolist(), '8 put holding': df_put['amt_holding_volume'].tolist(), '9 put delta_holding': put_deltas, '91 put iv': df_put['pct_implied_vol'].tolist() }) df_results.to_csv('../data/' + name_code + '_holdings.csv') ldgs = ['持仓量(看涨)', '持仓量(看跌)', '成交量(看涨)', '成交量(看跌)'] f3, ax3 = plt.subplots() p1 = ax3.bar(strikes, holding_call, width=wt, color=pu.colors[0]) p2 = ax3.bar(strikes1, holding_put, width=wt, color=pu.colors[1]) p3, = ax3.plot(strikes, trading_call, color=pu.colors[2], linestyle=pu.lines[2], linewidth=2) p4, = ax3.plot(strikes, trading_put, color=pu.colors[3], linestyle=pu.lines[3], linewidth=2) ax3.legend([p1, p2, p3, p4], ldgs, bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=4, mode="expand", borderaxespad=0., frameon=False) ax3.spines['top'].set_visible(False) ax3.spines['right'].set_visible(False) ax3.yaxis.set_ticks_position('left') ax3.xaxis.set_ticks_position('bottom') f3.set_size_inches((12, 8)) f3.savefig('../data/' + name_code + '_holdings.png', dpi=300, format='png', bbox_inches='tight') f4, ax4 = plt.subplots() p1 = ax4.bar(strikes, call_deltas, width=wt, color=pu.colors[0]) p2 = ax4.bar(strikes1, put_deltas, width=wt, color=pu.colors[1]) # p3, = ax3.plot(strikes, trading_call, color=pu.colors[2], linestyle=pu.lines[2], linewidth=2) # p4, = ax3.plot(strikes, trading_put, color=pu.colors[3], linestyle=pu.lines[3], linewidth=2) ax4.legend([p1, p2], ['看涨期权持仓量变化', '看跌期权持仓量变化'], borderaxespad=0., frameon=False) ax4.spines['top'].set_visible(False) ax4.spines['right'].set_visible(False) ax4.yaxis.set_ticks_position('left') ax4.xaxis.set_ticks_position('bottom') f4.set_size_inches((12, 8)) f4.savefig('../data/' + name_code + '_holding_delta.png', dpi=300, format='png', bbox_inches='tight')
import numpy as np from matplotlib import pylab as plt import pandas as pd import back_test.model.constant as c from Utilities.PlotUtil import PlotUtil from OptionStrategyLib.VolatilityModel.kernel_density import kde_sklearn pu = PlotUtil() df_data = pd.read_csv('../../../data/df_data.csv') # df_data = pd.read_csv('../../data/df_underlying.csv') dates = list(df_data[c.Util.DT_DATE]) histvols = np.array(df_data[c.Util.AMT_HISTVOL+'_20']) garman_klass_vols = np.array(df_data[c.Util.AMT_GARMAN_KLASS+'_20']) parkinson_vols = np.array(df_data[c.Util.AMT_PARKINSON_NUMBER+'_20']) logvols = np.log(histvols) x_grid = np.linspace(min(histvols), max(histvols), 1000) # plt.figure(1) pdf_cc = kde_sklearn(histvols, x_grid, bandwidth=0.03) # plt.plot(x_grid, pdf_cc,'r--', label='Estimate') # plt.hist(histvols, bins=30, normed=True, color=(0,.5,0,1), label='Histogram') # plt.figure(2) pdf_gk = kde_sklearn(garman_klass_vols, x_grid, bandwidth=0.03) # plt.plot(x_grid, pdf_gk,'r--', label='Estimate') # plt.hist(garman_klass_vols, bins=30, normed=True, color=(0,.5,0,1), label='Histogram') # plt.figure(3) pdf_p = kde_sklearn(parkinson_vols, x_grid, bandwidth=0.03)
def get_vol_data(evalDate, daycounter, calendar, contractType): svidata = svi_dataset.get(to_dt_date(evalDate)) paramset = calibrered_params_ts.get(to_dt_date(evalDate)) volSurface = SviVolSurface(evalDate, paramset, daycounter, calendar) spot = svidata.spot maturity_dates = sorted(svidata.dataSet.keys()) svi = SviPricingModel(volSurface, spot, daycounter, calendar, to_ql_dates(maturity_dates), ql.Option.Call, contractType) black_var_surface = svi.black_var_surface() const_vol = estimated_vols.get(to_dt_date(evalDate)) return spot, black_var_surface, const_vol pu = PlotUtil() # Evaluation Settings evalDate = ql.Date(3, 8, 2017) # endDate1 = ql.Date(28,8,2017) # endDate1 = ql.Date(11,8,2017) calendar = ql.China() daycounter = ql.ActualActual() fee = 0.6 / 100 dt = 1.0 / 365 rf = 0.03 svidata = svi_dataset.get(to_dt_date(evalDate)) S0 = svidata.spot maturity_dates = sorted(svidata.dataSet.keys()) maturitydt = calendar.advance(evalDate, ql.Period(3, ql.Months)) print('maturity date : ', maturitydt)
""" Settings and Collect Data """ ########## # start_date = datetime.date(2015, 2, 1) start_date = datetime.date(2017, 1, 1) end_date = datetime.date(2018, 8, 31) nbr_maturity = 1 moneyness = -5 ############ dt_close_position = end_date - datetime.timedelta(days=5) min_holding = 15 slippage = 0 pct_underlying_invest = 1.0 pu = PlotUtil() df_metrics = get_data.get_50option_mktdata(start_date, end_date) df_underlying = get_data.get_index_mktdata(start_date, end_date, c.Util.STR_INDEX_50ETF) df_underlying_llt = filtration_LLT(df_underlying, c.Util.AMT_CLOSE) df_iv = get_data.get_iv_by_moneyness(start_date, end_date, c.Util.STR_50ETF) df_iv_put = df_iv[df_iv[c.Util.CD_OPTION_TYPE] == c.Util.STR_PUT].dropna().reset_index(drop=True) df_iv_llt = filtration_LLT(df_iv_put, c.Util.PCT_IMPLIED_VOL) # plt.show() """ Init Portfolio and Account """ init_fund = 10000000 optionset = BaseOptionSet(df_metrics)