Resources

SAS Products

SAS Risk Dimensions - Using Trading Methods



Overview of Trading Methods

Set Up Your Environment

Define Your Portfolio

Register Market Data

Value Your Portfolio

Create the Project and Specify Analyses

Run the Projects

Example Code (ZIP file)



Overview

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.



Set Up Your Environment

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;



Define Your Portfolio

Next, describe the assets in your portfolio and identify the risk factors that affect portfolio value. The following code creates a data set called InstData that stores information about the instruments in your portfolio.

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;



Register Market Data

Next, provide historical risk factor values and current risk factor values. Declare the risk factors and register the market data in the environment. There are seven risk factors in this example, each representing the price of a particular stock. The risk factor declarations include reference mapping.

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;



Value Your Portfolio

Next, create a pricing method using the COMPILE procedure to value the portfolio.

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



Create the Project and Specify Analyses

Now, set up a project to simulate values for your portfolio based on the historical market data and the current market data.

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;



Run the Projects

Run each of the three projects, putting output files in the subdirectory of the environment specified in the OUT= option of the RUNPROJECT statement.

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;


Back to Examples index page