bitmex-rs
bitmex-rs copied to clipboard
Bulk Cancel Multiple Limit Orders Fails With: value: Custom("unsupported value")
@dovahcrow I just ran my test suite against the latest in master and found out bulk cancel is no longer working. Here is what it is basically doing:
let ord_id1 = gen_ord_id();
rt.block_on(bm.request(post_limit_order(6000., 100, ord_id1.clone()))).unwrap();
let ord_id2 = gen_ord_id();
rt.block_on(bm.request(post_limit_order(7000., 100, ord_id2.clone()))).unwrap();
let mut ord_ids: Vec<serde_json::Value> = Vec::new();
ord_ids.push(serde_json::Value::String(ord_id1.clone()));
ord_ids.push(serde_json::Value::String(ord_id2.clone()));
let _ = rt.block_on(bm.request(DeleteOrderRequest {
cl_ord_id: Some(serde_json::Value::Array(ord_ids)),
..Default::default()
})).unwrap();
Here is post_limit_order:
fn post_limit_order(price: f64, qty: i32, cl_ord_id: String) -> PostOrderRequest {
PostOrderRequest {
symbol: "XBTUSD".to_string(),
side: None,
simple_order_qty: None,
order_qty: Some(qty),
price: Some(price),
display_qty: None,
stop_px: None,
cl_ord_id: Some(cl_ord_id),
cl_ord_link_id: None,
peg_offset_value: None,
peg_price_type: None,
ord_type: Some(OrdType::Limit),
time_in_force: None,
exec_inst: None,
contingency_type: None,
text: Some("Shine".into()),
}
}
Here is the stack:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("unsupported value")
0: backtrace::backtrace::dbghelp::trace
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.55\src\backtrace\dbghelp.rs:98
1: backtrace::backtrace::trace_unsynchronized<closure-0>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.55\src\backtrace\mod.rs:66
2: backtrace::backtrace::trace<closure-0>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.55\src\backtrace\mod.rs:53
3: backtrace::capture::Backtrace::create
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.55\src\capture.rs:176
4: backtrace::capture::Backtrace::new_unresolved
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.55\src\capture.rs:170
5: failure::backtrace::internal::InternalBacktrace::new
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\failure-0.1.8\src\backtrace\internal.rs:46
6: failure::backtrace::Backtrace::new
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\failure-0.1.8\src\backtrace\mod.rs:121
7: failure::error::error_impl::{{impl}}::from<serde_urlencoded::ser::Error>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\failure-0.1.8\src\error\error_impl.rs:19
8: failure::error::{{impl}}::from<serde_urlencoded::ser::Error>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\failure-0.1.8\src\error\mod.rs:36
9: bitmex::rest::client::{{impl}}::request::{{closure}}<bitmex::rest::models::requests::DeleteOrderRequest>
at C:\Users\kr\.cargo\git\checkouts\bitmex-rs-2861a3a714a639fb\8dfa7d7\src\rest\client.rs:63
10: core::future::from_generator::{{impl}}::poll<generator-0>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\future\mod.rs:66
11: tokio::runtime::enter::{{impl}}::block_on::{{closure}}<core::future::from_generator::GenFuture<generator-0>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\enter.rs:160
12: tokio::coop::with_budget::{{closure}}<core::task::poll::Poll<core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>>,closure-0>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\coop.rs:127
13: std::thread::local::LocalKey<core::cell::Cell<tokio::coop::Budget>>::try_with<core::cell::Cell<tokio::coop::Budget>,closure-0,core::task::poll::Poll<core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>>>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\thread\local.rs:263
14: std::thread::local::LocalKey<core::cell::Cell<tokio::coop::Budget>>::with<core::cell::Cell<tokio::coop::Budget>,closure-0,core::task::poll::Poll<core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>>>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\thread\local.rs:239
15: tokio::coop::with_budget
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\coop.rs:120
16: tokio::coop::budget
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\coop.rs:96
17: tokio::runtime::enter::Enter::block_on<core::future::from_generator::GenFuture<generator-0>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\enter.rs:160
18: tokio::runtime::thread_pool::ThreadPool::block_on<core::future::from_generator::GenFuture<generator-0>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\thread_pool\mod.rs:82
19: tokio::runtime::{{impl}}::block_on::{{closure}}<core::future::from_generator::GenFuture<generator-0>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\mod.rs:446
20: tokio::runtime::context::enter<closure-0,core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\context.rs:72
21: tokio::runtime::handle::Handle::enter<closure-0,core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\handle.rs:76
22: tokio::runtime::Runtime::block_on<core::future::from_generator::GenFuture<generator-0>>
at C:\Users\kr\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.22\src\runtime\mod.rs:441
23: rust::main
at src\main.rs:29
24: std::rt::lang_start::{{closure}}<()>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
25: std::rt::lang_start_internal::{{closure}}
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\rt.rs:52
26: std::panicking::try::do_call
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:331
27: std::panicking::try
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:274
28: std::panic::catch_unwind
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panic.rs:394
29: std::rt::lang_start_internal
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\rt.rs:51
30: std::rt::lang_start<()>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
31: main
32: invoke_main
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
33: __scrt_common_main_seh
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
34: BaseThreadInitThunk
35: RtlUserThreadStart
', src\main.rs:29:13
stack backtrace:
0: backtrace::backtrace::trace_unsynchronized
at C:\Users\VssAdministrator\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace\mod.rs:66
1: std::sys_common::backtrace::_print_fmt
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\sys_common\backtrace.rs:78
2: std::sys_common::backtrace::_print::{{impl}}::fmt
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\sys_common\backtrace.rs:59
3: core::fmt::write
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libcore\fmt\mod.rs:1069
4: std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\io\mod.rs:1504
5: std::sys_common::backtrace::_print
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\sys_common\backtrace.rs:62
6: std::sys_common::backtrace::print
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\sys_common\backtrace.rs:49
7: std::panicking::default_hook::{{closure}}
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:198
8: std::panicking::default_hook
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:218
9: std::panicking::rust_panic_with_hook
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:511
10: std::panicking::begin_panic_handler
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:419
11: core::panicking::panic_fmt
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libcore\panicking.rs:111
12: core::option::expect_none_failed
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libcore\option.rs:1268
13: core::result::Result<alloc::vec::Vec<bitmex::rest::models::definitions::Order>, failure::error::Error>::unwrap<alloc::vec::Vec<bitmex::rest::models::definitions::Order>,failure::error::Error>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\result.rs:1005
14: rust::main
at .\src\main.rs:29
15: std::rt::lang_start::{{closure}}<()>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
16: std::rt::lang_start_internal::{{closure}}
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\rt.rs:52
17: std::panicking::try::do_call
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:331
18: std::panicking::try
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panicking.rs:274
19: std::panic::catch_unwind
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\panic.rs:394
20: std::rt::lang_start_internal
at /rustc/c7087fe00d2ba919df1d813c040a5d47e43b0fe7\/src\libstd\rt.rs:51
21: std::rt::lang_start<()>
at C:\Users\kr\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
22: main
23: invoke_main
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
24: __scrt_common_main_seh
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
25: BaseThreadInitThunk
26: RtlUserThreadStart
I created a minimal reproducible case:
use bitmex::rest::DeleteOrderRequest;
use serde_urlencoded::to_string as to_ustring;
fn main() {
let mut ord_ids: Vec<serde_json::Value> = Vec::new();
ord_ids.push(serde_json::Value::String("asdf".to_string()));
let req = DeleteOrderRequest {
cl_ord_id: Some(serde_json::Value::Array(ord_ids)),
..Default::default()
};
println!("{}", to_ustring(&req).unwrap());
}
It seems like we need to provide our own array serializer for vector type when doing the URL encoding.
I also took a look at serde_qs
, it does not support serialize a vec
of strings to a comma-separated string too. I think the solution here would be to annotate the corresponding vec
fields with #[serde(deserialize_with)]
. Unfortunately, I don't have much time recently for this.