11 grudnia 2009

Wyświetlanie formuł w komentarzach -- dodatek xla

Dzisiaj uczestniczyłem w szkoleniu noszącym tytuł Techniki numeryczne w wycenie opcji finansowych organizowanym przez CEETA. W trakcie szkolenia zauważyłem, że prowadzący posługuje się makrem przypisanym do skrótu klawiszowego, które wyświetla w komentarzach tekst formuł wpisanych w komórkach. Dzięki temu rozwiązaniu można w łatwy sposób przedstawiać, wyróżniać formuły stosowane w arkuszu.

Pomysł ten spodobał mi się na tyle, że postanowiłem zaimplementować go w postaci dodatku xla.

Słowa kluczowe: excel, makra, vba, addin


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:

Nazwa 'g++' nie jest rozpoznawana jako polecenie wewnętrzne lub
zewnętrzne, program wykonywalny lub plik wsadowy.

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


19 października 2009

Kopiowanie zakresu -- Excel VBA

Poniżej krótka procedura rozwiązująca odwieczny problem kopiowania zakresów w arkuszach Excela. Pierwszy argument procedury (CopiedRange) to, zgodnie z nazwą, kopiowany zakres, a drugi (RangeTo) to zakres docelowy. Zakres docelowy powinien być pojedyńczą komórką wskazującą lewy górny róg miejsca, w którym ma się znaleźć kopiowany zakres.

Sub CopyRange(CopiedRange As Range, RangeTo As Range) Dim nColumns As Long Dim nRows As Long With CopiedRange nColumns = .Columns.Count nRows = .Rows.Count End With With RangeTo Debug.Assert .Columns.Count * .Rows.Count = 1 Set RangeTo = Range(.Offset(0, 0), _ .Offset(nRows - 1, nColumns - 1)) End With RangeTo = CopiedRange.Value End Sub

Słowa kluczowe: excel, vba, makra


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
  • w liście referencji należy dodać bibliotekę Bloomberg Data Type Library
Bloomberg Data Type Library

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