I started this blog in 2013 as a way to capture my ideas for building an automated option trading system (Option Algo System - OAS). At that time, I had already built version 1 of an option trading backtesting system (Option Strategy Backtester - OSB) and I was researching how to best integrate my backtesting system (written in Java) with an auto trading system.
Needless to say, as I worked towards the auto trading goal I had to refactor/redesign my backtesting system to utilize its strategies in live trading. I'm now on version 3 of the backtesting system (OSB) and the architecture of the software has changed significantly. Version 4 will be a radical architecture change as the system moves from strategies defined in property files to strategies defined in a database, and updated in the user interface you see taking shape on this blog. Also the output will move from being auto-generated in CSV files to output also being stored in a database (MySQL).
The data architecture of the trading system (OAS) is still similar to the diagram below.
I've left a few details (columns) off of some of the tables in order to show all of the tables and their relationships in the diagram. For example, security_option will have many more columns. The equivalent table in the backtesting system (OSB) currently has 22 columns. That means for every option, there are 22 attributes. The two tables outlined in blue have been built in the auto trading system (OAS). In order to have the auto trading system (OAS) be minimally integrated with the backtesting system (OSB) the tables in red will need to be built along with the associated Java code. The tables not outlined, along with the associated Java code, will be built next. The last tables/code to be built are those outlined in green.
Until the first step of the integration is complete (tables in red), I will post some backtesting results from OSB version 3. I will shoot for weekly posts of backtesting results interspersed with OAS development posts. If you're not interested in the system development, but you're interested in options trading, I will start to post for you soon.
My first post with backtesting results will be next week (after I download the options data through this week for RUT, SPX, and NDX). This first backtesting post will cover a standard iron condor using monthly options exprirations, with end-of-day (EOD) option data for the three vehicles (RUT, SPX, NDX). I will show the results for three or four different short strike deltas iron condors with a fixed days-to-expiration (DTE) trade start. More details in the actual post ...
A blog about options trading strategies (Iron Condors, Strangles, Calendars, Butterflies), equities rotation strategies, and Java related technologies to backtest and automate trading.
Showing posts with label Data Model. Show all posts
Showing posts with label Data Model. Show all posts
Saturday, April 19, 2014
Friday, April 18, 2014
Spring Security 3.2 - Users, Roles, Permissions - Part 1
This series of posts will expand the authorization model for our application. At a high level, we are going to add unique permissions to all of our controller class methods and service class methods. This modification will be modeled after the authorization structure (chapter 7) in Spring In Practice (2013). The revised security table structure is shown below, and supersedes the structure in the post Another Data Model Update.
1. The first step in this update is to create the table structure. The foreign key and unique index constraints were discussed in the post where we first added roles to the application. These constraints are required for our link tables to work correctly.
2. To ease the creation of data, we will create stored procedures to load the data.
3. Finally, we will load our sample data. We've created permissions that will be used in our strategy controller. I will use the convention of CTRL as a prefix for permissions associated with Spring Controllers, and the SVC prefix for permissions associated with Spring Services. The class name comes next, followed by the method name, followed by the HTTP method for controllers. As we add methods to our application, we will need to add method permissions to the permissions table, and then map these permissions to roles.
4. The entity to store our permissions is shown below. Note that this class implements the GrantedAuthority interface, so each instance/record will be considered an authority from the perspective of Spring Security. Also note the lines highlighted in blue correspond to messages contained in the ValidationMessages.properties file under the resources directory.
5. Our role entity will need to be updated to reference the permissions in the permissions entity. There are a few changes to note that are highlighted in blue below:
6. The user entity will also need to be updated as shown below. As with the Role class, the changes are highlighted in blue.
In the next post, we will add/update the DAO layer
![]() |
Trading System V2 Security - ERM Diagram Update |
1. The first step in this update is to create the table structure. The foreign key and unique index constraints were discussed in the post where we first added roles to the application. These constraints are required for our link tables to work correctly.
DROP TABLE IF EXISTS USER_ROLES; DROP TABLE IF EXISTS ROLE_PERMISSIONS; DROP TABLE IF EXISTS USERS; DROP TABLE IF EXISTS ROLES; DROP TABLE IF EXISTS PERMISSIONS; CREATE TABLE USERS ( ID INT(6) NOT NULL AUTO_INCREMENT, USERNAME VARCHAR(50) NOT NULL, PASSWORD VARCHAR(50) NOT NULL, ENABLED TINYINT(1) NOT NULL, PRIMARY KEY (ID), UNIQUE INDEX USERNAME (USERNAME) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1; CREATE TABLE ROLES ( ID INT(6) NOT NULL AUTO_INCREMENT, ROLENAME VARCHAR(50) NOT NULL, PRIMARY KEY (ID), UNIQUE INDEX ROLENAME (ROLENAME) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1; CREATE TABLE USER_ROLES ( USER_ID int(6) NOT NULL, ROLE_ID int(6) NOT NULL, KEY USER (USER_ID), KEY ROLE (ROLE_ID), CONSTRAINT USER FOREIGN KEY (USER_ID) REFERENCES USERS (ID) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT ROLE FOREIGN KEY (ROLE_ID) REFERENCES ROLES (ID) ON DELETE CASCADE ON UPDATE CASCADE ) COLLATE='utf8_general_ci' ENGINE=InnoDB; CREATE TABLE PERMISSIONS ( ID INT(6) NOT NULL AUTO_INCREMENT, PERMISSIONNAME VARCHAR(50) NOT NULL, PRIMARY KEY(ID), UNIQUE INDEX PERMISSIONNAME (PERMISSIONNAME) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1; CREATE TABLE ROLE_PERMISSIONS ( ROLE_ID INT(6) NOT NULL, PERMISSION_ID INT(6) NOT NULL, FOREIGN KEY (ROLE_ID) REFERENCES ROLES (ID) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (PERMISSION_ID) REFERENCES PERMISSIONS (ID) ON DELETE CASCADE ON UPDATE CASCADE ) COLLATE='utf8_general_ci' ENGINE=InnoDB;
2. To ease the creation of data, we will create stored procedures to load the data.
delimiter // DROP PROCEDURE IF EXISTS createPermission; DROP PROCEDURE IF EXISTS createRole; DROP PROCEDURE IF EXISTS createRoleHasPermission; DROP PROCEDURE IF EXISTS createUser; DROP PROCEDURE IF EXISTS createUserHasRole; create procedure createPermission($name varchar(50)) begin insert into permissions (permissionname) values ($name); end // create procedure createRole($name varchar(50), out $id int) begin insert into roles (rolename) values ($name); set $id := last_insert_id(); end // create procedure createRoleHasPermission($role_id smallint, $perm_name varchar(50)) begin declare _perm_id int; select id from permissions where permissionname = $perm_name into _perm_id; insert into role_permissions (role_id, permission_id) values ($role_id, _perm_id); end // create procedure createUserEntry($name varchar(50), out $id int) begin insert into users (username, password, enabled) values ($name, 'password', 1); set $id := last_insert_id(); end // create procedure createUserHasRole($user_id int, $role_id smallint) begin insert into user_roles (user_id, role_id) values ($user_id, $role_id); end // delimiter ;
3. Finally, we will load our sample data. We've created permissions that will be used in our strategy controller. I will use the convention of CTRL as a prefix for permissions associated with Spring Controllers, and the SVC prefix for permissions associated with Spring Services. The class name comes next, followed by the method name, followed by the HTTP method for controllers. As we add methods to our application, we will need to add method permissions to the permissions table, and then map these permissions to roles.
-- Create permissions call createPermission('CTRL_STRATEGY_LIST_GET'); call createPermission('CTRL_STRATEGY_ADD_POST'); call createPermission('CTRL_STRATEGY_EDIT_GET'); call createPermission('CTRL_STRATEGY_EDIT_POST'); call createPermission('CTRL_STRATEGY_DELETE_GET'); -- Create roles call createRole('ROLE_ADMIN', @role_admin); call createRoleHasPermission(@role_admin, 'CTRL_STRATEGY_LIST_GET'); call createRoleHasPermission(@role_admin, 'CTRL_STRATEGY_ADD_POST'); call createRoleHasPermission(@role_admin, 'CTRL_STRATEGY_EDIT_GET'); call createRoleHasPermission(@role_admin, 'CTRL_STRATEGY_EDIT_POST'); call createRoleHasPermission(@role_admin, 'CTRL_STRATEGY_DELETE_GET'); call createRole('ROLE_TRADER', @role_trader); call createRole('ROLE_USER', @role_user); -- Create accounts call createUserEntry('admin', @admin); call createUserHasRole(@admin, @role_admin); call createUserEntry('trader', @trader); call createUserHasRole(@trader, @role_trader); call createUserEntry('user', @user); call createUserHasRole(@user, @role_user);
4. The entity to store our permissions is shown below. Note that this class implements the GrantedAuthority interface, so each instance/record will be considered an authority from the perspective of Spring Security. Also note the lines highlighted in blue correspond to messages contained in the ValidationMessages.properties file under the resources directory.
package com.dtr.oas.model; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import com.google.common.base.Objects; @Entity @Table(name = "PERMISSIONS") public class Permission extends BaseEntity implements GrantedAuthority { private static final long serialVersionUID = -5404269148967698143L; static Logger logger = LoggerFactory.getLogger(Permission.class); @NotNull(message = "{error.permission.permissionname.null}") @NotEmpty(message = "{error.permission.permissionname.empty}") @Size(max = 50, message = "{permission.permissionname.role.max}") @Column(name = "permissionname", length = 50) private String permissionname; @OneToMany(fetch = FetchType.EAGER) @JoinTable(name = "role_permissions", joinColumns = {@JoinColumn(name = "permission_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")} ) private Set<Role> permRoles; public String getPermissionname() { return permissionname; } public void setPermissionname(String permissionname) { this.permissionname = permissionname; } @Override public String getAuthority() { return permissionname; } public Set<Role> getPermRoles() { return permRoles; } public void setPermRoles(Set<Role> permRoles) { this.permRoles = permRoles; } @Override public String toString() { return String.format("%s(id=%d, permissionname='%s')", this.getClass().getSimpleName(), this.getId(), this.getPermissionname()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) return false; if (o instanceof Role) { final Permission other = (Permission) o; return Objects.equal(getId(), other.getId()) && Objects.equal(getPermissionname(), other.getPermissionname()); } return false; } @Override public int hashCode() { return Objects.hashCode(getId(), getPermissionname()); } }
5. Our role entity will need to be updated to reference the permissions in the permissions entity. There are a few changes to note that are highlighted in blue below:
- This class now extends GrantedAuthority so that a role and a permission will both be considered authorities by Spring Security.
- After noticing some issues during unit testing, FetchType.EAGER was added to the user_roles @OneToMany annotation.
- A @OneToMany entry was added for the relationship between this Role class and the Permission class.
- Getters and setters were added for the permissions instance variable.
- A getAuthority() method was added to meet the requirement of the GrantedAuthority interface implementation.
package com.dtr.oas.model; import java.io.Serializable; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinTable; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import com.google.common.base.Objects; @Entity @Table(name = "ROLES") public class Role extends BaseEntity implements Serializable, GrantedAuthority { private static final long serialVersionUID = 6874667425302308430L; static Logger logger = LoggerFactory.getLogger(Role.class); @NotNull(message = "{error.roles.role.null}") @NotEmpty(message = "{error.roles.role.empty}") @Size(max = 50, message = "{error.roles.role.max}") @Column(name = "rolename", length = 50) private String rolename; //@OneToMany(cascade = CascadeType.ALL) @OneToMany(fetch = FetchType.EAGER) @JoinTable(name = "user_roles", joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")} ) private Set<User> userRoles; @OneToMany(fetch = FetchType.EAGER) @JoinTable(name = "role_permissions", joinColumns = { @JoinColumn(name = "role_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id", referencedColumnName = "id") } ) private Set<Permission> permissions; public String getRolename() { return rolename; } public void setRolename(String rolename) { this.rolename = rolename; } public Set<User> getUserRoles() { return userRoles; } public void setUserRoles(Set<User> userRoles) { this.userRoles = userRoles; } public Set<Permission> getPermissions() { return permissions; } public void setPermissions(Set<Permission> permissions) { this.permissions = permissions; } @Override public String toString() { return String.format("%s(id=%d, rolename='%s')", this.getClass().getSimpleName(), this.getId(), this.getRolename()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) return false; if (o instanceof Role) { final Role other = (Role) o; return Objects.equal(getId(), other.getId()) && Objects.equal(getRolename(), other.getRolename()); } return false; } @Override public int hashCode() { return Objects.hashCode(getId(), getRolename()); } @Override public String getAuthority() { return getRolename(); } }
6. The user entity will also need to be updated as shown below. As with the Role class, the changes are highlighted in blue.
- After noticing some issues during unit testing, FetchType.EAGER was added to the user_roles @OneToMany annotation.
- The instance variable role was changed to they type Set and renamed roles. A user has been updated to contain multiple roles if required.
- The associated getter and setter have been updated.
- The toString() method has been updated to not include the role.
- A getPermissions() method has been added to retrieve all of the permissions associated with all of the roles associated with a given user.
- The grantedAuthority() method has been updated to return all of the roles and all of the permissions for a given user.
package com.dtr.oas.model; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinTable; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import com.google.common.base.Objects; @Entity @Table(name="USERS") public class User extends BaseEntity implements UserDetails { private static final long serialVersionUID = 6311364761937265306L; static Logger logger = LoggerFactory.getLogger(User.class); @NotNull(message = "{error.user.username.null}") @NotEmpty(message = "{error.user.username.empty}") @Size(max = 50, message = "{error.user.username.max}") @Column(name = "username", length = 50) private String username; @NotNull(message = "{error.user.password.null}") @NotEmpty(message = "{error.user.password.empty}") @Size(max = 50, message = "{error.user.password.max}") @Column(name = "password", length = 50) private String password; @Column(name = "enabled") private boolean enabled; @OneToMany(fetch = FetchType.EAGER) @JoinTable(name = "user_roles", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")} ) private Set<Role> roles; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean getEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } @Override public String toString() { return String.format("%s(id=%d, username=%s, password=%s, enabled=%b)", this.getClass().getSimpleName(), this.getId(), this.getUsername(), this.getPassword(), this.getEnabled()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) return false; if (o instanceof User) { final User other = (User) o; return Objects.equal(getId(), other.getId()) && Objects.equal(getUsername(), other.getUsername()) && Objects.equal(getPassword(), other.getPassword()) && Objects.equal(getEnabled(), other.getEnabled()); } return false; } @Override public int hashCode() { return Objects.hashCode(getId(), getUsername(), getPassword(), getEnabled()); } @Transient public Set<Permission> getPermissions() { Set<Permission> perms = new HashSet<Permission>(); for (Role role : roles) { perms.addAll(role.getPermissions()); } return perms; } @Override @Transient public Collection<GrantedAuthority> getAuthorities() { Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); authorities.addAll(getRoles()); authorities.addAll(getPermissions()); return authorities; } @Override public boolean isAccountNonExpired() { //return true = account is valid / not expired return true; } @Override public boolean isAccountNonLocked() { //return true = account is not locked return true; } @Override public boolean isCredentialsNonExpired() { //return true = password is valid / not expired return true; } @Override public boolean isEnabled() { return this.getEnabled(); } }
In the next post, we will add/update the DAO layer
Labels:
Authorization,
Data Model,
Hibernate,
MySQL,
Security,
Spring MVC
Wednesday, February 5, 2014
Data Model Details
The tables in the model include the user tables that are populated when a new user is created in the system. A user name is created by the UserService during the user registration phase.
After a user is created, an account is registered for that user by the AccountService. This table is a place holder at this point and will be refactored when connections to a broker are built. This table should be adequate during the first stages of system development. An account can be either regt or pm margined, and either funded or paper/simulation.
As strategies are developed, the strategy and strategy_settings tables are populated. An entry in the strategy_run is associated with a specific set of settings, a specific account, and specific date range. Multiple runs, can use the same set of strategy settings. The allocation amount from an account to a specific run is set in the account_strategy_run table. The allocation amount cannot be greater than the sum of the margin required by the strategy versus the account cash available. All of these updates are handled by the StrategyService.
A position is a set of options strikes, for example an iron condor, for specific expiration month. A new position (PositionService) and security_option(s) (SecuritiesService) are created by the StrategyService just prior to the first order being sent by the StrategyService. An order value object is created and sent via JMS to the OrderService. The OrderService creates an entry in the order table and sends the order to the broker connector via JMS. The OrderService monitors the status of orders and will update/cancel orders. Order status alerts are sent by the OrderService to the StrategyService.
- users
- user_details
- user_email
- user_phone
- user_address
After a user is created, an account is registered for that user by the AccountService. This table is a place holder at this point and will be refactored when connections to a broker are built. This table should be adequate during the first stages of system development. An account can be either regt or pm margined, and either funded or paper/simulation.
- account
As strategies are developed, the strategy and strategy_settings tables are populated. An entry in the strategy_run is associated with a specific set of settings, a specific account, and specific date range. Multiple runs, can use the same set of strategy settings. The allocation amount from an account to a specific run is set in the account_strategy_run table. The allocation amount cannot be greater than the sum of the margin required by the strategy versus the account cash available. All of these updates are handled by the StrategyService.
- strategy
- strategy_settings
- strategy_run
- account_strategy_run
A position is a set of options strikes, for example an iron condor, for specific expiration month. A new position (PositionService) and security_option(s) (SecuritiesService) are created by the StrategyService just prior to the first order being sent by the StrategyService. An order value object is created and sent via JMS to the OrderService. The OrderService creates an entry in the order table and sends the order to the broker connector via JMS. The OrderService monitors the status of orders and will update/cancel orders. Order status alerts are sent by the OrderService to the StrategyService.
- position
- security_option
- order - composed of options_security entities, and may result in multiple fills/transactions
The OrderService will match fills to orders and will send fills via JMS to the TransactionService. The TransactionService will update the fill and transaction tables. The TransactionService will send a fill alert via JMS to the StrategyService . The StrategyService will then call the PositionService to update the position_details table.
- fill - composed of options_security entities
- transaction - composed of options_security entities, and associated with an order and position
- position_details - composed of transaction entities
The MetricsService will update the trade_summary and trade_details_by_day tables, as well as query these tables for data to display in charts.
- trade_summary
- trade_details_by_day
The next post will contain some ideas about other functionality required by the system.
Labels:
Data Model,
Design
Tuesday, February 4, 2014
Another Data Model Update
After additional review of my notes and thinking through the use cases a bit more, I've updated the ERM diagram for the trading system. The current version is below.
The system will use Spring Security, and the associated tables are below. The users table in the diagram above is the same users table shown in the next table. Persistent logins will not be used, but the table is still included in the diagram.
I suspect I will have at least one more update to the trading system diagram, but the structure is getting pretty close. I will describe how the tables will be used in one of the next posts.
![]() |
Trading System V1 - ERM Diagram - Third Draft |
The system will use Spring Security, and the associated tables are below. The users table in the diagram above is the same users table shown in the next table. Persistent logins will not be used, but the table is still included in the diagram.
![]() |
Trading System V1 Security - ERM Diagram |
I suspect I will have at least one more update to the trading system diagram, but the structure is getting pretty close. I will describe how the tables will be used in one of the next posts.
Labels:
Data Model,
Design,
MySQL
Monday, February 3, 2014
Trading System V1 Data Model Thoughts Continued
After further review of the design notes I've kept over the last few months, I made some updates to the data model I posted yesterday. Here's the new model created in MySQL Workbench:
![]() |
Trading System V1 - ERM Diagram - Second Draft |
Labels:
Data Model,
Design,
MySQL
Sunday, February 2, 2014
Trading System V1 Thoughts
Using the data model from the revised backtesting system as a starting point, I've started planning the data model and Java component interaction / logical architecture. The first draft of the ERM diagram is below:
The security_option table is a placeholder for a parent table called security. The SecurityOption will be a subclass of the Security abstract class in code.
![]() |
Trading System V1 - ERM Diagram |
The security_option table is a placeholder for a parent table called security. The SecurityOption will be a subclass of the Security abstract class in code.
Labels:
Data Model,
Design,
MySQL
Saturday, February 1, 2014
Backtesting System V2 Thoughts
During the last few months, I've been studying how to retrofit my backtesting system to to work as plug-in strategy engines for a live trading system. Commercial algorithmic systems have had a big impact on the design and architecture of the new system.
A table structure for storing the back test results was one of the first focus areas. At this time, all of the back test results are automatically dumped to CSV files at the end of each run. Three files are generated:
A table structure for storing the back test results was one of the first focus areas. At this time, all of the back test results are automatically dumped to CSV files at the end of each run. Three files are generated:
- Trade summary - performance metrics for each trade at trade closure.
- For example, if one multi-legged trade is entered per monthly expiration over a two year period, then there will be 24 summary lines in this file.
- Trade summary by day - metrics for each trade by day.
- For example, if the days in trade (DIT) is 30 then each rade will have 30 lines in this file. For two years of monthly expiration trades, there will be 24 x 30 lines in this file.
- Trade blotter - list of all of the transactions for each trade (all legs - entry, adjustment, exit).
Labels:
Backtesting,
Data Model,
Design,
MySQL
Saturday, January 25, 2014
Backtesting System V1
Most of my focus during the last year, was spent on the backtesting engine for multi-legged options strategies. Backtesting of six legged options strategies with start dates at approximately 60 DTE will run in less than two minutes for nine years worth of trades. This application:
- Is written in Java (1.7), using the following libraries:
- commons-collections-3.2.1.jar
- commons-configuration-1.9.jar
- commons-dbutils-1.5.jar
- commons-io-2.4.jar
- commons-lang-2.6.jar
- commons-logging-1.1.1.jar
- guava-14.0-rc1.jar
- joda-time-2.1.jar
- log4j-1.2.17.jar
- mysql-connector-java-5.1.22-bin.jar
- Runs in Eclipse Juno (4.2) and Keppler (4.3)
- Uses property files for strategy and database settings
- Uses data stored in MySQL (5.5.29):
- Because of the amount of historical options data, there is a table for each symbol:
- ivolatility_rut (end-of-day options data from iVolatility.com)
- ivolatility_spx (end-of-day options data from iVolatility.com)
- ...
- livevol_rut (15-minute options data from LiveVol.com)
- livevol_spx (15-minute options data from LiveVol.com)
- ...
- hod_iwm (end-of-day options data from HistoricalOptionData.com)
- hod_spy (end-of-day options data from HistoricalOptionData.com)
- ...
- Contains two utility tables:
- market_holidays
- List of market holidays: Jan-1-2000 to Dec-31-2014
- optionsexpirations
- List of monthly expirations: Jan-1-2000 to Dec-31-2014
- The historical data from iVolatility is the most current, with options data spanning from Jan-4-2006 to Dec-20-2013.
Labels:
Backtesting,
Data Model,
MySQL
Subscribe to:
Posts (Atom)