Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
  • Loading branch information
m5l14i11 committed May 1, 2024
1 parent 1b2657c commit d5581e8
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 98 deletions.
33 changes: 29 additions & 4 deletions risk/_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
PositionClosed,
PositionOpened,
)
from core.events.risk import RiskThresholdBreached, RiskType
from core.events.risk import RiskAdjustRequested, RiskThresholdBreached, RiskType
from core.events.signal import (
ExitLongSignalReceived,
ExitShortSignalReceived,
Expand Down Expand Up @@ -69,16 +69,20 @@ async def on_receive(self, event: RiskEvent):
PositionOpened: self._open_position,
PositionClosed: self._close_position,
PositionAdjusted: self._adjust_position,
GoLongSignalReceived: self._handle_reverse,
GoShortSignalReceived: self._handle_reverse,
GoLongSignalReceived: [self._handle_reverse, self._handle_scale_in],
GoShortSignalReceived: [self._handle_reverse, self._handle_scale_in],
ExitLongSignalReceived: self._handle_signal_exit,
ExitShortSignalReceived: self._handle_signal_exit,
}

handler = handlers.get(type(event))

if handler:
await handler(event)
if isinstance(handler, list):
for h in handler:
await h(event)
else:
await handler(event)

async def _open_position(self, event: PositionOpened):
async with self.lock:
Expand Down Expand Up @@ -159,6 +163,27 @@ async def _handle_reverse(
):
await self._process_reverse_exit(short_position, event.entry_price)

async def _handle_scale_in(
self, event: Union[GoLongSignalReceived, GoShortSignalReceived]
):
async with self.lock:
long_position, short_position = self._position

if (
isinstance(event, GoLongSignalReceived)
and long_position
and long_position.adj_count < self.config["max_scale_in"]
and long_position.entry_price < event.entry_price
):
await self.tell(RiskAdjustRequested(long_position, event.entry_price))
if (
isinstance(event, GoShortSignalReceived)
and short_position
and short_position.adj_count < self.config["max_scale_in"]
and short_position.entry_price > event.entry_price
):
await self.tell(RiskAdjustRequested(short_position, event.entry_price))

async def _handle_signal_exit(
self, event: Union[ExitLongSignalReceived, ExitShortSignalReceived]
):
Expand Down
6 changes: 3 additions & 3 deletions ta_lib/core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ mod tests {

#[test]
fn test_nz() {
let source = Series::from([f32::NAN, 5.0, 4.0, 3.0, 5.0]);
let source = Series::from([3.0, 5.0, 4.0, 3.0, 5.0]);
let fill = Series::from([1.0, 0.5, 5.0, 2.0, 8.0]);

let expected = Series::from([1.0, 5.0, 4.0, 3.0, 5.0]);
let expected = Series::from([1.0, 3.0, 5.0, 4.0, 3.0]);

let result = nz!(source, fill);
let result = nz!(source.shift(1), fill);

assert_eq!(result, expected);
}
Expand Down
36 changes: 24 additions & 12 deletions ta_lib/core/src/math.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::series::Series;
use crate::smoothing::Smooth;
use crate::ZERO;
use std::ops::Neg;

const ZERO: f32 = 0.;

impl Series<f32> {
pub fn abs(&self) -> Self {
self.fmap(|val| val.map(|v| v.abs()))
Expand Down Expand Up @@ -57,7 +56,13 @@ impl Series<f32> {
impl Series<f32> {
pub fn sum(&self, period: usize) -> Self {
self.window(period)
.map(|w| w.iter().flatten().sum::<f32>())
.map(|w| {
if w.iter().all(|&x| x.is_none()) {
None
} else {
Some(w.iter().flatten().sum::<f32>())
}
})
.collect()
}

Expand All @@ -72,14 +77,21 @@ impl Series<f32> {
pub fn mad(&self, period: usize) -> Self {
self.window(period)
.map(|w| {
let len = w.len() as f32;
let mean = w.iter().flatten().sum::<f32>() / len;

w.iter()
.flatten()
.map(|value| (value - mean).abs())
.sum::<f32>()
/ len
if w.iter().all(|&x| x.is_none()) {
None
} else {
let len = w.len() as f32;
let mean = w.iter().flatten().sum::<f32>() / len;

let mad = w
.iter()
.flatten()
.map(|value| (value - mean).abs())
.sum::<f32>()
/ len;

Some(mad)
}
})
.collect()
}
Expand Down Expand Up @@ -195,7 +207,7 @@ mod tests {
#[test]
fn test_sum() {
let source = Series::from([f32::NAN, 2.0, 3.0, 4.0, 5.0]);
let expected = Series::from([0.0, 2.0, 5.0, 9.0, 12.0]);
let expected = Series::from([f32::NAN, 2.0, 5.0, 9.0, 12.0]);
let n = 3;

let result = source.sum(n);
Expand Down
4 changes: 2 additions & 2 deletions ta_lib/core/src/series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ mod tests {

#[test]
fn test_lowest() {
let source = Series::from([1.0, 2.0, 3.0, 4.0, 5.0]);
let expected = Series::from([1.0, 1.0, 1.0, 2.0, 3.0]);
let source = Series::from([f32::NAN, 2.0, 3.0, 1.0, 5.0]);
let expected = Series::from([f32::NAN, 2.0, 2.0, 1.0, 1.0]);
let period = 3;

let result = source.lowest(period);
Expand Down
55 changes: 27 additions & 28 deletions ta_lib/core/src/smoothing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::iff;
use crate::series::Series;
use crate::traits::Comparator;
use crate::ZERO;
use crate::{iff, nz};

#[derive(Copy, Clone)]
pub enum Smooth {
Expand All @@ -19,9 +21,7 @@ impl Series<f32> {
let mut sum = Series::zero(len);

for _ in 0..len {
let prev = sum.shift(1);

sum = iff!(prev.na(), seed, alpha * self + (1. - alpha) * prev)
sum = alpha * self + (1. - alpha) * nz!(sum.shift(1), seed)
}

sum
Expand All @@ -40,7 +40,13 @@ impl Series<f32> {

fn ma(&self, period: usize) -> Self {
self.window(period)
.map(|w| w.iter().flatten().sum::<f32>() / w.len() as f32)
.map(|w| {
if w.iter().all(|&x| x.is_none()) {
None
} else {
Some(w.iter().flatten().sum::<f32>() / w.len() as f32)
}
})
.collect()
}

Expand Down Expand Up @@ -99,30 +105,13 @@ impl Series<f32> {

fn kama(&self, period: usize) -> Series<f32> {
let len = self.len();
let change = self.change(period).abs();
let mom = self.change(period).abs();
let volatility = self.change(1).abs().sum(period);
let er = iff!(volatility.seq(&ZERO), Series::zero(len), mom / volatility);

let er = change / volatility;

let alpha = iff!(
er.na(),
Series::fill(2. / (period as f32 + 1.), len),
(er * 0.666_666_7).sqrt()
);

let mut kama = Series::empty(len);

for _ in 0..len {
let prev_kama = kama.shift(1);

kama = iff!(
prev_kama.na(),
self,
&prev_kama + &alpha * (self - &prev_kama)
)
}
let alpha = (er * 0.666_666_7).pow(2);

kama
self.ew(&alpha, self)
}

fn zlema(&self, period: usize) -> Series<f32> {
Expand Down Expand Up @@ -151,8 +140,8 @@ mod tests {

#[test]
fn test_ma() {
let source = Series::from([1.0, 2.0, 3.0, 4.0, 5.0]);
let expected = Series::from([1.0, 1.5, 2.0, 3.0, 4.0]);
let source = Series::from([f32::NAN, 2.0, 3.0, 4.0, 5.0]);
let expected = Series::from([f32::NAN, 1.0, 1.6666666, 3.0, 4.0]);

let result = source.ma(3);

Expand Down Expand Up @@ -199,6 +188,16 @@ mod tests {
assert_eq!(result, expected);
}

#[test]
fn test_kama() {
let source = Series::from([1.0, 2.0, 3.0, 4.0, 5.0]);
let expected = Series::from([f32::NAN, f32::NAN, f32::NAN, 4.0, 4.4444447]);

let result = source.kama(3);

assert_eq!(result, expected);
}

#[test]
fn test_linreg() {
let source = Series::from([
Expand Down
12 changes: 1 addition & 11 deletions ta_lib/indicators/momentum/src/kst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,7 @@ mod tests {
let period_four = 5;

let expected = vec![
0.0,
0.0,
-0.08674153,
-0.07785419,
0.8893757,
3.2460651,
5.4379296,
7.731903,
8.935576,
9.378514,
9.048229,
0.0, 0.0, 0.0, 0.0, 0.0, 3.2460651, 5.4379296, 7.731903, 8.935576, 9.378514, 9.048229,
8.414183,
];

Expand Down
52 changes: 28 additions & 24 deletions ta_lib/indicators/trend/src/frama.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
use core::prelude::*;

pub fn frama(
source: &Series<f32>,
high: &Series<f32>,
low: &Series<f32>,
close: &Series<f32>,
period: usize,
) -> Series<f32> {
let hh1 = high.highest(2 * period).shift(period);
let ll1 = low.lowest(2 * period).shift(period);
let n1 = (&hh1 - &ll1) / period as f32;
let len = (0.5 * period as f32).round() as usize;
let hh = high.highest(len);
let ll = low.lowest(len);

let hh2 = high.highest(period);
let ll2 = low.lowest(period);
let n2 = (&hh2 - &ll2) / period as f32;
let n1 = (&hh - &ll) / len as f32;
let n2 = (hh.shift(len) - ll.shift(len)) / len as f32;
let n3 = (high.highest(period) - low.lowest(period)) / period as f32;

let hh3 = hh1.max(&hh2);
let ll3 = ll1.min(&ll2);
let n3 = (hh3 - ll3) / (2. * period as f32);
let d = ((n1 + n2) / n3).log() / 2.0_f32.ln();

let d = ((n1 + n2).log() - n3.log()) / 2.0_f32.ln();
let alpha = (-4.6 * (d - 1.)).exp();

let alpha = iff!(
d.na(),
Series::fill(2. / (period as f32 + 1.), close.len()),
(-4.6 * (d - 1.)).exp()
);

close.ew(&alpha, close)
source.ew(&alpha, source)
}

#[cfg(test)]
Expand All @@ -35,12 +27,24 @@ mod tests {

#[test]
fn test_frama() {
let high = Series::from([18.904, 18.988, 18.992, 18.979, 18.941]);
let low = Series::from([18.825, 18.866, 18.950, 18.912, 18.877]);
let close = Series::from([18.889, 18.966, 18.963, 18.922, 18.940]);
let expected = vec![18.889, 18.9275, 18.94525, 18.939285, 18.939308];

let result: Vec<f32> = frama(&high, &low, &close, 3).into();
let high = Series::from([
5.0994, 5.0910, 5.1015, 5.1051, 5.1041, 5.1138, 5.1150, 5.1160, 5.1392, 5.1550, 5.1739,
5.2000, 5.2193,
]);
let low = Series::from([
5.0770, 5.0788, 5.0897, 5.0933, 5.0943, 5.0996, 5.1001, 5.0968, 5.1125, 5.1326, 5.1468,
5.1675, 5.1907,
]);
let source = Series::from([
5.0788, 5.0897, 5.0958, 5.1023, 5.0998, 5.1046, 5.1014, 5.1141, 5.1355, 5.1477, 5.1675,
5.2000, 5.2169,
]);
let expected = vec![
0.0, 0.0, 5.0958, 5.09975, 5.0997515, 5.100709, 5.10147, 5.1022835, 5.130958,
5.2076283, 5.172987, 5.1907825, 5.2242994,
];

let result: Vec<f32> = frama(&source, &high, &low, 3).into();

assert_eq!(result, expected);
}
Expand Down
10 changes: 8 additions & 2 deletions ta_lib/indicators/trend/src/kama.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ mod tests {

#[test]
fn test_kama() {
let source = Series::from([19.099, 19.079, 19.074, 19.139, 19.191]);
let expected = vec![19.099, 19.089, 19.081501, 19.112799, 19.173977];
let source = Series::from([
5.0788, 5.0897, 5.0958, 5.1023, 5.0998, 5.1046, 5.1014, 5.1141, 5.1355, 5.1477, 5.1675,
5.2000, 5.2169,
]);
let expected = vec![
0.0, 0.0, 0.0, 5.1023, 5.1018033, 5.1023088, 5.102306, 5.104807, 5.1141686, 5.129071,
5.1461506, 5.1700835, 5.190891,
];

let result: Vec<f32> = kama(&source, 3).into();

Expand Down
9 changes: 2 additions & 7 deletions ta_lib/indicators/trend/src/md.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ pub fn md(source: &Series<f32>, period: usize) -> Series<f32> {
let seed = source.smooth(Smooth::EMA, period);

for _ in 0..len {
let prev_mg = mg.shift(1);

mg = iff!(
prev_mg.na(),
seed,
&prev_mg + (source - &prev_mg) / ((source / &prev_mg).pow(4) * period as f32)
);
let prev_mg = nz!(mg.shift(1), seed);
mg = &prev_mg + (source - &prev_mg) / ((source / &prev_mg).pow(4) * period as f32);
}

mg
Expand Down
2 changes: 1 addition & 1 deletion ta_lib/indicators/trend/src/smma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod tests {
6.8310, 6.8355, 6.8360, 6.8345, 6.8285, 6.8395,
]);
let expected = [
6.8575, 6.8566666, 6.857111, 6.8580737, 6.8547153, 6.8556433, 6.8584285, 6.857785,
6.8574996, 6.8566666, 6.857111, 6.8580737, 6.8547153, 6.8556433, 6.8584285, 6.857785,
6.85369, 6.8507934, 6.846029, 6.8410187, 6.839179, 6.8381195, 6.8369126, 6.8341084,
6.835905,
];
Expand Down
3 changes: 2 additions & 1 deletion ta_lib/indicators/trend/src/vidya.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use core::prelude::*;

pub fn vidya(source: &Series<f32>, fast_period: usize, slow_period: usize) -> Series<f32> {
let alpha = 2. / (fast_period as f32 + 1.) * source.std(fast_period) / source.std(slow_period);
let k = source.std(fast_period) / source.std(slow_period);
let alpha = 2. / (fast_period as f32 + 1.) * k.nz(Some(ZERO));

source.ew(&alpha, source)
}
Expand Down
Loading

0 comments on commit d5581e8

Please sign in to comment.