BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
feresm
Fluorite | Level 6

back to this subject I am now beyond the READ DATA issues, I guess. However, when I run the code I got two data errors as in the files attached and a semantic error from the solver. I tried both options, using the smallest function and the percentile. The result is the same. Also, the expand does not show the objective function, but shows the constraints just fine. The main difficulty, I guess, is that when optimising I do not need the commodities anymore (COMMS), just the date.

 

Any help? Thanks, Marcio.

 

this is the code:

DATA max_limits;

  input ativo $ val_max;

  datalines;

  Nickel 5.5

  Tin 2.2

;

run;

 

%let max_metals=6.0;

/* The following are not used yet since we are validating the model with only two metal commodities */

%let max_agri=12;

%let max_total=20;

 

PROC OPTMODEL;

  /* Read historic and constraints table from WORKLIB */

  /* LIM_METALS contains the max values by asset/period

     and the max of total assets by type (in this case METALS) per period */

 

  set <str> PERIODS = /_1M _3M _6M _9M _1Y _2Y _3Y/;

  set <str> COMMS;

  set <num> DATES;

  set <num,str> DATES_COMMS;

  num lim_metals {COMMS, PERIODS};

  num hist_data {DATES_COMMS, PERIODS};

  num val_max{COMMS};

 

  read data WORK.LIM_METAL into COMMS=[commodity] {j in PERIODS} <lim_metals[commodity, j]=col(j)>;

  print lim_metals;

 

  read data max_limits INTO COMMS=[ativo] val_max;

  print val_max;

 

  read data WORK.HIST_VAR_4 INTO DATES_COMMS=[date ativo] {p in PERIODS} <hist_data[date,ativo,p]=col(p)>;

  print hist_data;

 

  /* Variables to optimise and constraints */

  /* The goal is to minimise the value at risk by calculating the amount allocated to each asset (Nickel and Tin) for each period. */

 

  var amount{COMMS, PERIODS} >= 0;

 

  /* Corrected IMPVAR definitions */

  impvar amount_data {date in DATES, comm in COMMS, p in PERIODS} = amount[comm, p] * hist_data[date, comm, p];

 

  impvar amount_date_comm_period {date in DATES} = sum{comm in COMMS, p in PERIODS} amount_data[date, comm, p];

 

  impvar total_comm {comm in COMMS} = sum{period in PERIODS} amount[comm, period];

 

  /* Constraints */

  con lim_comm {comm in COMMS}: total_comm[comm] <= val_max[comm];

  con lim_total: sum{comm in COMMS} total_comm[comm] <= &max_metals;

  

  expand;

  /* Objective Function */

  /* For 99% VaR (6th smallest value in the sample of 520 obs) */

  /* min value_at_risk = pctl(.99, of amount_date_comm_period[*]);*/

  min value_at_risk1= smallest(6, of amount_date_comm_period[*]);

  

  solve with nlp / algorithm=as ms;

  print amount;

  print value_at_risk1;

quit;

 

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

You have declared the DATES set but not populated it.  Adding the following statement (after you have populated DATES_COMMS) avoids the error:

DATES = setof {<d,c> in DATES_COMMS} d;

View solution in original post

3 REPLIES 3
Ksharp
Super User
Why not post it at OR forum and calling @RobPratt ,since you are using PROC OPTMODEL.
RobPratt
SAS Super FREQ

You have declared the DATES set but not populated it.  Adding the following statement (after you have populated DATES_COMMS) avoids the error:

DATES = setof {<d,c> in DATES_COMMS} d;
feresm
Fluorite | Level 6
Cannot thank you enough!

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

Register now

Discussion stats
  • 3 replies
  • 658 views
  • 0 likes
  • 3 in conversation