proof-of-portfolio 0.0.93__py3-none-any.whl → 0.0.95__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- proof_of_portfolio/_version.py +1 -1
- proof_of_portfolio/circuits/components/src/core/calmar.nr +23 -10
- proof_of_portfolio/circuits/components/src/core/omega.nr +43 -31
- proof_of_portfolio/circuits/components/src/utils/ann_excess_return.nr +8 -7
- proof_of_portfolio/circuits/components/src/utils/risk_normalization.nr +7 -9
- proof_of_portfolio/circuits/components/src/utils/weighting_distribution.nr +12 -7
- proof_of_portfolio/circuits/src/main.nr +18 -29
- proof_of_portfolio/circuits/target/circuits.json +1 -1
- proof_of_portfolio/circuits/vk/vk +0 -0
- proof_of_portfolio/proof_generator.py +41 -5
- {proof_of_portfolio-0.0.93.dist-info → proof_of_portfolio-0.0.95.dist-info}/METADATA +1 -1
- {proof_of_portfolio-0.0.93.dist-info → proof_of_portfolio-0.0.95.dist-info}/RECORD +15 -15
- {proof_of_portfolio-0.0.93.dist-info → proof_of_portfolio-0.0.95.dist-info}/WHEEL +0 -0
- {proof_of_portfolio-0.0.93.dist-info → proof_of_portfolio-0.0.95.dist-info}/entry_points.txt +0 -0
- {proof_of_portfolio-0.0.93.dist-info → proof_of_portfolio-0.0.95.dist-info}/top_level.txt +0 -0
proof_of_portfolio/_version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# This file is auto-generated during build
|
2
|
-
__version__ = "0.0.
|
2
|
+
__version__ = "0.0.95"
|
@@ -1,7 +1,6 @@
|
|
1
1
|
use crate::utils::{
|
2
|
-
ann_excess_return::ann_excess_return,
|
3
2
|
constants::{
|
4
|
-
ARRAY_SIZE, CALMAR_NOCONFIDENCE_VALUE,
|
3
|
+
ARRAY_SIZE, CALMAR_NOCONFIDENCE_VALUE, RATIO_SCALE_FACTOR, SCALE,
|
5
4
|
STATISTICAL_CONFIDENCE_MINIMUM_N,
|
6
5
|
},
|
7
6
|
risk_normalization::risk_normalization,
|
@@ -11,31 +10,33 @@ use super::drawdown::daily_max_drawdown;
|
|
11
10
|
pub fn calmar(
|
12
11
|
log_returns: [i64; ARRAY_SIZE],
|
13
12
|
actual_len: u32,
|
14
|
-
|
13
|
+
annual_risk_free: i64,
|
15
14
|
weights: [i64; ARRAY_SIZE],
|
16
15
|
use_weighting: bool,
|
17
16
|
bypass_confidence: bool,
|
18
17
|
avg_daily_return: i64,
|
19
18
|
variance_val: i64,
|
20
19
|
ann_excess_return_val: i64,
|
20
|
+
calmar_cap: i64,
|
21
|
+
days_in_year: i64,
|
22
|
+
drawdown_max_percent: i64,
|
21
23
|
) -> i64 {
|
22
24
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
23
25
|
CALMAR_NOCONFIDENCE_VALUE
|
24
26
|
} else {
|
25
|
-
let base_return_percentage = (avg_daily_return *
|
27
|
+
let base_return_percentage = (avg_daily_return * days_in_year * 100) / SCALE;
|
26
28
|
let max_drawdown_decimal = daily_max_drawdown(log_returns, actual_len);
|
27
|
-
let drawdown_normalization_factor =
|
29
|
+
let drawdown_normalization_factor =
|
30
|
+
risk_normalization(max_drawdown_decimal, drawdown_max_percent);
|
28
31
|
|
29
32
|
if drawdown_normalization_factor == 0 {
|
30
33
|
0
|
31
34
|
} else {
|
32
|
-
let raw_calmar =
|
33
|
-
* RATIO_SCALE_FACTOR;
|
34
|
-
let calmar_cap = 10 * RATIO_SCALE_FACTOR;
|
35
|
+
let raw_calmar = base_return_percentage * drawdown_normalization_factor;
|
35
36
|
if raw_calmar > calmar_cap {
|
36
|
-
calmar_cap
|
37
|
+
calmar_cap * RATIO_SCALE_FACTOR
|
37
38
|
} else {
|
38
|
-
raw_calmar
|
39
|
+
raw_calmar * RATIO_SCALE_FACTOR
|
39
40
|
}
|
40
41
|
}
|
41
42
|
}
|
@@ -67,6 +68,9 @@ fn test_calmar_normal_case() {
|
|
67
68
|
avg,
|
68
69
|
variance_val,
|
69
70
|
ann_excess,
|
71
|
+
1,
|
72
|
+
365,
|
73
|
+
10,
|
70
74
|
);
|
71
75
|
assert(result != 0);
|
72
76
|
}
|
@@ -91,6 +95,9 @@ fn test_calmar_insufficient_data() {
|
|
91
95
|
avg,
|
92
96
|
variance_val,
|
93
97
|
ann_excess,
|
98
|
+
1,
|
99
|
+
365,
|
100
|
+
10,
|
94
101
|
);
|
95
102
|
assert(result == 0);
|
96
103
|
}
|
@@ -116,6 +123,9 @@ fn test_calmar_exactly_30_days() {
|
|
116
123
|
avg,
|
117
124
|
variance_val,
|
118
125
|
ann_excess,
|
126
|
+
1,
|
127
|
+
365,
|
128
|
+
10,
|
119
129
|
);
|
120
130
|
assert(result != 0);
|
121
131
|
}
|
@@ -141,6 +151,9 @@ fn test_calmar_negative_returns() {
|
|
141
151
|
avg,
|
142
152
|
variance_val,
|
143
153
|
ann_excess,
|
154
|
+
1,
|
155
|
+
365,
|
156
|
+
10,
|
144
157
|
);
|
145
158
|
assert(result != 0);
|
146
159
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
use crate::utils::constants::{
|
2
|
-
ARRAY_SIZE,
|
3
|
-
OMEGA_SCALE_FACTOR, RATIO_SCALE_FACTOR, STATISTICAL_CONFIDENCE_MINIMUM_N,
|
2
|
+
ARRAY_SIZE, OMEGA_NOCONFIDENCE_VALUE, RATIO_SCALE_FACTOR, STATISTICAL_CONFIDENCE_MINIMUM_N,
|
4
3
|
};
|
5
4
|
|
6
5
|
pub fn omega(
|
@@ -9,6 +8,7 @@ pub fn omega(
|
|
9
8
|
weights: [i64; ARRAY_SIZE],
|
10
9
|
use_weighting: bool,
|
11
10
|
bypass_confidence: bool,
|
11
|
+
omega_loss_min: i64,
|
12
12
|
) -> i64 {
|
13
13
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
14
14
|
OMEGA_NOCONFIDENCE_VALUE
|
@@ -33,46 +33,58 @@ pub fn omega(
|
|
33
33
|
}
|
34
34
|
}
|
35
35
|
|
36
|
-
if sum_weights_positive
|
37
|
-
|
38
|
-
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
let positive_sum = (positive_sum_u128 / 1000000) as i64;
|
47
|
-
let negative_sum = (negative_sum_u128 / 1000000) as i64;
|
36
|
+
let mean_pos = if sum_weights_positive != 0 {
|
37
|
+
product_sum_positive / sum_weights_positive
|
38
|
+
} else {
|
39
|
+
0
|
40
|
+
};
|
41
|
+
let mean_neg = if sum_weights_negative != 0 {
|
42
|
+
(-product_sum_negative) / sum_weights_negative
|
43
|
+
} else {
|
44
|
+
0
|
45
|
+
};
|
48
46
|
|
49
|
-
let effective_denominator = if
|
50
|
-
|
47
|
+
let effective_denominator = if mean_neg >= omega_loss_min {
|
48
|
+
mean_neg
|
51
49
|
} else {
|
52
|
-
|
50
|
+
omega_loss_min
|
53
51
|
};
|
54
|
-
|
55
|
-
final_calc as i64
|
52
|
+
(mean_pos * RATIO_SCALE_FACTOR) / effective_denominator
|
56
53
|
} else {
|
57
|
-
let mut positive_sum:
|
58
|
-
let mut negative_sum:
|
54
|
+
let mut positive_sum: i64 = 0;
|
55
|
+
let mut negative_sum: i64 = 0;
|
56
|
+
let mut count_pos: u32 = 0;
|
57
|
+
let mut count_neg: u32 = 0;
|
59
58
|
|
60
59
|
for i in 0..ARRAY_SIZE {
|
61
60
|
if (i as u32) < actual_len {
|
62
61
|
if log_returns[i] > 0 {
|
63
|
-
positive_sum
|
62
|
+
positive_sum += log_returns[i];
|
63
|
+
count_pos += 1;
|
64
64
|
} else if log_returns[i] < 0 {
|
65
|
-
negative_sum
|
65
|
+
negative_sum += (-log_returns[i]);
|
66
|
+
count_neg += 1;
|
66
67
|
}
|
67
68
|
}
|
68
69
|
}
|
69
70
|
|
70
|
-
let
|
71
|
-
|
71
|
+
let mean_pos = if count_pos > 0 {
|
72
|
+
positive_sum / (count_pos as i64)
|
73
|
+
} else {
|
74
|
+
0
|
75
|
+
};
|
76
|
+
let mean_neg = if count_neg > 0 {
|
77
|
+
negative_sum / (count_neg as i64)
|
78
|
+
} else {
|
79
|
+
0
|
80
|
+
};
|
81
|
+
|
82
|
+
let effective_denominator = if mean_neg >= omega_loss_min {
|
83
|
+
mean_neg
|
72
84
|
} else {
|
73
|
-
|
85
|
+
omega_loss_min
|
74
86
|
};
|
75
|
-
(
|
87
|
+
(mean_pos * RATIO_SCALE_FACTOR) / effective_denominator
|
76
88
|
}
|
77
89
|
}
|
78
90
|
}
|
@@ -85,7 +97,7 @@ fn test_omega_all_positive() {
|
|
85
97
|
}
|
86
98
|
|
87
99
|
let weights = [100000; ARRAY_SIZE];
|
88
|
-
let result = omega(returns, 5, weights, false, false);
|
100
|
+
let result = omega(returns, 5, weights, false, false, 10000000);
|
89
101
|
assert(result == 10000000);
|
90
102
|
}
|
91
103
|
|
@@ -97,7 +109,7 @@ fn test_omega_all_negative() {
|
|
97
109
|
}
|
98
110
|
|
99
111
|
let weights = [100000; ARRAY_SIZE];
|
100
|
-
let result = omega(returns, 5, weights, false, false);
|
112
|
+
let result = omega(returns, 5, weights, false, false, 10000000);
|
101
113
|
assert(result == 0);
|
102
114
|
}
|
103
115
|
|
@@ -110,7 +122,7 @@ fn test_omega_mixed_returns() {
|
|
110
122
|
returns[3] = -300;
|
111
123
|
|
112
124
|
let weights = [100000; ARRAY_SIZE];
|
113
|
-
let result = omega(returns, 4, weights, false, false);
|
125
|
+
let result = omega(returns, 4, weights, false, false, 10000000);
|
114
126
|
assert(result == 22500000);
|
115
127
|
}
|
116
128
|
|
@@ -122,6 +134,6 @@ fn test_omega_zero_returns() {
|
|
122
134
|
}
|
123
135
|
|
124
136
|
let weights = [100000; ARRAY_SIZE];
|
125
|
-
let result = omega(returns, 5, weights, false, false);
|
137
|
+
let result = omega(returns, 5, weights, false, false, 10000000);
|
126
138
|
assert(result == 10000000);
|
127
139
|
}
|
@@ -3,9 +3,10 @@ use crate::utils::{average::average, constants::{ARRAY_SIZE, DAYS_IN_YEAR}};
|
|
3
3
|
pub fn ann_excess_return(
|
4
4
|
log_returns: [i64; ARRAY_SIZE],
|
5
5
|
actual_len: u32,
|
6
|
-
|
6
|
+
annual_risk_free: i64,
|
7
7
|
weights: [i64; ARRAY_SIZE],
|
8
8
|
use_weighting: bool,
|
9
|
+
days_in_year: i64,
|
9
10
|
) -> i64 {
|
10
11
|
let sum_of_weights = if use_weighting {
|
11
12
|
let mut sum: i64 = 0;
|
@@ -25,8 +26,8 @@ pub fn ann_excess_return(
|
|
25
26
|
use_weighting,
|
26
27
|
sum_of_weights,
|
27
28
|
);
|
28
|
-
let annualized = avg *
|
29
|
-
annualized -
|
29
|
+
let annualized = avg * days_in_year;
|
30
|
+
annualized - annual_risk_free
|
30
31
|
}
|
31
32
|
|
32
33
|
#[test]
|
@@ -37,7 +38,7 @@ fn test_ann_excess_return_positive() {
|
|
37
38
|
returns[2] = 150;
|
38
39
|
|
39
40
|
let weights = [100000; ARRAY_SIZE];
|
40
|
-
let result = ann_excess_return(returns, 3, 10000, weights, false);
|
41
|
+
let result = ann_excess_return(returns, 3, 10000, weights, false, 365);
|
41
42
|
assert(result > 0);
|
42
43
|
}
|
43
44
|
|
@@ -49,7 +50,7 @@ fn test_ann_excess_return_negative() {
|
|
49
50
|
returns[2] = -150;
|
50
51
|
|
51
52
|
let weights = [100000; ARRAY_SIZE];
|
52
|
-
let result = ann_excess_return(returns, 3, 10000, weights, false);
|
53
|
+
let result = ann_excess_return(returns, 3, 10000, weights, false, 365);
|
53
54
|
assert(result < 0);
|
54
55
|
}
|
55
56
|
|
@@ -61,7 +62,7 @@ fn test_ann_excess_return_equal_to_risk_free() {
|
|
61
62
|
returns[2] = 100;
|
62
63
|
|
63
64
|
let weights = [100000; ARRAY_SIZE];
|
64
|
-
let result = ann_excess_return(returns, 3, 36500, weights, false);
|
65
|
+
let result = ann_excess_return(returns, 3, 36500, weights, false, 365);
|
65
66
|
assert(result == 0);
|
66
67
|
}
|
67
68
|
|
@@ -72,6 +73,6 @@ fn test_ann_excess_return_zero_risk_free() {
|
|
72
73
|
returns[1] = 200;
|
73
74
|
|
74
75
|
let weights = [100000; ARRAY_SIZE];
|
75
|
-
let result = ann_excess_return(returns, 2, 0, weights, false);
|
76
|
+
let result = ann_excess_return(returns, 2, 0, weights, false, 365);
|
76
77
|
assert(result == 54750);
|
77
78
|
}
|
@@ -1,8 +1,6 @@
|
|
1
1
|
use crate::utils::constants::SCALE;
|
2
2
|
|
3
|
-
pub fn mdd_augmentation(drawdown_decimal: i64) -> i64 {
|
4
|
-
let max_drawdown_percentage = 10;
|
5
|
-
|
3
|
+
pub fn mdd_augmentation(drawdown_decimal: i64, max_drawdown_percentage: i64) -> i64 {
|
6
4
|
if (drawdown_decimal <= 0) | (drawdown_decimal >= SCALE) {
|
7
5
|
0
|
8
6
|
} else {
|
@@ -16,27 +14,27 @@ pub fn mdd_augmentation(drawdown_decimal: i64) -> i64 {
|
|
16
14
|
}
|
17
15
|
}
|
18
16
|
|
19
|
-
pub fn risk_normalization(drawdown_decimal: i64) -> i64 {
|
20
|
-
mdd_augmentation(drawdown_decimal)
|
17
|
+
pub fn risk_normalization(drawdown_decimal: i64, max_drawdown_percentage: i64) -> i64 {
|
18
|
+
mdd_augmentation(drawdown_decimal, max_drawdown_percentage)
|
21
19
|
}
|
22
20
|
|
23
21
|
#[test]
|
24
22
|
fn test_risk_normalization_zero_drawdown() {
|
25
|
-
let result = risk_normalization(0);
|
23
|
+
let result = risk_normalization(0, 10);
|
26
24
|
assert(result == 0);
|
27
25
|
}
|
28
26
|
|
29
27
|
#[test]
|
30
28
|
fn test_risk_normalization_high_drawdown() {
|
31
29
|
let drawdown_15_percent = (15 * SCALE) / 100;
|
32
|
-
let result = risk_normalization(drawdown_15_percent);
|
30
|
+
let result = risk_normalization(drawdown_15_percent, 10);
|
33
31
|
assert(result == 0);
|
34
32
|
}
|
35
33
|
|
36
34
|
#[test]
|
37
35
|
fn test_risk_normalization_low_drawdown() {
|
38
36
|
let drawdown_2_percent = (2 * SCALE) / 100;
|
39
|
-
let result = risk_normalization(drawdown_2_percent);
|
37
|
+
let result = risk_normalization(drawdown_2_percent, 10);
|
40
38
|
let expected = SCALE / 2;
|
41
39
|
assert(result == expected);
|
42
40
|
}
|
@@ -44,6 +42,6 @@ fn test_risk_normalization_low_drawdown() {
|
|
44
42
|
#[test]
|
45
43
|
fn test_risk_normalization_max_threshold() {
|
46
44
|
let drawdown_10_percent = (10 * SCALE) / 100;
|
47
|
-
let result = risk_normalization(drawdown_10_percent);
|
45
|
+
let result = risk_normalization(drawdown_10_percent, 10);
|
48
46
|
assert(result == 0);
|
49
47
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
use crate::utils::constants::ARRAY_SIZE;
|
1
|
+
use crate::utils::constants::{ARRAY_SIZE, SCALE};
|
2
2
|
|
3
3
|
fn exp_decay_scaled(neg_x_scaled: i64) -> i64 {
|
4
4
|
let scale: i64 = 100000;
|
@@ -17,18 +17,23 @@ fn exp_decay_scaled(neg_x_scaled: i64) -> i64 {
|
|
17
17
|
}
|
18
18
|
}
|
19
19
|
|
20
|
-
pub fn weighting_distribution(
|
20
|
+
pub fn weighting_distribution(
|
21
|
+
actual_len: u32,
|
22
|
+
weighted_decay_max: i64,
|
23
|
+
weighted_decay_min: i64,
|
24
|
+
weighted_decay_rate: i64,
|
25
|
+
) -> [i64; ARRAY_SIZE] {
|
21
26
|
let mut weights = [0; ARRAY_SIZE];
|
22
|
-
let max_weight
|
23
|
-
let min_weight
|
24
|
-
let decay_rate
|
27
|
+
let max_weight = weighted_decay_max;
|
28
|
+
let min_weight = weighted_decay_min;
|
29
|
+
let decay_rate = weighted_decay_rate;
|
25
30
|
let weight_range = max_weight - min_weight;
|
26
|
-
let scale
|
31
|
+
let scale = SCALE;
|
27
32
|
|
28
33
|
for i in 0..ARRAY_SIZE {
|
29
34
|
if (i as u32) < actual_len {
|
30
35
|
let position_from_newest = (actual_len - 1) - (i as u32);
|
31
|
-
let neg_x_scaled = -(decay_rate * (position_from_newest as i64))
|
36
|
+
let neg_x_scaled = -(decay_rate * (position_from_newest as i64));
|
32
37
|
let exp_val_scaled = exp_decay_scaled(neg_x_scaled);
|
33
38
|
|
34
39
|
let weighted_val = (weight_range * exp_val_scaled) / scale;
|
@@ -8,24 +8,28 @@ use components::core::merkle::{
|
|
8
8
|
use components::utils::{
|
9
9
|
ann_excess_return::ann_excess_return,
|
10
10
|
average::average,
|
11
|
-
constants::{ARRAY_SIZE, MAX_DAYS, MAX_RETURNS, MAX_SIGNALS, MERKLE_DEPTH
|
11
|
+
constants::{ARRAY_SIZE, MAX_DAYS, MAX_RETURNS, MAX_SIGNALS, MERKLE_DEPTH},
|
12
12
|
variance::variance,
|
13
|
-
weighting_distribution::weighting_distribution,
|
14
13
|
};
|
15
14
|
|
16
15
|
fn main(
|
17
16
|
log_returns: [i64; MAX_DAYS],
|
18
17
|
n_returns: u32,
|
18
|
+
daily_pnl: [i64; ARRAY_SIZE],
|
19
|
+
n_pnl: u32,
|
19
20
|
signals: [TradingSignal; MAX_SIGNALS],
|
20
21
|
signals_count: u32,
|
21
22
|
path_elements: [[Field; MERKLE_DEPTH]; MAX_SIGNALS],
|
22
23
|
path_indices: [[Field; MERKLE_DEPTH]; MAX_SIGNALS],
|
23
24
|
signals_merkle_root: pub Field,
|
24
|
-
risk_free_rate: pub i64,
|
25
25
|
use_weighting: bool,
|
26
26
|
bypass_confidence: pub bool,
|
27
|
-
account_size: i64,
|
28
27
|
weights: [i64; ARRAY_SIZE],
|
28
|
+
calmar_cap: i64,
|
29
|
+
days_in_year: i64,
|
30
|
+
omega_loss_min: i64,
|
31
|
+
annual_risk_free: i64,
|
32
|
+
drawdown_max_percent: i64,
|
29
33
|
) -> pub [Field; 9] {
|
30
34
|
// Verify all trading signals are included in the merkle tree
|
31
35
|
let mut all_verified = true;
|
@@ -92,37 +96,18 @@ fn main(
|
|
92
96
|
let ann_excess_return_val = ann_excess_return(
|
93
97
|
returns_array,
|
94
98
|
n_returns,
|
95
|
-
|
99
|
+
annual_risk_free,
|
96
100
|
weights,
|
97
101
|
use_weighting,
|
102
|
+
days_in_year,
|
98
103
|
);
|
99
104
|
|
100
|
-
let
|
101
|
-
for i in 0..MAX_DAYS {
|
102
|
-
if (i as u32) < n_returns {
|
103
|
-
let log_return = returns_array[i];
|
104
|
-
let x_squared = (log_return * log_return) / SCALE;
|
105
|
-
let x_cubed = (x_squared * log_return) / SCALE;
|
106
|
-
let x_fourth = (x_cubed * log_return) / SCALE;
|
107
|
-
let x_fifth = (x_fourth * log_return) / SCALE;
|
108
|
-
let exp_minus_one =
|
109
|
-
log_return + (x_squared / 2) + (x_cubed / 6) + (x_fourth / 24) + (x_fifth / 120);
|
110
|
-
daily_pnl_array[i] = (exp_minus_one * account_size) / SCALE;
|
111
|
-
}
|
112
|
-
}
|
113
|
-
|
114
|
-
let avg_daily_pnl = average(
|
115
|
-
daily_pnl_array,
|
116
|
-
n_returns,
|
117
|
-
weights,
|
118
|
-
use_weighting,
|
119
|
-
sum_of_weights,
|
120
|
-
);
|
105
|
+
let avg_daily_pnl = average(daily_pnl, n_pnl, weights, use_weighting, sum_of_weights);
|
121
106
|
|
122
107
|
let sharpe_ratio = sharpe(
|
123
108
|
returns_array,
|
124
109
|
n_returns,
|
125
|
-
|
110
|
+
annual_risk_free,
|
126
111
|
weights,
|
127
112
|
use_weighting,
|
128
113
|
bypass_confidence,
|
@@ -134,13 +119,16 @@ fn main(
|
|
134
119
|
let calmar_ratio = calmar(
|
135
120
|
returns_array,
|
136
121
|
n_returns,
|
137
|
-
|
122
|
+
annual_risk_free,
|
138
123
|
weights,
|
139
124
|
use_weighting,
|
140
125
|
bypass_confidence,
|
141
126
|
avg_daily_return,
|
142
127
|
variance_val,
|
143
128
|
ann_excess_return_val,
|
129
|
+
calmar_cap,
|
130
|
+
days_in_year,
|
131
|
+
drawdown_max_percent,
|
144
132
|
);
|
145
133
|
let omega_ratio = omega(
|
146
134
|
returns_array,
|
@@ -148,11 +136,12 @@ fn main(
|
|
148
136
|
weights,
|
149
137
|
use_weighting,
|
150
138
|
bypass_confidence,
|
139
|
+
omega_loss_min,
|
151
140
|
);
|
152
141
|
let sortino_ratio = sortino(
|
153
142
|
returns_array,
|
154
143
|
n_returns,
|
155
|
-
|
144
|
+
annual_risk_free,
|
156
145
|
weights,
|
157
146
|
use_weighting,
|
158
147
|
bypass_confidence,
|