Rust : channel、多线程与 CTP相关机制的模拟

21 篇文章 7 订阅

在CTP中,CTP thost会异步发送相关行情和交易回报信息给订阅方或策略管理者(这里简称为strategyManager)。那么,模拟一下CTP的机制,有利于在CTP平台上,构建策略交易支持体系。

一、主要涉及几方面:

1、thost异步发送相关信息

利用多线程,多生产者单消费者模式来模拟发送相关信息,可以选用标准库中的mpsc::channel.

2、策略管理者把相关信息发分给不同的策略

二、方案1: 单channel+单线程

use std::thread;
use std::sync::mpsc::channel;
use std::collections::VecDeque;
use std::time::Duration;
use rand::Rng;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::thread::Thread;
use std::cell::RefCell;

# [derive(Debug)]
struct RtnMarketData(String);
# [derive(Debug)]
struct RtnOrder(String);
# [derive(Debug)]
struct RtnTrade(String);


//模拟thost传过来的不同的值;
# [derive(Debug)]
enum TradeData{
    RtnMarketData(String),
    RtnOrder(String),
    RtnTrade(String),
}
struct Strategy{
    stra_name:String,
    stra_thread_builder:thread::Builder,
    stra_instructions:Vec<String>,//订阅的相关合约
}
impl Strategy{
    fn new(name:String,instrs:Vec<String>)->Self{
        Self{
            stra_name: name,
            stra_thread_builder: thread::Builder::new(),
            stra_instructions:instrs,
        }
    }
    fn OnRtnMarketData(&self,md:&TradeData){
         println!(" -> strategy:{:?} RtnMarketData=> recv:{:?}",self.stra_name,md);
    }
    fn OnRtnOrder(&self,order:&TradeData){
         println!(" -> strategy:{:?} RtnOrder => recv:{:?}",self.stra_name,order);
    }
    fn OnRtnTrade(&self,trade:&TradeData){
         println!(" -> strategy:{:?} RtnTrade=> recv:{:?}",self.stra_name,trade);
    }
}
struct StrategyGroup{
    //stra_list : RefCell<Vec<Strategy>>,
    stra_list : Vec<Strategy>,
}
impl StrategyGroup{
    fn new(list:Vec<Strategy>) -> Self{
        //stra_list:vec![Strategy::new("DSCJ",vec!["IC","IF"]),Strategy::new("WSDJ",vec!["cu,ag"])]
        Self{
            //stra_list:RefCell::new(list),
            stra_list:list,
        }
    }
}
struct StrategyManager{
    thread_builder : thread::Builder,
    stra_group:StrategyGroup,
}
impl StrategyManager{
    fn new(group:StrategyGroup)->Self{
       Self{
           thread_builder : thread::Builder::new(),
           stra_group:group,
       }
    }
}

fn simulate_send(tx:Sender<TradeData>,n_thread:u32){
    for i in 0..n_thread {
        let tx = tx.clone();
        thread::spawn(move||{
            let mut n = 0;
            loop{
                let rand_value:u32 = rand::thread_rng().gen_range(0, 1000);
                n = n + 1;
                println!("rand_value:{:?} n:{:?} thread id :{:?}",rand_value,n,i);
                thread::sleep(Duration::from_millis(300));
                match rand_value {
                    0...600 => {
                        match rand_value{
                            0...100 => tx.send(TradeData::RtnMarketData("IC".to_string())).unwrap(),
                            100...300=> tx.send(TradeData::RtnMarketData("IF".to_string())).unwrap(),
                            300...400=> tx.send(TradeData::RtnMarketData("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnMarketData("ag".to_string())).unwrap(),
                        }
                    },

                    600...900 => {
                        match rand_value{
                            600...700 =>tx.send(TradeData::RtnOrder("IC".to_string())).unwrap(),
                            700...750 =>tx.send(TradeData::RtnOrder("IF".to_string())).unwrap(),
                            750...800 =>tx.send(TradeData::RtnOrder("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnOrder("ag".to_string())).unwrap(),
                        }
                    },
                    _ => {
                        match rand_value{
                            900...920 =>tx.send(TradeData::RtnTrade("IC".to_string())).unwrap(),
                            920...940 =>tx.send(TradeData::RtnTrade("IF".to_string())).unwrap(),
                            940...960 =>tx.send(TradeData::RtnTrade("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnTrade("ag".to_string())).unwrap(),
                        }

                    }
                };

            }
        });
    }
}
fn dispatch_data(rx:&Receiver<TradeData>,stra_group:&StrategyGroup){
    //let (tx,rx) = channel();
    let strategys = &*stra_group.stra_list;
    loop{
        let  ref value = rx.recv().unwrap();
        match value {
            TradeData::RtnMarketData(d) =>{
                for strategy in strategys {
                    if strategy.stra_instructions.contains(&d){
                        strategy.OnRtnMarketData(value);
                    }
                }
            },
            TradeData::RtnOrder(e) =>{
                for strategy in strategys {
                    if strategy.stra_instructions.contains(&e){
                        strategy.OnRtnOrder(value);
                    }
                }
            },
            TradeData::RtnTrade(f) =>{
                for strategy in strategys {
                    if strategy.stra_instructions.contains(&f){
                        strategy.OnRtnTrade(value)
                    }
                }
            },
        }
    }

}
fn generate_strategyManager()-> StrategyManager {
    let strategy_01 =Strategy::new("DSCJ".to_string(),vec!["IC".to_string(),"IF".to_string()]);
    let strategy_02 =Strategy::new("WSDJ".to_string(),vec!["IF".to_string()]);
    let strategy_03 =Strategy::new("TTTT".to_string(),vec!["ag".to_string(),"cu".to_string()]);
    let stra_group = StrategyGroup::new(vec![strategy_01,strategy_02,strategy_03]);
    StrategyManager::new(stra_group)
}

fn main(){
    //模拟生成相关的策略、策略group、策略管理者
    let stra_manager = generate_strategyManager();
    // 模拟thost 
    let (tx,rx) = channel::<TradeData>();
    //模拟多线程异步进行接收thost相关的行情等信息
    simulate_send(tx,10);
    println!("main=>");

    dispatch_data(&rx,&stra_manager.stra_group);
    thread::sleep(Duration::from_millis(500000));
}

三、效果图

在这里插入图片描述
四、资源占用情况

在去掉了sleep之后,可以看到,内存一直在上升;因为10个线程不断的发行情,这个压力是很大的;策略的分发的速度又来不及,占用的资源会较大。

这个请大家注意!
在这里插入图片描述
五、方案2:多channel + 多线程方案

1、这个模拟,并没有模拟订阅thost的机制;
2、子策略并没有专有线程去接收相关信息;现在是strategyManager中单线程进行分发,并负责策略中信号处理。这部分应交给子策略中的专有线程处理。 即处理的链条过长。

下面的代码实现了两层:channel以及多线程轮询交易所的行情等信息,大大提高了交易的效率。

use std::thread;
use std::sync::mpsc::channel;
use std::collections::VecDeque;
use std::time::Duration;
use rand::Rng;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::thread::Thread;
use std::sync::{Arc, Mutex};
use std::marker::Send;
use std::cell::RefCell;


# [derive(Debug,Clone)]
struct RtnMarketData(String);
# [derive(Debug,Clone)]
struct RtnOrder(String);
# [derive(Debug,Clone)]
struct RtnTrade(String);


# [derive(Debug,Clone)]
enum TradeData{
    RtnMarketData(String),
    RtnOrder(String),
    RtnTrade(String),
}
trait Get_id{
    fn get_request_id(&self)-> u32;
}

struct Strategy{
    stra_name:String,
    receiver:Receiver<TradeData>,
    lock:Arc<Mutex<u32>>,
}
struct StrategyHandler{
    stra_name: String,
    stra_instructions: Vec<String>, //订阅的相关合约
    sender:Sender<TradeData>,
}
impl StrategyHandler{
    fn new(name:String,instrs:Vec<String>,send:Sender<TradeData>)->Self{
        Self{
            stra_name: name,
            stra_instructions: instrs,
            sender:send,
        }
    }
}

impl Strategy{
    fn new(name:String,recv:Receiver<TradeData>,lock:Arc<Mutex<u32>>)->Self{
        Self{
            stra_name:name,
            receiver:recv,
            lock:lock,
        }
    }
    fn spawn(self){
       thread::spawn(move||{
            loop{
                   let  value = self.receiver.recv().unwrap();
                   match value {
                       TradeData::RtnMarketData(_) =>{
                           self.OnRtnMarketData(value);
                       },
                       TradeData::RtnOrder(_) =>{
                           self.OnRtnOrder(value);
                       },
                       TradeData::RtnTrade(_) =>{
                           self.OnRtnTrade(value);
                       },
                  }
            };
       });
    }
    fn OnRtnMarketData(&self,md:TradeData){
        println!(" -> strategy:{:?} RtnMarketData=> recv:{:?}",self.stra_name,md);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 获取唯一ID,策略逻辑在此
        if rand_value < 400 {
            println!("触发交易信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
        thread::sleep(Duration::from_millis(rand_value));
    }
    fn OnRtnOrder(&self,order:TradeData){
        println!(" -> strategy:{:?} RtnOrder => recv:{:?}",self.stra_name,order);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 获取唯一ID
        if rand_value < 10 {
            println!("触发OnRtnOrder信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
    }
    fn OnRtnTrade(&self,trade:TradeData){
        println!(" -> strategy:{:?} RtnTrade=> recv:{:?}",self.stra_name,trade);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 获取唯一ID
        if rand_value < 300 {
            println!("触发OnRtnTrade信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
    }
}

impl Get_id for Strategy{
    fn get_request_id(&self)-> u32{
        let lock = self.lock.clone();
        let temp = *lock.lock().unwrap();
        *lock.lock().unwrap()= temp +1 ;
        println!("request_ID:{:?}",*lock.lock().unwrap());
        temp+1
    }
}

struct StrategyGroup{
    stra_list : Vec<Strategy>,
}
impl StrategyGroup{
    fn new(list:Vec<Strategy>) -> Self{
        Self{
            stra_list:list,
        }
    }
}
struct StrategyManager{
    stra_group: StrategyGroup,
}

impl StrategyManager{
    fn new(group: StrategyGroup)->Self{
       Self{
           stra_group: group,
       }
    }
}

fn simulate_send(tx:Sender<TradeData>,n_thread:u32){
    for i in 0..n_thread {
        let tx = tx.clone();
        thread::spawn(move||{
            let mut n = 0;
            loop{
                let rand_value:u32 = rand::thread_rng().gen_range(0, 1000);
                n = n + 1;
                println!("thost send info: thread id :{:?} ,次数 {:?} ",i,n);
                thread::sleep(Duration::from_millis(500));
                match rand_value {
                    0...600 => {
                        match rand_value{
                            0...100 => tx.send(TradeData::RtnMarketData("IC".to_string())).unwrap(),
                            100...300=> tx.send(TradeData::RtnMarketData("IF".to_string())).unwrap(),
                            300...400=> tx.send(TradeData::RtnMarketData("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnMarketData("ag".to_string())).unwrap(),
                        }
                    },

                    600...900 => {
                        match rand_value{
                            600...700 =>tx.send(TradeData::RtnOrder("IC".to_string())).unwrap(),
                            700...750 =>tx.send(TradeData::RtnOrder("IF".to_string())).unwrap(),
                            750...800 =>tx.send(TradeData::RtnOrder("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnOrder("ag".to_string())).unwrap(),
                        }
                    },
                    _ => {
                        match rand_value{
                            900...920 =>tx.send(TradeData::RtnTrade("IC".to_string())).unwrap(),
                            920...940 =>tx.send(TradeData::RtnTrade("IF".to_string())).unwrap(),
                            940...960 =>tx.send(TradeData::RtnTrade("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnTrade("ag".to_string())).unwrap(),
                        }

                    }
                };

            }
        });
    }
    //thost::new(tx).thost_thread_builder.spawn()
}
fn dispatch_data(rx:&Receiver<TradeData>,_handlers: Vec<StrategyHandler>){
    let handlers = &_handlers;
    loop{
        let  ref value = rx.recv().unwrap();
        match value {
            TradeData::RtnMarketData(d) =>{
                for  handler in handlers {
                    if handler.stra_instructions.contains(&d){
                        //strategy.OnRtnMarketData(value)
                        let tx = handler.sender.clone();
                        tx.send(TradeData::RtnMarketData(d.to_string())).unwrap();
                        println!("dispatch:{:?}",d);
                    }
                }
            },
            TradeData::RtnOrder(e) =>{
                for  handler in handlers {
                    if handler.stra_instructions.contains(&e){
                        let tx = handler.sender.clone();
                        tx.send(TradeData::RtnOrder(e.to_string())).unwrap();
                        println!("dispatch:{:?}",e);
                    }
                }
            },
            TradeData::RtnTrade(f) =>{
                for  handler in handlers {
                    if handler.stra_instructions.contains(&f){
                        let tx = handler.sender.clone();
                        tx.send(TradeData::RtnTrade(f.to_string())).unwrap();
                        println!("dispatch:{:?}",f);
                    }
                }
            },
        }
    }
}
fn strategy_init()-> Vec<StrategyHandler> {
    let (tx_01,rx_01) = channel::<TradeData>();
    let (tx_02,rx_02) = channel::<TradeData>();
    let (tx_03,rx_03) = channel::<TradeData>();
    let id = Arc::new(Mutex::new(0_u32));
    let stra_handler_01 = StrategyHandler::new("DSCJ".to_string(),vec!["IC".to_string(),"IH".to_string()],tx_01);
    let strategy_01 = Strategy::new("DSCJ".to_string(),rx_01,id.clone());
    println!("a");
    strategy_01.spawn();
    println!("b");
    let stra_handler_02 = StrategyHandler::new("TTTT".to_string(),vec!["IC".to_string(),"IF".to_string()],tx_02);
    let strategy_02 = Strategy::new("TTTT".to_string(),rx_02,id.clone());
    strategy_02.spawn();
    let stra_handler_03 = StrategyHandler::new("WSDJ".to_string(),vec!["ag".to_string(),"cu".to_string()],tx_03);
    let strategy_03 = Strategy::new("WSDJ".to_string(),rx_03,id.clone());
    strategy_03.spawn();
    vec![stra_handler_01,stra_handler_02,stra_handler_03]
}
// 等待=>


fn main(){
    //模拟生成相关的策略、策略group、策略管理者
    let handlers :Vec<StrategyHandler> = strategy_init();
    //模拟thost
    let (tx,rx) = channel::<TradeData>();
    //模拟N个多线程异步进行接收thost相关的行情等信息
    simulate_send(tx,2);
    println!("main=>");
    dispatch_data(&rx,handlers);
    thread::sleep(Duration::from_millis(500000));
}

上面的核心是:sender:Sender < TradeData >和 Receiver < TradeData >要分离,否则在启新线程中,就会把策略本身move进行。
上面不仅有多线程和异步接收相关的信息,而且还有同步交易的模拟,在功能上也比较完整。

六、方法3:单channel +多线程方案

当然,用channel很方便,但有没有简单用加锁的方式,来解决这个问题?

有的,但是架构上,仍二个Arc(Mutex< > ) 放在分开的两部分之中。

下面是代码:

use std::thread;
use std::sync::mpsc::channel;
use std::collections::VecDeque;
use std::time::Duration;
use rand::Rng;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::thread::Thread;
use std::sync::{Arc, Mutex};
use std::marker::Send;
use std::cell::RefCell;


# [derive(Debug,Clone)]
struct RtnMarketData(String);
# [derive(Debug,Clone)]
struct RtnOrder(String);
# [derive(Debug,Clone)]
struct RtnTrade(String);


# [derive(Debug,Clone)]
enum TradeData{
    RtnMarketData(String),
    RtnOrder(String),
    RtnTrade(String),
}
trait Get_id{
    fn get_request_id(&self)-> u32;
}
trait Get_data{
    fn push_data(&self,td:TradeData);
}
struct Strategy{
    stra_name:String,
    stra_instructions: Vec<String>, //订阅的相关合约
    lock_id:Arc<Mutex<u32>>,
    lock_data:Arc<Mutex<VecDeque<TradeData>>>,
}
struct Handler{
    stra_name:String,
    stra_instructions: Vec<String>, //订阅的相关合约
    lock_data:Arc<Mutex<VecDeque<TradeData>>>,
}
impl Handler{
    fn new(name:String,instrs:Vec<String>,lock_data:Arc<Mutex<VecDeque<TradeData>>>)->Self{
        Self{
            stra_name:name,
            stra_instructions: instrs, //订阅的相关合约
            lock_data:lock_data,
        }
    }
}
impl Get_data for Handler{
    fn push_data(&self,td:TradeData){
        let s_clone = self.lock_data.clone();
        if s_clone.is_poisoned(){
            println!("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ get_data  posion:{:?}",s_clone.is_poisoned());
        }
        let mut guard = match s_clone.lock() {
            Ok(guard) => guard,
            Err(poisoned) => {
                println!(" posion!");
                poisoned.into_inner()
            },
        };
        println!("push_back 成功!:{:?}",td);
        guard.push_back(td);

    }
}
impl Strategy{
    fn new(name:String,instrs:Vec<String>,lock_id:Arc<Mutex<u32>>,lock_data:Arc<Mutex<VecDeque<TradeData>>>)->Self{
        Self{
            stra_name:name,
            stra_instructions: instrs, //订阅的相关合约
            lock_id: lock_id,
            lock_data:lock_data,
        }
    }
    fn spawn(self){
       let lock = self.lock_data.clone();
       if lock.is_poisoned(){
           println!("=======================================>  spawn posion:{:?}",lock.is_poisoned());
       }

       thread::spawn(move||{
            loop{
                   let  value = lock.lock().unwrap().pop_back();//.unwrap();//front
                   println!("=> get value:{:?}",value);
                   thread::sleep(Duration::from_millis(100));
                   match value {
                       Some(TradeData::RtnMarketData(d)) =>{
                           self.OnRtnMarketData(TradeData::RtnMarketData(d));
                       },
                       Some(TradeData::RtnOrder(e)) =>{
                           self.OnRtnOrder(TradeData::RtnOrder(e));
                       },
                       Some(TradeData::RtnTrade(f)) =>{
                           self.OnRtnTrade(TradeData::RtnTrade(f));
                       },
                       _ =>{
                           println!("其它数据类型:{:?}",value);
                           continue;
                       },
                  }
            };
       });
    }
    fn OnRtnMarketData(&self,md:TradeData){
        println!(" -> strategy:{:?} RtnMarketData=> recv:{:?}",self.stra_name,md);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 交易获取唯一ID
        if rand_value < 400 {
            println!("触发交易信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
        thread::sleep(Duration::from_millis(rand_value));
    }
    fn OnRtnOrder(&self,order:TradeData){
        println!(" -> strategy:{:?} RtnOrder => recv:{:?}",self.stra_name,order);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 交易获取唯一ID
        if rand_value < 10 {
            println!("触发OnRtnOrder信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
    }
    fn OnRtnTrade(&self,trade:TradeData){
        println!(" -> strategy:{:?} RtnTrade=> recv:{:?}",self.stra_name,trade);
        let rand_value:u64 = rand::thread_rng().gen_range(200,500);
        // 交易获取唯一ID
        if rand_value < 300 {
            println!("触发OnRtnTrade信号:{:?} id:{:?}",rand_value,self.get_request_id());
        }
    }
}

impl Get_id for Strategy{
    fn get_request_id(&self)-> u32{
        let lock = self.lock_id.clone();
        let temp = *lock.lock().unwrap();
        *lock.lock().unwrap()= temp +1 ;
        println!("request_ID:{:?}",*lock.lock().unwrap());
        temp + 1
    }
}

struct StrategyGroup{
    stra_list : Vec<Strategy>,
}
impl StrategyGroup{
    fn new(list:Vec<Strategy>) -> Self{
        Self{
            stra_list:list,
        }
    }
}
struct StrategyManager{
    stra_group: StrategyGroup,
}

impl StrategyManager{
    fn new(group: StrategyGroup)->Self{
       Self{
           stra_group: group,
       }
    }
}

fn simulate_send(tx:Sender<TradeData>,n_thread:u32){
    for i in 0..n_thread {
        let tx = tx.clone();
        thread::spawn(move||{
            let mut n = 0;
            loop{
                let rand_value:u32 = rand::thread_rng().gen_range(0, 1000);
                n = n + 1;
                println!("thost send info: thread id :{:?} ,次数 {:?} ",i,n);
                thread::sleep(Duration::from_millis(50));
                match rand_value {
                    0...600 => {
                        match rand_value{
                            0...100 => tx.send(TradeData::RtnMarketData("IC".to_string())).unwrap(),
                            100...300=> tx.send(TradeData::RtnMarketData("IF".to_string())).unwrap(),
                            300...400=> tx.send(TradeData::RtnMarketData("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnMarketData("ag".to_string())).unwrap(),
                        }
                    },

                    600...900 => {
                        match rand_value{
                            600...700 =>tx.send(TradeData::RtnOrder("IC".to_string())).unwrap(),
                            700...750 =>tx.send(TradeData::RtnOrder("IF".to_string())).unwrap(),
                            750...800 =>tx.send(TradeData::RtnOrder("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnOrder("ag".to_string())).unwrap(),
                        }
                    },
                    _ => {
                        match rand_value{
                            900...920 =>tx.send(TradeData::RtnTrade("IC".to_string())).unwrap(),
                            920...940 =>tx.send(TradeData::RtnTrade("IF".to_string())).unwrap(),
                            940...960 =>tx.send(TradeData::RtnTrade("cu".to_string())).unwrap(),
                            _ =>tx.send(TradeData::RtnTrade("ag".to_string())).unwrap(),
                        }

                    }
                };

            }
        });
    }
    //thost::new(tx).thost_thread_builder.spawn()
}
fn dispatch_data(rx:&Receiver<TradeData>,ss: Vec<Handler>){
    let ss = &ss;
    loop{
        let  ref value = rx.recv().unwrap();
        match value {
            TradeData::RtnMarketData(d) =>{
                for  s in ss {
                    if s.stra_instructions.contains(&d){
                        println!("dispatch 2:{:?}",d);
                        s.push_data(TradeData::RtnMarketData(d.to_string()));
                    }
                }
            },
            TradeData::RtnOrder(e) =>{
                for  s in ss {
                    if s.stra_instructions.contains(&e){
                        println!("dispatch 4:{:?}",e);
                        s.push_data(TradeData::RtnOrder(e.to_string()));
                    }
                }
            },
            TradeData::RtnTrade(f) =>{
                for  s in ss {
                    if s.stra_instructions.contains(&f){
                        println!("dispatch 6:{:?}",f);
                        s.push_data(TradeData::RtnTrade(f.to_string()));
                    }
                }
            },
        }
    }
}
fn strategy_init()-> Vec<Handler> {
    let id = Arc::new(Mutex::new(0_u32));

    let v_01 :VecDeque<TradeData> = VecDeque::new();
    let data_01 = Arc::new(Mutex::new(v_01));

    let v_02 :VecDeque<TradeData> = VecDeque::new();
    let data_02 = Arc::new(Mutex::new(v_02));

    let v_03 :VecDeque<TradeData> = VecDeque::new();
    let data_03 = Arc::new(Mutex::new(v_03));

    let handler_01 = Handler::new("DSCJ".to_string(),vec!["IC".to_string(),"IF".to_string()],data_01.clone());
    let strategy_01 = Strategy::new("DSCJ".to_string(),vec!["IC".to_string(),"IF".to_string()],id.clone(),data_01.clone());
    strategy_01.spawn();
    let handler_02 = Handler::new("TTTT".to_string(),vec!["IC".to_string(),"IH".to_string()],data_02.clone());
    let strategy_02 = Strategy::new("TTTT".to_string(),vec!["IC".to_string(),"IH".to_string()],id.clone(),data_02.clone());
    strategy_02.spawn();
    let handler_03 = Handler::new("WSDJ".to_string(),vec!["cu".to_string(),"ag".to_string()],data_03.clone());
    let strategy_03 = Strategy::new("WSDJ".to_string(),vec!["cu".to_string(),"ag".to_string()],id.clone(),data_03.clone());
    strategy_03.spawn();
    vec![handler_01,handler_02,handler_03]
}

fn main(){
    //模拟生成相关的策略、策略group、策略管理者
    let handlers :Vec<Handler> = strategy_init();
    //模拟thost
    let (tx,rx) = channel::<TradeData>();
    //模拟N个多线程异步进行接收thost相关的行情等信息
    simulate_send(tx,2);
    println!("main=>");
    dispatch_data(&rx,handlers);
    thread::sleep(Duration::from_millis(500000));
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值