Create the Project and Specify Analyses
Investors often use specific strategies to trade financial instruments. One common strategy is called buy and hold. This strategy anticipates gains from holding instruments for a relatively long period of time. Other strategies involve a more active approach, using market information to trade instruments more frequently.
In the following example, you compare two trading strategies, convex trading and concave trading, to the buy and hold strategy. With the convex trading strategy, you buy instruments with increasing returns and you sell instruments with decreasing returns. With the concave trading strategy, you sell instruments with increasing returns and you buy instruments with decreasing returns. The convex trading strategy is a pro-cyclical strategy and the concave trading strategy is a counter-cyclical strategy.
To compare strategies, you create a portfolio that consists of shares of stock in several companies. You also create a cash account to fund additional purchases. For each of the trading strategies, you define a trading method that specifies how the stocks will be traded based on the current market state.
After that, you simulate market states using the variances and covariances that are calculated from the historical stock price data. You simulate forward three horizons.
First, set up the library for your analysis.
libname RDExamp "C:\users\sasdemo\RD_Examples"; %let test_env = tradingmethods;
In this code, you use the SAS Macro Language Facility to create the macro variable Test_Env. You assign the value tradingmethods to that variable.
Using macro variables in this way gives you the flexibility to change the physical location of the target library and environment name in just two lines of code. You can assign the library to any path as long as you have Write access to that directory.
Next, create a new SAS Risk Dimensions environment assigned the name TradingMethods in the RDExamp library.
proc risk; env new=RDExamp.&test_env; env save; run;
The instrument variables are as follows: InstType, InstID, Stock_Name, Stock_Symbol, TradeGroupID, Currency, and Holding. You create the variable TradeGroupID to group instruments into trading groups. Instruments within a trading group can be sold to fund the purchase of other instruments within the group. In this example you have one trading group called TradingGroup1.
data RDExamp.instdata; length Instid Insttype Stock_Name tradegroupid $32. Stock_Symbol $6.; length Currency $3.; infile datalines delimiter = '|'; input Insttype $ Instid $ Stock_Name $ Stock_Symbol $ tradegroupid $ Currency $ holding; datalines; Equity |instid1 |TechCompany |TEC |TradingGroup1 |USD |1 Equity |instid2 |BankCompany |BNK |TradingGroup1 |USD |1 Equity |instid3 |HealthCompany |HLTH |TradingGroup1 |USD |1 Equity |instid4 |AutoCompany |AUTO |TradingGroup1 |USD |1 Equity |instid5 |EnergyCompany |ENGY |TradingGroup1 |USD |1 Equity |instid6 |FoodCompany |FOOD |TradingGroup1 |USD |1 Equity |instid7 |GoodsCompany |GDS |TradingGroup1 |USD |1 ;
The following code creates the system cash account. The cash in this account can be used to purchase additional instruments. In addition, the proceeds from the sale of instruments are transferred to this account.
data RDExamp.Cashinst; length Instid Insttype $32.; length Currency $3.; infile datalines delimiter = '|'; input Insttype $ Instid $ Currency $ _SysCashAmount_; datalines; _syscash_ |system_cash_01 |USD |100 ;
Now register the instrument data in the environment and declare the instrument variables.
proc risk; env open = RDExamp.&test_env; declare instvars=( Stock_Symbol char 32 var label='Stock Price Reference', Stock_Name char 32 var label='Stock Price Name' ); instdata Equities file = RDExamp.instdata format = simple; instdata SysCash file = RDExamp.Cashinst format = simple; env save; run;
data RDexamp.histmkt; informat Date date9.; format Date date9.; length TEC AUTO BNK HLTH ENGY FOOD GDS 8; infile datalines delimiter = ' '; input Date TEC AUTO BNK HLTH ENGY FOOD GDS; datalines; 04Oct12 14.38 8.41 6.55 35.17 1.38 20.25 5.98 05Oct12 15.98 8.78 7.02 35.99 1.38 20.26 5.69 08Oct12 15.87 8.61 6.94 35.55 1.46 20.24 5.88 09Oct12 16.29 8.80 7.25 36.07 1.73 20.19 5.85 10Oct12 16.03 8.58 7.10 36.06 1.84 19.79 6.26 11Oct12 16.52 8.66 7.42 36.14 1.95 19.79 6.06 12Oct12 16.02 8.42 6.80 38.15 2.01 19.32 6.24 15Oct12 15.52 8.51 6.65 39.40 1.90 19.42 6.08 16Oct12 14.44 8.15 6.14 39.35 1.81 19.32 5.01 17Oct12 14.88 8.38 6.31 39.02 1.60 19.89 4.96 18Oct12 14.87 8.36 6.20 38.66 1.84 19.75 5.16 19Oct12 15.50 8.84 6.50 39.93 1.72 20.06 5.49 22Oct12 15.81 8.90 6.75 40.30 1.83 20.22 5.50 23Oct12 16.05 8.75 6.74 41.12 1.81 20.60 5.63 24Oct12 15.70 8.64 6.69 41.67 1.78 20.31 5.41 25Oct12 16.01 8.68 6.73 41.45 1.80 20.38 5.33 26Oct12 16.18 9.06 6.56 41.82 1.70 19.82 5.26 29Oct12 15.93 8.83 6.18 40.76 1.70 19.75 5.40 30Oct12 16.23 8.99 6.26 40.67 1.66 20.34 5.34 31Oct12 16.46 9.31 6.37 41.72 1.67 20.13 5.56 01Nov12 17.18 9.63 6.80 42.35 1.69 20.45 5.75 02Nov12 17.37 9.61 6.77 41.63 1.66 20.89 6.13 05Nov12 16.70 9.12 6.29 40.84 1.56 21.40 6.41 06Nov12 16.76 9.15 6.34 40.76 1.47 21.40 6.18 07Nov12 16.51 8.94 6.14 40.51 1.64 21.73 6.36 08Nov12 16.12 8.98 5.98 40.66 1.71 21.83 6.36 09Nov12 16.40 9.12 6.19 40.74 1.66 22.14 6.38 12Nov12 16.41 9.27 6.31 40.45 1.65 22.05 6.26 13Nov12 16.83 9.65 6.50 41.64 1.60 22.08 6.19 14Nov12 16.64 9.59 6.59 43.34 1.61 22.55 5.98 15Nov12 15.94 9.16 6.19 42.84 1.61 22.83 6.11 16Nov12 15.74 9.23 6.28 43.03 1.53 23.33 5.93 19Nov12 15.74 9.51 6.13 44.31 1.48 23.42 5.67 ;
data RDExamp.currentmkt; informat Date date9.; format date date9.; length TEC AUTO BNK HLTH ENGY FOOD GDS 8; infile datalines delimiter = ' '; input Date TEC AUTO BNK HLTH ENGY FOOD GDS; datalines; 19Nov12 15.74 9.51 6.13 44.31 1.48 23.42 5.67 ;
proc risk; environment open = RDExamp.&test_env; declare riskfactors= (TEC num var category=Equity label='TechCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='TEC'), AUTO num var category=Equity label='AutoCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='AUTO'), BNK num var category=Equity label='BankCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='BNK'), HLTH num var category=Equity label='HealthCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='HLTH'), ENGY num var category=Equity label='EnergyCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='ENGY'), FOOD num var category=Equity label='FoodCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='FOOD'), GDS num var category=Equity label='GoodsCompany Stock Price' group='Equity' mlevel=ratio refmap=(Stock='GDS') ); environment save; run;
proc risk; env open=RDExamp.&test_env; marketdata HistoricalMarket file=RDexamp.histmkt type=timeseries; marketdata CurrentMarket file=RDExamp.currentmkt type=current; env save; run;
proc compile env=RDExamp.&test_env outlib=RDExamp.&test_env; method EquityPrice desc= "Equity Pricing" kind= price; _value_ = Stock.Stock_Symbol; _cash_ = 0; endmethod; run;
The following code defines the trading methods. First, define the convex trading method.
proc compile env=RDExamp.&test_env outlib=RDExamp.&test_env; method ConvexTrading desc="Convex Trading Method" kind=trade; index = 0; do while (index >= 0); index = GET_NEXTINSTRUMENTINCLASS(index,"Equity"); if (index > 0) then do; inst_id = GET_INSTRUMENTID(index); val_previous_1 = GET_CURRENTVALUE(index,-1,1); val_current = GET_CURRENTVALUE(index,0,1); baseval=GET_BASEVALUE(index,1); holding_current = GET_CURRENTHOLDING(index); val_previous = val_previous_1; if val_previous = . then do; val_previous = baseval; end; equity_return =((val_current - (val_previous))/(val_previous));
/*If return is decreasing then SELL all holding*/ if equity_return < 0 then do; /* Step 1. Trade all shares for cash*/ return_code = TRADE(index, -1 * holding_current); /* Step 2. Transfer cash to the system cash account*/ current_cash = GET_CURRENTCASH(index); return_code = TRANSFERCASH(inst_id, "system_cash_01",current_cash); end; /*If return is increasing then BUY as much as possible*/
else if equity_return > 0 then do; /* Step 1. Check for money in the system cash account*/ avail_cash = GET_SYSTEMCASH ("system_cash_01"); if avail_cash > 0 then do; /* Step 2. Transfer system cash for trade*/ return_code = TRANSFERCASH("system_cash_01",inst_id,avail_cash); /* Step 3. Determine number of shares to purchase*/ buy_equity = floor(avail_cash/val_current); /* Step 4. Trade cash for shares*/ return_code = TRADE(index, buy_equity); /* Step 5. Transfer any remaining cash back to system cash account*/ current_cash = GET_CURRENTCASH(index); return_code = TRANSFERCASH(inst_id, "system_cash_01",current_cash); end; end; end; end; endmethod; run;
Then create the concave trading method.
proc compile env=RDExamp.&test_env outlib=RDExamp.&test_env; method ConcaveTrading desc="Concave Trading Method" kind=trade; index = 0; do while (index >= 0); index = GET_NEXTINSTRUMENTINCLASS(index,"Equity"); if (index > 0) then do; inst_id = GET_INSTRUMENTID(index); val_previous_1 = GET_CURRENTVALUE(index,-1,1); val_current = GET_CURRENTVALUE(index,0,1); baseval=GET_BASEVALUE(index,1); holding_current = GET_CURRENTHOLDING(index); val_previous = val_previous_1; if val_previous = . then do; val_previous = baseval; end; equity_return =((val_current - (val_previous))/(val_previous));
/*If return is increasing then SELL all holding*/ if equity_return > 0 then do; /* Step 1. Trade all shares for cash*/ return_code = TRADE(index, -1 * holding_current); /* Step 2. Transfer cash to the system cash account*/ current_cash = GET_CURRENTCASH(index); return_code = TRANSFERCASH(inst_id, "system_cash_01",current_cash); end;
/*If return is decreasing then BUY as much as possible*/ else if equity_return < 0 then do; /* Step 1. Check for money in the system cash account*/ avail_cash = GET_SYSTEMCASH ("system_cash_01"); if avail_cash > 0 then do; /* Step 2. Transfer system cash for trade*/ return_code = TRANSFERCASH("system_cash_01",inst_id,avail_cash); /* Step 3. Determine number of shares to purchase*/ buy_equity = floor(avail_cash/val_current); /* Step 4. Trade cash for shares*/ return_code = TRADE(index, buy_equity); /* Step 5. Transfer remaining cash to system cash account*/ current_cash = GET_CURRENTCASH(index); return_code = TRANSFERCASH(inst_id, "system_cash_01",current_cash); end; end; end; end; endmethod; run;
The following code pulls trading methods into the SAS Risk Dimensions environment. Use the INSTRUMENT statement to indicate which pricing methods to use for each of the instrument types.
proc risk; environment open = RDExamp.&test_env; instrument Equity methods = (Price EquityPrice) variables = ( Stock_Symbol tradegroupid Currency Holding Stock_Name ); env save; run
The following code creates a portfolio file from the instrument data set and identifies the cross-classifications for portfolio aggregation. Then, create a covariance simulation analysis to predict market states for the next five days. Lastly, it creates the project, specifying the portfolio, assigning the covariance simulation analysis, and specifying the trading method. The buy and hold trading strategy does not require a trading method because all instruments will be held and traded.
proc risk; environment open = RDExamp.&test_env; sources InstDataSource (Equities SysCash); read sources=InstDataSource out=Portfolio; crossclass InstIDCC (InstID); simulation Covariance method=covariance interval = weekday ndraws=100 alpha=(0.01) data = (HistoricalMarket) horizon = (1 2 3 4 5); project Convex_Trading analysis=(Covariance) portfolio=Portfolio crossclass=InstIDCC Trademethod=(ConvexTrading) Tradetime=ALLIMMEDIATE data=( CurrentMarket HistoricalMarket ); project Concave_Trading analysis=(Covariance) portfolio=Portfolio crossclass=InstIDCC Trademethod=(ConcaveTrading) Tradetime=ALLIMMEDIATE data=( CurrentMarket HistoricalMarket ); project Buy_Hold analysis=(Covariance) portfolio=Portfolio crossclass=InstIDCC data=( CurrentMarket HistoricalMarket ); env save; run;
proc risk; env open=RDExamp.&test_env; runproject Convex_Trading out= Convex_Trading options=(outall); env save; run; proc risk; env open=RDExamp.&test_env; runproject Concave_Trading out= Concave_Trading options=(outall); env save; run; proc risk; env open=RDExamp.&test_env; runproject Buy_Hold out= Buy_Hold options=(outall); env save; run;