Hello everyone,
I am facing an issue using DataForm. I have an abstract class IBacktestOption and several inherited classes. Let's take only two of them : OptionCall and CallSpread. These classes share 4 arguments with IBacktestOption and have their own arguments.
Here is the IBacktestOption class :
This is OptionCall class :
This is CallSpread class :
In my view I have my DataForm declare like this :
And in my view model I initialize my Collection (I use a ViList, which is a structure almost equivalent to a simple List) with an element of OptionCall type :
When I start my application, everything is fine, I have what I want i.e. my DataForm with my 6 fields : "Strike", "ID", "Gearing", "GlobalCap", "GlobalFloor", "Nom".
In my page, I also have a RadComboBox which enables me to choose which formula I want to use. This combobox is binded to this field in my view model :
When I use the ComboBox to change the formula, a new element is added to the DataForm and here is my issue : this new element only have the fields of IBacktestOption class. And when I use Navigation buttons to go back on my first element (OptionCall), the number of fields of the element have been reduced to 4 ("Gearing", "GlobalCap", "GlobalFloor", "Nom").
I want to know if it is possible to have the fields of the inherited classes instead of the ones of IBacktestOption.
Moreover, in reality I don't need to have a list of IBacktestOption in my DataForm, I only need to have the current option (the one which is selected in the combobox). So, I have tried to empty my List when I change the option type in the combobox :
It works, I have the good number of fields for each option type. But, I need to click on the Next Item Navigation Button to reach my element. Indeed, the first one is empty. It is not really handy for a user. So, I also want to know if there is a way to click on this button automatically.
Finally, I have a last request. As, I don't really need a List for my elements, I tried to use a IBacktestOption instead of a ViList<IBacktestOption> in BactestOpt field. But I didn't manage to have fields printed in DataForm, the DataForm was empty...
Thank you very much for your help.
Regards,
Thomas
I am facing an issue using DataForm. I have an abstract class IBacktestOption and several inherited classes. Let's take only two of them : OptionCall and CallSpread. These classes share 4 arguments with IBacktestOption and have their own arguments.
Here is the IBacktestOption class :
public
abstract
class
IBacktestOption
{
#region fields
private
double
mGearing;
public
double
Gearing {
get
{
return
mGearing; }
set
{ mGearing = value; } }
private
double
? mGlobalCap;
public
double
? GlobalCap {
get
{
return
mGlobalCap; }
set
{ mGlobalCap = value; } }
private
double
? mGlobalFloor;
public
double
? GlobalFloor {
get
{
return
mGlobalFloor; }
set
{ mGlobalFloor = value; } }
public
string
Nom {
get
;
set
; }
#endregion
protected
IBacktestOption(
double
aGearing,
double
? aGlobalCap,
double
? aGlobalFloor)
{
Gearing = aGearing;
GlobalCap = aGlobalCap;
GlobalFloor = aGlobalFloor;
}
public
abstract
Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest);
public
abstract
bool
CheckOption();
}
This is OptionCall class :
class
OptionCall : IBacktestOption, IEditableObject, INotifyPropertyChanged
{
#region fields
private
double
mStrike;
public
double
Strike {
get
{
return
mStrike; }
set
{ mStrike = value; } }
OptionCallData backupOptParamData;
private
int
mID;
public
struct
OptionCallData
{
internal
int
ID;
internal
double
Strike;
internal
double
? CapGlobal;
internal
double
? FloorGlobal;
internal
double
Gearing;
}
public
int
ID
{
get
{
return
mID; }
}
#endregion Fields
#region constructors
public
static
OptionCall CreateNewOptionCall(
double
strike,
double
gearing = 1,
double
? cap =
null
,
double
? floor =
null
)
{
return
new
OptionCall(strike,gearing,cap,floor);
}
public
OptionCall(
double
strike,
double
gearing = 1,
double
? cap =
null
,
double
? floor =
null
) :
base
(gearing,cap,floor)
{
Strike = strike;
Nom =
"Call"
;
}
#endregion
public
override
Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest)
{
/* ... */
}
public
override
bool
CheckOption()
{
return
true
;
}
#region Edition
public
void
BeginEdit()
{
}
public
void
CancelEdit()
{
mStrike =
this
.backupOptParamData.Strike;
GlobalCap =
this
.backupOptParamData.CapGlobal;
GlobalFloor =
this
.backupOptParamData.FloorGlobal;
Gearing =
this
.backupOptParamData.Gearing;
}
public
void
EndEdit()
{
this
.backupOptParamData.Strike = mStrike;
this
.backupOptParamData.CapGlobal = GlobalCap;
this
.backupOptParamData.FloorGlobal = GlobalFloor;
this
.backupOptParamData.Gearing = Gearing;
}
#endregion Edition
#region Events
public
event
PropertyChangedEventHandler PropertyChanged;
private
void
NotifyPropertyChanged(
string
info)
{
if
(PropertyChanged !=
null
)
PropertyChanged(
this
,
new
PropertyChangedEventArgs(info));
}
#endregion Events
}
This is CallSpread class :
class
CallSpread : IBacktestOption, IEditableObject, INotifyPropertyChanged
{
#region fields
private
double
mStrike1;
public
double
Strike1 {
get
{
return
mStrike1; }
set
{ mStrike1 = value; } }
private
double
mStrike2;
public
double
Strike2 {
get
{
return
mStrike2; }
set
{ mStrike2 = value; } }
OptionCallData backupOptParamData;
private
int
mID;
public
struct
OptionCallData
{
internal
int
ID;
internal
double
Strike1;
internal
double
Strike2;
internal
double
? CapGlobal;
internal
double
? FloorGlobal;
internal
double
Gearing;
}
public
int
ID
{
get
{
return
mID; }
}
#endregion Fields
#region constructors
public
static
CallSpread CreateNewCallSpread(
double
strike1,
double
strike2,
double
gearing = 1,
double
? cap =
null
,
double
? floor =
null
)
{
return
new
CallSpread(strike1, strike2, gearing, cap, floor);
}
public
CallSpread(
double
strike1,
double
strike2,
double
gearing = 1,
double
? cap =
null
,
double
? floor =
null
) :
base
(gearing,cap,floor)
{
Strike1 = Math.Min(strike1, strike2);
Strike2 = Math.Max(strike1, strike2);
Nom =
"Call Spread"
;
}
#endregion
public
override
Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest)
{
/* ... */
}
public
override
bool
CheckOption()
{
return
true
;
}
#region Edition
public
void
BeginEdit()
{
}
public
void
CancelEdit()
{
mStrike1 =
this
.backupOptParamData.Strike1;
mStrike2 =
this
.backupOptParamData.Strike2;
GlobalCap =
this
.backupOptParamData.CapGlobal;
GlobalFloor =
this
.backupOptParamData.FloorGlobal;
Gearing =
this
.backupOptParamData.Gearing;
}
public
void
EndEdit()
{
this
.backupOptParamData.Strike1 = mStrike1;
this
.backupOptParamData.Strike2 = mStrike2;
this
.backupOptParamData.CapGlobal = GlobalCap;
this
.backupOptParamData.FloorGlobal = GlobalFloor;
this
.backupOptParamData.Gearing = Gearing;
}
#endregion Edition
#region Events
public
event
PropertyChangedEventHandler PropertyChanged;
private
void
NotifyPropertyChanged(
string
info)
{
if
(PropertyChanged !=
null
)
PropertyChanged(
this
,
new
PropertyChangedEventArgs(info));
}
#endregion Events
}
In my view I have my DataForm declare like this :
<
telerik:RadDataForm
Grid.Column
=
"1"
Margin
=
"12,0,6,21"
Grid.ColumnSpan
=
"2"
HorizontalContentAlignment
=
"Stretch"
VerticalContentAlignment
=
"Stretch"
ItemsSource
=
"{Binding BacktestOpt}"
CommandButtonsVisibility
=
"Cancel,Commit,Edit,Navigation"
Grid.Row
=
"1"
Height
=
"456"
Grid.RowSpan
=
"2"
/>
And in my view model I initialize my Collection (I use a ViList, which is a structure almost equivalent to a simple List) with an element of OptionCall type :
private
ViList<IBacktestOption> mBacktestOpt;
public
ViList<IBacktestOption> BacktestOpt
{
get
{
if
(mBacktestOpt ==
null
&& Formule == 0)
{
ViList<IBacktestOption> newBacktestOpt =
new
ViList<IBacktestOption>();
newBacktestOpt.Add(Creators.CreateNewOptionCall(0));
this
.mBacktestOpt =
new
ViList<IBacktestOption>(newBacktestOpt);
Formule = PayoffFormule.CALL;
}
return
mBacktestOpt;
}
set
{
mBacktestOpt = value;
OnPropertyChanged(
"BacktestOpt"
);
}
}
When I start my application, everything is fine, I have what I want i.e. my DataForm with my 6 fields : "Strike", "ID", "Gearing", "GlobalCap", "GlobalFloor", "Nom".
In my page, I also have a RadComboBox which enables me to choose which formula I want to use. This combobox is binded to this field in my view model :
private
PayoffFormule mFormule;
public
PayoffFormule Formule
{
get
{
return
mFormule; }
set
{
mFormule = value;
switch
(mFormule)
{
case
PayoffFormule.CALL :
Backtest.Option = Creators.CreateNewOptionCall(0);
break
;
case
PayoffFormule.PUT :
Backtest.Option = Creators.CreateNewOptionPut(0);
break
;
case
PayoffFormule.ASIAN_CALL:
Backtest.Option = Creators.CreateNewAsianCall(0);
break
;
case
PayoffFormule.ASIAN_PUT:
Backtest.Option = Creators.CreateNewAsianPut(0);
break
;
case
PayoffFormule.CALL_SPREAD:
Backtest.Option = Creators.CreateNewCallSpread(0,0.15);
break
;
default
:
break
;
}
BacktestOpt.Add(Backtest.Option);
OnPropertyChanged(
"BacktestOpt"
);
OnPropertyChanged(
"Formule"
);
}
}
When I use the ComboBox to change the formula, a new element is added to the DataForm and here is my issue : this new element only have the fields of IBacktestOption class. And when I use Navigation buttons to go back on my first element (OptionCall), the number of fields of the element have been reduced to 4 ("Gearing", "GlobalCap", "GlobalFloor", "Nom").
I want to know if it is possible to have the fields of the inherited classes instead of the ones of IBacktestOption.
Moreover, in reality I don't need to have a list of IBacktestOption in my DataForm, I only need to have the current option (the one which is selected in the combobox). So, I have tried to empty my List when I change the option type in the combobox :
private
PayoffFormule mFormule;
public
PayoffFormule Formule
{
get
{
return
mFormule; }
set
{
mFormule = value;
BacktestOpt.RemoveAt(0);
switch
(mFormule)
{
case
PayoffFormule.CALL :
Backtest.Option = Creators.CreateNewOptionCall(0);
break
;
case
PayoffFormule.PUT :
Backtest.Option = Creators.CreateNewOptionPut(0);
break
;
case
PayoffFormule.ASIAN_CALL:
Backtest.Option = Creators.CreateNewAsianCall(0);
break
;
case
PayoffFormule.ASIAN_PUT:
Backtest.Option = Creators.CreateNewAsianPut(0);
break
;
case
PayoffFormule.CALL_SPREAD:
Backtest.Option = Creators.CreateNewCallSpread(0,0.15);
break
;
default
:
break
;
}
BacktestOpt.Add(Backtest.Option);
OnPropertyChanged(
"BacktestOpt"
);
OnPropertyChanged(
"Formule"
);
}
}
It works, I have the good number of fields for each option type. But, I need to click on the Next Item Navigation Button to reach my element. Indeed, the first one is empty. It is not really handy for a user. So, I also want to know if there is a way to click on this button automatically.
Finally, I have a last request. As, I don't really need a List for my elements, I tried to use a IBacktestOption instead of a ViList<IBacktestOption> in BactestOpt field. But I didn't manage to have fields printed in DataForm, the DataForm was empty...
Thank you very much for your help.
Regards,
Thomas