In this post I will talk about the StockFighter framework
that I crated for the Swift language named RSStockFighter. If you have not heard about StockFighter,
it is a really nice (and free) online coding challenge where you need to solve
a series of problems by using your coding skills. You can read about StockFigher here. The
GitHub repository for RSStockFighter is here. I am currently finishing up my third book on
the Swift programming language so I have not had a lot of time to play the
StockFighter game (yet) but I have used RSStockFighter to make it though level
4.
I first read about StockFighter on DZone. The idea behind StockFighter is you are a
developer that has been tasked to create an automated trading system designed
to automate stock trading for your firm.
The game has several levels that progressively get harder. The first few levels are designed to get you
familiar with the API while later levels require you to incorporate logic to
determine when to buy and when to sell your stocks. Don’t worry if you do not have any stock
market experience, the game teaches you everything you need to know to complete
each level.
All of the APIs are REST based which means you can use any
language you want to complete the levels.
I obviously chose to use the Swift language. Why?
Because I really like programming with the Swift language. RSStockFighter is designed to make it very
easy to interact with the StockFighter API so you can focus on solving the
levels rather than the backend network code.
When I started looking at the StockFighter API, my first
thought was I needed to create a framework for the API so I would not need to
keep creating or cutting/pasting the code to perform the network requests in
each challenge. In this post I will explain
how I designed RSStockFighter and how you can use it in your code.
At the time I am writing this document, StockFighter has ten
documented API calls (I have currently implemented seven of the calls in RSStockFighter).
One of my biggest concerns is the StockFighter challenge has not been around
very long therefore I suspect they will be changing and/or adding to the
API. This means that it needs to be easy
to add new API calls to RSStockFighter.
When I have a design problem like this I usually start off by pulling
out one of my design pattern books and look through it to see if any of the
patterns may solve my problem. In this
case the command pattern was perfectly suited for my needs.
The command
pattern falls under the behavioral patter group. In this pattern we encapsulate the logic of our
actions into types that conforms to a command protocol. We can then provide instances of the command
types for use by an invoker. The invoker
will use the interface provided by the protocol to invoke the actions on the
types that conform to that protocol.
What this means is we will create a separate command type for each one
of our API calls. We will then submit
instances of these types to our invoker which will make the call to the
StockFighter API.
The class
structure to make our API calls will look like this:
The StockFighter request types will encapsulate the
information needed to make the individual requests. The RSStockFighterTransaction
type will contain an instance of a StockFighter request type and also the
information to make the network request.
Finally the RSStockFighterTransactionRequest
will contain methods to make the actual network request to the StockFighter
API.
I created a type named StockFighterHelper
which implements the Façade pattern to hide the underlying RSStockFighterTransaction and RSStockFighterTransactionRequest
types. I did this for two reasons. The first is to hide the complexity of the
types and the second is to make it easy to change the interfaces of these types
if needed.
In addition to the seven StockFighter request types we also
have seven StockFighter response types.
These response types will encapsulate the logic needed to parse the
response. This will make it easy to pull
the information from the response, as we need it.
Enough about the design of RSStockFighter, lets see how we
would use it. We will start off by
seeing if the StockFighter API is up.
The following code will make a request to check the status of the
stockFighter API.
func apiStatus() {
StockFighterHelper.sendStockFighterTransaction(request,
success: {
(dict:NSDictionary!) -> Void in
self.checkStatusResponse(dict)
}, failure: {
(str: String) -> Void in
print("Error: \(str)")
})
}
}
In this function we begin by creating an instance of the StockFighterAPIStatus type. We then call the static sendStockFighterTransaction() method from the StockFighterHelper protocol.
The sendStockFighterTransaction()
method takes three parameters which are:
- transType: An instance of a type that conforms to the StockFigherRequestType type which contains the information for our request.
- success: A completion handler that will be called if the StockFighter API call was successful
- failure: A completion handler that will be called if the StockFigher API call failed.
The checkStatusResponse() method called if the API call was
successful looks like this:
let response = StockFighterAPIStatusResponse(dict: dict)
print("StockFighter is up:
\(response.ok)")
}
}
In this method we use the StockfighterAPIStatusResponse type to parse the response. We then print a message to the console
letting us know if the Stock Fighter API is up or not.
That was pretty easy but lets look at a more difficult API
call like placing a new order. The
following code demonstrates how to do this:
let order = StockFighterOrder(symbol:SF_STOCK_SYMBOL, price:95.00,qty: 100,direction:SF_OrderDirection.Buy,orderType:SF_OrderTypes.Limit.rawValue)
StockFighterHelper.sendStockFighterTransaction(order, success: {
(dict:NSDictionary!) -> Void in
self.checkOrderResponse(dict)
}, failure: {(str: String) -> Void in
print(str)
})
})
In this example we create an instance of the StockFighterOrder type. The initializer for this
type takes five parameters which are:
- symbol: The stock symbol for the stock to place the order for
- price: The maximum price to buy or minimum price to sell the stock at
- qty: The quantity to buy or sell
- direction: Specifies if this is a buy or a sell order
- orderType: The order type
If the API call was successful we would parse the response
using the StockFighterOrderResponse
type like this:
Pretty easy, don’t you think? The seven StockFighter request types that I
have implemented in RSStockFighter are:
- StockFighterAPIStatus
- StockFighterVenueStatus
- StockFighterStocksOnVenue
- StockFighterOrder
- StockFighterOrderBook
- StockFighterQueryOrder
- StockFighterCancelOrder
- StockFighterAPIStatusResponse
- StockFighterVenueStatusResponse
- StockFighterStocksOnVenueResponse
- StockFighterOrderResponse
- StockFighterOrderBookResponse
- StockFighterQueryOrderResponse
- StockFighterCancelOrderResponse
There are two enumerations defined in this
framework that you will be working with.
These are the SF_OrderTypes
and SF_OrderDirection
enumerations. The SF_OrderTypes enumeration defines the type of order we are placing (You
can read more about order types in the StockFighter help pages) and has the
following values:
- Limit - Immediately matches any order on the books that has an offer price as good or better than the one listed on the order. This order type is good until cancelled
- Market - Immediately matches any order. Do not use this type.
- FOK - Fill or Kill: Immediately fills the whole order. If it cannot fill the whole order immediately then the whole order is killed
- IOC - Immediate or Cancel: Immediately fills or partially fills the whole order and then cancels any shares that remains.
- Buy - The order is a purchase shares
- Sell - The order is to sell shares
Before you can use the API, you do need to make changes to a
couple global constants. These constants
are in the StockFighterInfo.swift file.
- SF_API_KEY – Your API ley
- SF_VENUE – The venue you are using for this challenge
- SF_ACCOUNT – The account you are using for this challenge
- SF_STOCK_SYMBOL – The symbol of the stock you are using for this challenge
Overall the framework consists of six files that you will
need to download and include in your project.
These files are:
- StockFighterInfo
- StockFighterKeys
- StockFighterRequestTypes
- StockFighterResponseTypes
- RSStockFighterTransactionRequest
- RSStockFighterTransaction
So why am I releasing
this framework? I would like to see
how many Swift Developers can complete this challenge. As you go though the levels using
RSStockFighter, post a comment to this blog posting telling us how far you have
advanced (please no hints on how to complete a level).
Is using
RSStockFighter cheating at the challenge?
Personally I do not think so.
I see using RSStockFighter like using any other third party framework
(like the Alamofire framework) in our applications. We use third party frameworks in our day to
day development work to make our lives easier so we can focus on the business
logic, why not use them to make challenges like this easier so we can focus on
the business logic.
Good luck and happy coding.
No comments:
Post a Comment