diff --git a/src/main.rs b/src/main.rs index 5bfba0b..4d2538d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,9 @@ fn main() { let api = GetInfo2Builder::new() .access_key(access_key.clone()) .finalize(); - println!("{}", api.exec().unwrap()); + for (coin, amount) in api.exec().unwrap().funds.iter() { + println!("coin: {} amount: {}", coin, amount); + } let api = TradeBuilder::new() .access_key(access_key.clone()) @@ -51,11 +53,20 @@ fn main() { .price(1.0) .amount(0.1) .finalize(); - match api.exec() { - Ok(res) => { - println!("{}", res); - let json: Value = serde_json::from_str(res.as_str()).unwrap(); - let order_id = json["return"]["order_id"].as_u64().unwrap(); + match api.exec() + .and_then(|res| { + println!( + "received: {}, remains: {}, order_id: {}", + res.received, + res.remains, + res.order_id + ); + if res.order_id == 0 { + panic!("Complete trade."); + } + Ok(res.order_id) + }) + .and_then(|order_id| { let api = CancelOrderBuilder::new() .access_key(access_key.clone()) .order_id(order_id) @@ -63,14 +74,29 @@ fn main() { .finalize(); let wait_time = time::Duration::from_secs(5); thread::sleep(wait_time); - println!("{}", api.exec().unwrap()); - } - _ => return, + api.exec() + }) + .and_then(|res| { + println!("Cancel order_id: {}", res.order_id); + Ok(()) + }) { + + Ok(_) => println!("Complete trade and cancel"), + Err(e) => println!("Error: {}", e), } let api = ActiveOrdersBuilder::new() .access_key(access_key.clone()) .currency_pair(Some("zaif_jpy".to_string())) .finalize(); - println!("{}", api.exec().unwrap()); + for (order_id, order) in api.exec().unwrap().iter() { + println!( + "order_id: {}, currency_pair: {}, action: {}, amount: {}, price: {}", + order_id, + order.currency_pair, + order.action, + order.amount, + order.price + ); + } } diff --git a/src/trade_api/active_orders.rs b/src/trade_api/active_orders.rs index e21ecd5..49f462d 100644 --- a/src/trade_api/active_orders.rs +++ b/src/trade_api/active_orders.rs @@ -1,8 +1,10 @@ -extern crate reqwest; +extern crate serde; +extern crate serde_json; use std::collections::HashMap; -use core::*; +use trade_api::TradeApi; +use core::AccessKey; builder!(ActiveOrdersBuilder => ActiveOrders { access_key: AccessKey = AccessKey::new("", ""), @@ -10,24 +12,36 @@ builder!(ActiveOrdersBuilder => ActiveOrders { }); impl ActiveOrders { - pub fn exec(&self) -> reqwest::Result { - let param: &mut HashMap = &mut HashMap::new(); - param.insert("method".to_string(), "active_orders".to_string()); + pub fn exec(&self) -> serde_json::Result> { + serde_json::from_value(::exec(&self)?) + } +} + +impl TradeApi for ActiveOrders { + fn method(&self) -> &str { + "active_orders" + } + fn parameters(&self) -> HashMap { + let mut param = HashMap::new(); if let Some(ref currency_pair) = self.currency_pair { param.insert( "currency_pair".to_string(), format!("{}", currency_pair.clone()), ); } - - let api = ApiBuilder::new() - .access_key(self.access_key.clone()) - .uri("https://api.zaif.jp/tapi") - .method(Method::Post) - .param(param.clone()) - .finalize(); - - api.exec() + param + } + fn access_key(&self) -> &AccessKey { + &self.access_key } } +#[derive(Deserialize)] +pub struct ActiveOrdersResponse { + pub currency_pair: String, + pub action: String, + pub amount: f64, + pub price: f64, + pub timestamp: String, + pub comment: String, +} diff --git a/src/trade_api/cancel_order.rs b/src/trade_api/cancel_order.rs index 95b7643..79fbb01 100644 --- a/src/trade_api/cancel_order.rs +++ b/src/trade_api/cancel_order.rs @@ -1,8 +1,10 @@ -extern crate reqwest; +extern crate serde; +extern crate serde_json; use std::collections::HashMap; -use core::*; +use trade_api::TradeApi; +use core::AccessKey; builder!(CancelOrderBuilder => CancelOrder { access_key: AccessKey = AccessKey::new("", ""), @@ -11,9 +13,17 @@ builder!(CancelOrderBuilder => CancelOrder { }); impl CancelOrder { - pub fn exec(&self) -> reqwest::Result { - let param: &mut HashMap = &mut HashMap::new(); - param.insert("method".to_string(), "cancel_order".to_string()); + pub fn exec(&self) -> serde_json::Result { + serde_json::from_value(::exec(&self)?) + } +} + +impl TradeApi for CancelOrder { + fn method(&self) -> &str { + "cancel_order" + } + fn parameters(&self) -> HashMap { + let mut param = HashMap::new(); param.insert("order_id".to_string(), format!("{}", self.order_id)); if let Some(ref currency_pair) = self.currency_pair { param.insert( @@ -21,15 +31,15 @@ impl CancelOrder { format!("{}", currency_pair.clone()), ); } - - let api = ApiBuilder::new() - .access_key(self.access_key.clone()) - .uri("https://api.zaif.jp/tapi") - .method(Method::Post) - .param(param.clone()) - .finalize(); - - api.exec() + param + } + fn access_key(&self) -> &AccessKey { + &self.access_key } } +#[derive(Deserialize)] +pub struct CancelOrderResponse { + pub order_id: u64, + pub funds: HashMap, +} diff --git a/src/trade_api/get_info2.rs b/src/trade_api/get_info2.rs index 0d09c29..b327b08 100644 --- a/src/trade_api/get_info2.rs +++ b/src/trade_api/get_info2.rs @@ -1,29 +1,38 @@ -extern crate reqwest; +extern crate serde; +extern crate serde_json; use std::collections::HashMap; -use core::*; +use trade_api::TradeApi; +use core::AccessKey; builder!(GetInfo2Builder => GetInfo2 { access_key: AccessKey = AccessKey::new("", "") }); impl GetInfo2 { - pub fn new(access_key: AccessKey) -> GetInfo2 { - GetInfo2 { access_key: access_key } + pub fn exec(&self) -> serde_json::Result { + serde_json::from_value(::exec(&self)?) } - pub fn exec(&self) -> reqwest::Result { - let param: &mut HashMap = &mut HashMap::new(); - param.insert("method".to_string(), "get_info2".to_string()); - - let api = ApiBuilder::new() - .access_key(self.access_key.clone()) - .uri("https://api.zaif.jp/tapi") - .method(Method::Post) - .param(param.clone()) - .finalize(); +} - api.exec() +impl TradeApi for GetInfo2 { + fn method(&self) -> &str { + "get_info2" + } + fn parameters(&self) -> HashMap { + HashMap::new() + } + fn access_key(&self) -> &AccessKey { + &self.access_key } } +#[derive(Deserialize)] +pub struct GetInfo2Response { + pub funds: HashMap, + pub deposit: HashMap, + pub rights: HashMap, + pub open_orders: i64, + pub server_time: i64, +} diff --git a/src/trade_api/mod.rs b/src/trade_api/mod.rs index 73d1939..23d0777 100644 --- a/src/trade_api/mod.rs +++ b/src/trade_api/mod.rs @@ -1,3 +1,11 @@ +extern crate reqwest; +extern crate serde_json; + +use std::collections::HashMap; +use self::serde_json::Value; + +use core::*; + pub use self::get_info2::*; pub use self::trade::*; pub use self::active_orders::*; @@ -7,3 +15,31 @@ mod get_info2; mod trade; mod active_orders; mod cancel_order; + +trait TradeApi { + fn method(&self) -> &str; + fn parameters(&self) -> HashMap; + fn access_key(&self) -> &AccessKey; + + fn exec(&self) -> serde_json::Result { + let mut param = self.parameters().clone(); + param.insert("method".to_string(), self.method().to_string()); + + let api = ApiBuilder::new() + .access_key(self.access_key().clone()) + .uri("https://api.zaif.jp/tapi") + .method(Method::Post) + .param(param) + .finalize(); + + let res = match api.exec() { + Ok(res) => res, + Err(e) => panic!("reqwest Error: {}", e), + }; + let result: Value = serde_json::from_str(res.as_str())?; + if result["success"].as_i64().unwrap() != 1 { + panic!("error: {}", result["error"]); + } + Ok(result["return"].clone()) + } +} diff --git a/src/trade_api/trade.rs b/src/trade_api/trade.rs index f32ab38..eab81b1 100644 --- a/src/trade_api/trade.rs +++ b/src/trade_api/trade.rs @@ -1,8 +1,10 @@ -extern crate reqwest; +extern crate serde; +extern crate serde_json; use std::collections::HashMap; -use core::*; +use trade_api::TradeApi; +use core::AccessKey; #[derive(Copy, Clone)] pub enum TradeAction { @@ -31,9 +33,17 @@ builder!(TradeBuilder => Trade { }); impl Trade { - pub fn exec(&self) -> reqwest::Result { - let param: &mut HashMap = &mut HashMap::new(); - param.insert("method".to_string(), "trade".to_string()); + pub fn exec(&self) -> serde_json::Result { + serde_json::from_value(::exec(&self)?) + } +} + +impl TradeApi for Trade { + fn method(&self) -> &str { + "trade" + } + fn parameters(&self) -> HashMap { + let mut param = HashMap::new(); param.insert("currency_pair".to_string(), self.currency_pair.clone()); param.insert("action".to_string(), self.action.param_string()); param.insert("price".to_string(), format!("{}", self.price)); @@ -44,15 +54,17 @@ impl Trade { if let Some(ref comment) = self.comment { param.insert("comment".to_string(), format!("{}", comment.clone())); } - - let api = ApiBuilder::new() - .access_key(self.access_key.clone()) - .uri("https://api.zaif.jp/tapi") - .method(Method::Post) - .param(param.clone()) - .finalize(); - - api.exec() + param + } + fn access_key(&self) -> &AccessKey { + &self.access_key } } +#[derive(Deserialize)] +pub struct TradeResponse { + pub received: f64, + pub remains: f64, + pub order_id: u64, + pub funds: HashMap, +}