math learning curve in FX business

In FX business (not saying “system”) , most of the initial learning obstacles are math-related. A large part of it is due to the need to forecast fx rates. “Hedge” and “risk” are all about uncertainty in FX rate movements.

To avoid confusion, in this blog we don’t really talk about FX Futures contracts at all. “Future” doesn’t mean “Futures contract”.

If you as an enterprise just needs to convert currency at the spot rate, it’s straightforward. But any solution to future-proof your corporate FX needs tends to involve derivatives tied to future FX rates. Incidentally, every derivative (forwards, options, swaps ..) has an expiration date.

Whenever you consider future FX rates, the 2 countries’ interest rates come into play. I feel the Interest-Rate-Parity formula is quite basic and unavoidable, just like PCP and price/yield conversion. Other obstacles include
– Cross rate calc
– triangular arbitrage


sybase triggers to print debug msg

(“debug msg” to show what’s going on. )

Looks like a jdbc insert might fail due to the debug msg. EVEN if u can keep your debug msg and keep jdbc happy, there would still be a lingering doubt — debug msg is not perfectly compatible with java …. In view of the cost of production support, to play safe in a large, fast-paced environment,

Suggestion: enable debug msg during trigger development only, unless you are very sure how to make the debug msg compatible.

This affects sybase, and may affect mssql.

Perl: defensible turf but y@@

Reason: in every team including GS, no one has a deeper or more complete experience than mine.

reason: i explored way beyond everyday language features. if i walk into a perl shop, most of the features used i already know.

Lesson: “3 years on a … job” seems to prove qualification for similar jobs, but nonono, because those x years could be very limited.

Look at C. i used it in Chartered Semi but almost no pointers, no memory management, no threading, no system programming… For java i actually used a lot of things, but there are many more experienced guys.

A lot of 5-year java developers are completely unprepared against threading challenges.

Which area can I target as my next?

* threading?
* MOM?
* SQL + relational design?

some pro^con of triggers

+ if 2 programs need to CUD but can’t share the DAO.
Example: 2 java programs running on 2 machines. U may have to copy the jar to share code.
Example: sometimes u may even use command line to CUD

+ to achieve the same data quality level, those same SQL must be run anyway, in trigger or in app


– perf. extra load on the bottleneck — DB server
– migrating to another DB vendor

assignment overloading && other op overloading

Notice many overloaded operators return a value to be used as RHS of assignment. It’s good to become thoroughly familiar with this interaction — [ op= and overloaded operators ]

When you assign returned value of any (pbclone/pbref) function, you get op= . op= simply reads the RHS, and doesn’t care if the func is pbclone or pbref.

financial jargon: financing ie capital formation

“in response to a $-seeker, finding $-providers and getting the $ to the receiver.” The return side of the transaction is perhaps(?) supported by other teams

financing means
– getting $ for party A
– getting $ from party B
(Party A is always a client to me. Party B usually is a client too.)

Financing is always(?) a kind of broker job between $-seekers and $–providers. Our firm (the financing team) earns fees from them.

Financing usually involves
– debt, lending.
– equity

“financing a position” means? I think it means finding fund so Party A can take a particular position.

A “financing solution” is a clever deal.

“financing services”

“financing professionals”. Often a person working in the financing business focuses on that business.

protected virtual dtor #tricky

[[boost]] P 24 explains the technique of protected virtual destructor. Here’s my take —

The superclass A destructor is called by B’s destructor. See Remember you first clean up the outermost layer of the onion, and remember the B fields exist on the outer layer, outside A’s real estate.

Now, if someone gets hold of an A pointer, where the pointee is B, she can’t call delete on the pointer. Compile time (not run time) error. The special dtor is a protection.

class Base{
  protected: virtual ~Base(){cout <<"base dtor" <<endl;}
class Derived : public Base {
  public: virtual ~Derived(){cout <<"derived dtor" <<endl;}
int main(){
  Base * p1 = new Derived;
  Derived * p2 = new Derived;
  delete p1; //won't compile
  delete p2; // ok

If I swap the 2 words public and protected then I can delete Base ptr but not Derived ptr (compiler error)!

So it seems declared type must have a public dtor. In our examples, even though object is Derived, delete is allowed only on the ptr whose declared type has a public dtor.

Now, What if i have a private dtor? Probably less common, but it’s possible to invoke this private virtual dtor —

class Base{
  public:virtual ~Base(){cout <<"base dtor" <<endl;}
class Derived : public Base {
  private: virtual ~Derived(){cout <<"derived dtor" <<endl;}
int main(){
  Base * p1 = new Derived;
  delete p1; // ok private destructor called!

In my experiments, qq(new) is mandatory as a stackVar or this class will trigger a compiler error, because compiler can’t destroy the object automatically.

operator-overload return type — some examples

Summary — return type MUST be void in some cases, MUST be some specific type in some other cases, and can be up-to-you in other cases.

C++FAQ P297 points out that

A) overloaded operator often returns by reference to provide L-value semantics. Look at subscript operator and de-reference (the asterisk) a.k.a “unwrap” operators

B) In contrast, op-overload-converter (OOC) must have no return type since that’s redundant and confusing. Examples —

MyClass::operator const char*() const {…} // notice the double const. See full source code of String in [[nittyGrittyC++]]

operator string(); // P203 [[stl tutorial]]. You can also put your own class in there, like

operator myType();

—————– in contrast,
operator ()(){…} // can return bool or anything you like
operator= needs return type which is usually qq(return *this) by reference
operator+ must have return type since the result of addition or concat must be returned.

static_cast from nonref to ptr — idioms

MyClass e;

char* ptr2char = static_cast(e); // explicit

char* ptr2char2 = e; // implicit

char* ptr2char3 = (char*) e; //C-style explicit. After the bloomberg interview, I guess it’s legal but i would never do it

These mean the same. All invoke the qq/operator char*()/ ie the converter method in MyClass.

Q: How about a cvctor (convertor ctor)?
A: char* isn’t a class so can’t have a cvtor !!

assigning^constructing a c++obj: a few diff

Assignment operator is a field-by-field and bitwise overwrite [1] without eating up new memory. Both LHS and RHS must be (preexisting) objects with addresses.

A constructor always eats up (heap or stack) new memory, and reduces free memory.

[1] If a field is a pointer, then the same address is put into the LHS’s field bitwise. LHS and RHS both point to the same address — shallow copy.

Q: what if a field is a reference?
A: Can’t reassign. Default op= will trigger an error (compile time or runtime).
A: reference field is rare.

clear a python list: slice-delete vs create empty list

— based on

data = []
temp = []
for x in range(2) :
    # temp list populated from a file
    #### now we need to empty temp
    temp = []  # reseating, may need “global”
    # del temp[:]  # bug

Look at the last line. What’s going on? Well, temp=[] would Instantiate a new list object, disconnected to the lists already saved as data[0]. Java{temp=new List(); }. (C++ would treat it as assignment but here treated as rebinding). Variable “temp” rebinds to the new object. The reference count on the original list object drops to 1 since only data[0] points to it

But del temp[:] is different. This is same as java{ temp.del(…); } or temp.empty_myself_set_length_to_zero() i.e. _edit_in_place_. Variable “temp” remains bound to the same object as before. Therefore, the list already saved in data[0] is now emptied! Both data[0] and temp are nicknames for the same list object, whose reference count remains 2. Alternatively,

temp[:] = [] # same as del but more versatile — “overwrite_entire_list
java{ temp.replace(range_start ,range_end , new_content); }

virtual — only 1 of the big 3 please

In practice, people seldom virtualize these by mistake, but i feel it’s good to know why.

ctr (incl copier) are never virtual– object is incomplete during construction.

assignment can be (uselessly) marked virtual but won’t work as virtual. Virtual is strict on params. All overrides must specify identical params as the “root” version [1].

There’s always a (default or custom) op= with a param “const HostClass&”, so this func signature is as unique as a fingerprint — Will never match the root version.

Among the big 3, only dtor should be virtual.

[1] both c++ and java. [[annotated ref manual]] explains why.

c++ nested class has NO ptr to enclosing-class object

See also the post in the recrec blog that’s dedicated to the same topic.

Q: Does a non-static nested class have an implicit pointer to the enclosing-class object [1]?

Specifically, say Class O defines a non-static nested class N, and has a non-static field n1 of type N. Given an object o2 of type O, in java, n1 has an implicit pointer to the o2 object. Not in C++. See P790 [[c++ primer]] and P187 ARM.

[1] and can access the non-static fields and methods of the enclosing object?

Q: what’s the difference between static vs non-static nested class in c++?

half-open interval — From^To

The common milestone design attaches 2 non-nullable datetime columns F (fromDate) and T (toDate) to each row. “My” F is always identical to my predecessor’s T, and my T is identical to my sucessor’s F.

[2] In otherwords, the entire timespan (till 9999/12/31) is fully covered, with overlaps on the joint instants.

Fruit of the labor is — given any instant, there’s always 1 and only 1 matching row. Standard query is getDate() >= From and getDate() < To. Therefore known as half-open interval — closed on F, open on T.

What if F and T are date types not datetime? Statement [2] still holds, with each joint-instant at a day’s first moment.

##destructor is event-driven — what events?

Destructor fires when…

* AFTER subclass destructor [ISA]
* stackVar going out of scope (automatically destroyed — A U T O variable
** special case — exceptional stack unwinding
* delete
** special case — cascading delete — Host object destructor [HASA]

Now, in the ISA situation all destructors should be virtual, so how does the parent destructor fire? Boris told me child destructor doesn’t need explicit call to parent destructor. System guarantees all destructor fire from descendants to ancestors.

python operator are wrapper over method

Java/c# operators are the basis of (and faster than) methods, but Python turns the stack upside down — some of the most common, workhorse operators are based on special methods —

dot —- __getattr__()
[key] i.e. key access —- __getitem__()
for-loop —- depends on more than one special method
the plus sign (“+”) —— __add__()
assignment? See other post

In terms of run-time performance, these efficient-looking operators are just as slow as a method call.

Q: I guess in python even the basic “+” cannot be a plain vanilla addition for simple types like integer. Why?

%%A: the basic addition operator should/ought-to change object state, like editing a spreadsheet cell in-place, but python integer addition creates a new Integer object. Therefore, I guess the Integer class must customize __add__() method

%%A: variable of a java primitive int type, c# simple int type or c++ nonref int type (not a ptr or reference) can have the basic addition operator, but python has no nonref type variable. All python int variables are pointers to Integer instances.

heap allocation +! malloc()

Someone speculated that “in any programming language, heap memory is allocated always using the C function malloc(). There’s no alternative.” Nigel disagrees. If a language is not based on C, then it can use its own heap-library.

The heap-mgmt library is a wholesaler/retailer. For efficiency heap-library requests large blocks [1] of memory and gives out small chunks to the application. Probably many languages have a heap-mgmt library. C’s heap library (in glibc) uses malloc(). Nigel felt C# has its own heap-mgmt library and may have a malloc-equivalent. JVM is written in C but it could re-implement the heap-mgmt library with its own malloc-equivalent.

Everyone must file tax returns with the same government, but through different tax consultants. Tax consultants are not part of the government. Similarly, Heap-mgmt library is one level above system calls. It makes system calls (perhaps brk()/sbrk()) to request the large blocks from OS. Every language must use system calls to request memory but possibly using its own heap-mgmt library.

bash – test a command is available

Based on [[ teach yourself shell programming ]]
Background — i was looking for a 1)reliable and 2) efficient solution.

type yourCmd > /dev/null 2>&1
echo $? #### should always echo a zero (ok) or non-zero (nok)

type cd > /dev/null 2>&1 && echo ok
type cdddd > /dev/null 2>&1 || echo nok

These were tested personally but some readers (see comment below) reported they don’t always work.

overriding vs field hiding in java and c++

[[Java precisely]] P40 summarizes

· In a non-static field access o.f, the field referred to is determined by the compile-time type of the object expression o
· In a non-static call to a non-private method o.m(), the method called is determined by the run-time class of the target object: the object to which o evaluates to

Say extends,

Q: if you only have an object o=new C(), how can you access f and m() declared in
A: With the exception below, you can’t access B::m(). The method call o.m() resolves at run time and always binds to C::m(). However, f is a different story. You can cast o to B and o.f would refer to B::f

A special context — super.f and super.m() do give you access to parent’s members, but you can only use this syntax in C’s constructors or non-static methods, essentially in source code.

I wonder what C++ does.. Here are some tidbits.

o.B::m() actually let’s you call parent’s m() via a subclass object. Also see Item 50 in [[eff c++]]

bcp fragility imt INSERT #possibly

Created date default convert(date,getDate()) not null

Such a column is OK with insert, but to satisfy/pacify bcp, you must change datatype to datetime:

Created datetime default convert(date,getDate()) not null

No official explanation. Here’s my hypothesis. bcp, trying to be the fastest, bypasses triggers. And conversions too, perhaps. The explicit convert() is NOT ignored during table creation.

bcp IN

Q: what if a column is an identity?
A: -N

Q: what if i want to insert a null into Col2?
a: put nothing between the filed terminators

Q: what if i want my triggers to enforce data integrity?
A: bcp, to enable its maximum speed for loading data, does not fire rules and triggers.;pt=1806/*#X describes some solution.

Q: what if i want to use the default column value for Col3?
A: see;pt=1806/*#X
A: i couldn’t get it to work. My biggest concern with bcp in-mode is, no usable error message (no error file found) to help debug =} give up on bcp for now. No time

office protocol – don’t just imitate a colleague

For a guy like me, lacking “commonsense” in communication protocols, the obvious advice below isn’t obvious — it’s basic — Don’t imitate a role model blindly.

A role model with 4+ years spent in the current company can freely mention (generally, without reference to any individual) changing job, but if you are less than a year old here, it’s a taboo topic, like the name of the reining Chinese emperor (in ancient times).

Even if in a group every colleague seems to freely talk about this sensitive topic, I would say safety-first — a new employee should avoid the risk unless she doesn’t care about negative consequences.

Someone well-established in the office can openly criticize the company. She can compare the current company with competing companies, and few would question her loyalty. She can suggest many “improvements” but if I were to do the same, many would take it as lecturing and GS-superiority.
Americans like joking. Some may make jokes of a colleague’s weight or marriage and it may seem to be an OK joke, but can I do the same? Absolutely not unless that person is my best friend.

As a consultant, I was told to dress in long sleeve shirts everyday. Then I saw some employees dress in T-shirts. Should I follow? If I do, some may feel I’m not showing enough respect. I should not over-dress either, coming in business suits everyday. I guess I should imitate other consultants.

when (not) to use "my" in perl

A practical issue — everyday decision
An important issue — affecting maintenance, error-prone (?)
We would like simple if-then, Do/Don’t guidelines.

— Common choices for variables —
Choice: top-my ie top-level lexical . outside any subroutine.
Choice: sub-my ie subroutine-level lexical.
Choice: main-my ie lexicals in main() subroutine, which (if present) is the highest-level subroutine in a typical script.

Ground rule in large companies: use strict ‘vars’. No need to explain why.
guideline: short-scope scratchpad vars -> sub-my

Q: Problem with top-my?
A: No big problem. Minor problem — No warning if the variable name is in use.

Design: collect most variables as top-my

If a $startDate needs to be passed among subroutines, i feel top-my is ok.

sybase date/time data types

(Based on some online resource) Use datetime, smalldatetime, date, and time to store absolute date and time information. Use timestamp to store binary-type information.

In versions earlier than 12.5.1, only datetime and smalldatetime were available. As of version 12.5.1, date and time are these separate datatypes:

– date
– time
– smalldatetime
– datetime

* [8] datetime columns hold dates between January 1, 1753 and December 31, 9999. datetime values are accurate to 1/300 second on platforms that support this level of granularity. Storage size is 8 bytes: 4 bytes for the number of days since the base date of January 1, 1900 and 4 bytes for the time of day.

* [4] smalldatetime columns hold dates from January 1, 1900 to June 6, 2079, with accuracy to the minute. Its storage size is 4 bytes: 2 bytes for the number of days after January 1, 1900, and 2 bytes for the number of minutes after midnight.

* [4] date columns hold dates from January 1, 0001 to December 31, 9999. Storage size is 4 bytes.

* [4] many wall street systems use int to represent dates.

* time is between 00:00:00:000 and 23:59:59:999. You can use either military time or 12AM for noon and 12PM for midnight. A time value must contain either a colon or the AM or PM signifier. AM or PM may be in either uppercase or lowercase.

When entering date and time information, always enclose the time or date in single or double quotes.

If you pass getDate() into a Date column, u lose the time portion.

Simple deadlock demo

package com.test1;

* showcasing Thread.yield(), Thread.join(), anon class
public class DeadlockSimpleDemo {
public static void main(String[] args) {
Thread thr1 = startNewThread("lockA", "lockB");
Thread thr2 = startNewThread("lockB", "lockA"); // identical string literals are the same objects
// thr1.join();
// thr2.join();

private static Thread startNewThread(final String lock1, final String lock2) {
Thread ret = new Thread() {
public void run() {
synchronized (lock1) {
System.out.println(currentThread() + lock1 + " acquired, grabbing "
+ lock2);
yield(); // needed to produce a deadlock
synchronized (lock2) {
System.out.println(currentThread() + lock1
+ " acquired, -> then acquired " + lock2);
System.out.println(currentThread() + "end of run()");
return ret;

trigger to prevent duplicate data

Background: the table may have an ID column, DateCreated, DateModified. Also the primary key is not this ID but identiy column or something else.

This trigger basically tests all the account-detail columns and detect a duplicate row. However, if you define a uniqu composite index covering all these columns, then you won’t need this trigger. But this trigger lets you
– add more complex checks
– apply specialized remedies based on context

43 if ( select count(*) from Accts m, inserted i
44 where m.ID=i.ID
45 and m.OriginationDate = i.OriginationDate
46 and m.USState = i.USState
47 and m.AcctNum = i.AcctNum
49 and m.OfficeID = i.OfficeID ) = 2 rollback trigger — duplicate row