21 października 2009

DevCpp i instalacja biblioteki boost

Do instalacji biblioteki boost w środowisku DevCpp należy:

  1. Zainstalować środowisko programistyczne Bloodshed Dev-C++. Program można pobrać ze strony The Dev-C++ Resource Site.
  2. Pobrać kod źródłowy biblioteki boost ze strony Boost Downloads i rozpakować go do wybranego katalogu.
  3. Pobrać lub skompilować program bjam. Plik wykonywalny należy umieścić w katalogu, do którego rozpakowano źródła bibiloteki.

Przed przystąpieniem do kompilacji biblioteki należy upewnić się, że plik wykonywalny kompilatora g++.exe znajduje się na ścieżce wyszukiwania. Aby uzyskać odpowiedź na to pytanie można wprowadzić w oknie Command Prompt następujące polecenie.

g++ --version

Jeśli w wyniku tego polecenia zostanie wypisany komunikat poniższej treści lub podobny, to wszystko jest na dobrej drodze.

g++ (GCC) 3.4.2 (mingw-special)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Jeżeli jednak otrzymamy komunikat:


a instalacja Dev-Cpp przebiegła bezbłędnie, to należy dodać do ścieżki wyszykiwania katalog, w którym został zainstalowany kompilator. Można zrobić to na dwa sposoby.

Pierwszy sposób polega na trwałej modyfikacji zmiennej środowiskowej PATH. Zmiany można dokonać wybierając po kolei: My Computer -> Properties -> Advanced -> Environment Variables -> System Variables -> Edit, a następnie dodać po średniku katalogu, w którym znajdują się pliki wykonywalne Dev-Cpp. Kolejne kroki przedstawione są na obrazkach.

System Properties/Advanced Environment Variables Edit System Variables

Drugi sposób to rozszerzenie zmiennej środowiskowej PATH na czas trwania okna poleceń (Command Prompt).

set PATH=%PATH%;C:\Dev-Cpp\bin

W powyższych przykładach przyjęte zostało założenie, że Dev-Cpp został zainstalowany w domyślnym katalogu.

Zawartość zmiennej środowiskowej PATH można sprawdzić wykonując polecenie:

path

lub:

echo %PATH%

Minimalna instalacja z domyślnymi parametrami wykonywana jest po wydanym poleceniu:

bjam --toolset=gcc install

Jeśli nie chcemy budować biblioteki w domyślnym katalogu i jednocześnie chcemy skompilować bibliotekę na wszystkie możliwe sposoby, to uzyskamy ten efekt wydając polecenie:

bjam --build-dir=C:\Boost-build ^ --toolset=gcc ^ --build-type=complete install

Więcej opcji kompilacji można uzyskać wydając polecenie:

bjam --help

Słowa kluczowe: cplusplus, boost


11 sierpnia 2009

Rekurencyjne wypisywanie zawartości katalogu -- SAS 4GL

Na tej stronie znalazłem kod makra w języku 4GL służącego do wypisywania rekurencyjnie zawartości katalogów. Zmodyfikowałem to makro tak, aby lepiej odpowiadało moim potrzebom. Dodałem możliwość ograniczania głębokości rekurencji

%macro DirWalk(DIRNAME, MAXDEPTH=-1); %local I FILEREF RC DIRID FILESCNT LEVEL LEN; %let DIRNAME = %sysfunc(translate(&DIRNAME, "/", "\")); %let DIRNAME = %sysfunc(compress(&DIRNAME, '"')); %let LEN = %sysfunc(length(&DIRNAME)); %let LAST = %sysfunc(substr(&DIRNAME, &LEN, 1)); %if "&LAST" = "/" %then %let DIRNAME = %sysfunc(substr(&DIRNAME, 1, &LEN - 1)); %let LEVEL = %eval(&MAXDEPTH); %if %sysfunc(symexist(DEPTH)) = 0 %then %let DEPTH = 1; %let RC = %sysfunc(filename(FILEREF, "&DIRNAME")); %let DIRID = %sysfunc(dopen(&FILEREF)); %if &DIRID > 0 %then %do; * seems to be a directory, so walk it; %let FILESCNT = %sysfunc(dnum(&DIRID)); %if &FILESCNT > 0 %then %do; %do I = 1 %to &FILESCNT; %let NAME = %sysfunc(trim(&DIRNAME/%sysfunc(dread(&DIRID, \ &I)))); %put &DEPTH &LEVEL &I &NAME; %if &LEVEL ne 0 %then %do; %let DEPTH = %eval(&DEPTH + 1); %dirWalk("&NAME", \ MAXDEPTH=%sysfunc(max(&LEVEL - 1, -1))); %let DEPTH = %eval(&DEPTH - 1); %end; %end; %end; %let RC = %sysfunc(dclose(&DIRID)); %end; %mend DirWalk;

Makro o można wywoływać na kilka sposobów:

%DirWalk("C:/katalog/", MAXDEPTH=0); %DirWalk("C:/katalog/", MAXDEPTH=1); %DirWalk("C:/katalog/", MAXDEPTH=-1); %DirWalk("C:/katalog/");

Pierwsze wywołanie spowoduje wypisanie jedynie zawartości katalogu "C:/katalog/". Po drugim wywołaniu zobaczymy zawartość podanego katalogu oraz katalogów bezpośrednio w nim się znajdujących. Ostatnie dwa wywołania są równoważne i powodują wypisania zawartości podanego katalogu oraz wszystkich podkatalogów w nim znajdujących niezależnie od głębokości na której są położone w drzewie katalogów.

Samo wypisywanie zawartości katalogu jest mało przydatne. O wiele większą korzyść można odnieść z listy plików i katalogów zapisanych w tablicy. Służy temu kolejne makro (na uwagę zasługuje makro w nim zagnieżdżone):

%macro ListRecursive(DATASET, DIRNAME, MAXDEPTH=-1); %let DIRNAME = &DIRNAME; %let DATASET = &DATASET; %macro DataDirWalk(DIRNAME, MAXDEPTH=-1); %local I FILEREF RC DIRID FILESCNT LEVEL LEN; %let DIRNAME = %sysfunc(translate(&DIRNAME, "/", "\")); %let DIRNAME = %sysfunc(compress(&DIRNAME, '"')); %let LEN = %sysfunc(length(&DIRNAME)); %let LAST = %sysfunc(substr(&DIRNAME, &LEN, 1)); %if "&LAST" = "/" %then %let DIRNAME = %sysfunc(substr(&DIRNAME, 1, &LEN - 1)); %let LEVEL = %eval(&MAXDEPTH); %if %sysfunc(symexist(DEPTH)) = 0 %then %let DEPTH = 1; %let RC = %sysfunc(filename(FILEREF, "&DIRNAME")); %let DIRID = %sysfunc(dopen(&FILEREF)); %if &DIRID > 0 %then %do; %let FILESCNT = %sysfunc(dnum(&DIRID)); %if &FILESCNT > 0 %then %do; %do I = 1 %to &FILESCNT; %let NAME = %sysfunc(dread(&DIRID, &I)); %let PATH = %sysfunc(trim(&DIRNAME/&NAME)); fileNum = &I; fileName = "&NAME"; filePath = "&PATH"; parentDir = "&DIRNAME"; depth = &DEPTH; output; %if &LEVEL ne 0 %then %do; %let DEPTH = %eval(&DEPTH + 1); %DataDirWalk("&PATH", \ MAXDEPTH=%sysfunc(max(&LEVEL-1, -1))); %let DEPTH = %eval(&DEPTH - 1); %end; %end; %end; %let RC = %sysfunc(dclose(&DIRID)); %end; %mend DataDirWalk; data &DATASET; format fileName $32.; format filePath $128.; format parentDir $96.; format depth best4.; format fileNum best8.; %DataDirWalk(&DIRNAME, MAXDEPTH=&MAXDEPTH); run; %mend;

Słowa kluczowe: sas, 4GL, makra


24 lipca 2009

Bloomberg API i płaszczyzna zmienności FX (VBA)

Z Bloomberg API po raz pierwszy zetknąłem się latem 2006 lub 2007 roku. Wtedy jeszcze nie wiedziałem, jak i gdzie mógłbym je zastosować. Przełom nastąpił w zeszłym roku spędziłem ponad tydzień ucząc się tego narzędzia i sprawdzając jego możliwości.

Korzystając z Bloomberg API należy pamiętać o przynajmniej dwóch faktach:

  • zapytania obsługiwane są w sposób synchroniczny
  • dane pobierane za pomocą Bloomberg API nie mogą opuszczać licencjonowanego stanowiska

Jako przykład zastosowania Bloomberg API stworzyłem klasę FxVolGetter, która ma służyć do pobierania kwotowań zmienności FX:

Option Explicit Option Base 0 Const IMP_VOL_TYPE = "DFLT_VOL_SURF_MID" Const QUOTE_FORMAT_FIELD = "IMP_VOL_QUOTE_FORMAT" Enum QUOTE_FORMAT QUOTE_B QUOTE_C QUOTE_P QUOTE_R End Enum Private blbObj As BLP_DATA_CTRLLib.BlpData Private blbCookies As Integer Private blbFields As String Private blbOverFields As String Private blbOverValues As Variant Private Sub Class_Initialize() Set blbObj = New BlpData blbCookies = 1 blbFields = IMP_VOL_TYPE blbOverFields = QUOTE_FORMAT_FIELD blbOverValues = Array("B", "C", "P", "R") End Sub Public Function sendRequest(blbCode As String, _ Optional quoteType As QUOTE_FORMAT = QUOTE_B) As Variant Dim tmp As Variant '' send request to Bloomberg Call blbObj.Subscribe(blbCode, _ blbCookies, _ blbFields, _ blbOverFields, _ blbOverValues(quoteType), _ tmp) '' assign the results sendRequest = tmp(0, 0) End Function

... oraz przykład jej zastosowania:

Option Explicit Option Base 0 Sub Test() Dim volGetter As FxVolGetter Dim ticker(2) As String Dim vSurf As Variant Dim reset As Variant Dim i As Integer Set volGetter = New FxVolGetter ticker(0) = "EURUSD BGN Curncy" ticker(1) = "XAUUSD BGN Curncy" ticker(2) = "EURCHF BGN Curncy" For i = 0 To UBound(ticker) '' I need to reset the result container '' before I write to it vSurf = reset vSurf = volGetter.sendRequest(ticker(i)) '' here you can play further with the '' contents of the "res" variable '' ... Next i End Sub

Słowa kluczowe: vba, bloomberg api, zmienność implikowana


15 lipca 2009

Tworzenie listy tablic -- SAS

Poniżej zamieszczam kod makra SAS, które służy tworzeniu listy tablic.

Lista tablic jest tworzona w oparciu o dopasowanie nazw biblioteki i tablicy do zadanych wzorców (wyrażenia regularne). Domyślnie makro nie pobiera jedynie nazwę wynikowego zbioru/tablicy. W takim przypadku działanie makra sprowadza się do skopiowania tablicy sashelp.vstable, która zawiera pary biblioteka x tablica. Zawężenie zbioru tablic można uzyskać podając wzorce zapisane za pomocą wyrażeń regularnych, do którego ma pasować nazwa tablicy i/lub nazwa biblioteki, w której znajduje się tablica.

Opis konstrukcji wyrażeń regularnych w SAS można znaleźć w dokumencie An Introduction to Perl Regular Expressions in SAS 9 [pdf, 489 kB].

Korzystając z zamieszczoneg niżej makra należy pamiętać o tym, że wszystkie nazwy bibliotek i tablic dostępne w widoku sashelp.vstable zapisywane są wyłącznie przy użyciu wielkich liter. Oznacza to, że fragmenty nazw zawarte w wyrażeniu regularnym powinny być również pisane wielką literą niezależnie od sposobu ich wyświetlania przez system SAS oraz zapisu w kodzie. Innym rozwiązaniem jest stworzenie wzorca, który jest niewrażliwy na wielkość liter. Wzorce takie tworzy się poprzez dodanie na końcu pojedynczej litery i (por. tekst komentarza w kodzie poniżej).

%macro ListTables(DATASET, LIBRE="/^./", TBLRE="/^./"); data &DATASET; set sashelp.vstable; if _n_ = 1 then do; LibraryPattern = prxparse(&LIBRE); TablePattern = prxparse(&TBLRE); end; retain LibraryPattern; retain TablePattern; fitsLibraryPattern = prxmatch(LibraryPattern, strip(Libname)); fitsTablePattern = prxmatch(TablePattern, strip(Memname)); if fitsLibraryPattern and fitsTablePattern; keep libname memname ; run; %mend;

Słowa kluczowe: sas, 4GL, makra, regexp, wyrażenia regularne


08 lipca 2009

Tworzenie katalogu -- SAS

Poniżej zamieszczam kod makra SAS, które służy tworzeniu katalogów.

/* ==== CREATEDIR(DIRNAME) Tworzy katalog DIRNAME np. %CreateDir("C:\katalog"); ==== */ %macro CreateDir(DIR_NAME); options noxwait; %let DIR_NAME = %sysfunc(compress(&DIR_NAME, '"')); %put "&DIR_NAME"; data _null_; d_name = '"' || "&DIR_NAME" || '"'; rc = filename('f_ref', d_name); if not fexist('f_ref') then call system('md ' || d_name); run; %mend;

Słowa kluczowe: sas, 4GL, makra