-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfom.cpp
75 lines (63 loc) · 1.91 KB
/
fom.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "fom.hpp"
#include <iostream>
#include <iomanip>
#include <utility>
#include <cmath>
namespace {
const double a = sqrt(M_PI / 8);
const double b = 1 / sqrt(2 * M_PI);
double phi(double x)
{
return b * exp(-x * x * .5);
}
double abcdf(double x)
{
const double y = .5 + .5 * sqrt(1 - exp(-x * x * a));
return x > 0 ? y : 1 - y;
}
double yt(long d, long e) {
return d >= e ? 0 : (e - d) / days_of_year;
}
bool xdom(double tt, double iv, double k)
{
return tt <= 0 or iv <= 0 or k <= 0;
}
std::pair<double, double> z(double tt, double iv, double s, double k) {
const double v = sqrt(tt) * iv;
const double r = (.5 * tt * iv * iv + log(s / k)) / v;
return { r, r - v };
}
}
long round_cents(double price) { return lrint(price * 100); }
PriceDelta Contract::at(MarketPoint m)
{
switch (contract_type) {
case ContractType::CALL:
if (m.price <= 0)
return { 0, 0 };
{
double tt = yt(m.day, expiration);
if (xdom(tt, m.iv, strike)) {
if (m.price <= strike) return { 0, 0 };
else return { m.price - strike, 1 };
}
auto [ d1, d2 ] = z(tt, m.iv, m.price, strike);
double delta = abcdf(d1) * quantity;
double kd = abcdf(d2) * quantity;
return { m.price * delta - strike * kd, delta };
}
case ContractType::PUT:
break;
}
if (m.price <= 0)
return { strike - m.price, 1 };
double tt = yt(m.day, expiration);
if (xdom(tt, m.iv, strike)) {
if (strike <= m.price) return { 0, 0 };
else return { strike - m.price, -1 };
}
auto [ d1, d2 ] = z(tt, m.iv, m.price, strike);
double delta = abcdf(-d1) * quantity;
double kd = abcdf(-d2) * quantity;
return { strike * kd - m.price * delta, -delta };
}