mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-13 17:42:42 +08:00
ENH: Restrict limit prices to a penny precision
to account for minimum price variation. On an order to buy, between .05 below to .95 above a penny, use that penny. On an order to sell, between .05 above to .95 below a penny, use that penny.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
from nose_parameterized import parameterized
|
||||
from unittest import TestCase
|
||||
|
||||
from zipline.finance.blotter import round_for_minimum_price_variation
|
||||
|
||||
|
||||
class BlotterTestCase(TestCase):
|
||||
|
||||
@parameterized.expand([(0.00, 0.00),
|
||||
(0.01, 0.01),
|
||||
(0.0005, 0.00),
|
||||
(1.006, 1.00),
|
||||
(1.0095, 1.01),
|
||||
(1.00949, 1.00),
|
||||
(1.0005, 1.00)])
|
||||
def test_round_for_minimum_price_variation_buy(self, price, expected):
|
||||
result = round_for_minimum_price_variation(price, is_buy=True)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
@parameterized.expand([(0.00, 0.00),
|
||||
(0.01, 0.01),
|
||||
(0.0005, 0.00),
|
||||
(1.006, 1.01),
|
||||
(1.0005, 1.00),
|
||||
(1.00051, 1.01),
|
||||
(1.0095, 1.01)])
|
||||
def test_round_for_minimum_price_variation_sell(self, price, expected):
|
||||
result = round_for_minimum_price_variation(price, is_buy=False)
|
||||
self.assertEqual(result, expected)
|
||||
@@ -42,6 +42,14 @@ ORDER_STATUS = Enum(
|
||||
)
|
||||
|
||||
|
||||
# On an order to buy, between .05 below to .95 above a penny, use that penny.
|
||||
# On an order to sell, between .05 above to .95 below a penny, use that penny.
|
||||
# buy: [.0095, .0195) -> round to .01, sell: (.0005, .0105] -> round to .01
|
||||
def round_for_minimum_price_variation(x, is_buy, diff=(0.0095 - .005)):
|
||||
# relies on rounding half away from zero, unlike numpy's bankers' rounding
|
||||
return round(x - (diff if is_buy else -diff), 2)
|
||||
|
||||
|
||||
class Blotter(object):
|
||||
|
||||
def __init__(self):
|
||||
@@ -107,6 +115,9 @@ class Blotter(object):
|
||||
raise OverflowError("Can't order more than %d shares" %
|
||||
self.max_shares)
|
||||
|
||||
if limit_price:
|
||||
limit_price = round_for_minimum_price_variation(limit_price,
|
||||
amount > 0)
|
||||
order = Order(
|
||||
dt=self.current_dt,
|
||||
sid=sid,
|
||||
|
||||
Reference in New Issue
Block a user