Skip to content

Commit

Permalink
market order
Browse files Browse the repository at this point in the history
  • Loading branch information
Dave Pettypiece committed Oct 25, 2016
1 parent 93c704b commit af88662
Show file tree
Hide file tree
Showing 2 changed files with 383 additions and 0 deletions.
298 changes: 298 additions & 0 deletions src/order/args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
from datetime import datetime
import argparse
import common.arg_helper
import v20.transaction


class OrderArguments(object):
def __init__(self, parser):
self.parser = parser
self.order_request = {}
self.params_parsers = []

def parse_arguments(self, args):
for parser in self.params_parsers:
parser(args)

def add_instrument(self):
self.parser.add_argument(
"--instrument",
type=common.arg_helper.instrument,
required=True,
help="The instrument to place the Order for"
)

self.params_parsers.append(
lambda args: self.parse_instrument(args)
)

def parse_instrument(self, args):
if args.instrument is None:
return

self.order_request["instrument"] = args.instrument


def add_units(self):
self.parser.add_argument(
"--units",
help=(
"The number of units for the Order. "
"Negative values indicate sell, Positive values indicate buy"
)
)

self.params_parsers.append(
lambda args: self.parse_units(args)
)


def parse_units(self, args):
if args.units is None:
return

self.order_request["units"] = args.units


def add_time_in_force(self, choices=["FOK", "IOC", "GTC", "GFD", "GTD"]):
self.parser.add_argument(
"--time-in-force",
choices=choices,
help="The time-in-force to use for the Order"
)

if "GTD" in choices:
self.parser.add_argument(
"--gtd-time",
type=date_time(),
help=(
"The date to use when the time-in-force is GTD. "
"Format is 'YYYY-MM-DD HH:MM:SS"
)
)

self.params_parsers.append(
lambda args: self.parse_time_in_force(args)
)


def parse_time_in_force(self, args):
if args.time_in_force is None:
return

self.order_request["timeInForce"] = args.time_in_force

if args.time_in_force != "GTD":
return

if args.gtd_time is None:
self.parser.error(
"must set --gtd-time \"YYYY-MM-DD HH:MM:SS\" when "
"--time-in-force=GTD"
)
return

self.order_request["gtdTime"] = args.gtd_time.strftime("%Y-%m-%dT%H:%M:%S.000000000Z")


def add_price_bound(self):
self.parser.add_argument(
"--price-bound",
help="The worst price bound allowed for the Order"
)

self.params_parsers.append(
lambda args: self.parse_price_bound(args)
)


def parse_price_bound(self, args):
if args.price_bound is None:
return

self.order_request["priceBound"] = args.price_bound


def add_position_fill(self):
self.parser.add_argument(
"--position-fill",
choices=["DEFAULT", "OPEN_ONLY", "REDUCE_FIRST", "REDUCE_ONLY"],
required=False,
help="Specification of how the Order may affect open positions."
)

self.params_parsers.append(
lambda args: self.parse_position_fill(args)
)


def parse_position_fill(self, args):
if args.position_fill is None:
return

self.order_request["positionFill"] = args.position_fill


def add_client_order_extensions(self):
self.parser.add_argument(
"--client-order-id",
help="The client-provided ID to assign to the Order"
)

self.parser.add_argument(
"--client-order-tag",
help="The client-provided tag to assign to the Order"
)

self.parser.add_argument(
"--client-order-comment",
help="The client-provided comment to assign to the Order"
)

self.params_parsers.append(
lambda args: self.parse_client_order_extensions(args)
)


def parse_client_order_extensions(self, args):
if (args.client_order_id is None and
args.client_order_tag is None and
args.client_order_comment is None):
return

kwargs = {}

if args.client_order_id is not None:
kwargs["id"] = args.client_order_id

if args.client_order_tag is not None:
kwargs["tag"] = args.client_order_tag

if args.client_order_comment is not None:
kwargs["comment"] = args.client_order_comment

self.order_request["clientExtensions"] = v20.transaction.ClientExtensions(
**kwargs
)


def add_client_trade_extensions(self):
self.parser.add_argument(
"--client-trade-id",
help="The client-provided ID to assign a Trade opened by the Order"
)

self.parser.add_argument(
"--client-trade-tag",
help="The client-provided tag to assign to a Trade opened by the Order"
)

self.parser.add_argument(
"--client-trade-comment",
help="The client-provided comment to assign to a Trade opened by the Order"
)

self.params_parsers.append(
lambda args: self.parse_client_trade_extensions(args)
)


def parse_client_trade_extensions(self, args):
if (args.client_trade_id is None and
args.client_trade_tag is None and
args.client_trade_comment is None):
return None

kwargs = {}

if args.client_trade_id is not None:
kwargs["id"] = args.client_trade_id

if args.client_trade_tag is not None:
kwargs["tag"] = args.client_trade_tag

if args.client_trade_comment is not None:
kwargs["comment"] = args.client_trade_comment

self.order_request["tradeClientExtensions"] = v20.transaction.ClientExtensions(
**kwargs
)


def add_take_profit_on_fill(self):
self.parser.add_argument(
"--take-profit-price",
help=(
"The price of the Take Profit to add to a Trade opened by this "
"Order"
)
)

self.params_parsers.append(
lambda args: self.parse_take_profit_on_fill(args)
)


def parse_take_profit_on_fill(self, args):
if args.take_profit_price is None:
return

kwargs = {}

kwargs["price"] = args.take_profit_price

self.order_request["takeProfitOnFill"] = \
v20.transaction.TakeProfitDetails(**kwargs)


def add_stop_loss_on_fill(self):
self.parser.add_argument(
"--stop-loss-price",
help=(
"The price of the Stop Loss to add to a Trade opened by this "
"Order"
)
)

self.params_parsers.append(
lambda args: self.parse_stop_loss_on_fill(args)
)


def parse_stop_loss_on_fill(self, args):
if args.stop_loss_price is None:
return

kwargs = {}

kwargs["price"] = args.stop_loss_price

self.order_request["stopLossOnFill"] = \
v20.transaction.StopLossDetails(**kwargs)


def add_trailing_stop_loss_on_fill(self):
self.parser.add_argument(
"--trailing-stop-loss-distance",
help=(
"The price distance for the Trailing Stop Loss to add to a Trade "
"opened by this Order"
)
)

self.params_parsers.append(
lambda args: self.parse_trailing_stop_loss_on_fill(args)
)


def parse_trailing_stop_loss_on_fill(self, args):
if args.trailing_stop_loss_distance is None:
return

kwargs = {}

kwargs["distance"] = args.stop_loss_distance

self.order_request["trailingStopLossOnFill"] = v20.transaction.TrailingStopLossDetails(
**kwargs
)
85 changes: 85 additions & 0 deletions src/order/market.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env python

import argparse
import common.config
import common.arg_helper
from args import OrderArguments
from v20.order import MarketOrderRequest
from common.view import print_response_transaction


def main():

parser = argparse.ArgumentParser()

#
# Add the command line argument to parse to the v20 config
#
common.config.add_argument(parser)

#
# Add the command line arguments required for a Market Order
#
orderArgs = OrderArguments(parser)
orderArgs.add_instrument()
orderArgs.add_units()
orderArgs.add_time_in_force(["FOK", "IOC"])
orderArgs.add_price_bound()
orderArgs.add_position_fill()
orderArgs.add_take_profit_on_fill()
orderArgs.add_stop_loss_on_fill()
orderArgs.add_trailing_stop_loss_on_fill()
orderArgs.add_client_order_extensions()
orderArgs.add_client_trade_extensions()

args = parser.parse_args()

#
# Extract the Market order parameters from the parsed arguments
#
orderArgs.parse_arguments(args)

account_id = args.config.active_account

api = args.config.create_context()

#
# Create a MarketOrderRequest from the parsed arguments
#
order_request = MarketOrderRequest(**orderArgs.order_request)

#
# Submit the request to create the Market Order
#
response = api.order.create(account_id, order=order_request)

if response.status / 100 != 2:
print "Error {}: {}".format (response.status, response.body)
return

#
# Print out the resulting transactions if they exist in the response
#
print_response_transaction(
response, 201, "Order Create", "orderCreateTransaction"
)

print_response_transaction(
response, 201, "Order Fill", "orderFillTransaction"
)

print_response_transaction(
response, 201, "Order Cancel", "orderCancelTransaction"
)

print_response_transaction(
response, 201, "Order Reissue", "orderReissueTransaction"
)

print_response_transaction(
response, 400, "Order Reject", "orderRejectTransaction"
)


if __name__ == "__main__":
main()

0 comments on commit af88662

Please sign in to comment.