proof-of-portfolio 0.0.110__py3-none-any.whl → 0.0.112__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/__init__.py +20 -0
- proof_of_portfolio/_version.py +1 -1
- proof_of_portfolio/circuits/components/src/core/calmar.nr +14 -12
- proof_of_portfolio/circuits/components/src/core/omega.nr +13 -11
- proof_of_portfolio/circuits/components/src/core/sharpe.nr +8 -5
- proof_of_portfolio/circuits/components/src/core/sortino.nr +10 -4
- proof_of_portfolio/circuits/components/src/core/tstat.nr +12 -9
- proof_of_portfolio/circuits/components/src/utils/constants.nr +13 -12
- proof_of_portfolio/circuits/components/src/utils/variance.nr +3 -3
- proof_of_portfolio/circuits/src/main.nr +12 -2
- proof_of_portfolio/circuits/target/circuits.json +1 -1
- proof_of_portfolio/circuits/vk/vk +0 -0
- proof_of_portfolio/proof_generator.py +15 -2
- {proof_of_portfolio-0.0.110.dist-info → proof_of_portfolio-0.0.112.dist-info}/METADATA +1 -1
- {proof_of_portfolio-0.0.110.dist-info → proof_of_portfolio-0.0.112.dist-info}/RECORD +18 -18
- {proof_of_portfolio-0.0.110.dist-info → proof_of_portfolio-0.0.112.dist-info}/WHEEL +0 -0
- {proof_of_portfolio-0.0.110.dist-info → proof_of_portfolio-0.0.112.dist-info}/entry_points.txt +0 -0
- {proof_of_portfolio-0.0.110.dist-info → proof_of_portfolio-0.0.112.dist-info}/top_level.txt +0 -0
proof_of_portfolio/__init__.py
CHANGED
@@ -73,6 +73,11 @@ def _prove_worker(
|
|
73
73
|
bypass_confidence=False,
|
74
74
|
daily_checkpoints=2,
|
75
75
|
account_size=None,
|
76
|
+
omega_noconfidence_value=0.0,
|
77
|
+
sharpe_noconfidence_value=-100,
|
78
|
+
sortino_noconfidence_value=-100,
|
79
|
+
calmar_noconfidence_value=-100,
|
80
|
+
statistical_confidence_noconfidence_value=-100,
|
76
81
|
):
|
77
82
|
"""
|
78
83
|
Worker function to run proof generation in a separate process.
|
@@ -101,6 +106,11 @@ def _prove_worker(
|
|
101
106
|
bypass_confidence=bypass_confidence,
|
102
107
|
daily_checkpoints=daily_checkpoints,
|
103
108
|
account_size=account_size,
|
109
|
+
omega_noconfidence_value=omega_noconfidence_value,
|
110
|
+
sharpe_noconfidence_value=sharpe_noconfidence_value,
|
111
|
+
sortino_noconfidence_value=sortino_noconfidence_value,
|
112
|
+
calmar_noconfidence_value=calmar_noconfidence_value,
|
113
|
+
statistical_confidence_noconfidence_value=statistical_confidence_noconfidence_value,
|
104
114
|
)
|
105
115
|
|
106
116
|
proof_results = result.get("proof_results", {})
|
@@ -194,6 +204,11 @@ def prove_sync(
|
|
194
204
|
bypass_confidence=False,
|
195
205
|
daily_checkpoints=2,
|
196
206
|
account_size=None,
|
207
|
+
omega_noconfidence_value=0.0,
|
208
|
+
sharpe_noconfidence_value=-100,
|
209
|
+
sortino_noconfidence_value=-100,
|
210
|
+
calmar_noconfidence_value=-100,
|
211
|
+
statistical_confidence_noconfidence_value=-100,
|
197
212
|
):
|
198
213
|
"""
|
199
214
|
Synchronous wrapper for the prove function for backward compatibility.
|
@@ -227,4 +242,9 @@ def prove_sync(
|
|
227
242
|
bypass_confidence=bypass_confidence,
|
228
243
|
daily_checkpoints=daily_checkpoints,
|
229
244
|
account_size=account_size,
|
245
|
+
omega_noconfidence_value=omega_noconfidence_value,
|
246
|
+
sharpe_noconfidence_value=sharpe_noconfidence_value,
|
247
|
+
sortino_noconfidence_value=sortino_noconfidence_value,
|
248
|
+
calmar_noconfidence_value=calmar_noconfidence_value,
|
249
|
+
statistical_confidence_noconfidence_value=statistical_confidence_noconfidence_value,
|
230
250
|
)
|
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.112"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
use crate::utils::constants::{
|
2
|
-
ARRAY_SIZE,
|
3
|
-
STATISTICAL_CONFIDENCE_MINIMUM_N,
|
2
|
+
ARRAY_SIZE, RATIO_SCALE_FACTOR, SCALE,
|
3
|
+
STATISTICAL_CONFIDENCE_MINIMUM_N, CALMAR_NOCONFIDENCE_VALUE,
|
4
4
|
};
|
5
5
|
use super::drawdown::daily_max_drawdown;
|
6
6
|
|
@@ -12,9 +12,10 @@ pub fn calmar(
|
|
12
12
|
calmar_cap: i64,
|
13
13
|
days_in_year: i64,
|
14
14
|
_drawdown_max_percent: i64,
|
15
|
+
noconfidence_value: i64,
|
15
16
|
) -> i64 {
|
16
17
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
17
|
-
|
18
|
+
noconfidence_value
|
18
19
|
} else {
|
19
20
|
let ann_excess_return = avg_daily_return * days_in_year;
|
20
21
|
let max_drawdown_decimal = daily_max_drawdown(log_returns, actual_len);
|
@@ -45,7 +46,7 @@ fn test_calmar_normal_case() {
|
|
45
46
|
}
|
46
47
|
|
47
48
|
let avg = 25;
|
48
|
-
let result = calmar(returns, 40, false, avg, 1, 365, 10);
|
49
|
+
let result = calmar(returns, 40, false, avg, 1, 365, 10, CALMAR_NOCONFIDENCE_VALUE);
|
49
50
|
assert(result != 0);
|
50
51
|
}
|
51
52
|
|
@@ -56,7 +57,7 @@ fn test_calmar_insufficient_data() {
|
|
56
57
|
returns[1] = -500;
|
57
58
|
|
58
59
|
let avg = 250;
|
59
|
-
let result = calmar(returns, 2, false, avg, 1, 365, 10);
|
60
|
+
let result = calmar(returns, 2, false, avg, 1, 365, 10, CALMAR_NOCONFIDENCE_VALUE);
|
60
61
|
assert(result == CALMAR_NOCONFIDENCE_VALUE);
|
61
62
|
}
|
62
63
|
|
@@ -68,7 +69,7 @@ fn test_calmar_exactly_30_days() {
|
|
68
69
|
}
|
69
70
|
|
70
71
|
let avg = 100;
|
71
|
-
let result = calmar(returns, 30, false, avg, 1, 365, 10);
|
72
|
+
let result = calmar(returns, 30, false, avg, 1, 365, 10, CALMAR_NOCONFIDENCE_VALUE);
|
72
73
|
assert(result != 0);
|
73
74
|
}
|
74
75
|
|
@@ -80,7 +81,7 @@ fn test_calmar_negative_returns() {
|
|
80
81
|
}
|
81
82
|
|
82
83
|
let avg = -100;
|
83
|
-
let result = calmar(returns, 50, false, avg, 1, 365, 10);
|
84
|
+
let result = calmar(returns, 50, false, avg, 1, 365, 10, CALMAR_NOCONFIDENCE_VALUE);
|
84
85
|
assert(result != 0);
|
85
86
|
}
|
86
87
|
|
@@ -103,6 +104,7 @@ fn test_calmar_scaling() {
|
|
103
104
|
calmar_cap,
|
104
105
|
days_in_year,
|
105
106
|
drawdown_max_percent,
|
107
|
+
CALMAR_NOCONFIDENCE_VALUE,
|
106
108
|
);
|
107
109
|
|
108
110
|
assert(result >= 0);
|
@@ -115,7 +117,7 @@ fn test_calmar_parity() {
|
|
115
117
|
returns[1] = -1000000i64;
|
116
118
|
returns[2] = 1000000i64;
|
117
119
|
let avg = 666667i64;
|
118
|
-
let result = calmar(returns, 3u32, true, avg, 1i64, 365i64, 10i64);
|
120
|
+
let result = calmar(returns, 3u32, true, avg, 1i64, 365i64, 10i64, CALMAR_NOCONFIDENCE_VALUE);
|
119
121
|
let expected = 1000000i64;
|
120
122
|
let diff = if result > expected {
|
121
123
|
result - expected
|
@@ -130,7 +132,7 @@ fn test_calmar_less_than_60_days() {
|
|
130
132
|
let mut returns = [0; ARRAY_SIZE];
|
131
133
|
returns[0] = 1000000i64;
|
132
134
|
let avg = 1000000i64;
|
133
|
-
let result = calmar(returns, 59u32, false, avg, 1i64, 365i64, 10i64);
|
135
|
+
let result = calmar(returns, 59u32, false, avg, 1i64, 365i64, 10i64, CALMAR_NOCONFIDENCE_VALUE);
|
134
136
|
assert(result == -100000000i64);
|
135
137
|
}
|
136
138
|
|
@@ -138,7 +140,7 @@ fn test_calmar_less_than_60_days() {
|
|
138
140
|
fn test_calmar_zero_variance() {
|
139
141
|
let mut returns = [0; ARRAY_SIZE];
|
140
142
|
let avg = 0i64;
|
141
|
-
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64);
|
143
|
+
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64, CALMAR_NOCONFIDENCE_VALUE);
|
142
144
|
assert(result == 0i64);
|
143
145
|
}
|
144
146
|
|
@@ -149,7 +151,7 @@ fn test_calmar_all_positive() {
|
|
149
151
|
returns[i] = 1000000i64;
|
150
152
|
}
|
151
153
|
let avg = 1000000i64;
|
152
|
-
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64);
|
154
|
+
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64, CALMAR_NOCONFIDENCE_VALUE);
|
153
155
|
assert(result == 0i64);
|
154
156
|
}
|
155
157
|
|
@@ -160,6 +162,6 @@ fn test_calmar_all_negative() {
|
|
160
162
|
returns[i] = -1000000i64;
|
161
163
|
}
|
162
164
|
let avg = -1000000i64;
|
163
|
-
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64);
|
165
|
+
let result = calmar(returns, 60u32, true, avg, 1i64, 365i64, 10i64, CALMAR_NOCONFIDENCE_VALUE);
|
164
166
|
assert(result == 0i64);
|
165
167
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
use crate::utils::constants::{
|
2
|
-
ARRAY_SIZE,
|
3
|
-
STATISTICAL_CONFIDENCE_MINIMUM_N,
|
2
|
+
ARRAY_SIZE, RATIO_SCALE_FACTOR, SCALE,
|
3
|
+
STATISTICAL_CONFIDENCE_MINIMUM_N, OMEGA_NOCONFIDENCE_VALUE,
|
4
4
|
};
|
5
5
|
|
6
6
|
pub fn omega(
|
@@ -11,9 +11,10 @@ pub fn omega(
|
|
11
11
|
bypass_confidence: bool,
|
12
12
|
omega_loss_min: i64,
|
13
13
|
_daily_rf: i64,
|
14
|
+
noconfidence_value: i64,
|
14
15
|
) -> i64 {
|
15
16
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
16
|
-
|
17
|
+
noconfidence_value
|
17
18
|
} else {
|
18
19
|
if use_weighting {
|
19
20
|
let mut product_sum_positive: i64 = 0;
|
@@ -109,7 +110,7 @@ fn test_omega_all_positive() {
|
|
109
110
|
}
|
110
111
|
|
111
112
|
let weights = [100000; ARRAY_SIZE];
|
112
|
-
let result = omega(returns, 5, weights, false, false, 10000000, 0);
|
113
|
+
let result = omega(returns, 5, weights, false, false, 10000000, 0, OMEGA_NOCONFIDENCE_VALUE);
|
113
114
|
assert(result == 0);
|
114
115
|
}
|
115
116
|
|
@@ -121,7 +122,7 @@ fn test_omega_all_negative() {
|
|
121
122
|
}
|
122
123
|
|
123
124
|
let weights = [100000; ARRAY_SIZE];
|
124
|
-
let result = omega(returns, 5, weights, false, false, 10000000, 0);
|
125
|
+
let result = omega(returns, 5, weights, false, false, 10000000, 0, OMEGA_NOCONFIDENCE_VALUE);
|
125
126
|
assert(result == 0);
|
126
127
|
}
|
127
128
|
|
@@ -134,7 +135,7 @@ fn test_omega_mixed_returns() {
|
|
134
135
|
returns[3] = -300;
|
135
136
|
|
136
137
|
let weights = [100000; ARRAY_SIZE];
|
137
|
-
let result = omega(returns, 4, weights, false, false, 10000000, 0);
|
138
|
+
let result = omega(returns, 4, weights, false, false, 10000000, 0, OMEGA_NOCONFIDENCE_VALUE);
|
138
139
|
assert(result == 0);
|
139
140
|
}
|
140
141
|
|
@@ -146,7 +147,7 @@ fn test_omega_zero_returns() {
|
|
146
147
|
}
|
147
148
|
|
148
149
|
let weights = [100000; ARRAY_SIZE];
|
149
|
-
let result = omega(returns, 5, weights, false, false, 10000000, 0);
|
150
|
+
let result = omega(returns, 5, weights, false, false, 10000000, 0, OMEGA_NOCONFIDENCE_VALUE);
|
150
151
|
assert(result == 0);
|
151
152
|
}
|
152
153
|
|
@@ -158,7 +159,7 @@ fn test_omega_ptn_parity() {
|
|
158
159
|
returns[2] = 0;
|
159
160
|
returns[3] = 15000000;
|
160
161
|
let weights = [0; ARRAY_SIZE];
|
161
|
-
let result = omega(returns, 4, weights, false, true, 10000000, 0);
|
162
|
+
let result = omega(returns, 4, weights, false, true, 10000000, 0, OMEGA_NOCONFIDENCE_VALUE);
|
162
163
|
assert(result == 1250000);
|
163
164
|
}
|
164
165
|
|
@@ -181,6 +182,7 @@ fn test_omega_scaling() {
|
|
181
182
|
bypass_confidence,
|
182
183
|
omega_loss_min,
|
183
184
|
daily_rf,
|
185
|
+
OMEGA_NOCONFIDENCE_VALUE,
|
184
186
|
);
|
185
187
|
assert(result > 0);
|
186
188
|
}
|
@@ -192,7 +194,7 @@ fn test_omega_parity() {
|
|
192
194
|
returns[1] = -2000000i64;
|
193
195
|
returns[2] = 1500000i64;
|
194
196
|
let weights = [100000i64; ARRAY_SIZE];
|
195
|
-
let result = omega(returns, 3u32, weights, false, true, 10000000i64, 0i64);
|
197
|
+
let result = omega(returns, 3u32, weights, false, true, 10000000i64, 0i64, OMEGA_NOCONFIDENCE_VALUE);
|
196
198
|
let expected = 250000i64;
|
197
199
|
let diff = if result > expected {
|
198
200
|
result - expected
|
@@ -207,7 +209,7 @@ fn test_omega_less_than_60_days() {
|
|
207
209
|
let mut returns = [0; ARRAY_SIZE];
|
208
210
|
returns[0] = 1000000i64;
|
209
211
|
let weights = [100000i64; ARRAY_SIZE];
|
210
|
-
let result = omega(returns, 59u32, weights, false, false, 10000000i64, 0i64);
|
212
|
+
let result = omega(returns, 59u32, weights, false, false, 10000000i64, 0i64, OMEGA_NOCONFIDENCE_VALUE);
|
211
213
|
assert(result == 0i64);
|
212
214
|
}
|
213
215
|
|
@@ -215,6 +217,6 @@ fn test_omega_less_than_60_days() {
|
|
215
217
|
fn test_omega_zero_variance() {
|
216
218
|
let mut returns = [0; ARRAY_SIZE];
|
217
219
|
let weights = [100000i64; ARRAY_SIZE];
|
218
|
-
let result = omega(returns, 60u32, weights, false, true, 10000000i64, 0i64);
|
220
|
+
let result = omega(returns, 60u32, weights, false, true, 10000000i64, 0i64, OMEGA_NOCONFIDENCE_VALUE);
|
219
221
|
assert(result == 0i64);
|
220
222
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
use crate::utils::{
|
2
2
|
constants::{
|
3
|
-
ARRAY_SIZE, RATIO_SCALE_FACTOR, SCALE,
|
4
|
-
SHARPE_STDDEV_MINIMUM, STATISTICAL_CONFIDENCE_MINIMUM_N,
|
3
|
+
ARRAY_SIZE, RATIO_SCALE_FACTOR, SCALE,
|
4
|
+
SHARPE_STDDEV_MINIMUM, STATISTICAL_CONFIDENCE_MINIMUM_N, SHARPE_NOCONFIDENCE_VALUE,
|
5
5
|
},
|
6
6
|
sqrt::sqrt,
|
7
7
|
};
|
@@ -16,9 +16,10 @@ pub fn sharpe(
|
|
16
16
|
_avg_daily_return: i64,
|
17
17
|
variance_val: i64,
|
18
18
|
ann_excess_return_val: i64,
|
19
|
+
noconfidence_value: i64,
|
19
20
|
) -> i64 {
|
20
21
|
let result = if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
21
|
-
|
22
|
+
noconfidence_value
|
22
23
|
} else {
|
23
24
|
let excess_return = ann_excess_return_val;
|
24
25
|
let volatility = if actual_len < 2 {
|
@@ -61,6 +62,7 @@ fn test_sharpe_normal_case() {
|
|
61
62
|
avg,
|
62
63
|
variance_val,
|
63
64
|
ann_excess,
|
65
|
+
SHARPE_NOCONFIDENCE_VALUE,
|
64
66
|
);
|
65
67
|
assert(result != 0);
|
66
68
|
}
|
@@ -85,7 +87,7 @@ fn test_sharpe_low_volatility() {
|
|
85
87
|
false,
|
86
88
|
avg,
|
87
89
|
variance_val,
|
88
|
-
ann_excess,
|
90
|
+
ann_excess, SHARPE_NOCONFIDENCE_VALUE,
|
89
91
|
);
|
90
92
|
assert(result == SHARPE_NOCONFIDENCE_VALUE);
|
91
93
|
}
|
@@ -112,7 +114,7 @@ fn test_sharpe_high_volatility() {
|
|
112
114
|
false,
|
113
115
|
avg,
|
114
116
|
variance_val,
|
115
|
-
ann_excess,
|
117
|
+
ann_excess, SHARPE_NOCONFIDENCE_VALUE,
|
116
118
|
);
|
117
119
|
assert(result != 0);
|
118
120
|
}
|
@@ -139,6 +141,7 @@ fn test_sharpe_scaling() {
|
|
139
141
|
avg_daily_return,
|
140
142
|
variance_val,
|
141
143
|
ann_excess_return_val,
|
144
|
+
SHARPE_NOCONFIDENCE_VALUE,
|
142
145
|
);
|
143
146
|
assert(result > 0); // scaling test, result should be positive
|
144
147
|
}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
use crate::utils::{
|
2
2
|
constants::{
|
3
3
|
ARRAY_SIZE, DAYS_IN_YEAR,
|
4
|
-
RATIO_SCALE_FACTOR, SCALE, SORTINO_DOWNSIDE_MINIMUM,
|
5
|
-
STATISTICAL_CONFIDENCE_MINIMUM_N,
|
4
|
+
RATIO_SCALE_FACTOR, SCALE, SORTINO_DOWNSIDE_MINIMUM,
|
5
|
+
STATISTICAL_CONFIDENCE_MINIMUM_N, SORTINO_NOCONFIDENCE_VALUE,
|
6
6
|
},
|
7
7
|
sqrt::sqrt,
|
8
8
|
};
|
@@ -18,9 +18,10 @@ pub fn sortino(
|
|
18
18
|
_variance_val: i64,
|
19
19
|
ann_excess_return_val: i64,
|
20
20
|
daily_rf: i64,
|
21
|
+
noconfidence_value: i64,
|
21
22
|
) -> i64 {
|
22
23
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
23
|
-
|
24
|
+
noconfidence_value
|
24
25
|
} else {
|
25
26
|
let excess_return = ann_excess_return_val;
|
26
27
|
|
@@ -100,7 +101,7 @@ pub fn sortino(
|
|
100
101
|
|
101
102
|
(excess_return * RATIO_SCALE_FACTOR) / effective_downside_volatility
|
102
103
|
} else {
|
103
|
-
|
104
|
+
0
|
104
105
|
}
|
105
106
|
}
|
106
107
|
}
|
@@ -129,6 +130,7 @@ fn test_sortino_normal_case() {
|
|
129
130
|
variance_val,
|
130
131
|
ann_excess,
|
131
132
|
0,
|
133
|
+
SORTINO_NOCONFIDENCE_VALUE,
|
132
134
|
);
|
133
135
|
assert(result != 0);
|
134
136
|
}
|
@@ -155,6 +157,7 @@ fn test_sortino_no_negative_returns() {
|
|
155
157
|
variance_val,
|
156
158
|
ann_excess,
|
157
159
|
0,
|
160
|
+
SORTINO_NOCONFIDENCE_VALUE,
|
158
161
|
);
|
159
162
|
assert(result == SORTINO_NOCONFIDENCE_VALUE);
|
160
163
|
}
|
@@ -181,6 +184,7 @@ fn test_sortino_all_negative_returns() {
|
|
181
184
|
variance_val,
|
182
185
|
ann_excess,
|
183
186
|
0,
|
187
|
+
SORTINO_NOCONFIDENCE_VALUE,
|
184
188
|
);
|
185
189
|
assert(result != 0);
|
186
190
|
}
|
@@ -209,6 +213,7 @@ fn test_sortino_high_downside_volatility() {
|
|
209
213
|
variance_val,
|
210
214
|
ann_excess,
|
211
215
|
0,
|
216
|
+
SORTINO_NOCONFIDENCE_VALUE,
|
212
217
|
);
|
213
218
|
assert(result != 0);
|
214
219
|
}
|
@@ -238,6 +243,7 @@ fn test_sortino_scaling() {
|
|
238
243
|
variance_val,
|
239
244
|
ann_excess_return_val,
|
240
245
|
daily_rf,
|
246
|
+
SORTINO_NOCONFIDENCE_VALUE,
|
241
247
|
);
|
242
248
|
assert(result > 0); // scaling test, result should be positive
|
243
249
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
use crate::utils::{
|
2
2
|
constants::{
|
3
|
-
ARRAY_SIZE, STATISTICAL_CONFIDENCE_MINIMUM_N,
|
3
|
+
ARRAY_SIZE, STATISTICAL_CONFIDENCE_MINIMUM_N, RATIO_SCALE_FACTOR,
|
4
|
+
STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE,
|
4
5
|
},
|
5
6
|
sqrt::sqrt,
|
6
7
|
};
|
@@ -14,17 +15,18 @@ pub fn statistical_confidence(
|
|
14
15
|
avg_daily_return: i64,
|
15
16
|
variance_val: i64,
|
16
17
|
_ann_excess_return_val: i64,
|
18
|
+
noconfidence_value: i64,
|
17
19
|
) -> i64 {
|
18
20
|
// Check minimum sample size for statistical confidence
|
19
21
|
if !bypass_confidence & actual_len < STATISTICAL_CONFIDENCE_MINIMUM_N {
|
20
22
|
if actual_len < 2 {
|
21
|
-
|
23
|
+
noconfidence_value
|
22
24
|
} else {
|
23
25
|
// Allow computation for sample sizes between 2 and minimum, but with reduced confidence
|
24
|
-
compute_t_statistic(log_returns, actual_len, weights, use_weighting, avg_daily_return, variance_val)
|
26
|
+
compute_t_statistic(log_returns, actual_len, weights, use_weighting, avg_daily_return, variance_val, noconfidence_value)
|
25
27
|
}
|
26
28
|
} else {
|
27
|
-
compute_t_statistic(log_returns, actual_len, weights, use_weighting, avg_daily_return, variance_val)
|
29
|
+
compute_t_statistic(log_returns, actual_len, weights, use_weighting, avg_daily_return, variance_val, noconfidence_value)
|
28
30
|
}
|
29
31
|
}
|
30
32
|
|
@@ -35,12 +37,13 @@ fn compute_t_statistic(
|
|
35
37
|
_use_weighting: bool,
|
36
38
|
avg_daily_return: i64,
|
37
39
|
variance_val: i64,
|
40
|
+
noconfidence_value: i64,
|
38
41
|
) -> i64 {
|
39
42
|
let avg = avg_daily_return;
|
40
43
|
let var = variance_val;
|
41
44
|
|
42
45
|
if var <= 0 {
|
43
|
-
|
46
|
+
noconfidence_value
|
44
47
|
} else {
|
45
48
|
let std_dev = sqrt(var as u64) as i64;
|
46
49
|
let n_sqrt = sqrt(actual_len as u64) as i64;
|
@@ -67,7 +70,7 @@ fn test_tstat_normal_case() {
|
|
67
70
|
let avg = 320;
|
68
71
|
let variance_val = 200000;
|
69
72
|
let ann_excess = 116700;
|
70
|
-
let result = statistical_confidence(returns, 5, weights, false, false, avg, variance_val, ann_excess);
|
73
|
+
let result = statistical_confidence(returns, 5, weights, false, false, avg, variance_val, ann_excess, STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
71
74
|
assert(result != 0);
|
72
75
|
}
|
73
76
|
|
@@ -80,7 +83,7 @@ fn test_tstat_insufficient_data() {
|
|
80
83
|
let avg = 1000;
|
81
84
|
let variance_val = 0;
|
82
85
|
let ann_excess = 365000;
|
83
|
-
let result = statistical_confidence(returns, 1, weights, false, false, avg, variance_val, ann_excess);
|
86
|
+
let result = statistical_confidence(returns, 1, weights, false, false, avg, variance_val, ann_excess, STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
84
87
|
assert(result == STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
85
88
|
}
|
86
89
|
|
@@ -95,7 +98,7 @@ fn test_tstat_zero_variance() {
|
|
95
98
|
let avg = 100;
|
96
99
|
let variance_val = 0;
|
97
100
|
let ann_excess = 36500;
|
98
|
-
let result = statistical_confidence(returns, 5, weights, false, false, avg, variance_val, ann_excess);
|
101
|
+
let result = statistical_confidence(returns, 5, weights, false, false, avg, variance_val, ann_excess, STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
99
102
|
assert(result == STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
100
103
|
}
|
101
104
|
|
@@ -109,6 +112,6 @@ fn test_tstat_exactly_two_samples() {
|
|
109
112
|
let avg = 250;
|
110
113
|
let variance_val = 1125000;
|
111
114
|
let ann_excess = 91150;
|
112
|
-
let result = statistical_confidence(returns, 2, weights, false, false, avg, variance_val, ann_excess);
|
115
|
+
let result = statistical_confidence(returns, 2, weights, false, false, avg, variance_val, ann_excess, STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE);
|
113
116
|
assert(result != 0);
|
114
117
|
}
|
@@ -22,22 +22,23 @@ pub global STATISTICAL_CONFIDENCE_MINIMUM_N: u32 = 60;
|
|
22
22
|
pub global ANNUAL_RISK_FREE_RATE_BP: i64 = 419;
|
23
23
|
pub global DAILY_LOG_RISK_FREE_RATE: i64 = 114794;
|
24
24
|
|
25
|
-
// Minimum values for ratio calculations (scaled
|
26
|
-
pub global SHARPE_STDDEV_MINIMUM: i64 =
|
27
|
-
pub global OMEGA_LOSS_MINIMUM: i64 =
|
28
|
-
pub global SORTINO_DOWNSIDE_MINIMUM: i64 =
|
25
|
+
// Minimum values for ratio calculations (0.01 scaled by SCALE/1000)
|
26
|
+
pub global SHARPE_STDDEV_MINIMUM: i64 = SCALE / 1000;
|
27
|
+
pub global OMEGA_LOSS_MINIMUM: i64 = SCALE / 1000;
|
28
|
+
pub global SORTINO_DOWNSIDE_MINIMUM: i64 = SCALE / 1000;
|
29
29
|
|
30
30
|
// Scaling factors for precision in integer calculations
|
31
|
-
pub global OMEGA_SCALE_FACTOR: i64 =
|
32
|
-
pub global SHARPE_SCALE_FACTOR: i64 =
|
33
|
-
pub global LARGE_POSITIVE_VALUE: i64 =
|
34
|
-
pub global RATIO_SCALE_FACTOR: i64 =
|
31
|
+
pub global OMEGA_SCALE_FACTOR: i64 = SCALE * 10;
|
32
|
+
pub global SHARPE_SCALE_FACTOR: i64 = SCALE / 100;
|
33
|
+
pub global LARGE_POSITIVE_VALUE: i64 = SCALE * 10;
|
34
|
+
pub global RATIO_SCALE_FACTOR: i64 = SCALE / 100; // RATIO_SCALE_FACTOR: 10^6 for ratio outputs
|
35
35
|
|
36
|
-
|
37
|
-
pub global SHARPE_NOCONFIDENCE_VALUE: i64 = -100000000;
|
36
|
+
// Test values for no-confidence matching PTN defaults
|
38
37
|
pub global OMEGA_NOCONFIDENCE_VALUE: i64 = 0;
|
39
|
-
pub global
|
40
|
-
pub global
|
38
|
+
pub global SHARPE_NOCONFIDENCE_VALUE: i64 = -100 * SCALE;
|
39
|
+
pub global SORTINO_NOCONFIDENCE_VALUE: i64 = -100 * SCALE;
|
40
|
+
pub global CALMAR_NOCONFIDENCE_VALUE: i64 = -100 * SCALE;
|
41
|
+
pub global STATISTICAL_CONFIDENCE_NOCONFIDENCE_VALUE: i64 = -100 * SCALE;
|
41
42
|
|
42
43
|
// Position and trading constants
|
43
44
|
pub global PRICE_SCALE: u64 = 1_000_000_000_000;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
use crate::utils::{average::average, constants::ARRAY_SIZE};
|
1
|
+
use crate::utils::{average::average, constants::{ARRAY_SIZE, SCALE}};
|
2
2
|
|
3
3
|
pub fn variance(
|
4
4
|
daily_returns: [i64; ARRAY_SIZE],
|
@@ -35,7 +35,7 @@ pub fn variance(
|
|
35
35
|
if (i as u32) < actual_len {
|
36
36
|
let diff = daily_returns[i] - mean;
|
37
37
|
let sq_diff = diff * diff;
|
38
|
-
let pre_scaled_sq_diff = sq_diff /
|
38
|
+
let pre_scaled_sq_diff = sq_diff / SCALE;
|
39
39
|
weighted_sum_sq_diff += pre_scaled_sq_diff * weights[i];
|
40
40
|
}
|
41
41
|
}
|
@@ -50,7 +50,7 @@ pub fn variance(
|
|
50
50
|
if (i as u32) < actual_len {
|
51
51
|
let diff = daily_returns[i] - mean;
|
52
52
|
let sq_diff = diff * diff;
|
53
|
-
let scaled_sq_diff = sq_diff /
|
53
|
+
let scaled_sq_diff = sq_diff / SCALE;
|
54
54
|
sum_sq_diff += scaled_sq_diff;
|
55
55
|
}
|
56
56
|
}
|
@@ -8,7 +8,7 @@ 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, SCALE},
|
12
12
|
variance::variance,
|
13
13
|
};
|
14
14
|
|
@@ -31,6 +31,11 @@ fn main(
|
|
31
31
|
annual_risk_free: i64,
|
32
32
|
daily_rf: i64,
|
33
33
|
drawdown_max_percent: i64,
|
34
|
+
omega_noconfidence: i64,
|
35
|
+
sharpe_noconfidence: i64,
|
36
|
+
sortino_noconfidence: i64,
|
37
|
+
calmar_noconfidence: i64,
|
38
|
+
stat_confidence_noconfidence: i64,
|
34
39
|
) -> pub [Field; 9] {
|
35
40
|
// Verify all trading signals are included in the merkle tree
|
36
41
|
let mut all_verified = true;
|
@@ -62,7 +67,7 @@ fn main(
|
|
62
67
|
// Equal weights when weighting is disabled
|
63
68
|
let mut equal_weights = [0; ARRAY_SIZE];
|
64
69
|
for i in 0..ARRAY_SIZE {
|
65
|
-
equal_weights[i] =
|
70
|
+
equal_weights[i] = SCALE / 1000;
|
66
71
|
}
|
67
72
|
equal_weights
|
68
73
|
};
|
@@ -115,6 +120,7 @@ fn main(
|
|
115
120
|
avg_daily_return,
|
116
121
|
variance_val,
|
117
122
|
ann_excess_return_val,
|
123
|
+
sharpe_noconfidence,
|
118
124
|
);
|
119
125
|
let dmd = daily_max_drawdown(returns_array, n_returns);
|
120
126
|
let calmar_ratio = calmar(
|
@@ -125,6 +131,7 @@ fn main(
|
|
125
131
|
calmar_cap,
|
126
132
|
days_in_year,
|
127
133
|
drawdown_max_percent,
|
134
|
+
calmar_noconfidence,
|
128
135
|
);
|
129
136
|
let omega_ratio = omega(
|
130
137
|
returns_array,
|
@@ -134,6 +141,7 @@ fn main(
|
|
134
141
|
bypass_confidence,
|
135
142
|
omega_loss_min,
|
136
143
|
daily_rf,
|
144
|
+
omega_noconfidence,
|
137
145
|
);
|
138
146
|
let sortino_ratio = sortino(
|
139
147
|
returns_array,
|
@@ -146,6 +154,7 @@ fn main(
|
|
146
154
|
variance_val,
|
147
155
|
ann_excess_return_val,
|
148
156
|
daily_rf,
|
157
|
+
sortino_noconfidence,
|
149
158
|
);
|
150
159
|
let stat_confidence = statistical_confidence(
|
151
160
|
returns_array,
|
@@ -156,6 +165,7 @@ fn main(
|
|
156
165
|
avg_daily_return,
|
157
166
|
variance_val,
|
158
167
|
ann_excess_return_val,
|
168
|
+
stat_confidence_noconfidence,
|
159
169
|
);
|
160
170
|
|
161
171
|
let pnl_score_result = avg_daily_pnl;
|