SoFunction
Updated on 2025-04-11

Summary of the application of Rust declaration macros in different K-line bar types

Rust's macro functions are profound and profound. In the K-line bar, there are often many different time-sharing k-line charts, such as 1, 2, 3, 5,. . . . 60, 120, 250, 300…. . Different minute types.
If you don't use macros, then handwriting will be more troublesome. Let's try macros to implement different types of bars.

1. Data and functions

The structure of bar

For simplicity, we abstract the Bar of different time-sharing into the following structure.

 struct Bar{
     open :f64,
     close:f64,
     high:f64,
     low:f64,
 }

At the same time, this structure needs to implement a trait

trait BarPrint{
    fn print_self(&self);
}

2. The implementation of a single bar

Let's first consider that impl_single_bar accepts a single type parameter, such as Bar1, Bar3, Bar5,...

trait BarPrint{
    fn print_self(&self);
}
// Bar1,Bar2,Bar3,Bar5,Bar10,Bar15,Bar30,Bar45,Bar60,.....
macro_rules!  impl_single_bar {
    ($bar:ident) => (
        #[derive(Debug)]
        struct $bar{
            open:f64,
            close:f64,
            high:f64,
            low:f64,
        }
        impl $bar{
            fn new() -> Self{
                $bar{
                    open:0.0,
                    close:0.0,
                    high:0.0,
                    low:0.0,
               }
            }
        }
        impl BarPrint for $bar {
            fn print_self(&self){
                println!("impl_single_bar =>close:{:?} open: {:?}, high:{:?}, low:{:?}",&,&,&,&);
            }
        }
    );
}
fn main(){
    impl_single_bar!(Bar1); //This can be placed outside the main() function without affecting    let  bar = Bar1::new();
    println!("bar:{:?}",bar);
    bar.print_self(); 
    impl_single_bar!(Bar2);
    let  bar2 = Bar2::new();
    println!("bar:{:?}",bar2);
    bar2.print_self(); 
}

Output:

bar:Bar1 { open: 0.0, close: 0.0, high: 0.0, low: 0.0 }
impl_single_bar =>close:0.0 open: 0.0, high:0.0, low:0.0
bar:Bar2 { open: 0.0, close: 0.0, high: 0.0, low: 0.0 }
impl_single_bar =>close:0.0 open: 0.0, high:0.0, low:0.0

This is indeed more convenient, but because the parameters are inputs, it is necessary

impl_single_bar!(Bar1);
impl_single_bar!(Bar2);

It is still not convenient to write a line of functions for each type.
Notice:
1. impl_single_bar!(Bar1), can be placed outside the main() function and will not be affected;
2. $bar:ident, or $bar:tt. tt is a partial language tree, which is larger than the concept of identity.

3. Implement multi-type parameter input

Here we need to use the repetition of the rust macro. I won't go into details here, there is a lot of relevant information.

1. Try to write to generate multiple types of macros

macro_rules! create_bars{
    ($($bar:ident),*) => {
        $(
            #[derive(Debug)]
            struct $bar{
                open:f64,
                close:f64,
                high:f64,
                low:f64,
            }
        )*
    }
}

2. You can also skip the above, directly

trait BarPrint{
    fn print_self(&self);
}
macro_rules! impl_multi_bars{
    ($($bar:ident),*) => {
        $(
            #[derive(Debug)]
            struct $bar{
                open:f64,
                close:f64,
                high:f64,
                low:f64,
            }
            impl $bar{
                fn new() -> Self{
                    $bar{
                        open:0.0,
                        close:0.0,
                        high:0.0,
                        low:0.0,
                    }
                }
            }
            impl BarPrint for $bar {
                fn print_self(&self){
                    println!("impl_multi_bars => close:{:?} open: {:?}, high:{:?}, low:{:?}",&,&,&,&);
                }
            }
        )*
    }      
}
fn main(){
    create_bars!(Bar3,Bar4);
    let bar3 =Bar3{open:0.0,close:0.0,high:0.0,low:0.0};
    println!("bar3:{:?}",bar3);
    let bar4 =Bar4{open:0.0,close:0.0,high:0.0,low:0.0};
    println!("bar4:{:?}",bar4);
    // Test to generate multiple structs Bar5, Bar6, Bar7, and test the method of implementing them at the same time    impl_multi_bars!(Bar5,Bar6,Bar7);//You can place it outside the main() function, and call it directly within the main() function.    let  bar5 = Bar5::new();
    println!("bar5:{:?}",bar5);
    bar5.print_self();
}

Output:

bar3:Bar3 { open: 0.0, close: 0.0, high: 0.0, low: 0.0 }
bar4:Bar4 { open: 0.0, close: 0.0, high: 0.0, low: 0.0 }
bar5:Bar5 { open: 0.0, close: 0.0, high: 0.0, low: 0.0 }
impl_multi_bars => close:0.0 open: 0.0, high:0.0, low:0.0

Compared with 2, you need to write multiple types into one line, that is:

   impl_multi_bars!(Bar5,Bar6,Bar7);

This is the article about the application of Rust statement macros in different K-line bar types. For more related Rust statement macros, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!